Skip to content

Commit

Permalink
Allow self-signed ca certs with EcDSA and Ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
cviecco committed Jun 4, 2024
1 parent efb227d commit ff06b61
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 37 deletions.
43 changes: 29 additions & 14 deletions lib/certgen/certgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
Expand Down Expand Up @@ -200,20 +201,30 @@ func GetSignerFromPEMBytes(privateKey []byte) (crypto.Signer, error) {
}
}

// copied from https://golang.org/src/crypto/tls/generate_cert.go
func publicKey(priv interface{}) interface{} {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &k.PublicKey
case *ecdsa.PrivateKey:
return &k.PublicKey
case ed25519.PrivateKey:
return k.Public().(ed25519.PublicKey)
case *ed25519.PrivateKey:
return k.Public().(*ed25519.PublicKey)
func getSignerHashFromPublic(pub interface{}) (crypto.Hash, error) {
// crypto.SHA256
switch pub := pub.(type) {
case *rsa.PublicKey:
return crypto.SHA256, nil
case *ecdsa.PublicKey:
switch pub.Curve {
case elliptic.P224(), elliptic.P256():
return crypto.SHA256, nil

Check warning on line 212 in lib/certgen/certgen.go

View check run for this annotation

Codecov / codecov/patch

lib/certgen/certgen.go#L211-L212

Added lines #L211 - L212 were not covered by tests
case elliptic.P384():
return crypto.SHA384, nil
case elliptic.P521():
return crypto.SHA512, nil
default:
return 0, fmt.Errorf("x509: unknown elliptic curve")

Check warning on line 218 in lib/certgen/certgen.go

View check run for this annotation

Codecov / codecov/patch

lib/certgen/certgen.go#L215-L218

Added lines #L215 - L218 were not covered by tests
}
//Ed25519 signatures (by default) dont have a prefered signer
case *ed25519.PublicKey, ed25519.PublicKey:
return 0, nil

default:
return nil
return 0, fmt.Errorf("unknown key type")

Check warning on line 225 in lib/certgen/certgen.go

View check run for this annotation

Codecov / codecov/patch

lib/certgen/certgen.go#L225

Added line #L225 was not covered by tests
}

}

// ValidatePublicKeyStrenght checks if the "strength" of the key is good enough to be considered secure
Expand Down Expand Up @@ -268,7 +279,11 @@ func GenSelfSignedCACert(commonName string, organization string, caPriv crypto.S
return nil, err
}
sum := sha256.Sum256([]byte(commonName))
signedCN, err := caPriv.Sign(rand.Reader, sum[:], crypto.SHA256)
hashfunc, err := getSignerHashFromPublic(caPriv.Public())
if err != nil {
return nil, err

Check warning on line 284 in lib/certgen/certgen.go

View check run for this annotation

Codecov / codecov/patch

lib/certgen/certgen.go#L284

Added line #L284 was not covered by tests
}
signedCN, err := caPriv.Sign(rand.Reader, sum[:], hashfunc)
if err != nil {
return nil, err
}
Expand All @@ -289,7 +304,7 @@ func GenSelfSignedCACert(commonName string, organization string, caPriv crypto.S
IsCA: true,
}

return x509.CreateCertificate(rand.Reader, &template, &template, publicKey(caPriv), caPriv)
return x509.CreateCertificate(rand.Reader, &template, &template, caPriv.Public(), caPriv)
}

// From RFC 4120 section 5.2.2 (https://tools.ietf.org/html/rfc4120)
Expand Down
49 changes: 26 additions & 23 deletions lib/certgen/certgen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,32 +540,35 @@ func TestGenx509CertGoodWithRealm(t *testing.T) {

// GenSelfSignedCACert
func TestGenSelfSignedCACertGood(t *testing.T) {
caPriv, err := GetSignerFromPEMBytes([]byte(testSignerPrivateKey))
if err != nil {
t.Fatal(err)
}
derCACert, err := GenSelfSignedCACert("some hostname", "some organization", caPriv)
if err != nil {
t.Fatal(err)
}
validPemKeys := []string{testSignerPrivateKey, pkcs8ecPrivateKey, pkcs8Ed25519PrivateKey}
for _, signerPem := range validPemKeys {
caPriv, err := GetSignerFromPEMBytes([]byte(signerPem))
if err != nil {
t.Fatal(err)
}
derCACert, err := GenSelfSignedCACert("some hostname", "some organization", caPriv)
if err != nil {
t.Fatal(err)
}

cert, pemCert, err := derBytesCertToCertAndPem(derCACert)
if err != nil {
t.Fatal(err)
}
t.Logf("got '%s'", pemCert)
cert, pemCert, err := derBytesCertToCertAndPem(derCACert)
if err != nil {
t.Fatal(err)
}
t.Logf("got '%s'", pemCert)

// Now we use it to generate a user Cert
userPub, err := getPubKeyFromPem(testUserPEMPublicKey)
if err != nil {
t.Fatal(err)
}
_, err = GenUserX509Cert("username", userPub, cert, caPriv, nil,
testDuration, nil, nil, nil, testlogger.New(t))
if err != nil {
t.Fatal(err)
// Now we use it to generate a user Cert
userPub, err := getPubKeyFromPem(testUserPEMPublicKey)
if err != nil {
t.Fatal(err)
}
_, err = GenUserX509Cert("username", userPub, cert, caPriv, nil,
testDuration, nil, nil, nil, testlogger.New(t))
if err != nil {
t.Fatal(err)
}
//t.Logf("got '%s'", certString)
}
//t.Logf("got '%s'", certString)

}

Expand Down

0 comments on commit ff06b61

Please sign in to comment.