示例#1
0
// DecryptBytes takes in base64-encoded encrypted bytes and the base64-encoded
// private key and decrypts it. A bytes.Buffer is returned to allow the caller
// to do useful thing with it (get it as a []byte, get it as a string, use it
// as an io.Reader, etc), and also because this function doesn't know if what
// comes out is binary data or a string, so let the caller decide.
func DecryptBytes(encodedCrypt, privKey string) (*bytes.Buffer, error) {
	privKeyBytes, err := base64.StdEncoding.DecodeString(privKey)
	if err != nil {
		return nil, fmt.Errorf("Error decoding base64 private key: %s", err)
	}

	cryptBytes, err := base64.StdEncoding.DecodeString(encodedCrypt)
	if err != nil {
		return nil, fmt.Errorf("Error decoding base64 crypted bytes: %s", err)
	}

	entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(privKeyBytes)))
	if err != nil {
		return nil, fmt.Errorf("Error parsing private key: %s", err)
	}

	entityList := &openpgp.EntityList{entity}
	md, err := openpgp.ReadMessage(bytes.NewBuffer(cryptBytes), entityList, nil, nil)
	if err != nil {
		return nil, fmt.Errorf("Error decrypting the messages: %s", err)
	}

	ptBuf := bytes.NewBuffer(nil)
	ptBuf.ReadFrom(md.UnverifiedBody)

	return ptBuf, nil
}
示例#2
0
func TestFetchKeybasePubkeys(t *testing.T) {
	testset := []string{"keybase:jefferai", "keybase:hashicorp"}
	ret, err := FetchKeybasePubkeys(testset)
	if err != nil {
		t.Fatalf("bad: %v", err)
	}

	fingerprints := []string{}
	for _, user := range testset {
		data, err := base64.StdEncoding.DecodeString(ret[user])
		if err != nil {
			t.Fatalf("error decoding key for user %s: %v", user, err)
		}
		entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data)))
		if err != nil {
			t.Fatalf("error parsing key for user %s: %v", user, err)
		}
		fingerprints = append(fingerprints, hex.EncodeToString(entity.PrimaryKey.Fingerprint[:]))
	}

	exp := []string{
		"0f801f518ec853daff611e836528efcac6caa3db",
		"91a6e7f85d05c65630bef18951852d87348ffc4c",
	}

	if !reflect.DeepEqual(fingerprints, exp) {
		t.Fatalf("fingerprints do not match; expected \n%#v\ngot\n%#v\n", exp, fingerprints)
	}
}
示例#3
0
// EncryptShares takes an ordered set of Shamir key share fragments and
// PGP public keys and encrypts each Shamir key fragment with the corresponding
// public key
//
// Note: There is no corresponding test function; this functionality is
// thoroughly tested in the init and rekey command unit tests
func EncryptShares(secretShares [][]byte, pgpKeys []string) ([][]byte, error) {
	if len(secretShares) != len(pgpKeys) {
		return nil, fmt.Errorf("Mismatch between number of generated shares and number of PGP keys")
	}
	encryptedShares := [][]byte{}
	for i, keystring := range pgpKeys {
		data, err := base64.StdEncoding.DecodeString(keystring)
		if err != nil {
			return nil, fmt.Errorf("Error decoding given PGP key: %s", err)
		}
		entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data)))
		if err != nil {
			return nil, fmt.Errorf("Error parsing given PGP key: %s", err)
		}
		ctBuf := bytes.NewBuffer(nil)
		pt, err := openpgp.Encrypt(ctBuf, []*openpgp.Entity{entity}, nil, nil, nil)
		if err != nil {
			return nil, fmt.Errorf("Error setting up encryption for PGP message: %s", err)
		}
		_, err = pt.Write([]byte(hex.EncodeToString(secretShares[i])))
		if err != nil {
			return nil, fmt.Errorf("Error encrypting PGP message: %s", err)
		}
		pt.Close()
		encryptedShares = append(encryptedShares, ctBuf.Bytes())
	}
	return encryptedShares, nil
}
示例#4
0
文件: keys.go 项目: nerdzeu/nerdz-api
// ReadKeyRing reads one or more public/private keys. Unsupported keys are
// ignored as long as at least a single valid key is found.
func ReadKeyRing(r io.Reader) (el EntityList, err error) {
	packets := packet.NewReader(r)
	var lastUnsupportedError error

	for {
		var e *Entity
		e, err = ReadEntity(packets)
		if err != nil {
			// TODO: warn about skipped unsupported/unreadable keys
			if _, ok := err.(errors.UnsupportedError); ok {
				lastUnsupportedError = err
				err = readToNextPublicKey(packets)
			} else if _, ok := err.(errors.StructuralError); ok {
				// Skip unreadable, badly-formatted keys
				lastUnsupportedError = err
				err = readToNextPublicKey(packets)
			}
			if err == io.EOF {
				err = nil
				break
			}
			if err != nil {
				el = nil
				break
			}
		} else {
			el = append(el, e)
		}
	}

	if len(el) == 0 && err == nil {
		err = lastUnsupportedError
	}
	return
}
示例#5
0
文件: gpgv.go 项目: u-root/u-root
func verifyDetachedSignature(key *packet.PublicKey, contentf, sigf io.Reader) error {
	var hashFunc crypto.Hash

	packets := packet.NewReader(sigf)
	p, err := packets.Next()
	if err != nil {
		return err
	}
	switch sig := p.(type) {
	case *packet.Signature:
		hashFunc = sig.Hash
	case *packet.SignatureV3:
		hashFunc = sig.Hash
	default:
		return errors.UnsupportedError("unrecognized signature")
	}

	h := hashFunc.New()
	if _, err := io.Copy(h, contentf); err != nil && err != io.EOF {
		return err
	}
	switch sig := p.(type) {
	case *packet.Signature:
		err = key.VerifySignature(h, sig)
	case *packet.SignatureV3:
		err = key.VerifySignatureV3(h, sig)
	default:
		panic("unreachable")
	}
	return err
}
示例#6
0
func testSignedManifest(t *testing.T, modify func(*pods.Manifest, *openpgp.Entity)) (*pods.Manifest, *openpgp.Entity) {
	testManifest := testManifest(t)

	if fakeSigner == nil {
		var err error
		fakeSigner, err = openpgp.ReadEntity(packet.NewReader(bytes.NewReader(fakeEntity)))
		Assert(t).IsNil(err, "should have read entity")
	}

	if modify != nil {
		modify(testManifest, fakeSigner)
	}

	manifestBytes, err := testManifest.Marshal()
	Assert(t).IsNil(err, "manifest bytes error should have been nil")

	var buf bytes.Buffer
	sigWriter, err := clearsign.Encode(&buf, fakeSigner.PrivateKey, nil)
	Assert(t).IsNil(err, "clearsign Encode error should have been nil")

	sigWriter.Write(manifestBytes)
	sigWriter.Close()

	manifest, err := pods.ManifestFromBytes(buf.Bytes())
	Assert(t).IsNil(err, "should have generated manifest from signed bytes")

	return manifest, fakeSigner
}
示例#7
0
文件: sign.go 项目: kubernetes/helm
// loadKey loads a GPG key found at a particular path.
func loadKey(keypath string) (*openpgp.Entity, error) {
	f, err := os.Open(keypath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	pr := packet.NewReader(f)
	return openpgp.ReadEntity(pr)
}
示例#8
0
文件: pgp.go 项目: lbn/gorwell
func PublicKeyToPGPClient(publicKey string) PGPClient {
	block, err := armor.Decode(strings.NewReader(publicKey))
	if err != nil {
		panic(err)
	}
	entity, err := openpgp.ReadEntity(packet.NewReader(block.Body))
	if err != nil {
		panic(err)
	}
	return PGPClient{openpgp.EntityList{entity}}
}
示例#9
0
文件: gpgv.go 项目: u-root/u-root
func readPublicSigningKey(keyf io.Reader) (*packet.PublicKey, error) {
	keypackets := packet.NewReader(keyf)
	p, err := keypackets.Next()
	if err != nil {
		return nil, err
	}
	switch pkt := p.(type) {
	case *packet.PublicKey:
		debug("key: ", pkt)
		return pkt, nil
	default:
		log.Printf("ReadPublicSigningKey: got %T, want *packet.PublicKey", pkt)
	}
	return nil, errors.StructuralError("expected first packet to be PublicKey")
}
示例#10
0
// GetEntities takes in a string array of base64-encoded PGP keys and returns
// the openpgp Entities
func GetEntities(pgpKeys []string) ([]*openpgp.Entity, error) {
	ret := make([]*openpgp.Entity, 0, len(pgpKeys))
	for _, keystring := range pgpKeys {
		data, err := base64.StdEncoding.DecodeString(keystring)
		if err != nil {
			return nil, fmt.Errorf("Error decoding given PGP key: %s", err)
		}
		entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data)))
		if err != nil {
			return nil, fmt.Errorf("Error parsing given PGP key: %s", err)
		}
		ret = append(ret, entity)
	}
	return ret, nil
}
示例#11
0
func encryptEmail(e *Email) error {
	if len(e.OpenPGPEncryptTo) == 0 {
		return nil
	}

	buf := &bytes.Buffer{}
	var destEntities []*openpgp.Entity
	for _, eto := range e.OpenPGPEncryptTo {
		r := bytes.NewBufferString(eto)
		blk, err := armor.Decode(r)
		if err != nil {
			return err
		}

		rr := packet.NewReader(blk.Body)
		e, err := openpgp.ReadEntity(rr)
		if err != nil {
			return err
		}

		destEntities = append(destEntities, e)
	}

	aew, err := armor.Encode(buf, "PGP MESSAGE", map[string]string{
		"Version": "OpenPGP",
	})
	if err != nil {
		return err
	}

	wr, err := openpgp.Encrypt(aew, destEntities, nil, nil, nil)
	if err != nil {
		return err
	}

	_, err = wr.Write([]byte(e.Body))
	if err != nil {
		wr.Close()
		return err
	}

	wr.Close()
	aew.Close()

	e.Body = string(buf.Bytes())
	return nil
}
示例#12
0
func TestPubKeyFilesFlagSetKeybase(t *testing.T) {
	tempDir, err := ioutil.TempDir("", "vault-test")
	if err != nil {
		t.Fatalf("Error creating temporary directory: %s", err)
	}
	defer os.RemoveAll(tempDir)

	err = ioutil.WriteFile(tempDir+"/pubkey2", []byte(pubKey2), 0755)
	if err != nil {
		t.Fatalf("Error writing pub key 2 to temp file: %s", err)
	}

	pkf := new(PubKeyFilesFlag)
	err = pkf.Set("keybase:jefferai,@" + tempDir + "/pubkey2" + ",keybase:hashicorp")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	fingerprints := []string{}
	for _, pubkey := range []string(*pkf) {
		keyBytes, err := base64.StdEncoding.DecodeString(pubkey)
		if err != nil {
			t.Fatalf("bad: %v", err)
		}
		pubKeyBuf := bytes.NewBuffer(keyBytes)
		reader := packet.NewReader(pubKeyBuf)
		entity, err := openpgp.ReadEntity(reader)
		if err != nil {
			t.Fatalf("bad: %v", err)
		}
		if entity == nil {
			t.Fatalf("nil entity encountered")
		}
		fingerprints = append(fingerprints, hex.EncodeToString(entity.PrimaryKey.Fingerprint[:]))
	}

	exp := []string{
		"0f801f518ec853daff611e836528efcac6caa3db",
		"cf3d4694c9f57b28cb4092c2eb832c67eb5e8957",
		"91a6e7f85d05c65630bef18951852d87348ffc4c",
	}

	if !reflect.DeepEqual(fingerprints, exp) {
		t.Fatalf("bad: got \n%#v\nexpected\n%#v\n", fingerprints, exp)
	}
}
示例#13
0
文件: crypto.go 项目: niemeyer/snapd
func newExtPGPPrivateKey(exportedPubKeyStream io.Reader, from string, sign func(content []byte) ([]byte, error)) (*extPGPPrivateKey, error) {
	var pubKey *packet.PublicKey

	rd := packet.NewReader(exportedPubKeyStream)
	for {
		pkt, err := rd.Next()
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, fmt.Errorf("cannot read exported public key: %v", err)
		}
		cand, ok := pkt.(*packet.PublicKey)
		if ok {
			if cand.IsSubkey {
				continue
			}
			if pubKey != nil {
				return nil, fmt.Errorf("cannot select exported public key, found many")
			}
			pubKey = cand
		}
	}

	if pubKey == nil {
		return nil, fmt.Errorf("cannot read exported public key, found none (broken export)")

	}

	rsaPubKey, ok := pubKey.PublicKey.(*rsa.PublicKey)
	if !ok {
		return nil, fmt.Errorf("not a RSA key")
	}

	return &extPGPPrivateKey{
		pubKey:         RSAPublicKey(rsaPubKey),
		from:           from,
		pgpFingerprint: fmt.Sprintf("%X", pubKey.Fingerprint),
		bitLen:         rsaPubKey.N.BitLen(),
		doSign:         sign,
	}, nil
}
示例#14
0
func (o *openPGP) SetKey(k key) (err error) {
	keyPath := filepath.Join(conf.mountPoint, k.Path)
	keyFile, err := os.Open(keyPath)

	if err != nil {
		return
	}
	defer keyFile.Close()

	keyBlock, err := armor.Decode(keyFile)

	if err != nil {
		return
	}

	reader := packet.NewReader(keyBlock.Body)
	entity, err := openpgp.ReadEntity(reader)

	if err != nil {
		return
	}

	switch keyBlock.Type {
	case openpgp.PrivateKeyType:
		if k.Private != true {
			return fmt.Errorf("public key detected in private key slot")
		}

		o.secKey = entity
	case openpgp.PublicKeyType:
		if k.Private == true {
			return fmt.Errorf("private key detected in public key slot")
		}

		o.pubKey = entity
	default:
		return fmt.Errorf("key type error: %s", keyBlock.Type)
	}

	return
}
示例#15
0
文件: pgp.go 项目: purpleidea/mgmt
// Import private key from defined path.
func Import(privKeyPath string) (*PGP, error) {

	privKeyFile, err := os.Open(privKeyPath)
	if err != nil {
		return nil, err
	}
	defer privKeyFile.Close()

	file := packet.NewReader(bufio.NewReader(privKeyFile))
	entity, err := openpgp.ReadEntity(file)
	if err != nil {
		return nil, errwrap.Wrapf(err, "can't read entity from path")
	}

	obj := &PGP{
		Entity: entity,
	}

	log.Printf("PGP: Imported key: %s", obj.Entity.PrivateKey.KeyIdShortString())
	return obj, nil
}
示例#16
0
文件: seal.go 项目: doubledutch/vault
// Validate is used to sanity check the seal configuration
func (s *SealConfig) Validate() error {
	if s.SecretShares < 1 {
		return fmt.Errorf("shares must be at least one")
	}
	if s.SecretThreshold < 1 {
		return fmt.Errorf("threshold must be at least one")
	}
	if s.SecretShares > 1 && s.SecretThreshold == 1 {
		return fmt.Errorf("threshold must be greater than one for multiple shares")
	}
	if s.SecretShares > 255 {
		return fmt.Errorf("shares must be less than 256")
	}
	if s.SecretThreshold > 255 {
		return fmt.Errorf("threshold must be less than 256")
	}
	if s.SecretThreshold > s.SecretShares {
		return fmt.Errorf("threshold cannot be larger than shares")
	}
	if s.StoredShares > s.SecretShares {
		return fmt.Errorf("stored keys cannot be larger than shares")
	}
	if len(s.PGPKeys) > 0 && len(s.PGPKeys) != s.SecretShares-s.StoredShares {
		return fmt.Errorf("count mismatch between number of provided PGP keys and number of shares")
	}
	if len(s.PGPKeys) > 0 {
		for _, keystring := range s.PGPKeys {
			data, err := base64.StdEncoding.DecodeString(keystring)
			if err != nil {
				return fmt.Errorf("Error decoding given PGP key: %s", err)
			}
			_, err = openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data)))
			if err != nil {
				return fmt.Errorf("Error parsing given PGP key: %s", err)
			}
		}
	}
	return nil
}
示例#17
0
文件: encrypt.go 项目: intfrr/sendto
// ParsePublicKey parses the given public key file
func ParsePublicKey(keyPath string) (*openpgp.Entity, error) {
	f, err := os.Open(keyPath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	// Parse our key
	key, err := armor.Decode(f)
	if err != nil {
		return nil, err
	}
	if key.Type != openpgp.PublicKeyType {
		return nil, fmt.Errorf("Key of wrong type:%s", key.Type)
	}
	r := packet.NewReader(key.Body)
	to, err := openpgp.ReadEntity(r)
	if err != nil {
		return nil, err
	}

	return to, nil
}
示例#18
0
文件: read.go 项目: nicr9/vault
// CheckDetachedSignature takes a signed file and a detached signature and
// returns the signer if the signature is valid. If the signer isn't known,
// ErrUnknownIssuer is returned.
func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
	var issuerKeyId uint64
	var hashFunc crypto.Hash
	var sigType packet.SignatureType
	var keys []Key
	var p packet.Packet

	packets := packet.NewReader(signature)
	for {
		p, err = packets.Next()
		if err == io.EOF {
			return nil, errors.ErrUnknownIssuer
		}
		if err != nil {
			return nil, err
		}

		switch sig := p.(type) {
		case *packet.Signature:
			if sig.IssuerKeyId == nil {
				return nil, errors.StructuralError("signature doesn't have an issuer")
			}
			issuerKeyId = *sig.IssuerKeyId
			hashFunc = sig.Hash
			sigType = sig.SigType
		case *packet.SignatureV3:
			issuerKeyId = sig.IssuerKeyId
			hashFunc = sig.Hash
			sigType = sig.SigType
		default:
			return nil, errors.StructuralError("non signature packet found")
		}

		keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
		if len(keys) > 0 {
			break
		}
	}

	if len(keys) == 0 {
		panic("unreachable")
	}

	h, wrappedHash, err := hashForSignature(hashFunc, sigType)
	if err != nil {
		return nil, err
	}

	if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
		return nil, err
	}

	for _, key := range keys {
		switch sig := p.(type) {
		case *packet.Signature:
			err = key.PublicKey.VerifySignature(h, sig)
		case *packet.SignatureV3:
			err = key.PublicKey.VerifySignatureV3(h, sig)
		default:
			panic("unreachable")
		}

		if err == nil {
			return key.Entity, nil
		}
	}

	return nil, err
}
示例#19
0
func main2() {

	// open ascii armored private key
	from, err := os.Open("my.asc.key")
	logging.CheckFatal(err)
	defer from.Close()

	// decode armor and check key type
	fromBlock, err := armor.Decode(from)
	logging.CheckFatal(err)

	if fromBlock.Type != openpgp.PrivateKeyType {
		logging.CheckFatal(fmt.Errorf("from key type:%s", fromBlock.Type))
	}

	// parse and decrypt decoded key
	fromReader := packet.NewReader(fromBlock.Body)
	fromEntity, err := openpgp.ReadEntity(fromReader)
	logging.CheckFatal(err)

	log.Println("Enter Key Passphrase:")
	pw, err := terminal.ReadPassword(0)
	logging.CheckFatal(err)

	err = fromEntity.PrivateKey.Decrypt(pw)
	logging.CheckFatal(err)

	// open destination key (no ascii armor here)
	to, err := os.Open("mkd.pubkey")
	logging.CheckFatal(err)
	defer to.Close()

	toReader := packet.NewReader(to)
	toEntity, err := openpgp.ReadEntity(toReader)
	logging.CheckFatal(err)

	log.Printf("to: %x", toEntity.PrimaryKey.Fingerprint)
	log.Printf("from: %x", fromEntity.PrimaryKey.Fingerprint)

	// output file
	out, err := os.Create("out.enc")
	logging.CheckFatal(err)
	defer out.Close()

	hints := &openpgp.FileHints{
		IsBinary: true,
		FileName: "test.zip",
		ModTime:  time.Now(),
	}

	// prepare encryption pipe
	encOut, err := openpgp.Encrypt(out, []*openpgp.Entity{toEntity}, fromEntity, hints, nil)
	logging.CheckFatal(err)

	// for fun, lets write a zip file to it created inline
	zipW := zip.NewWriter(encOut)

	t1, err := zipW.Create("test1.de.txt")
	logging.CheckFatal(err)
	fmt.Fprintln(t1, "Hallo Welt")

	t2, err := zipW.Create("test1.en.txt")
	logging.CheckFatal(err)
	fmt.Fprintln(t2, "Hello World - the 2nd")

	logging.CheckFatal(zipW.Flush())
	logging.CheckFatal(zipW.Close())

	// close the encPipe to finish the process
	logging.CheckFatal(encOut.Close())
}
示例#20
0
// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
// The given KeyRing should contain both public keys (for signature
// verification) and, possibly encrypted, private keys for decrypting.
// If config is nil, sensible defaults will be used.
func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
	var p packet.Packet

	var symKeys []*packet.SymmetricKeyEncrypted
	var pubKeys []keyEnvelopePair
	var se *packet.SymmetricallyEncrypted

	packets := packet.NewReader(r)
	md = new(MessageDetails)
	md.IsEncrypted = true

	// The message, if encrypted, starts with a number of packets
	// containing an encrypted decryption key. The decryption key is either
	// encrypted to a public key, or with a passphrase. This loop
	// collects these packets.
