Beispiel #1
0
// 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
}
Beispiel #2
0
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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
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)
}
Beispiel #5
0
// 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
}
Beispiel #6
0
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
}
Beispiel #7
0
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)
}
Beispiel #8
0
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
}
Beispiel #10
0
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
}
Beispiel #12
0
// 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)))
}
Beispiel #13
0
// 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}
}
Beispiel #14
0
// 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
}
Beispiel #15
0
// 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
}
Beispiel #16
0
// 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
}
Beispiel #17
0
// 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
}
Beispiel #19
0
// 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
}
Beispiel #20
0
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)
}