@@ -6,6 +6,7 @@ package x509
6
6
7
7
import (
8
8
"crypto"
9
+ "crypto/dsa"
9
10
"crypto/ecdsa"
10
11
"crypto/elliptic"
11
12
"crypto/rand"
@@ -3048,3 +3049,129 @@ func TestInvalidPolicyWithAnyKeyUsage(t *testing.T) {
3048
3049
t .Fatalf ("unexpected error, got %q, want %q" , err , expectedErr )
3049
3050
}
3050
3051
}
3052
+
3053
+ func TestCertificateChainSignedByECDSA (t * testing.T ) {
3054
+ caKey , err := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
3055
+ if err != nil {
3056
+ t .Fatal (err )
3057
+ }
3058
+ root := & Certificate {
3059
+ SerialNumber : big .NewInt (1 ),
3060
+ Subject : pkix.Name {CommonName : "X" },
3061
+ NotBefore : time .Now ().Add (- time .Hour ),
3062
+ NotAfter : time .Now ().Add (365 * 24 * time .Hour ),
3063
+ IsCA : true ,
3064
+ KeyUsage : KeyUsageCertSign | KeyUsageCRLSign ,
3065
+ BasicConstraintsValid : true ,
3066
+ }
3067
+ caDER , err := CreateCertificate (rand .Reader , root , root , & caKey .PublicKey , caKey )
3068
+ if err != nil {
3069
+ t .Fatal (err )
3070
+ }
3071
+ root , err = ParseCertificate (caDER )
3072
+ if err != nil {
3073
+ t .Fatal (err )
3074
+ }
3075
+
3076
+ leafKey , _ := ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
3077
+ leaf := & Certificate {
3078
+ SerialNumber : big .NewInt (42 ),
3079
+ Subject : pkix.Name {CommonName : "leaf" },
3080
+ NotBefore : time .Now ().Add (- 10 * time .Minute ),
3081
+ NotAfter : time .Now ().Add (24 * time .Hour ),
3082
+ KeyUsage : KeyUsageDigitalSignature ,
3083
+ ExtKeyUsage : []ExtKeyUsage {ExtKeyUsageServerAuth },
3084
+ BasicConstraintsValid : true ,
3085
+ }
3086
+ leafDER , err := CreateCertificate (rand .Reader , leaf , root , & leafKey .PublicKey , caKey )
3087
+ if err != nil {
3088
+ t .Fatal (err )
3089
+ }
3090
+ leaf , err = ParseCertificate (leafDER )
3091
+ if err != nil {
3092
+ t .Fatal (err )
3093
+ }
3094
+
3095
+ inter , err := ParseCertificate (dsaSelfSignedCNX (t ))
3096
+ if err != nil {
3097
+ t .Fatal (err )
3098
+ }
3099
+
3100
+ inters := NewCertPool ()
3101
+ inters .AddCert (root )
3102
+ inters .AddCert (inter )
3103
+
3104
+ wantErr := "certificate signed by unknown authority"
3105
+ _ , err = leaf .Verify (VerifyOptions {Intermediates : inters , Roots : NewCertPool ()})
3106
+ if ! strings .Contains (err .Error (), wantErr ) {
3107
+ t .Errorf ("got %v, want %q" , err , wantErr )
3108
+ }
3109
+ }
3110
+
3111
+ // dsaSelfSignedCNX produces DER-encoded
3112
+ // certificate with the properties:
3113
+ //
3114
+ // Subject=Issuer=CN=X
3115
+ // DSA SPKI
3116
+ // Matching inner/outer signature OIDs
3117
+ // Dummy ECDSA signature
3118
+ func dsaSelfSignedCNX (t * testing.T ) []byte {
3119
+ t .Helper ()
3120
+ var params dsa.Parameters
3121
+ if err := dsa .GenerateParameters (& params , rand .Reader , dsa .L1024N160 ); err != nil {
3122
+ t .Fatal (err )
3123
+ }
3124
+
3125
+ var dsaPriv dsa.PrivateKey
3126
+ dsaPriv .Parameters = params
3127
+ if err := dsa .GenerateKey (& dsaPriv , rand .Reader ); err != nil {
3128
+ t .Fatal (err )
3129
+ }
3130
+ dsaPub := & dsaPriv .PublicKey
3131
+
3132
+ type dsaParams struct { P , Q , G * big.Int }
3133
+ paramDER , err := asn1 .Marshal (dsaParams {dsaPub .P , dsaPub .Q , dsaPub .G })
3134
+ if err != nil {
3135
+ t .Fatal (err )
3136
+ }
3137
+ yDER , err := asn1 .Marshal (dsaPub .Y )
3138
+ if err != nil {
3139
+ t .Fatal (err )
3140
+ }
3141
+
3142
+ spki := publicKeyInfo {
3143
+ Algorithm : pkix.AlgorithmIdentifier {
3144
+ Algorithm : oidPublicKeyDSA ,
3145
+ Parameters : asn1.RawValue {FullBytes : paramDER },
3146
+ },
3147
+ PublicKey : asn1.BitString {Bytes : yDER , BitLength : 8 * len (yDER )},
3148
+ }
3149
+
3150
+ rdn := pkix.Name {CommonName : "X" }.ToRDNSequence ()
3151
+ b , err := asn1 .Marshal (rdn )
3152
+ if err != nil {
3153
+ t .Fatal (err )
3154
+ }
3155
+ rawName := asn1.RawValue {FullBytes : b }
3156
+
3157
+ algoIdent := pkix.AlgorithmIdentifier {Algorithm : oidSignatureDSAWithSHA256 }
3158
+ tbs := tbsCertificate {
3159
+ Version : 0 ,
3160
+ SerialNumber : big .NewInt (1002 ),
3161
+ SignatureAlgorithm : algoIdent ,
3162
+ Issuer : rawName ,
3163
+ Validity : validity {NotBefore : time .Now ().Add (- time .Hour ), NotAfter : time .Now ().Add (24 * time .Hour )},
3164
+ Subject : rawName ,
3165
+ PublicKey : spki ,
3166
+ }
3167
+ c := certificate {
3168
+ TBSCertificate : tbs ,
3169
+ SignatureAlgorithm : algoIdent ,
3170
+ SignatureValue : asn1.BitString {Bytes : []byte {0 }, BitLength : 8 },
3171
+ }
3172
+ dsaDER , err := asn1 .Marshal (c )
3173
+ if err != nil {
3174
+ t .Fatal (err )
3175
+ }
3176
+ return dsaDER
3177
+ }
0 commit comments