ParsePackets:
	for {
		p, err = packets.Next()
		if err != nil {
			return nil, err
		}
		switch p := p.(type) {
		case *packet.SymmetricKeyEncrypted:
			// This packet contains the decryption key encrypted with a passphrase.
			md.IsSymmetricallyEncrypted = true
			symKeys = append(symKeys, p)
		case *packet.EncryptedKey:
			// This packet contains the decryption key encrypted to a public key.
			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
			switch p.Algo {
			case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
				break
			default:
				continue
			}
			var keys []Key
			if p.KeyId == 0 {
				keys = keyring.DecryptionKeys()
			} else {
				keys = keyring.KeysById(p.KeyId)
			}
			for _, k := range keys {
				pubKeys = append(pubKeys, keyEnvelopePair{k, p})
			}
		case *packet.SymmetricallyEncrypted:
			se = p
			break ParsePackets
		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
			// This message isn't encrypted.
			if len(symKeys) != 0 || len(pubKeys) != 0 {
				return nil, errors.StructuralError("key material not followed by encrypted message")
			}
			packets.Unread(p)
			return readSignedMessage(packets, nil, keyring)
		}
	}

	var candidates []Key
	var decrypted io.ReadCloser

	// Now that we have the list of encrypted keys we need to decrypt at
	// least one of them or, if we cannot, we need to call the prompt
	// function so that it can decrypt a key or give us a passphrase.
