Beispiel #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
}
Beispiel #2
0
func PGPDecrypt(source io.Reader, sink io.Writer, kr openpgp.KeyRing) (*SignatureStatus, error) {
	peeker := NewPeeker(source)

	var r io.Reader
	r = peeker

	armored, clearsigned := PGPDetect(peeker)
	if clearsigned {
		return pgpDecryptClearsign(peeker, sink, kr)
	}

	if armored {
		b, err := armor.Decode(r)
		if err != nil {
			return nil, err
		}
		r = b.Body
	}

	G.Log.Debug("Calling into openpgp ReadMessage for decryption")
	md, err := openpgp.ReadMessage(r, kr, nil, nil)
	if err != nil {
		if err == errors.ErrKeyIncorrect {
			return nil, PGPNoDecryptionKeyError{Msg: "unable to find decryption key for this message"}
		}
		return nil, err
	}

	if md.IsSigned {
		G.Log.Debug("message is signed (SignedByKeyId: %+v) (have key? %v)", md.SignedByKeyId, md.SignedBy != nil)
	}

	n, err := io.Copy(sink, md.UnverifiedBody)
	if err != nil {
		return nil, err
	}
	G.Log.Debug("PGPDecrypt: copied %d bytes to writer", n)

	var status SignatureStatus
	if md.IsSigned {
		status.IsSigned = true
		status.KeyID = md.SignedByKeyId
		if md.Signature != nil {
			status.SignatureTime = md.Signature.CreationTime
		}
		if md.SignedBy != nil {
			status.Entity = md.SignedBy.Entity
		}
		if md.SignatureError != nil {
			status.SignatureError = md.SignatureError
		} else {
			status.Verified = true
		}
	}

	status.RecipientKeyIDs = md.EncryptedToKeyIds

	return &status, nil
}
Beispiel #3
0
func TestPGPEncryptLong(t *testing.T) {
	tc := SetupTest(t, "pgp_encrypt", 1)
	defer tc.Cleanup()
	bundleSrc, err := tc.MakePGPKey("*****@*****.**")
	if err != nil {
		t.Fatal(err)
	}
	bundleDst, err := tc.MakePGPKey("*****@*****.**")
	if err != nil {
		t.Fatal(err)
	}

	msg := make([]byte, 1024*1024)

	rand.Read(msg)

	G.Log.Info("msg size: %d", len(msg))

	sink := NewBufferCloser()
	recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
	if err := PGPEncrypt(bytes.NewReader(msg), sink, bundleSrc, recipients); err != nil {
		t.Fatal(err)
	}

	out := sink.Bytes()
	if len(out) == 0 {
		t.Fatal("no output")
	}

	// check that each recipient can read the message
	for _, recip := range recipients {
		kr := openpgp.EntityList{recip.Entity}
		emsg := bytes.NewBuffer(out)
		md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
		if err != nil {
			t.Fatal(err)
		}
		text, err := ioutil.ReadAll(md.UnverifiedBody)
		if err != nil {
			t.Fatal(err)
		}
		if string(text) != string(msg) {
			t.Errorf("message: %q, expected %q", string(text), string(msg))
		}
	}
}
Beispiel #4
0
func TestPGPEncryptQuick(t *testing.T) {
	tc := SetupTest(t, "pgp_encrypt", 1)
	defer tc.Cleanup()
	bundleSrc, err := tc.MakePGPKey("*****@*****.**")
	if err != nil {
		t.Fatal(err)
	}
	bundleDst, err := tc.MakePGPKey("*****@*****.**")
	if err != nil {
		t.Fatal(err)
	}

	f := func(msg []byte) bool {
		sink := NewBufferCloser()
		recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
		if err := PGPEncrypt(bytes.NewReader(msg), sink, bundleSrc, recipients); err != nil {
			return false
		}
		out := sink.Bytes()
		if len(out) == 0 {
			return false
		}

		// check that each recipient can read the message
		for _, recip := range recipients {
			kr := openpgp.EntityList{recip.Entity}
			emsg := bytes.NewBuffer(out)
			md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
			if err != nil {
				return false
			}
			data, err := ioutil.ReadAll(md.UnverifiedBody)
			if err != nil {
				return false
			}
			if !bytes.Equal(data, msg) {
				return false
			}
		}
		return true
	}

	if err := quick.Check(f, nil); err != nil {
		t.Error(err)
	}
}
Beispiel #5
0
func (ps *ParsedSig) AssertPayload(expected []byte) error {

	ring := EmptyKeyRing{}
	md, err := openpgp.ReadMessage(bytes.NewReader(ps.SigBody), ring, nil, nil)
	if err != nil {
		return err
	}
	data, err := ioutil.ReadAll(md.UnverifiedBody)
	if err != nil {
		return err
	}
	if !FastByteArrayEq(data, expected) {
		err = fmt.Errorf("Signature did not contain expected text")
		return err
	}
	return nil
}
Beispiel #6
0
func TestPGPEncryptString(t *testing.T) {
	tc := SetupTest(t, "pgp_encrypt", 1)
	defer tc.Cleanup()
	bundleSrc, err := tc.MakePGPKey("*****@*****.**")
	if err != nil {
		t.Fatal(err)
	}
	bundleDst, err := tc.MakePGPKey("*****@*****.**")
	if err != nil {
		t.Fatal(err)
	}

	msg := "59 seconds"
	recipients := []*PGPKeyBundle{bundleSrc, bundleDst}
	out, err := PGPEncryptString(msg, bundleSrc, recipients)
	if err != nil {
		t.Fatal(err)
	}

	if len(out) == 0 {
		t.Fatal("no output")
	}

	// check that each recipient can read the message
	for _, recip := range recipients {
		kr := openpgp.EntityList{recip.Entity}
		emsg := bytes.NewBuffer(out)
		md, err := openpgp.ReadMessage(emsg, kr, nil, nil)
		if err != nil {
			t.Fatal(err)
		}
		text, err := ioutil.ReadAll(md.UnverifiedBody)
		if err != nil {
			t.Fatal(err)
		}
		if string(text) != msg {
			t.Errorf("message: %q, expected %q", string(text), msg)
		}
	}
}
Beispiel #7
0
func (ps *ParsedSig) Verify(k PGPKeyBundle) (err error) {
	ps.MD, err = openpgp.ReadMessage(bytes.NewReader(ps.SigBody), k, nil, nil)
	if err != nil {
		return
	}
	if !ps.MD.IsSigned || ps.MD.SignedBy == nil {
		err = fmt.Errorf("Message wasn't signed")
		return
	}
	if !k.MatchesKey(ps.MD.SignedBy) {
		err = fmt.Errorf("Got wrong SignedBy key %v",
			hex.EncodeToString(ps.MD.SignedBy.PublicKey.Fingerprint[:]))
		return
	}
	if ps.MD.UnverifiedBody == nil {
		err = fmt.Errorf("no signed material found")
		return
	}

	ps.LiteralData, err = ioutil.ReadAll(ps.MD.UnverifiedBody)
	if err != nil {
		return
	}

	// We'll see a sig error here after reading in the UnverifiedBody above,
	// if there was one to see.
	if err = ps.MD.SignatureError; err != nil {
		return
	}

	if ps.MD.Signature == nil && ps.MD.SignatureV3 == nil {
		err = fmt.Errorf("No available signature after checking signature")
		return
	}

	// Hopefully by here we've covered all of our bases.
	return nil
}
Beispiel #8
0
func parseDecryptAndTestUnsealKeys(t *testing.T,
	input, rootToken string,
	fingerprints bool,
	backupKeys map[string][]string,
	backupKeysB64 map[string][]string,
	core *vault.Core) {

	decoder := base64.StdEncoding
	priv1Bytes, err := decoder.DecodeString(pgpkeys.TestPrivKey1)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 1: %s", err)
	}
	priv2Bytes, err := decoder.DecodeString(pgpkeys.TestPrivKey2)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 2: %s", err)
	}
	priv3Bytes, err := decoder.DecodeString(pgpkeys.TestPrivKey3)
	if err != nil {
		t.Fatalf("Error decoding bytes for private key 3: %s", err)
	}

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

	testFunc := func(bkeys map[string][]string) {
		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) != 4 {
			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 bkeys != 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, bkeys) {
				t.Fatalf("test map and backup map do not match, test map is\n%#v\nbackup map is\n%#v", testMap, bkeys)
			}
		}

		unsealKeys := []string{}
		ptBuf := bytes.NewBuffer(nil)
		for i, privKeyBytes := range privBytes {
			if i > 2 {
				break
			}
			ptBuf.Reset()
			entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(privKeyBytes)))
			if err != nil {
				t.Fatalf("Error parsing private key %d: %s", i, err)
			}
			var keyBytes []byte
			keyBytes, err = base64.StdEncoding.DecodeString(encodedKeys[i])
			if err != nil {
				t.Fatalf("Error 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")
			}
		}
	}

	testFunc(backupKeysB64)
}
Beispiel #9
0
func TestInit_PGP(t *testing.T) {
	ui := new(cli.MockUi)
	c := &InitCommand{
		Meta: meta.Meta{
			Ui: ui,
		},
	}

	core := vault.TestCore(t)
	ln, addr := http.TestServer(t, core)
	defer ln.Close()

	init, err := core.Initialized()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if init {
		t.Fatal("should not be initialized")
	}

	tempDir, pubFiles, err := getPubKeyFiles(t)
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(tempDir)

	args := []string{
		"-address", addr,
		"-key-shares", "2",
		"-pgp-keys", pubFiles[0] + ",@" + pubFiles[1] + "," + pubFiles[2],
		"-key-threshold", "2",
		"-root-token-pgp-key", pubFiles[0],
	}

	// This should fail, as key-shares does not match pgp-keys size
	if code := c.Run(args); code == 0 {
		t.Fatalf("bad (command should have failed): %d\n\n%s", code, ui.ErrorWriter.String())
	}

	args = []string{
		"-address", addr,
		"-key-shares", "4",
		"-pgp-keys", pubFiles[0] + ",@" + pubFiles[1] + "," + pubFiles[2] + "," + pubFiles[3],
		"-key-threshold", "2",
		"-root-token-pgp-key", pubFiles[0],
	}

	ui.OutputWriter.Reset()

	if code := c.Run(args); code != 0 {
		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
	}

	init, err = core.Initialized()
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if !init {
		t.Fatal("should be initialized")
	}

	sealConf, err := core.SealAccess().BarrierConfig()
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	pgpKeys := []string{}
	for _, pubFile := range pubFiles {
		pub, err := pgpkeys.ReadPGPFile(pubFile)
		if err != nil {
			t.Fatalf("bad: %v", err)
		}
		pgpKeys = append(pgpKeys, pub)
	}

	expected := &vault.SealConfig{
		Type:            "shamir",
		SecretShares:    4,
		SecretThreshold: 2,
		PGPKeys:         pgpKeys,
	}
	if !reflect.DeepEqual(expected, sealConf) {
		t.Fatalf("expected:\n%#v\ngot:\n%#v\n", expected, sealConf)
	}

	re, err := regexp.Compile("\\s+Initial Root Token:\\s+(.*)")
	if err != nil {
		t.Fatalf("Error compiling regex: %s", err)
	}
	matches := re.FindAllStringSubmatch(ui.OutputWriter.String(), -1)
	if len(matches) != 1 {
		t.Fatalf("Unexpected number of tokens found, got %d", len(matches))
	}

	encRootToken := matches[0][1]
	privKeyBytes, err := base64.StdEncoding.DecodeString(pgpkeys.TestPrivKey1)
	if err != nil {
		t.Fatalf("error decoding private key: %v", err)
	}
	ptBuf := bytes.NewBuffer(nil)
	entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(privKeyBytes)))
	if err != nil {
		t.Fatalf("Error parsing private key: %s", err)
	}
	var rootBytes []byte
	rootBytes, err = base64.StdEncoding.DecodeString(encRootToken)
	if err != nil {
		t.Fatalf("Error decoding root token: %s", err)
	}
	entityList := &openpgp.EntityList{entity}
	md, err := openpgp.ReadMessage(bytes.NewBuffer(rootBytes), entityList, nil, nil)
	if err != nil {
		t.Fatalf("Error decrypting root token: %s", err)
	}
	ptBuf.ReadFrom(md.UnverifiedBody)
	rootToken := ptBuf.String()

	parseDecryptAndTestUnsealKeys(t, ui.OutputWriter.String(), rootToken, false, nil, nil, core)

	client, err := c.Client()
	if err != nil {
		t.Fatalf("Error fetching client: %v", err)
	}

	client.SetToken(rootToken)

	tokenInfo, err := client.Auth().Token().LookupSelf()
	if err != nil {
		t.Fatalf("Error looking up root token info: %v", err)
	}

	if tokenInfo.Data["policies"].([]interface{})[0].(string) != "root" {
		t.Fatalf("expected root policy")
	}
}
Beispiel #10
0
func PGPDecrypt(g *GlobalContext, source io.Reader, sink io.Writer, kr openpgp.KeyRing) (*SignatureStatus, error) {

	var sc StreamClassification
	var err error

	sc, source, err = ClassifyStream(source)
	if err != nil {
		return nil, err
	}

	if sc.Format != CryptoMessageFormatPGP {
		return nil, WrongCryptoFormatError{
			Wanted:    CryptoMessageFormatPGP,
			Received:  sc.Format,
			Operation: "decrypt",
		}
	}

	if sc.Type == CryptoMessageTypeClearSignature {
		return pgpDecryptClearsign(g, source, sink, kr)
	}

	if sc.Armored {
		b, err := armor.Decode(source)
		if err != nil {
			return nil, err
		}
		source = b.Body
	}

	g.Log.Debug("Calling into openpgp ReadMessage for decryption")
	md, err := openpgp.ReadMessage(source, kr, nil, nil)
	if err != nil {
		if err == errors.ErrKeyIncorrect {
			return nil, NoDecryptionKeyError{Msg: "unable to find a PGP decryption key for this message"}
		}
		return nil, err
	}

	if md.IsSigned {
		g.Log.Debug("message is signed (SignedByKeyId: %+v) (have key? %v)", md.SignedByKeyId, md.SignedBy != nil)
	}

	n, err := io.Copy(sink, md.UnverifiedBody)
	if err != nil {
		return nil, err
	}
	g.Log.Debug("PGPDecrypt: copied %d bytes to writer", n)

	var status SignatureStatus
	if md.IsSigned {
		status.IsSigned = true
		status.KeyID = md.SignedByKeyId
		if md.Signature != nil {
			status.SignatureTime = md.Signature.CreationTime
		}
		if md.SignedBy != nil {
			status.Entity = md.SignedBy.Entity
		}
		if md.SignatureError != nil {
			status.SignatureError = md.SignatureError
		} else {
			status.Verified = true
		}
	}

	status.RecipientKeyIDs = md.EncryptedToKeyIds

	return &status, nil
}