@@ -6,6 +6,7 @@ package x509
66
77import (
88 "crypto"
9+ "crypto/dsa"
910 "crypto/ecdsa"
1011 "crypto/elliptic"
1112 "crypto/rand"
@@ -2837,3 +2838,129 @@ func TestVerifyBareWildcard(t *testing.T) {
28372838 t .Fatalf ("VerifyHostname unexpected success with bare wildcard SAN" )
28382839 }
28392840}
2841+
2842+ func TestCertificateChainSignedByECDSA (t * testing.T ) {
2843+ caKey , err := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
2844+ if err != nil {
2845+ t .Fatal (err )
2846+ }
2847+ root := & Certificate {
2848+ SerialNumber : big .NewInt (1 ),
2849+ Subject : pkix.Name {CommonName : "X" },
2850+ NotBefore : time .Now ().Add (- time .Hour ),
2851+ NotAfter : time .Now ().Add (365 * 24 * time .Hour ),
2852+ IsCA : true ,
2853+ KeyUsage : KeyUsageCertSign | KeyUsageCRLSign ,
2854+ BasicConstraintsValid : true ,
2855+ }
2856+ caDER , err := CreateCertificate (rand .Reader , root , root , & caKey .PublicKey , caKey )
2857+ if err != nil {
2858+ t .Fatal (err )
2859+ }
2860+ root , err = ParseCertificate (caDER )
2861+ if err != nil {
2862+ t .Fatal (err )
2863+ }
2864+
2865+ leafKey , _ := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
2866+ leaf := & Certificate {
2867+ SerialNumber : big .NewInt (42 ),
2868+ Subject : pkix.Name {CommonName : "leaf" },
2869+ NotBefore : time .Now ().Add (- 10 * time .Minute ),
2870+ NotAfter : time .Now ().Add (24 * time .Hour ),
2871+ KeyUsage : KeyUsageDigitalSignature ,
2872+ ExtKeyUsage : []ExtKeyUsage {ExtKeyUsageServerAuth },
2873+ BasicConstraintsValid : true ,
2874+ }
2875+ leafDER , err := CreateCertificate (rand .Reader , leaf , root , & leafKey .PublicKey , caKey )
2876+ if err != nil {
2877+ t .Fatal (err )
2878+ }
2879+ leaf , err = ParseCertificate (leafDER )
2880+ if err != nil {
2881+ t .Fatal (err )
2882+ }
2883+
2884+ inter , err := ParseCertificate (dsaSelfSignedCNX (t ))
2885+ if err != nil {
2886+ t .Fatal (err )
2887+ }
2888+
2889+ inters := NewCertPool ()
2890+ inters .AddCert (root )
2891+ inters .AddCert (inter )
2892+
2893+ wantErr := "certificate signed by unknown authority"
2894+ _ , err = leaf .Verify (VerifyOptions {Intermediates : inters , Roots : NewCertPool ()})
2895+ if ! strings .Contains (err .Error (), wantErr ) {
2896+ t .Errorf ("got %v, want %q" , err , wantErr )
2897+ }
2898+ }
2899+
2900+ // dsaSelfSignedCNX produces DER-encoded
2901+ // certificate with the properties:
2902+ //
2903+ // Subject=Issuer=CN=X
2904+ // DSA SPKI
2905+ // Matching inner/outer signature OIDs
2906+ // Dummy ECDSA signature
2907+ func dsaSelfSignedCNX (t * testing.T ) []byte {
2908+ t .Helper ()
2909+ var params dsa.Parameters
2910+ if err := dsa .GenerateParameters (& params , rand .Reader , dsa .L1024N160 ); err != nil {
2911+ t .Fatal (err )
2912+ }
2913+
2914+ var dsaPriv dsa.PrivateKey
2915+ dsaPriv .Parameters = params
2916+ if err := dsa .GenerateKey (& dsaPriv , rand .Reader ); err != nil {
2917+ t .Fatal (err )
2918+ }
2919+ dsaPub := & dsaPriv .PublicKey
2920+
2921+ type dsaParams struct { P , Q , G * big.Int }
2922+ paramDER , err := asn1 .Marshal (dsaParams {dsaPub .P , dsaPub .Q , dsaPub .G })
2923+ if err != nil {
2924+ t .Fatal (err )
2925+ }
2926+ yDER , err := asn1 .Marshal (dsaPub .Y )
2927+ if err != nil {
2928+ t .Fatal (err )
2929+ }
2930+
2931+ spki := publicKeyInfo {
2932+ Algorithm : pkix.AlgorithmIdentifier {
2933+ Algorithm : oidPublicKeyDSA ,
2934+ Parameters : asn1.RawValue {FullBytes : paramDER },
2935+ },
2936+ PublicKey : asn1.BitString {Bytes : yDER , BitLength : 8 * len (yDER )},
2937+ }
2938+
2939+ rdn := pkix.Name {CommonName : "X" }.ToRDNSequence ()
2940+ b , err := asn1 .Marshal (rdn )
2941+ if err != nil {
2942+ t .Fatal (err )
2943+ }
2944+ rawName := asn1.RawValue {FullBytes : b }
2945+
2946+ algoIdent := pkix.AlgorithmIdentifier {Algorithm : oidSignatureDSAWithSHA256 }
2947+ tbs := tbsCertificate {
2948+ Version : 0 ,
2949+ SerialNumber : big .NewInt (1002 ),
2950+ SignatureAlgorithm : algoIdent ,
2951+ Issuer : rawName ,
2952+ Validity : validity {NotBefore : time .Now ().Add (- time .Hour ), NotAfter : time .Now ().Add (24 * time .Hour )},
2953+ Subject : rawName ,
2954+ PublicKey : spki ,
2955+ }
2956+ c := certificate {
2957+ TBSCertificate : tbs ,
2958+ SignatureAlgorithm : algoIdent ,
2959+ SignatureValue : asn1.BitString {Bytes : []byte {0 }, BitLength : 8 },
2960+ }
2961+ dsaDER , err := asn1 .Marshal (c )
2962+ if err != nil {
2963+ t .Fatal (err )
2964+ }
2965+ return dsaDER
2966+ }
0 commit comments