cloudflare / go

Go with Cloudflare experimental patches
BSD 3-Clause "New" or "Revised" License
328 stars 48 forks source link

Incorrect PublicKeyAlgorithm.String() of x509.EdDilithium3 in parsed certificate #175

Closed y12studio closed 3 months ago

y12studio commented 3 months ago

Description:

The ParseCertificate function is generating a certificate with incorrect PublicKeyAlgorithm.String() values.

Steps to reproduce:

  1. Run the TestCreateCert test in the app_test.go file.
  2. Observe the test failure with the error message indicating that the PublicKeyAlgorithm.String() values do not match the expected values.

Expected result:

The ParseCertificate function should generate a certificate with PublicKeyAlgorithm.String() set to Ed448-Dilithium3.

Actual result:

The ParseCertificate function generates a certificate with PublicKeyAlgorithm.String() set to Ed25519-Dilithium3.

Code snippet:

The relevant code snippet is:

https://github.com/cloudflare/circl/blob/75b28edc25ec569e6353a2b944b0b83d48a9c2e8/sign/eddilithium3/eddilithium.go#L31

// PublicKey is the type of an EdDilithium3 public key.
type PublicKey struct {
    e ed448.PublicKey
    d mode3.PublicKey
}

app.go

func CreateCert() ([]byte, error) {
    scheme := x509.CirclSchemeByPublicKeyAlgorithm(x509.EdDilithium3)
    pk, sk, err := scheme.GenerateKey()
    if err != nil {
        return nil, err
    }
    serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
    serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
    notBefore := time.Now()
    notAfter := notBefore.Add(365 * 24 * time.Hour)

    template := &x509.Certificate{
        SerialNumber: serialNumber,
        Subject: pkix.Name{
            Organization: []string{"Foo 1983"},
        },
        NotBefore:             notBefore,
        NotAfter:              notAfter,
        KeyUsage:              x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
        ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
        BasicConstraintsValid: true,
    }

    cert, err := x509.CreateCertificate(rand.Reader, template, template, pk, sk)
    return cert, err
}

app_test.go

func TestCreateCert(t *testing.T) {
    assert := assert.New(t)
    cert, _ := CreateCert()
    parsedCert, _ := x509.ParseCertificate(cert)
    assert.Equal("Foo 1983", parsedCert.Subject.Organization[0], "Organization should be Foo 1983")
    assert.Equal(x509.SignatureAlgorithm(17), parsedCert.SignatureAlgorithm, "SignatureAlgorithm should be x509.SignatureAlgorithm(17)")
    assert.Equal("Ed448-Dilithium3", parsedCert.SignatureAlgorithm.String(), "SignatureAlgorithm should be Ed448-Dilithium3")
    assert.Equal(x509.PublicKeyAlgorithm(5), parsedCert.PublicKeyAlgorithm, "PublicKeyAlgorithm should be x509.PublicKeyAlgorithm(5)")
    assert.Equal("Ed448-Dilithium3", parsedCert.PublicKeyAlgorithm.String(), "PublicKeyAlgorithm should be Ed448-Dilithium3")
}

go test

--- FAIL: TestCreateCert (0.00s)
                Error:          Not equal: 
                                expected: "Ed448-Dilithium3"
                                actual  : "Ed25519-Dilithium3"
                Test:           TestCreateCert
                Messages:       PublicKeyAlgorithm should be Ed448-Dilithium3
bwesterb commented 3 months ago

Thanks for this. We didn't properly update this Go fork after we updated our Dilithium implementation in CIRCL. Dilithium3 was renamed to Dilithium2. I'll create a fix.