Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GopherCon 2019 Review: PKI for Gophers

Hunter
August 20, 2019

GopherCon 2019 Review: PKI for Gophers

A summary of how to implement PKI in golang

Hunter

August 20, 2019
Tweet

Other Decks in Programming

Transcript

  1. GopherCon 2019 Review: PKI
    for Gophers
    Hunter Chen

    View full-size slide

  2. ● Original Presenter: Eric Chiang
    ● Original Slides: https://t.co/xZZSxNF8l3
    ○ Code Samples
    ○ Brief explanation of security concepts
    ● Liveblog of the Presentation:
    https://about.sourcegraph.com/go/gophercon-2019-pki-for-gophers
    ● Video will be posted in the future (along with all the other talks at GopherCon 2019):
    https://www.youtube.com/channel/UCx9QVEApa5BKLw9r8cnOFEA/feed
    Original Presentation

    View full-size slide

  3. ● ECDSA Package:
    func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)
    func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool
    type PrivateKey
    func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error)
    func (priv *PrivateKey) Public() crypto.PublicKey
    func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)
    type PublicKey
    ● Elliptic Package
    ● SHA512 Package
    ● Generate Key → Hash → Sign → Verify
    ● Note: When generating, use crypto/rand, not math/rand
    Digital Signatures

    View full-size slide

  4. ● X509 Package:
    func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte,
    err error)
    func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error)
    type Certificate
    func ParseCertificate(asn1Data []byte) (*Certificate, error)
    func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error
    func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error)

    ● Generate Key → Create Cert Template → Create Cert → Marshal Key
    → Encode Key and Cert
    ● Go marshals the key into DER format
    ● PEM Package
    Certificates

    View full-size slide

  5. ● Serving Certificates:
    ○ Generate certificate
    ○ Use TLS Package to load certificate and private key as TLS certificate
    ○ Pass TLS certificate into TLSConfig when creating server
    ○ Configure Client to trust server
    ■ add certificate into pool
    ● Client Certificates:
    ○ Same process
    ■ Generate certificate
    ■ Create TLS certificate
    ■ Pass TLS certificate into client config when creating client
    ■ Configure server to authenticate clients
    ● Also add client CA into pool
    Serving Certificates and Client Certificates

    View full-size slide

  6. ● Making Requests
    ○ X509 Package
    func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{})
    (csr []byte, err error)
    type CertificateRequest
    func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error)
    func (c *CertificateRequest) CheckSignature() error
    ○ Generate Key → Create Request → Send Request
    ○ Parse Request → Check Signature → Create Certificate → Send Certificate
    ● Authentication (With JWTs)
    ○ Get JWT from header of request → Parse → Verify with CA
    ■ Many different packages and ways to verify JWT. Pick your favorite
    Certificate Signing Requests (CSRs)

    View full-size slide

  7. ● Not that good
    ○ Fails open
    ○ Better for smaller number of certifications
    ● Use OCSP instead
    ○ In the TLS Package
    ■ Certificate struct has a OCSPStaple []byte field
    ○ Create OCSPResponse using OCSP Package under /x/crypto
    func CreateResponse(issuer, responderCert *x509.Certificate, template Response, priv
    crypto.Signer) ([]byte, error)
    type Response
    func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error)
    func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error)
    ○ Create Response → Send Response
    ○ For reading OCSP
    ■ Loop through certificate chain → Parse each OCSP Response
    Certificate Revocation Lists (CRLs) and OCSPs

    View full-size slide

  8. ● Just set the GetCertificate field in the TLS config
    ○ Pass a function with a switch statement for each domain
    ○ Return the corresponding certificate for each domain
    ● Go does not support encrypted SNIs
    Server Name Identification (SNIs)

    View full-size slide

  9. ● Golang supports hardware keys
    ○ tls.Certificate has a field called PrivateKey
    ○ Use manufacturer libraries to pass the interface into the
    CreateCertificateRequest method
    ■ Example: YubiKey
    ● pault.ag/go/ykpiv
    ● yk.GenerateECWithPolicies
    ● Pass into x509.CreateCertificateRequest
    ● Or, pass into field PrivateKey when creating tls.Certificate
    Hardware Keys

    View full-size slide

  10. ● Logs every certificate signed by an authority
    ● Make a request to CT endpoint
    ○ https://ct.googleapis.com/pilot
    ● Use CT Client to make request
    ○ Client Package
    type LogClient
    func New(uri string, hc *http.Client, opts jsonclient.Options) (*LogClient, error)
    func (c *LogClient) GetEntries(ctx context.Context, start, end int64) ([]ct.LogEntry, error)
    func (c *LogClient) GetSTH(ctx context.Context) (*ct.SignedTreeHead, error)
    ○ Make new Client → Get STH → Get Entries
    Certificate Transparency

    View full-size slide

  11. Thank you!
    Finished!

    View full-size slide