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. • 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
  2. • 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
  3. • 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
  4. • 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
  5. • 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)
  6. • 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
  7. • 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)
  8. • 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
  9. • 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