Example #1
0
// Sign signs msg with priv, reading randomness from rand. If opts is a
// *PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will
// be used. This method is intended to support keys where the private part is
// kept in, for example, a hardware module. Common uses should use the Sign*
// functions in this package.
func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
	if pssOpts, ok := opts.(*PSSOptions); ok {
		return SignPSS(rand, priv, pssOpts.Hash, msg, pssOpts)
	}

	return SignPKCS1v15(rand, priv, opts.HashFunc(), msg)
}
Example #2
0
// Sign performs a signature using the PKCS #11 key.
func (ps *PKCS11Key) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error) {
	// Verify that the length of the hash is as expected
	hash := opts.HashFunc()
	hashLen := hash.Size()
	if len(msg) != hashLen {
		err = errors.New("input size does not match hash function output size")
		return
	}

	// Add DigestInfo prefix
	// TODO: Switch mechanisms based on CKA_KEY_TYPE
	mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)}
	prefix, ok := hashPrefixes[hash]
	if !ok {
		err = errors.New("unknown hash function")
		return
	}
	signatureInput := append(prefix, msg...)

	// Open a session
	session, err := ps.openSession()
	if err != nil {
		return
	}
	defer ps.closeSession(session)

	// Perform the sign operation
	err = ps.module.SignInit(session, mechanism, ps.privateKeyHandle)
	if err != nil {
		return
	}

	signature, err = ps.module.Sign(session, signatureInput)
	return
}
Example #3
0
// Sign signs the given message with priv.
// Ed25519 performs two passes over messages to be signed and therefore cannot
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
// indicate the message hasn't been hashed. This can be achieved by passing
// crypto.Hash(0) as the value for opts.
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
	if opts.HashFunc() != crypto.Hash(0) {
		return nil, errors.New("ed25519: cannot sign hashed message")
	}

	return Sign(priv, message), nil
}
Example #4
0
// Sign performs a signature using the PKCS #11 key.
func (ps *Key) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error) {
	ps.sessionMu.Lock()
	defer ps.sessionMu.Unlock()
	if ps.session == nil {
		return nil, errors.New("Session was nil")
	}

	// When the alwaysAuthenticate bit is true (e.g. on a Yubikey NEO in PIV mode),
	// each Sign has to include a Logout/Login, or the next Sign request will get
	// CKR_USER_NOT_LOGGED_IN. This is very slow, but on the NEO it's not possible
	// to clear the CKA_ALWAYS_AUTHENTICATE bit, so this is the only available
	// workaround.
	// Also, since logged in / logged out is application state rather than session
	// state, we take a global lock while we do the logout and login, and during
	// the signing.
	if ps.alwaysAuthenticate {
		modulesMu.Lock()
		defer modulesMu.Unlock()
		if err := ps.module.Logout(*ps.session); err != nil {
			return nil, fmt.Errorf("logout: %s", err)
		}
		if err = ps.module.Login(*ps.session, pkcs11.CKU_USER, ps.pin); err != nil {
			return nil, fmt.Errorf("login: %s", err)
		}
	}

	// Verify that the length of the hash is as expected
	hash := opts.HashFunc()
	hashLen := hash.Size()
	if len(msg) != hashLen {
		err = fmt.Errorf("input size does not match hash function output size: %d vs %d", len(msg), hashLen)
		return
	}

	// Add DigestInfo prefix
	// TODO: Switch mechanisms based on CKA_KEY_TYPE
	mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)}
	prefix, ok := hashPrefixes[hash]
	if !ok {
		err = errors.New("unknown hash function")
		return
	}
	signatureInput := append(prefix, msg...)

	// Perform the sign operation
	err = ps.module.SignInit(*ps.session, mechanism, ps.privateKeyHandle)
	if err != nil {
		return nil, fmt.Errorf("sign init: %s", err)
	}

	signature, err = ps.module.Sign(*ps.session, signatureInput)
	if err != nil {
		return nil, fmt.Errorf("sign: %s", err)
	}
	return
}
Example #5
0
// Sign implements the crypto.Signer operation for the given key.
func (key *PrivateKey) Sign(r io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
	if len(msg) != opts.HashFunc().Size() {
		return nil, errors.New("input must be hashed message")
	}

	op := signOpFromKeyHash(key, opts.HashFunc())
	if op == gokeyless.OpError {
		return nil, errors.New("invalid key type or hash")
	}
	return key.execute(op, msg)
}
Example #6
0
// Sign implements the crypto.Signer operation for the given key.
func (key *PrivateKey) Sign(r io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
	if len(msg) != opts.HashFunc().Size() {
		return nil, errors.New("input must be hashed message")
	}

	conn, err := key.client.DialAny(key.ski)
	if err != nil {
		return nil, err
	}

	op := signOpFromKeyHash(key, opts.HashFunc())
	if op == gokeyless.OpError {
		return nil, errors.New("invalid key type or hash")
	}
	return conn.KeyOperation(op, msg, key.ski, key.digest)
}
Example #7
0
func (pks *PKSigner) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error) {
	// RSA is kind of a small disaster because of the way that the
	// crypto.Signer interface is laid out.
	//
	// For PKCS1v1.5 RSA signatures, the input to the actual
	// signature function is an ASN.1 DER-encoded
	// structure. WebCrypto has hash-specific mechanisms which
	// know how to generate that structure, but they all assume
	// the data is un-hashed, which is not the case with the
	// crypto.Signer interface, so we have to ues {hash: {name:
	// 'none'}}, which just performs the raw signature operation.
	//
	// This means we have to generate the ASN.1 structure
	// ourselves, which we can do by just having the correct
	// prefixes for all the hashes we might want to use. Prefixes
	// are taken from src/crypto/rsa/pkcs1v15.go. No other
	// signatures require this song and dance

	hash := hashNames[opts.HashFunc()]

	var algorithm js.M
	switch k := pks.Public().(type) {
	case *rsa.PublicKey:
		if pssOpts, ok := opts.(*rsa.PSSOptions); ok {
			algorithm = js.M{
				"name":       "RSA-PSS",
				"saltLength": pssOpts.SaltLength,
				"hash":       js.M{"name": hash},
			}
		} else {
			algorithm = js.M{
				"name": "RSASSA-PKCS1-v1_5",
				"hash": js.M{"name": "none"},
			}

			prefix, ok := hashPrefixes[opts.HashFunc()]
			if !ok {
				return nil, ErrUnsupportedHash
			}

			msg = append(prefix, msg...)
		}
	case *ecdsa.PublicKey:
		curveName, ok := curveNames[k.Curve]
		if !ok {
			return nil, ErrUnsupported
		}

		algorithm = js.M{
			"name":       "ECDSA",
			"hash":       js.M{"name": hash},
			"namedCurve": curveName,
		}
	}

	_, privkey, err := pks.pk.GetKeyPair(pks.cert.Raw, algorithm)
	if err != nil {
		return nil, err
	}

	return pks.pk.Sign(algorithm, privkey, msg)
}