@@ -205,6 +205,17 @@ type publicKeyInfo struct {
205
205
PublicKey asn1.BitString
206
206
}
207
207
208
+ func (pki * publicKeyInfo ) Equal (other crypto.PublicKey ) bool {
209
+ pki2 , ok := other .(* publicKeyInfo )
210
+ if ! ok {
211
+ return false
212
+ }
213
+ return (pki .Algorithm .Algorithm .Equal (pki2 .Algorithm .Algorithm ) &&
214
+ bytes .Equal (pki .Algorithm .Parameters .FullBytes , pki2 .Algorithm .Parameters .FullBytes ) &&
215
+ pki .PublicKey .BitLength == pki2 .PublicKey .BitLength &&
216
+ bytes .Equal (pki .PublicKey .Bytes , pki2 .PublicKey .Bytes ))
217
+ }
218
+
208
219
// RFC 5280, 4.2.1.1
209
220
type authKeyId struct {
210
221
Id []byte `asn1:"optional,tag:0"`
@@ -909,6 +920,10 @@ func (c *Certificate) hasSANExtension() bool {
909
920
// This is a low-level API that performs very limited checks, and not a full
910
921
// path verifier. Most users should use [Certificate.Verify] instead.
911
922
func (c * Certificate ) CheckSignatureFrom (parent * Certificate ) error {
923
+ return c .checkSignatureFrom (parent , nil )
924
+ }
925
+
926
+ func (c * Certificate ) checkSignatureFrom (parent * Certificate , opts * VerifyOptions ) error {
912
927
// RFC 5280, 4.2.1.9:
913
928
// "If the basic constraints extension is not present in a version 3
914
929
// certificate, or the extension is present but the cA boolean is not
@@ -923,11 +938,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
923
938
return ConstraintViolationError {}
924
939
}
925
940
926
- if parent .PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
927
- return ErrUnsupportedAlgorithm
928
- }
929
-
930
- return checkSignature (c .SignatureAlgorithm , c .RawTBSCertificate , c .Signature , parent .PublicKey , false )
941
+ return checkSignature (c .SignatureAlgorithm , c .RawTBSCertificate , c .Signature , parent .PublicKey , false , opts )
931
942
}
932
943
933
944
// CheckSignature verifies that signature is a valid signature over signed from
@@ -938,7 +949,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
938
949
// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
939
950
// signatures are currently accepted.
940
951
func (c * Certificate ) CheckSignature (algo SignatureAlgorithm , signed , signature []byte ) error {
941
- return checkSignature (algo , signed , signature , c .PublicKey , true )
952
+ return checkSignature (algo , signed , signature , c .PublicKey , true , nil )
942
953
}
943
954
944
955
func (c * Certificate ) hasNameConstraints () bool {
@@ -960,10 +971,24 @@ func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm,
960
971
961
972
// checkSignature verifies that signature is a valid signature over signed from
962
973
// a crypto.PublicKey.
963
- func checkSignature (algo SignatureAlgorithm , signed , signature []byte , publicKey crypto.PublicKey , allowSHA1 bool ) (err error ) {
974
+ func checkSignature (algo SignatureAlgorithm , signed , signature []byte , publicKey crypto.PublicKey , allowSHA1 bool , opts * VerifyOptions ) (err error ) {
964
975
var hashType crypto.Hash
965
976
var pubKeyAlgo PublicKeyAlgorithm
966
977
978
+ if algo == UnknownSignatureAlgorithm {
979
+ pki , ok := publicKey .(* publicKeyInfo )
980
+ if ! ok || opts == nil || opts .UnknownAlgorithmVerifier == nil {
981
+ return ErrUnsupportedAlgorithm
982
+ }
983
+
984
+ return opts .UnknownAlgorithmVerifier (
985
+ pki .Algorithm ,
986
+ signed ,
987
+ signature ,
988
+ pki .PublicKey .Bytes ,
989
+ )
990
+ }
991
+
967
992
for _ , details := range signatureAlgorithmDetails {
968
993
if details .algo == algo {
969
994
hashType = details .hash
@@ -1585,7 +1610,7 @@ func signTBS(tbs []byte, key crypto.Signer, sigAlg SignatureAlgorithm, rand io.R
1585
1610
}
1586
1611
1587
1612
// Check the signature to ensure the crypto.Signer behaved correctly.
1588
- if err := checkSignature (sigAlg , tbs , signature , key .Public (), true ); err != nil {
1613
+ if err := checkSignature (sigAlg , tbs , signature , key .Public (), true , nil ); err != nil {
1589
1614
return nil , fmt .Errorf ("x509: signature returned by signer is invalid: %w" , err )
1590
1615
}
1591
1616
@@ -2259,7 +2284,7 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
2259
2284
2260
2285
// CheckSignature reports whether the signature on c is valid.
2261
2286
func (c * CertificateRequest ) CheckSignature () error {
2262
- return checkSignature (c .SignatureAlgorithm , c .RawTBSCertificateRequest , c .Signature , c .PublicKey , true )
2287
+ return checkSignature (c .SignatureAlgorithm , c .RawTBSCertificateRequest , c .Signature , c .PublicKey , true , nil )
2263
2288
}
2264
2289
2265
2290
// RevocationListEntry represents an entry in the revokedCertificates
0 commit comments