// sigSerializeUserAttribute calculates the user attribute packet hash // TODO: clean up & contribute this to go.crypto/openpgp func (pubkey *Pubkey) sigSerializeUserAttribute(uat *UserAttribute, hashFunc crypto.Hash) (h hash.Hash, err error) { if !hashFunc.Available() { return nil, errors.UnsupportedError("hash function") } h = hashFunc.New() // Get user attribute opaque packet var uatOpaque *packet.OpaquePacket if uatOpaque, err = uat.GetOpaquePacket(); err != nil { return } // Get public key opaque packet. var pkOpaque *packet.OpaquePacket if pkOpaque, err = pubkey.GetOpaquePacket(); err != nil { return } // RFC 4880, section 5.2.4 // Write the signature prefix and public key contents to hash pubkey.PublicKey.SerializeSignaturePrefix(h) h.Write(pkOpaque.Contents) // V4 certification hash var buf [5]byte // User attribute constant buf[0] = 0xd1 // Big-endian length of user attribute contents l := len(uatOpaque.Contents) buf[1] = byte(l >> 24) buf[2] = byte(l >> 16) buf[3] = byte(l >> 8) buf[4] = byte(l) h.Write(buf[:]) // User attribute contents h.Write(uatOpaque.Contents) return }
func checksumFor(h crypto.Hash, payload []byte) ([]byte, error) { if !h.Available() { return nil, errors.New("requested hash function not available") } hash := h.New() hash.Write(payload) // guaranteed not to error return hash.Sum([]byte{}), nil }
// userIdSignatureHash returns a Hash of the message that needs to be signed // to assert that pk is a valid key for id. func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) { if !hashFunc.Available() { return nil, errors.UnsupportedError("hash function") } h = hashFunc.New() updateUserIdSignatureHash(id, pk, h) return }
func (pkcs1v15 *pkcs1v15Sign) Sign(src []byte, hash crypto.Hash, prk *rsa.PrivateKey) ([]byte, error) { if !hash.Available() { return nil, errors.New("unsupport hash type") } h := hash.New() h.Write(src) hashed := h.Sum(nil) return rsa.SignPKCS1v15(rand.Reader, prk, hash, hashed) }
// keySignatureHash returns a Hash of the message that needs to be signed for // pk to assert a subkey relationship to signed. func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { if !hashFunc.Available() { return nil, errors.UnsupportedError("hash function") } h = hashFunc.New() updateKeySignatureHash(pk, signed, h) return }
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 }
func (pkcs1v15 *pkcs1v15Sign) Verify(src []byte, sign []byte, hash crypto.Hash, puk *rsa.PublicKey) error { if !hash.Available() { return errors.New("unsupport hash type") } h := hash.New() h.Write(src) hashed := h.Sum(nil) return rsa.VerifyPKCS1v15(puk, hash, hashed, sign) }
func NewHashRender(w Responser, hasher crypto.Hash) Render { if !hasher.Available() { panic(ErrHash.Error()) } render := &HashRender{ response: w, hash: hasher.New(), } return render }
func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { if !hashFunc.Available() { return nil, errors.UnsupportedError("hash function") } h = hashFunc.New() // RFC 4880, section 5.2.4 pk.SerializeSignaturePrefix(h) pk.serializeWithoutHeaders(h) return }
func (e *Entry) Calculate(h crypto.Hash) (sum []byte, err error) { if !h.Available() { return nil, HashUnavailableError{h} } hash := h.New() if file, err := os.Open(e.Filename); err != nil { return nil, err } else if _, err = io.Copy(hash, file); err != nil { return nil, err } return hash.Sum(nil), nil }
// userIdSignatureV3Hash returns a Hash of the message that needs to be signed // to assert that pk is a valid key for id. func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) { if !hfn.Available() { return nil, errors.UnsupportedError("hash function") } h = hfn.New() // RFC 4880, section 5.2.4 pk.SerializeSignaturePrefix(h) pk.serializeWithoutHeaders(h) h.Write([]byte(id)) return }
// hashForSignature returns a pair of hashes that can be used to verify a // signature. The signature may specify that the contents of the signed message // should be preprocessed (i.e. to normalize line endings). Thus this function // returns two hashes. The second should be used to hash the message itself and // performs any needed preprocessing. func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) { if !hashId.Available() { return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId))) } h := hashId.New() switch sigType { case packet.SigTypeBinary: return h, h, nil case packet.SigTypeText: return h, NewCanonicalTextHash(h), nil } return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType))) }
// NewHmacAuth returns an HmacAuth object that can be used to sign or // authenticate HTTP requests based on the supplied parameters. func NewHmacAuth(hash crypto.Hash, key []byte, header string, headers []string) HmacAuth { if hash.Available() == false { var name string var supported bool if name, supported = algorithmName[hash]; !supported { name = "#" + strconv.Itoa(int(hash)) } panic("hmacauth: hash algorithm " + name + " is unavailable") } canonicalHeaders := make([]string, len(headers)) for i, h := range headers { canonicalHeaders[i] = http.CanonicalHeaderKey(h) } return &hmacAuth{hash, key, header, canonicalHeaders} }
// CheckSignature verifies a signature made by the key on a CSR, such // as on the CSR itself. func CheckSignature(csr *x509.CertificateRequest, algo x509.SignatureAlgorithm, signed, signature []byte) error { var hashType crypto.Hash switch algo { case x509.SHA1WithRSA, x509.ECDSAWithSHA1: hashType = crypto.SHA1 case x509.SHA256WithRSA, 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 := csr.PublicKey.(type) { case *rsa.PublicKey: return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) case *ecdsa.PublicKey: ecdsaSig := new(struct{ R, S *big.Int }) 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 nil } return x509.ErrUnsupportedAlgorithm }
// CheckSignature verifies that signature is a valid signature over signed from // c's public key. func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) { var hashType crypto.Hash switch algo { case SHA1WithRSA, DSAWithSHA1: hashType = crypto.SHA1 case SHA256WithRSA, DSAWithSHA256: hashType = crypto.SHA256 case SHA384WithRSA: hashType = crypto.SHA384 case SHA512WithRSA: hashType = crypto.SHA512 default: return ErrUnsupportedAlgorithm } if !hashType.Available() { return ErrUnsupportedAlgorithm } h := hashType.New() h.Write(signed) digest := h.Sum(nil) switch pub := c.PublicKey.(type) { case *rsa.PublicKey: return rsa.VerifyPKCS1v15(pub, hashType, 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("DSA signature contained zero or negative values") } if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) { return errors.New("DSA verification failure") } return } return ErrUnsupportedAlgorithm }
// sigSerializeUserAttribute calculates the user attribute packet hash // TODO: clean up & contribute this to golang.org/x/crypto/openpgp. func (pubkey *PrimaryKey) sigSerializeUserAttribute(uat *UserAttribute, hashFunc crypto.Hash) (hash.Hash, error) { if !hashFunc.Available() { return nil, errgo.Newf("unsupported hash function: %v", hashFunc) } h := hashFunc.New() // Get user attribute opaque packet uatOpaque, err := uat.opaquePacket() if err != nil { return nil, errgo.Mask(err) } // Get public key opaque packet. pkOpaque, err := pubkey.opaquePacket() if err != nil { return nil, errgo.Mask(err) } // Get public key v4 packet. User attributes not supported pre-v4. pk, err := pubkey.PublicKey.publicKeyPacket() if err != nil { return nil, errgo.Mask(err) } // RFC 4880, section 5.2.4 // Write the signature prefix and public key contents to hash pk.SerializeSignaturePrefix(h) h.Write(pkOpaque.Contents) // V4 certification hash var buf [5]byte // User attribute constant buf[0] = 0xd1 // Big-endian length of user attribute contents l := len(uatOpaque.Contents) buf[1] = byte(l >> 24) buf[2] = byte(l >> 16) buf[3] = byte(l >> 8) buf[4] = byte(l) h.Write(buf[:]) // User attribute contents h.Write(uatOpaque.Contents) return h, nil }
// CheckSignature verifies that the signature on c is a valid signature using // the public key in c. func (c *CertificateSigningRequest) CheckSignature() (err error) { var hashType crypto.Hash switch c.SignatureAlgorithm { case x509.SHA1WithRSA, x509.ECDSAWithSHA1: hashType = crypto.SHA1 case x509.SHA256WithRSA, 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(c.RawCertificationRequestInfo) digest := h.Sum(nil) switch pub := c.PublicKey.(type) { case *rsa.PublicKey: return rsa.VerifyPKCS1v15(pub, hashType, digest, c.Signature) case *ecdsa.PublicKey: ecdsaSig := new(ecdsaSignature) if _, err := asn1.Unmarshal(c.Signature, ecdsaSig); err != nil { return err } if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { return errors.New("crypto/x509: ECDSA signature contained zero or negative values") } if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) { return errors.New("crypto/x509: ECDSA verification failure") } return } return x509.ErrUnsupportedAlgorithm }
// userIdSignatureHash returns a Hash of the message that needs to be signed // to assert that pk is a valid key for id. func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) { if !hashFunc.Available() { return nil, errors.UnsupportedError("hash function") } h = hashFunc.New() // RFC 4880, section 5.2.4 pk.SerializeSignaturePrefix(h) pk.serializeWithoutHeaders(h) var buf [5]byte buf[0] = 0xb4 buf[1] = byte(len(id) >> 24) buf[2] = byte(len(id) >> 16) buf[3] = byte(len(id) >> 8) buf[4] = byte(len(id)) h.Write(buf[:]) h.Write([]byte(id)) return }
// CreateCertificateSigningRequest creates a new certificate signing request // based on a template. The following members of template are used: Subject. // // The certificate signing request is signed with the parameter priv which is // the private key of the requester. The public part of the priv key is // included in the certification request information // // The returned slice is the certificate signing request in DER encoding. // // The only supported key type are RSA and ECDSA (*rsa.PrivateKey or // *ecdsa.PrivateKey for priv) func CreateCertificateSigningRequest(rand io.Reader, template *CertificateSigningRequest, priv interface{}) (csr []byte, err error) { var publicKeyBytes []byte var publicKeyAlgorithm pkix.AlgorithmIdentifier var signatureAlgorithm pkix.AlgorithmIdentifier var hashFunc crypto.Hash switch priv := priv.(type) { case *rsa.PrivateKey: signatureAlgorithm.Algorithm = oidSignatureSHA1WithRSA hashFunc = crypto.SHA1 publicKeyBytes, err = asn1.Marshal(rsaPublicKey{ N: priv.PublicKey.N, E: priv.PublicKey.E, }) publicKeyAlgorithm.Algorithm = oidPublicKeyRSA case *ecdsa.PrivateKey: switch priv.Curve { case elliptic.P224(), elliptic.P256(): hashFunc = crypto.SHA256 signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA256 case elliptic.P384(): hashFunc = crypto.SHA384 signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA384 case elliptic.P521(): hashFunc = crypto.SHA512 signatureAlgorithm.Algorithm = oidSignatureECDSAWithSHA512 default: return nil, errors.New("x509: unknown elliptic curve") } oid, ok := oidFromNamedCurve(priv.PublicKey.Curve) if !ok { return nil, errors.New("x509: unknown elliptic curve") } publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA var paramBytes []byte paramBytes, err = asn1.Marshal(oid) if err != nil { return } publicKeyAlgorithm.Parameters.FullBytes = paramBytes publicKeyBytes = elliptic.Marshal(priv.PublicKey.Curve, priv.PublicKey.X, priv.PublicKey.Y) default: return nil, errors.New("x509: only RSA private keys supported") } if err != nil { return } var asn1Subject []byte if len(template.RawSubject) > 0 { asn1Subject = template.RawSubject } else { asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence()) } if err != nil { return } encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes} c := certificationRequestInfo{ Version: 0, Subject: asn1.RawValue{FullBytes: asn1Subject}, SubjectPKInfo: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey}, } csrInfoContents, err := asn1.Marshal(c) if err != nil { return } c.Raw = csrInfoContents if !hashFunc.Available() { return nil, x509.ErrUnsupportedAlgorithm } h := hashFunc.New() h.Write(csrInfoContents) digest := h.Sum(nil) var signature []byte switch priv := priv.(type) { case *rsa.PrivateKey: signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest) case *ecdsa.PrivateKey: var r, s *big.Int if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil { signature, err = asn1.Marshal(ecdsaSignature{r, s}) } default: panic("internal error") } if err != nil { return } csr, err = asn1.Marshal(certificateSigningRequest{ nil, c, signatureAlgorithm, asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, }) return }
func _chash(h crypto.Hash, src interface{}) string { if !h.Available() { panic(fmt.Errorf("Hash %v is not available", h)) } return _hash(h.New(), src) }