Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: fork google/martian/v3/mitm to build expired certs (#37)
To move forward with ooni/probe#1803, I want to generate expired certificates. To this end, I have forked the mitm package to peek into internals and further customize certificate generation. I forked at google/martian@19163e1. The diff between the original code and my code is the following: ```diff --- mitmx/mitm.go.orig 2023-09-06 10:42:30 +++ mitmx/mitmx.go 2023-09-06 10:46:28 @@ -12,10 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package mitm provides tooling for MITMing TLS connections. It provides +// Package mitmx provides tooling for MITMing TLS connections. It provides // tooling to create CA certs and generate TLS configs that can be used to MITM // a TLS connection with a provided CA certificate. -package mitm +// +// This package is a fork of the mitm package in github.com/google/martian/v3. +package mitmx import ( "bytes" @@ -51,7 +53,6 @@ validity time.Duration org string h2Config *h2.Config - getCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error) roots *x509.CertPool skipVerify bool handshakeErrorCallback func(*http.Request, error) @@ -63,6 +64,12 @@ // NewAuthority creates a new CA certificate and associated // private key. func NewAuthority(name, organization string, validity time.Duration) (*x509.Certificate, *rsa.PrivateKey, error) { + return NewAuthorityWithTimeNow(name, organization, validity, time.Now) +} + +// NewAuthorityWithTimeNow is like NewAuthority but allows to customize the time.Now func +func NewAuthorityWithTimeNow( + name, organization string, validity time.Duration, timeNow func() time.Time) (*x509.Certificate, *rsa.PrivateKey, error) { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, err @@ -96,8 +103,8 @@ KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, - NotBefore: time.Now().Add(-validity), - NotAfter: time.Now().Add(validity), + NotBefore: timeNow().Add(-validity), + NotAfter: timeNow().Add(validity), DNSNames: []string{name}, IsCA: true, } @@ -260,7 +267,22 @@ } log.Debugf("mitm: cache miss for %s", hostname) + + tlsc, err = c.NewCertWithoutCacheWithTimeNow(hostname, time.Now) + if err != nil { + return nil, err + } + c.certmu.Lock() + c.certs[hostname] = tlsc + c.certmu.Unlock() + + return tlsc, nil +} + +// NewCertWithoutCacheWithTimeNow is the most fundamental building block for building a certificate +// that completely bypasses caching and allows for setting a custom time.Now func. +func (c *Config) NewCertWithoutCacheWithTimeNow(hostname string, timeNow func() time.Time) (*tls.Certificate, error) { serial, err := rand.Int(rand.Reader, MaxSerialNumber) if err != nil { return nil, err @@ -276,8 +298,8 @@ KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, - NotBefore: time.Now().Add(-c.validity), - NotAfter: time.Now().Add(c.validity), + NotBefore: timeNow().Add(-c.validity), + NotAfter: timeNow().Add(c.validity), } if ip := net.ParseIP(hostname); ip != nil { @@ -297,15 +319,11 @@ return nil, err } - tlsc = &tls.Certificate{ + tlsc := &tls.Certificate{ Certificate: [][]byte{raw, c.ca.Raw}, PrivateKey: c.priv, Leaf: x509c, } - c.certmu.Lock() - c.certs[hostname] = tlsc - c.certmu.Unlock() - return tlsc, nil } ```
- Loading branch information