Пример #1
0
func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
	var buffer []byte
	if version == VersionSSL30 || version >= VersionTLS12 {
		buffer = []byte{}
	}

	prf, hash := prfAndHashForVersion(version, cipherSuite)
	if hash != 0 {
		return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}
	}

	return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}
}
Пример #2
0
// Sign generates a sign based on the Algorithm instance variable.
// This fulfills the `Signer` interface
func (s RsaSign) PayloadSign(payload []byte) ([]byte, error) {
	hash, err := rsaHashForAlg(s.SignatureAlgorithm())
	if err != nil {
		return nil, ErrUnsupportedAlgorithm
	}

	privkey := s.PrivateKey
	if privkey == nil {
		return nil, ErrMissingPrivateKey
	}

	h := hash.New()
	h.Write(payload)

	switch s.SignatureAlgorithm() {
	case jwa.RS256, jwa.RS384, jwa.RS512:
		return rsa.SignPKCS1v15(rand.Reader, privkey, hash, h.Sum(nil))
	case jwa.PS256, jwa.PS384, jwa.PS512:
		return rsa.SignPSS(rand.Reader, privkey, hash, h.Sum(nil), &rsa.PSSOptions{
			SaltLength: rsa.PSSSaltLengthAuto,
		})
	default:
		return nil, ErrUnsupportedAlgorithm
	}
}
Пример #3
0
// Parse reads a binary specification for a string-to-key transformation from r
// and returns a function which performs that transform.
func Parse(r io.Reader) (f func(out, in []byte), err error) {
	var buf [9]byte

	_, err = io.ReadFull(r, buf[:2])
	if err != nil {
		return
	}

	// GNU Extensions; handle them before we try to look for a hash, which won't
	// be needed in most cases anyway.
	if buf[0] == 101 {
		return parseGNUExtensions(r)
	}

	hash, ok := HashIdToHash(buf[1])
	if !ok {
		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
	}
	if !hash.Available() {
		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
	}
	h := hash.New()

	switch buf[0] {
	case 0:
		f := func(out, in []byte) {
			Simple(out, h, in)
		}
		return f, nil
	case 1:
		_, err = io.ReadFull(r, buf[:8])
		if err != nil {
			return
		}
		f := func(out, in []byte) {
			Salted(out, h, in, buf[:8])
		}
		return f, nil
	case 3:
		_, err = io.ReadFull(r, buf[:9])
		if err != nil {
			return
		}
		count := decodeCount(buf[8])
		f := func(out, in []byte) {
			Iterated(out, h, in, buf[:8], count)
		}
		return f, nil
	}

	return nil, errors.UnsupportedError("S2K function")
}
Пример #4
0
// Parse reads a binary specification for a string-to-key transformation from r
// and returns a function which performs that transform.
func Parse(r io.Reader) (f func(out, in []byte), err error) {
	var buf [9]byte

	_, err = io.ReadFull(r, buf[:2])
	if err != nil {
		return
	}

	hash, ok := HashIdToHash(buf[1])
	if !ok {
		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
	}
	if !hash.Available() {
		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
	}
	h := hash.New()

	switch buf[0] {
	case 0:
		f := func(out, in []byte) {
			Simple(out, h, in)
		}
		return f, nil
	case 1:
		_, err = io.ReadFull(r, buf[:8])
		if err != nil {
			return
		}
		f := func(out, in []byte) {
			Salted(out, h, in, buf[:8])
		}
		return f, nil
	case 3:
		_, err = io.ReadFull(r, buf[:9])
		if err != nil {
			return
		}
		count := decodeCount(buf[8])
		f := func(out, in []byte) {
			Iterated(out, h, in, buf[:8], count)
		}
		return f, nil
	}

	return nil, errors.UnsupportedError("S2K function")
}
Пример #5
0
// Parse reads a binary specification for a string-to-key transformation from r
// and returns a function which performs that transform.
func Parse(r io.Reader) (f func(out, in []byte), err os.Error) {
	var buf [9]byte

	_, err = io.ReadFull(r, buf[:2])
	if err != nil {
		return
	}

	hash, ok := HashIdToHash(buf[1])
	if !ok {
		return nil, error.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
	}
	h := hash.New()
	if h == nil {
		return nil, error.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
	}

	switch buf[0] {
	case 1:
		f := func(out, in []byte) {
			Simple(out, h, in)
		}
		return f, nil
	case 2:
		_, err := io.ReadFull(r, buf[:8])
		if err != nil {
			return
		}
		f := func(out, in []byte) {
			Salted(out, h, in, buf[:8])
		}
		return f, nil
	case 3:
		_, err := io.ReadFull(r, buf[:9])
		if err != nil {
			return
		}
		count := (16 + int(buf[8]&15)) << (uint32(buf[8]>>4) + 6)
		f := func(out, in []byte) {
			Iterated(out, h, in, buf[:8], count)
		}
		return f, nil
	}

	return nil, error.UnsupportedError("S2K function")
}
Пример #6
0
// PayloadSign generates a sign based on the Algorithm instance variable.
// This fulfills the `PayloadSigner` interface
func (s EcdsaSign) PayloadSign(payload []byte) ([]byte, error) {
	hash, err := ecdsaHashForAlg(s.SignatureAlgorithm())
	if err != nil {
		return nil, err
	}

	privkey := s.PrivateKey
	if privkey == nil {
		return nil, errors.New("cannot proceed with Sign(): no private key available")
	}

	keysiz := hash.Size()
	curveBits := privkey.Curve.Params().BitSize
	if curveBits != keysiz*8 {
		return nil, errors.New("key size does not match curve bit size")
	}

	h := hash.New()
	h.Write(payload)
	signed := h.Sum(nil)
	if debug.Enabled {
		debug.Printf("payload = %s, signed -> %x", payload, signed)
	}

	r, v, err := ecdsa.Sign(rand.Reader, privkey, signed)
	if err != nil {
		return nil, err
	}

	out := make([]byte, keysiz*2)
	keys := [][]byte{r.Bytes(), v.Bytes()}
	for i, data := range keys {
		start := i * keysiz
		padlen := keysiz - len(data)
		copy(out[start+padlen:], data)
	}

	return out, nil
}
Пример #7
0
// Encrypt encrypts a message to a number of recipients and, optionally, signs
// it. hints contains optional information, that is also encrypted, that aids
// the recipients in processing the message. The resulting WriteCloser must
// be closed after the contents of the file have been written.
func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints) (plaintext io.WriteCloser, err error) {
	var signer *packet.PrivateKey
	if signed != nil {
		signer = signed.signingKey().PrivateKey
		if signer == nil || signer.Encrypted {
			return nil, error_.InvalidArgumentError("signing key must be decrypted")
		}
	}

	// These are the possible ciphers that we'll use for the message.
	candidateCiphers := []uint8{
		uint8(packet.CipherAES128),
		uint8(packet.CipherAES256),
		uint8(packet.CipherCAST5),
	}
	// These are the possible hash functions that we'll use for the signature.
	candidateHashes := []uint8{
		hashToHashId(crypto.SHA256),
		hashToHashId(crypto.SHA512),
		hashToHashId(crypto.SHA1),
		hashToHashId(crypto.RIPEMD160),
	}
	// In the event that a recipient doesn't specify any supported ciphers
	// or hash functions, these are the ones that we assume that every
	// implementation supports.
	defaultCiphers := candidateCiphers[len(candidateCiphers)-1:]
	defaultHashes := candidateHashes[len(candidateHashes)-1:]

	encryptKeys := make([]Key, len(to))
	for i := range to {
		encryptKeys[i] = to[i].encryptionKey()
		if encryptKeys[i].PublicKey == nil {
			return nil, error_.InvalidArgumentError("cannot encrypt a message to key id " + strconv.Uitob64(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys")
		}

		sig := to[i].primaryIdentity().SelfSignature

		preferredSymmetric := sig.PreferredSymmetric
		if len(preferredSymmetric) == 0 {
			preferredSymmetric = defaultCiphers
		}
		preferredHashes := sig.PreferredHash
		if len(preferredHashes) == 0 {
			preferredHashes = defaultHashes
		}
		candidateCiphers = intersectPreferences(candidateCiphers, preferredSymmetric)
		candidateHashes = intersectPreferences(candidateHashes, preferredHashes)
	}

	if len(candidateCiphers) == 0 || len(candidateHashes) == 0 {
		return nil, error_.InvalidArgumentError("cannot encrypt because recipient set shares no common algorithms")
	}

	cipher := packet.CipherFunction(candidateCiphers[0])
	hash, _ := s2k.HashIdToHash(candidateHashes[0])
	symKey := make([]byte, cipher.KeySize())
	if _, err := io.ReadFull(rand.Reader, symKey); err != nil {
		return nil, err
	}

	for _, key := range encryptKeys {
		if err := packet.SerializeEncryptedKey(ciphertext, rand.Reader, key.PublicKey, cipher, symKey); err != nil {
			return nil, err
		}
	}

	encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey)
	if err != nil {
		return
	}

	if signer != nil {
		ops := &packet.OnePassSignature{
			SigType:    packet.SigTypeBinary,
			Hash:       hash,
			PubKeyAlgo: signer.PubKeyAlgo,
			KeyId:      signer.KeyId,
			IsLast:     true,
		}
		if err := ops.Serialize(encryptedData); err != nil {
			return nil, err
		}
	}

	if hints == nil {
		hints = &FileHints{}
	}

	w := encryptedData
	if signer != nil {
		// If we need to write a signature packet after the literal
		// data then we need to stop literalData from closing
		// encryptedData.
		w = noOpCloser{encryptedData}

	}
	literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, hints.EpochSeconds)
	if err != nil {
		return nil, err
	}

	if signer != nil {
		return signatureWriter{encryptedData, literalData, hash, hash.New(), signer}, nil
	}
	return literalData, nil
}
Пример #8
0
// Parse reads a binary specification for a string-to-key transformation from r
// and returns a function which performs that transform.
func Parse(r io.Reader) (f func(out, in []byte), err error) {
	var buf [9]byte

	_, err = io.ReadFull(r, buf[:2])
	if err != nil {
		return
	}

	hash, ok := HashIdToHash(buf[1])
	if !ok {
		return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1])))
	}
	if !hash.Available() {
		return nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hash)))
	}
	h := hash.New()

	switch buf[0] {
	case 0:
		f := func(out, in []byte) {
			Simple(out, h, in)
		}
		return f, nil
	case 1:
		_, err = io.ReadFull(r, buf[:8])
		if err != nil {
			return
		}
		f := func(out, in []byte) {
			Salted(out, h, in, buf[:8])
		}
		return f, nil
	case 3:
		_, err = io.ReadFull(r, buf[:9])
		if err != nil {
			return
		}
		count := decodeCount(buf[8])
		f := func(out, in []byte) {
			Iterated(out, h, in, buf[:8], count)
		}
		return f, nil

	// GNU Extensions
	case 101:

		// A three-byte string identifier
		_, err = io.ReadFull(r, buf[:3])
		if err != nil {
			return
		}
		gnuExt := string(buf[:3])

		if gnuExt != "GNU" {
			return nil, errors.UnsupportedError("Malformed GNU extension: " + gnuExt)
		}
		_, err = io.ReadFull(r, buf[:1])
		if err != nil {
			return
		}
		gnuExtType := int(buf[0])
		if gnuExtType != 1 {
			return nil, errors.UnsupportedError("unknown S2K GNU protection mode: " + strconv.Itoa(int(gnuExtType)))
		}
		return nil, nil
	}

	return nil, errors.UnsupportedError("S2K function")
}