Boulder: Write minimal CFSSL replacement inside boulder

Created on 26 Jun 2020  路  1Comment  路  Source: letsencrypt/boulder

This audit by Andrew Ayer raises some good points about the complexity of CFSSL leading to a variety of gotchas, footguns, and unexpected or undesired behavior: https://www.agwa.name/blog/post/security_review_of_cfssl_signer_code. In particular, the logic around what SANs are written into the final cert is quite complex.

We use a pretty minimal subset of CFSSL, based on the limited variety of certs that we issue. For example, I don't believe we care about the notBefore and notAfter fields included in the CSR, as we issue 90-day certs. Similarly, I believe we have rules around what SANs we put in the final cert, although I don't personally know exactly what those are (only names ACME has validated?).

We should look into pulling this functionality directly into boulder, with a slimmer, more obviously-correct design.

areca

Most helpful comment

Very basic sketch of a much smaller API

type IssuanceRequest struct {
    PublicKey          []byte
    SignatureAlgorithm x509.SignatureAlgorithm

    Serial []byte

    DNSNames []string
    // IPAddresses []net.IP

    IncludeMustStaple bool
    IncludeCTPoison   bool
    IncludeSCTList    []byte
}

type Signer struct {
    issuer *x509.Certiifcate
    signer crypto.Signer
    profile struct {
        allowedKeyTypes            map[keyType]bool
        allowedSignatureAlgorithms map[x509.SignatureAlgorithm]bool

        allowDNSNames bool
        // allowIPAddresses bool

        allowMustStaple bool
        allowCTPoison   bool
        allowSCTList    bool

        // -----
        keyUsage       x509.KeyUsage
        extKeyUsage    []x509.ExtKeyUsage
        ocspURL        string
        crlURL         string
        issuerURL      string
        policies       []PolicyInformation
        validityPeriod time.Duration // could also be set in IssuanceRequest with a min/max bound in profile
        // ----- or -----
        template *x509.Certificate
        // -----
    }
}

func (s Signer) Issue(req IssuanceRequest) ([]byte, error)

>All comments

Very basic sketch of a much smaller API

type IssuanceRequest struct {
    PublicKey          []byte
    SignatureAlgorithm x509.SignatureAlgorithm

    Serial []byte

    DNSNames []string
    // IPAddresses []net.IP

    IncludeMustStaple bool
    IncludeCTPoison   bool
    IncludeSCTList    []byte
}

type Signer struct {
    issuer *x509.Certiifcate
    signer crypto.Signer
    profile struct {
        allowedKeyTypes            map[keyType]bool
        allowedSignatureAlgorithms map[x509.SignatureAlgorithm]bool

        allowDNSNames bool
        // allowIPAddresses bool

        allowMustStaple bool
        allowCTPoison   bool
        allowSCTList    bool

        // -----
        keyUsage       x509.KeyUsage
        extKeyUsage    []x509.ExtKeyUsage
        ocspURL        string
        crlURL         string
        issuerURL      string
        policies       []PolicyInformation
        validityPeriod time.Duration // could also be set in IssuanceRequest with a min/max bound in profile
        // ----- or -----
        template *x509.Certificate
        // -----
    }
}

func (s Signer) Issue(req IssuanceRequest) ([]byte, error)
Was this page helpful?
0 / 5 - 0 ratings