75 lines
1.8 KiB
Go
75 lines
1.8 KiB
Go
package su3
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/dsa"
|
|
"crypto/ecdsa"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/asn1"
|
|
"errors"
|
|
"math/big"
|
|
)
|
|
|
|
type dsaSignature struct {
|
|
R, S *big.Int
|
|
}
|
|
|
|
type ecdsaSignature dsaSignature
|
|
|
|
func checkSignature(c *x509.Certificate, algo x509.SignatureAlgorithm, signed, signature []byte) (err error) {
|
|
var hashType crypto.Hash
|
|
|
|
switch algo {
|
|
case x509.SHA1WithRSA, x509.DSAWithSHA1, x509.ECDSAWithSHA1:
|
|
hashType = crypto.SHA1
|
|
case x509.SHA256WithRSA, x509.DSAWithSHA256, x509.ECDSAWithSHA256:
|
|
hashType = crypto.SHA256
|
|
case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
|
|
hashType = crypto.SHA384
|
|
case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
|
|
hashType = crypto.SHA512
|
|
default:
|
|
return x509.ErrUnsupportedAlgorithm
|
|
}
|
|
|
|
if !hashType.Available() {
|
|
return x509.ErrUnsupportedAlgorithm
|
|
}
|
|
h := hashType.New()
|
|
|
|
h.Write(signed)
|
|
digest := h.Sum(nil)
|
|
|
|
switch pub := c.PublicKey.(type) {
|
|
case *rsa.PublicKey:
|
|
// the digest is already hashed, so we force a 0 here
|
|
return rsa.VerifyPKCS1v15(pub, 0, digest, signature)
|
|
case *dsa.PublicKey:
|
|
dsaSig := new(dsaSignature)
|
|
if _, err := asn1.Unmarshal(signature, dsaSig); err != nil {
|
|
return err
|
|
}
|
|
if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
|
|
return errors.New("x509: DSA signature contained zero or negative values")
|
|
}
|
|
if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
|
|
return errors.New("x509: DSA verification failure")
|
|
}
|
|
return
|
|
case *ecdsa.PublicKey:
|
|
ecdsaSig := new(ecdsaSignature)
|
|
if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
|
|
return err
|
|
}
|
|
if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
|
|
return errors.New("x509: ECDSA signature contained zero or negative values")
|
|
}
|
|
if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) {
|
|
return errors.New("x509: ECDSA verification failure")
|
|
}
|
|
return
|
|
}
|
|
return x509.ErrUnsupportedAlgorithm
|
|
}
|