martinisecurity / zlint

X.509 Certificate Linter focused on Web PKI standards and requirements.
https://zmap.io
Apache License 2.0
0 stars 0 forks source link

SHAKEN CP v1.4 #9

Closed microshine closed 11 months ago

microshine commented 1 year ago

Here is Key Sizes implementation which implements two rules.

https://github.com/martinisecurity/zlint/pull/9/files#diff-354aa65e58c7f9915206f679673c1890ac05ced2c326387b26bfcfed77404eb6

I asked ChatGPT to unify the rules into the single rule, and here is the result. Maybe this scenario is better because it allows using the same Rule ID for different CP versions validation.

@rmhrisk What do you think?

package shaken

import (
    "github.com/zmap/zcrypto/encoding/asn1"
    "github.com/zmap/zcrypto/x509"
    "github.com/zmap/zlint/v3/lint"
    "github.com/zmap/zlint/v3/util"
)

var (
    ecdsaWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
    ecdsaWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
)

type shakenKeySizeLint struct{}

func init() {
    lint.RegisterLint(&lint.Lint{
        Name: "e_shaken_cp_key_size",
        Description: "Verifies key size requirements for various SHAKEN CP versions",
        Citation: "SHAKEN CP Section 6.1.5 for v1.1 through v1.4",
        Source: lint.UnitedStatesSHAKENCP,
        EffectiveDate: util.SpecificDate(2020, 4, 7), // This can be the earliest effective date
        Lint: NewShakenKeySizeLint,
    })
}

func NewShakenKeySizeLint() lint.LintInterface {
    return &shakenKeySizeLint{}
}

func (l *shakenKeySizeLint) CheckApplies(c *x509.Certificate) bool {
    return util.HasPolicyIdentifierOID(c, util.ShakenCPv1_1OID) ||
        util.HasPolicyIdentifierOID(c, util.ShakenCPv1_2OID) ||
        util.HasPolicyIdentifierOID(c, util.ShakenCPv1_3OID) ||
        util.HasPolicyIdentifierOID(c, util.ShakenCPv1_4OID)
}

func (l *shakenKeySizeLint) Execute(c *x509.Certificate) *lint.LintResult {
    if util.HasPolicyIdentifierOID(c, util.ShakenCPv1_1OID) || 
       util.HasPolicyIdentifierOID(c, util.ShakenCPv1_2OID) ||
       util.HasPolicyIdentifierOID(c, util.ShakenCPv1_3OID) {

        if !c.SignatureAlgorithmOID.Equal(ecdsaWithSHA256) {
            return &lint.LintResult{
                Status:  lint.Error,
                Details: "STI certificates under CP v1.1 to v1.3 shall use the ECDSA with SHA-256 algorithm when generating digital signatures",
            }
        }
    } else if util.HasPolicyIdentifierOID(c, util.ShakenCPv1_4OID) {
        if !c.SignatureAlgorithmOID.Equal(ecdsaWithSHA256) && !c.SignatureAlgorithmOID.Equal(ecdsaWithSHA384) {
            return &lint.LintResult{
                Status:  lint.Error,
                Details: "STI certificates under CP v1.4 shall use the ECDSA with SHA-256 or ECDSA with SHA-384 algorithm when generating digital signatures",
            }
        }
    }

    return &lint.LintResult{
        Status: lint.Pass,
    }
}