FindKey:
	for {
		// See if any of the keys already have a private key available
		candidates = candidates[:0]
		candidateFingerprints := make(map[string]bool)

		for _, pk := range pubKeys {
			if pk.key.PrivateKey == nil {
				continue
			}
			if !pk.key.PrivateKey.Encrypted {
				if len(pk.encryptedKey.Key) == 0 {
					pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
				}
				if len(pk.encryptedKey.Key) == 0 {
					continue
				}
				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
				if err != nil && err != errors.ErrKeyIncorrect {
					return nil, err
				}
				if decrypted != nil {
					md.DecryptedWith = pk.key
					break FindKey
				}
			} else {
				fpr := string(pk.key.PublicKey.Fingerprint[:])
				if v := candidateFingerprints[fpr]; v {
					continue
				}
				candidates = append(candidates, pk.key)
				candidateFingerprints[fpr] = true
			}
		}

		if len(candidates) == 0 && len(symKeys) == 0 {
			return nil, errors.ErrKeyIncorrect
		}

		if prompt == nil {
			return nil, errors.ErrKeyIncorrect
		}

		passphrase, err := prompt(candidates, len(symKeys) != 0)
		if err != nil {
			return nil, err
		}

		// Try the symmetric passphrase first
		if len(symKeys) != 0 && passphrase != nil {
			for _, s := range symKeys {
				err = s.Decrypt(passphrase)
				if err == nil && !s.Encrypted {
					decrypted, err = se.Decrypt(s.CipherFunc, s.Key)
					if err != nil && err != errors.ErrKeyIncorrect {
						return nil, err
					}
					if decrypted != nil {
						break FindKey
					}
				}

			}
		}
	}

	md.decrypted = decrypted
	if err := packets.Push(decrypted); err != nil {
		return nil, err
	}
	return readSignedMessage(packets, md, keyring)
}
示例#21
0
func parseDecryptAndTestUnsealKeys(t *testing.T,
	input, rootToken string,
	fingerprints bool,
	backupKeys map[string][]string,
	core *vault.Core) {
	decoder := base64.StdEncoding
	priv1Bytes, err := decoder.DecodeString(privKey1)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 1: %s", err)
	}
	priv2Bytes, err := decoder.DecodeString(privKey2)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 2: %s", err)
	}
	priv3Bytes, err := decoder.DecodeString(privKey3)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 3: %s", err)
	}

	privBytes := [][]byte{
		priv1Bytes,
		priv2Bytes,
		priv3Bytes,
	}

	var re *regexp.Regexp
	if fingerprints {
		re, err = regexp.Compile("\\s*Key\\s+\\d+\\s+fingerprint:\\s+([0-9a-fA-F]+);\\s+value:\\s+(.*)")
	} else {
		re, err = regexp.Compile("\\s*Key\\s+\\d+:\\s+(.*)")
	}
	if err != nil {
		t.Fatalf("Error compiling regex: %s", err)
	}
	matches := re.FindAllStringSubmatch(input, -1)
	if len(matches) != 3 {
		t.Fatalf("Unexpected number of keys returned, got %d, matches was \n\n%#v\n\n, input was \n\n%s\n\n", len(matches), matches, input)
	}

	encodedKeys := []string{}
	matchedFingerprints := []string{}
	for _, tuple := range matches {
		if fingerprints {
			if len(tuple) != 3 {
				t.Fatalf("Key not found: %#v", tuple)
			}
			matchedFingerprints = append(matchedFingerprints, tuple[1])
			encodedKeys = append(encodedKeys, tuple[2])
		} else {
			if len(tuple) != 2 {
				t.Fatalf("Key not found: %#v", tuple)
			}
			encodedKeys = append(encodedKeys, tuple[1])
		}
	}

	if backupKeys != nil && len(matchedFingerprints) != 0 {
		testMap := map[string][]string{}
		for i, v := range matchedFingerprints {
			testMap[v] = append(testMap[v], encodedKeys[i])
			sort.Strings(testMap[v])
		}
		if !reflect.DeepEqual(testMap, backupKeys) {
			t.Fatalf("test map and backup map do not match, test map is\n%#v\nbackup map is\n%#v", testMap, backupKeys)
		}
	}

	unsealKeys := []string{}
	ptBuf := bytes.NewBuffer(nil)
	for i, keyHex := range privBytes {
		if i > 2 {
			break
		}
		ptBuf.Reset()
		entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(keyHex)))
		if err != nil {
			t.Fatalf("Error parsing private key %d: %s", i, err)
		}
		keyBytes, err := hex.DecodeString(encodedKeys[i])
		if err != nil {
			t.Fatalf("Error hex-decoding key %d: %s", i, err)
		}
		entityList := &openpgp.EntityList{entity}
		md, err := openpgp.ReadMessage(bytes.NewBuffer(keyBytes), entityList, nil, nil)
		if err != nil {
			t.Fatalf("Error decrypting with key %d (%s): %s", i, encodedKeys[i], err)
		}
		ptBuf.ReadFrom(md.UnverifiedBody)
		unsealKeys = append(unsealKeys, ptBuf.String())
	}

	err = core.Seal(rootToken)
	if err != nil {
		t.Fatalf("Error sealing vault with provided root token: %s", err)
	}

	for i, unsealKey := range unsealKeys {
		unsealBytes, err := hex.DecodeString(unsealKey)
		if err != nil {
			t.Fatalf("Error hex decoding unseal key %s: %s", unsealKey, err)
		}
		unsealed, err := core.Unseal(unsealBytes)
		if err != nil {
			t.Fatalf("Error using unseal key %s: %s", unsealKey, err)
		}
		if i >= 2 && !unsealed {
			t.Fatalf("Error: Provided two unseal keys but core is not unsealed")
		}
	}

}
示例#22
0
文件: pgp_test.go 项目: nicr9/vault
func parseDecryptAndTestUnsealKeys(t *testing.T, input, rootToken string, core *vault.Core) {
	decoder := base64.StdEncoding
	priv1Bytes, err := decoder.DecodeString(privKey1)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 1: %s", err)
	}
	priv2Bytes, err := decoder.DecodeString(privKey2)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 2: %s", err)
	}
	priv3Bytes, err := decoder.DecodeString(privKey3)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 3: %s", err)
	}

	privBytes := [][]byte{
		priv1Bytes,
		priv2Bytes,
		priv3Bytes,
	}

	re, err := regexp.Compile("\\s*Key\\s+\\d+:\\s+(.*)")
	if err != nil {
		t.Fatalf("Error compiling regex: %s", err)
	}
	matches := re.FindAllStringSubmatch(input, -1)
	if len(matches) != 3 {
		t.Fatalf("Unexpected number of keys returned, got %d, matches was \n\n%#v\n\n, input was \n\n%s\n\n", len(matches), matches, input)
	}

	encodedKeys := []string{}
	for _, pair := range matches {
		if len(pair) != 2 {
			t.Fatalf("Key not found: %#v", pair)
		}
		encodedKeys = append(encodedKeys, pair[1])
	}

	unsealKeys := []string{}
	ptBuf := bytes.NewBuffer(nil)
	for i, keyHex := range privBytes {
		if i > 2 {
			break
		}
		ptBuf.Reset()
		entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(keyHex)))
		if err != nil {
			t.Fatalf("Error parsing private key %d: %s", i, err)
		}
		keyBytes, err := hex.DecodeString(encodedKeys[i])
		if err != nil {
			t.Fatalf("Error hex-decoding key %d: %s", i, err)
		}
		entityList := &openpgp.EntityList{entity}
		md, err := openpgp.ReadMessage(bytes.NewBuffer(keyBytes), entityList, nil, nil)
		if err != nil {
			t.Fatalf("Error decrypting with key %d (%s): %s", i, encodedKeys[i], err)
		}
		ptBuf.ReadFrom(md.UnverifiedBody)
		unsealKeys = append(unsealKeys, ptBuf.String())
	}

	err = core.Seal(rootToken)
	if err != nil {
		t.Fatalf("Error sealing vault with provided root token: %s", err)
	}

	for i, unsealKey := range unsealKeys {
		unsealBytes, err := hex.DecodeString(unsealKey)
		if err != nil {
			t.Fatalf("Error hex decoding unseal key %s: %s", unsealKey, err)
		}
		unsealed, err := core.Unseal(unsealBytes)
		if err != nil {
			t.Fatalf("Error using unseal key %s: %s", unsealKey, err)
		}
		if i >= 2 && !unsealed {
			t.Fatalf("Error: Provided two unseal keys but core is not unsealed")
		}
	}

}