func (s *SftpSession) DecryptFile(fname string) (string, error) { lr, err := os.Open(fname) if err != nil { return "", err } defer lr.Close() /* slurped, err := ioutil.ReadAll(lr) if err != nil { return "", err } */ fdecrypted := strings.TrimSuffix(fname, filepath.Ext(fname)) lw, err := os.Create(fdecrypted) if err != nil { return "", fmt.Errorf("open file error: %s, %s\n", fdecrypted, err.Error()) } var armorStart = []byte("-----BEGIN ") var msg *openpgp.MessageDetails var dcrypterr error buf := bufio.NewReaderSize(lr, 512) peek, err := buf.Peek(15) if err != nil { return "", fmt.Errorf("armor peek: %s, %s\n", fdecrypted, dcrypterr.Error()) } if bytes.HasPrefix(peek, armorStart) { // armored log.Printf("armored: %s\n", fname) // try reading in an armored block dearmor, err := armor.Decode(buf) if err != nil { log.Printf("not armored: %s\n", fname) return "", fmt.Errorf("armor read msg error: %s, %s\n", fdecrypted, dcrypterr.Error()) } else { log.Printf("armored: %s\n", fname) // Decrypt the dearmored message msg, dcrypterr = openpgp.ReadMessage(dearmor.Body, s.entityList, nil, nil) } } else { // Decrypt the binary message msg, dcrypterr = openpgp.ReadMessage(buf, s.entityList, nil, nil) } if dcrypterr != nil { return "", fmt.Errorf("decrypt read msg error: %s, %s\n", fdecrypted, dcrypterr.Error()) } _, err = io.Copy(lw, msg.UnverifiedBody) if err != nil { return "", err } return fdecrypted, nil }
func Decrypt(index int, kring openpgp.EntityList, keyName string, isSigned bool, filename string, passphrase []byte) (string, error) { err := DecryptPw(kring, keyName, passphrase) if err != nil { return "", err } f2, err := os.Open(filename) if err != nil { logrus.Errorf("#%d: error in Create: %s", index, err) return "", err } md, err := openpgp.ReadMessage(f2, kring, nil /* no prompt */, nil) if err != nil { logrus.Errorf("#%d: error reading message: %s", index, err) return "", err } /* testTime, _ := time.Parse("2006-01-02", "2013-07-01") if isSigned { signKey, _ := kring[0].signingKey(testTime) expectedKeyId := signKey.PublicKey.KeyId if md.SignedByKeyId != expectedKeyId { logrus.Errorf("#%d: message signed by wrong key id, got: %d, want: %d", i, *md.SignedBy, expectedKeyId) } if md.SignedBy == nil { logrus.Errorf("#%d: failed to find the signing Entity", i) } } */ plaintext, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { logrus.Errorf("#%d: error reading encrypted contents: %s", index, err) return "", err } /* encryptKey, _ := kring[0].encryptionKey(testTime) expectedKeyId := encryptKey.PublicKey.KeyId if len(md.EncryptedToKeyIds) != 1 || md.EncryptedToKeyIds[0] != expectedKeyId { logrus.Errorf("#%d: expected message to be encrypted to %v, but got %#v", i, expectedKeyId, md.EncryptedToKeyIds) } if string(plaintext) != message { logrus.Errorf("#%d: got: %s, want: %s", index, string(plaintext), message) } */ if isSigned { if md.SignatureError != nil { logrus.Errorf("#%d: signature error: %s", index, md.SignatureError) } if md.Signature == nil { logrus.Error("signature missing") } } return string(plaintext), nil }
// Decode - this function wraps around a Decoder object to decode the passed in data. // @param io.Reader[] src - This parameter will be used to read the encrypted data // @param io.Writer[] dest - This parameter will be used to write the unencrypted data func (d *Decoder) Decode(r io.Reader, w io.Writer) error { entitylist, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(d.Key)) if err != nil { return err } entity := entitylist[0] if entity.PrivateKey != nil && entity.PrivateKey.Encrypted { if len(d.Passphrase) == 0 { return errors.New("Private key is encrypted but you did not provide a passphrase") } err := entity.PrivateKey.Decrypt(d.Passphrase) if err != nil { return errors.New("Failed to decrypt private key. Did you use the wrong passphrase? (" + err.Error() + ")") } } for _, subkey := range entity.Subkeys { if subkey.PrivateKey != nil && subkey.PrivateKey.Encrypted { err := subkey.PrivateKey.Decrypt(d.Passphrase) if err != nil { return errors.New("Failed to decrypt subkey. Did you use the wrong passphrase? (" + err.Error() + ")") } } } read, err := openpgp.ReadMessage(r, entitylist, nil, nil) if err != nil { return err } _, err = io.Copy(w, read.LiteralData.Body) return err }
// 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 }
func decryptString(decryptionString string, encryptionPassphraseString string) (string, error) { encryptionPassphrase := []byte(encryptionPassphraseString) decbuf := bytes.NewBuffer([]byte(decryptionString)) result, err := armor.Decode(decbuf) if err != nil { return "", err } alreadyPrompted := false md, err := openpgp.ReadMessage(result.Body, nil, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { if alreadyPrompted { return nil, errors.New("Could not decrypt using passphrase") } else { alreadyPrompted = true } return encryptionPassphrase, nil }, nil) if err != nil { return "", err } bytes, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { return "", err } return string(bytes), nil }
func GpgDecrypt(text2decrypt string) string { encrypted := bytes.NewBuffer([]byte(text2decrypt)) bin_encrypt, err := armor.Decode(encrypted) if err != nil { log.Printf("[PGP] not an armored payload: %s", err.Error()) return "" } cleartext_md, err := openpgp.ReadMessage(bin_encrypt.Body, nil, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { return []byte(config.GetTribeID()), nil }, nil) if err != nil { log.Printf("[PGP] Can't decrypt payload: %s", err.Error()) return "" } plaintext, err := ioutil.ReadAll(cleartext_md.UnverifiedBody) if err != nil { log.Printf("[PGP] Can't read cleartext: %s", err.Error()) return "" } return string(plaintext) }
func (o *openPGP) Decrypt(input *os.File, output *os.File, verify bool) (err error) { keyRing := openpgp.EntityList{} keyRing = append(keyRing, o.secKey) if o.pubKey != nil { keyRing = append(keyRing, o.secKey) } messageDetails, err := openpgp.ReadMessage(input, keyRing, nil, nil) if err != nil { return } _, err = io.Copy(output, messageDetails.UnverifiedBody) if err != nil { return } if verify && !(messageDetails.IsSigned && messageDetails.SignatureError == nil) { return errors.New("file has been decrypted but signature verification failed") } return }
func Decrypt(data string, key_file string) (string, error) { secretKeyring, err := os.Open(key_file) if err != nil { return nil, err } defer secretKeyring.Close() // Taken from crypt and adapted decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(data)) entityList, err := openpgp.ReadArmoredKeyRing(secretKeyring) if err != nil { return nil, err } md, err := openpgp.ReadMessage(decoder, entityList, nil, nil) if err != nil { return nil, err } gzReader, err := gzip.NewReader(md.UnverifiedBody) if err != nil { return nil, err } defer gzReader.Close() bytes, err := ioutil.ReadAll(gzReader) if err != nil { return nil, err } return string(bytes), nil }
func Fuzz(data []byte) int { md, err := openpgp.ReadMessage(bytes.NewBuffer(data), emptyKR{}, newPromptFunction(), nil) if err != nil { return 0 } buf := new(bytes.Buffer) _, err = io.Copy(buf, md.UnverifiedBody) if err != nil { if _, ok := err.(pgperrors.SignatureError); ok { // The message structure is correct. It parsed // correctly, but only failed an integrity // check. We return 1 for it. Fully correct // messages will return 2 below. return 1 } return 0 } verifiedBody := buf.Bytes() if !bytes.Equal(plainBytes, verifiedBody) { // There seems to be no way of telling if an MDC was // checked for. If there was, we could check for that // and panic here. For now, we just assume that this // is a non-MDC protected message that has been // modified. return 1 } return 2 }
func (client PGP) DecryptBytes(esecret []byte) []byte { md, err := openpgp.ReadMessage(bytes.NewBuffer(esecret), client.PrivateEntities, nil, nil) if err != nil { panic(err) } bytes, _ := ioutil.ReadAll(md.UnverifiedBody) return bytes }
func main() { flag.Parse() if cpuprofile != "" { profFD, err := os.Create(cpuprofile) if err != nil { log.Fatalf("Cpuprofile: os.Create(): %v", err) } pprof.StartCPUProfile(profFD) defer pprof.StopCPUProfile() } c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGPIPE) go func() { <-c if cpuprofile != "" { pprof.StopCPUProfile() } // In case we had a hang, we print the stack trace here. buf := make([]byte, 256*1024) n := runtime.Stack(buf, true) fmt.Fprintln(os.Stderr, string(buf[0:n])) os.Exit(1) }() var fd *os.File = os.Stdin var err error if filename != "" { fd, err = os.Open(filename) if err != nil { log.Fatalf("Input: os.Open(): %v", err) } defer fd.Close() } md, err := openpgp.ReadMessage(fd, emptyKR{}, newPromptFunction(), nil) if err != nil { log.Fatalf("openpgp.ReadMessage(): %v", err) } log.Println("openpgp.ReadMessage() returned without error") _, err = io.Copy(os.Stdout, md.UnverifiedBody) if err != nil { log.Fatalf("Reading unverified plain text: io.Copy(): %v", err) } // Check that any authentication code for the message was // verified successfully if md.SignatureError != nil { log.Fatalln("Integrity Check FAILED:", md.SignatureError) } }
func decryptOpenpgp(data io.Reader, gpghome string, pass []byte) (io.Reader, error) { privkeyfile, err := os.Open(fmt.Sprintf("%s%ssecring.gpg", gpghome, string(os.PathSeparator))) if err != nil { fmt.Println("Failed to open secring", err) return nil, err } privring, err := openpgp.ReadKeyRing(privkeyfile) if err != nil { fmt.Println("Failed to open secring", err) return nil, err } //reader := bytes.NewReader(data) //brk,_ := ioutil.ReadAll(data) //fmt.Println("wtf",string(brk)) //fmt.Println("here is where eof panic") block, err := armor.Decode(data) if err != nil { fmt.Println(err) panic(err) } if len(pass) == 0 { fmt.Fprintf(os.Stderr, "Password: "******"") } for _, entity := range privring { if entity.PrivateKey != nil && entity.PrivateKey.Encrypted { entity.PrivateKey.Decrypt(pass) } for _, subkey := range entity.Subkeys { if subkey.PrivateKey != nil && subkey.PrivateKey.Encrypted { subkey.PrivateKey.Decrypt(pass) } } } md, err := openpgp.ReadMessage(block.Body, privring, nil, nil) if err != nil { return nil, err } return md.UnverifiedBody, nil //plaintext, err := ioutil.ReadAll(md.UnverifiedBody) //if err != nil { // panic(err) // } // return plaintext, nil }
func main() { encrypt_out := flag.String("out", "ciphertext.out", "Ciphertext") log.Println("Create key pair") // Create a key-pair entity, _ := openpgp.NewEntity("The Receiver", "testing", "*****@*****.**", nil) log.Println("Start encryption") config := &packet.Config{ DefaultHash: crypto.SHA256, } file, err := os.OpenFile(*encrypt_out, os.O_WRONLY|os.O_CREATE, 0600) // For some reason it uses RIPEMD160 ? plain, err := openpgp.Encrypt(file, []*openpgp.Entity{entity}, nil, nil, config) if err != nil { log.Fatal(err) } // Input of plaintext: a stream (as we typically would get from a // network stream). plain.Write([]byte("Hello World plaintext!\n")) plain.Close() // Decrypt read_file, _ := os.Open(*encrypt_out) keyring := openpgp.EntityList{entity} message, err := openpgp.ReadMessage(read_file, keyring, func(keys []openpgp.Key, sym bool) ([]byte, error) { log.Printf("Prompt got called\n") return nil, nil }, nil) if err != nil { log.Fatal(err) } // Read the encrypted file and dump plain-text to stdout. body_reader := message.UnverifiedBody buffer := make([]byte, 1024) for { n, _ := body_reader.Read(buffer) if n == 0 { break } os.Stdout.Write(buffer[0:n]) } log.Println("Done.") }
func decodeBase64EncryptedMessage(s string, keyring openpgp.KeyRing) string { // Decrypt base64 encoded encrypted message using decrypted private key dec, err := base64.StdEncoding.DecodeString(s) if err != nil { log.Fatalln("ERR:", err) } debug.Printf("keyring: #%v", keyring) md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), keyring, nil, nil) if err != nil { log.Fatalln("ERR: Error reading message - ", err) } bytes, err := ioutil.ReadAll(md.UnverifiedBody) debug.Printf("md:", string(bytes)) return string(bytes) }
func ReadEncrypted(ciphertext io.ReadCloser, el openpgp.EntityList, passphrase []byte) (io.ReadCloser, error) { md, err := openpgp.ReadMessage(ciphertext, el, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { if symmetric { return nil, fmt.Errorf("No support for symmetrical encryption") } for _, key := range keys { if err := key.PrivateKey.Decrypt(passphrase); err != nil { return nil, ErrCannotDecryptKey } return nil, nil } return nil, ErrNoMatchingKeys }, nil) if err != nil { return nil, err } return &encryptedReader{ciphertext, md.UnverifiedBody}, nil }
// Decrypt uses PGP to obtain the data key from the EncryptedKey store in the MasterKey and returns it func (key *MasterKey) Decrypt() ([]byte, error) { ring, err := key.secRing() if err != nil { return nil, fmt.Errorf("Could not load secring: %s", err) } block, err := armor.Decode(strings.NewReader(key.EncryptedKey)) if err != nil { return nil, fmt.Errorf("Armor decoding failed: %s", err) } md, err := openpgp.ReadMessage(block.Body, ring, key.passphrasePrompt, nil) if err != nil { return nil, fmt.Errorf("Reading PGP message failed: %s", err) } if b, err := ioutil.ReadAll(md.UnverifiedBody); err == nil { return b, nil } return nil, fmt.Errorf("The key could not be decrypted with any of the GPG entries") }
func printMessage() { decbuf := bytes.NewBuffer([]byte(encryptedMessage)) result, err := armor.Decode(decbuf) if err != nil { log.Fatal(err) } md, err := openpgp.ReadMessage(result.Body, nil, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { return []byte("golang"), nil }, nil) if err != nil { log.Fatal(err) } fmt.Println("dec version:", result.Header["Version"]) fmt.Println("dec type:", result.Type) bytes, err := ioutil.ReadAll(md.UnverifiedBody) fmt.Println("md:", string(bytes)) }
// Decrypt decrypt an encrypted message func (g *Gpg) Decrypt(blob []byte) ([]byte, error) { // Open the private key file privateRingBuffer, err := os.Open(g.PrivateKeyring) if err != nil { return nil, err } defer privateRingBuffer.Close() privateRing, err := openpgp.ReadKeyRing(privateRingBuffer) if err != nil { return nil, err } privateKey := getKeyByEmail(privateRing, g.Email) fmt.Print("GPG Passphrase: ") passphrase, err := terminal.ReadPassword(0) fmt.Println("") log.Printf("[DEBUG] GPG Decrypting private key using passphrase") //passphraseByte := []byte(passphrase) privateKey.PrivateKey.Decrypt(passphrase) for _, subkey := range privateKey.Subkeys { subkey.PrivateKey.Decrypt(passphrase) } log.Printf("[DEBUG] GPG Finished decrypting private key using passphrase") armoredBlock, err := armor.Decode(bytes.NewReader(blob)) if err != nil { return nil, err } // Decrypt it with the contents of the private key md, err := openpgp.ReadMessage(armoredBlock.Body, privateRing, nil, nil) if err != nil { return nil, fmt.Errorf("GPG Read message failed: %v", err) } plain, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { return nil, err } return plain, nil }
func (pkr PassphraseKeyring) ReadMessage(r io.Reader, keyring openpgp.KeyRing, prompt interface{}, config *packet.Config) (md *openpgp.MessageDetails, err error) { var handler Prompter switch t := prompt.(type) { case Prompter: handler = t case openpgp.PromptFunction: handler = NewPrompter(t) } if handler == nil { handler = pkr.Prompt } p := &passphrase{ Keyring: pkr.Keyring, handler: handler, tried: make(map[uint64]struct{}), } return openpgp.ReadMessage(r, keyring, p.check, config) }
// Decrypt an encrypted msg. func (obj *PGP) Decrypt(encString string) (string, error) { entityList := openpgp.EntityList{obj.Entity} // decode the base64 string dec, err := base64.StdEncoding.DecodeString(encString) if err != nil { return "", errwrap.Wrapf(err, "fail at decoding encrypted string") } // decrypt it with the contents of the private key md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), entityList, nil, nil) if err != nil { return "", errwrap.Wrapf(err, "can't read message") } bytes, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { return "", errwrap.Wrapf(err, "can't read unverified body") } return string(bytes), nil }
// Deocde decodes data using the secconf codec. func Decode(data []byte, secertKeyring io.Reader) ([]byte, error) { decoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBuffer(data)) entityList, err := openpgp.ReadArmoredKeyRing(secertKeyring) if err != nil { return nil, err } md, err := openpgp.ReadMessage(decoder, entityList, nil, nil) if err != nil { return nil, err } gzReader, err := gzip.NewReader(md.UnverifiedBody) if err != nil { return nil, err } defer gzReader.Close() bytes, err := ioutil.ReadAll(gzReader) if err != nil { return nil, err } return bytes, nil }
// DecryptData decrypts data using OpenPGP decryption. func DecryptData(input []byte, password string) []byte { inputReader := bytes.NewReader(input) tried := false md, err := openpgp.ReadMessage(inputReader, nil, func(keys []openpgp.Key, symmetric bool) ([]byte, error) { if tried { return nil, errors.New("invalid password") } tried = true return []byte(password), nil }, nil) PanicIfErr(err) output, err := ioutil.ReadAll(md.UnverifiedBody) PanicIfErr(err) return output }
// UntrustedSignatureContents returns UNTRUSTED contents of the signature WITHOUT ANY VERIFICATION, // along with a short identifier of the key used for signing. // WARNING: The short key identifier (which correponds to "Key ID" for OpenPGP keys) // is NOT the same as a "key identity" used in other calls ot this interface, and // the values may have no recognizable relationship if the public key is not available. func (m gpgSigningMechanism) UntrustedSignatureContents(untrustedSignature []byte) (untrustedContents []byte, shortKeyIdentifier string, err error) { // This uses the Golang-native OpenPGP implementation instead of gpgme because we are not doing any cryptography. md, err := openpgp.ReadMessage(bytes.NewReader(untrustedSignature), openpgp.EntityList{}, nil, nil) if err != nil { return nil, "", err } if !md.IsSigned { return nil, "", errors.New("The input is not a signature") } content, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { // Coverage: An error during reading the body can happen only if // 1) the message is encrypted, which is not our case (and we don’t give ReadMessage the key // to decrypt the contents anyway), or // 2) the message is signed AND we give ReadMessage a correspnding public key, which we don’t. return nil, "", err } // Uppercase the key ID for minimal consistency with the gpgme-returned fingerprints // (but note that key ID is a suffix of the fingerprint only for V4 keys, not V3)! return content, strings.ToUpper(fmt.Sprintf("%016X", md.SignedByKeyId)), nil }
// DecryptMessage is largely from // http://chiselapp.com/user/loser/repository/auricular/artifact/e14b57f441816f449105d201e7fb429f76907c65 func DecryptMessage(recipient, cipher string) (fromId uint64, msg string, err error) { // if DEBUG { log.Printf("Within decryptMessage: cipher == %v\n", cipher) } r := bytes.NewBufferString(cipher) // r := strings.NewReader(cipher) block, err := armor.Decode(r) if err != nil { return 0, "", fmt.Errorf("Error decrypting message: %v", err) } if DEBUG { log.Printf("Getting entity from private keyring\n") } myPrivateKey, err := GetEntityFrom(recipient, PRIVATE_KEYRING_FILENAME) if err != nil { return 0, "", fmt.Errorf("Error getting private key for %s: %v", recipient, err) } entities := openpgp.EntityList([]*openpgp.Entity{myPrivateKey}) if DEBUG { log.Printf("Got entities\n") } details, err := openpgp.ReadMessage(block.Body, entities, nil, nil) if err != nil { return 0, "", fmt.Errorf("Error reading message block body: %v", err) } // Read the message body if DEBUG { log.Printf("Reading raw message body\n") } raw, err := ioutil.ReadAll(details.UnverifiedBody) if err != nil { return 0, "", fmt.Errorf("Error reading decrypted message body: %v", err) } return details.SignedByKeyId, string(raw), nil }
// Make sure to pass in a passphrase to prevent interactive prompt. func Decrypt(e string, p []byte) (string, error) { if len(p) <= 0 { p = PrivatePrompt(c.R + "Oh really? " + c.X) cached_passphrase = p } b := bytes.NewBufferString(PrivKey()) ring, err := openpgp.ReadArmoredKeyRing(b) if err != nil { return "", err } first := ring[0] if first.PrivateKey != nil && first.PrivateKey.Encrypted { err := first.PrivateKey.Decrypt(p) if err != nil { return "", err } } for _, subkey := range first.Subkeys { if subkey.PrivateKey != nil && subkey.PrivateKey.Encrypted { subkey.PrivateKey.Decrypt(p) } } dec, err := base64.StdEncoding.DecodeString(e) if err != nil { return "", err } md, err := openpgp.ReadMessage(bytes.NewBuffer(dec), ring, nil, nil) if err != nil { return "", err } bytes, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { return "", err } return string(bytes), nil }
func (ctx *SecureContext) DecryptFile(filePath string) (*openpgp.MessageDetails, error) { secfile, err := os.Open(filePath) if err != nil { return nil, err } block, err := armor.Decode(secfile) if err != nil { return nil, err } promptCallback := func(keys []openpgp.Key, symmetric bool) ([]byte, error) { for _, k := range keys { err := k.PrivateKey.Decrypt([]byte(ctx.Password)) if err != nil { return nil, err } return nil, nil } return nil, errors.New("invalid password or no private key") } return openpgp.ReadMessage(block.Body, ctx.PrivateRing, promptCallback, nil) }
// decrypt uses PGP to decrypt symmetrically encrypted and armored text // with the provided password. func (c *OpenPGPClient) Decrypt(ciphertext []byte, password []byte) (plaintext []byte, err error) { decbuf := bytes.NewBuffer(ciphertext) armorBlock, err := armor.Decode(decbuf) if err != nil { return } failed := false prompt := func(keys []openpgp.Key, symmetric bool) ([]byte, error) { // If the given passphrase isn't correct, the function will be called again, forever. // This method will fail fast. // Ref: https://godoc.org/golang.org/x/crypto/openpgp#PromptFunction if failed { return nil, &errors.SafeDecryptionFailed{} } failed = true return password, nil } md, err := openpgp.ReadMessage(armorBlock.Body, nil, prompt, c.packetConfig) if err != nil { return } decryptedBuf, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { return } plaintext = decryptedBuf return }
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") } } }
func main() { log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // Parse the flags flag.Parse() // Open the private key file privateKeyFile, err := os.Open(*privateKey) if err != nil { log.Fatal(err) } // Parse the file keyring, err := openpgp.ReadArmoredKeyRing(privateKeyFile) if err != nil { log.Fatal(err) } for _, key := range keyring { if key.PrivateKey != nil && key.PrivateKey.Encrypted { if err := key.PrivateKey.Decrypt([]byte(*password)); err != nil { log.Fatal(err) } } if key.Subkeys != nil { for _, subkey := range key.Subkeys { if err := subkey.PrivateKey.Decrypt([]byte(*password)); err != nil { log.Fatal(err) } } } } // Open the email file emailFile, err := os.Open(*input) if err != nil { log.Fatal(err) } // Parse the email rootEmail, err := mail.ReadMessage(emailFile) if err != nil { log.Fatal(err) } // Print some data fmt.Print("Original headers:\n") for key, values := range rootEmail.Header { fmt.Printf("\t%s: %v\n", key, strings.Join(values, ", ")) } // Get the Content-Type contentType := rootEmail.Header.Get("content-type") // Get the boundary mediaType, params, err := mime.ParseMediaType(contentType) if err != nil { log.Fatal(err) } // Parse the body if !strings.HasPrefix(mediaType, "multipart/") { log.Fatal("Email isn't multipart") } // Find the manifest and decode it var man *manifest.Manifest rootBody, err := ioutil.ReadAll(rootEmail.Body) if err != nil { log.Fatal(err) } // Create a new multipart reader rootReader := multipart.NewReader(bytes.NewReader(rootBody), params["boundary"]) for { part, err := rootReader.NextPart() if err == io.EOF { break } if err != nil { log.Fatal(err) } // Add the header as this library is weird header := "" for key, values := range part.Header { header += key + ": " + strings.Join(values, ", ") + "\n" } body, err := ioutil.ReadAll(part) if err != nil { log.Fatal(err) } body = append([]byte(header+"\n\n"), body...) // Parse the email email, err := mail.ReadMessage(bytes.NewReader(body)) if err != nil { log.Fatal(err) } mediaType, _, err := mime.ParseMediaType(email.Header.Get("content-type")) if err != nil { log.Fatal(err) } // We found the body if mediaType == "application/x-pgp-manifest+json" { block, err := armor.Decode(email.Body) if err != nil { log.Fatal(err) } body, err := ioutil.ReadAll(block.Body) if err != nil { log.Fatal(err) } md, err := openpgp.ReadMessage(bytes.NewReader(body), keyring, nil, nil) if err != nil { log.Fatal(err) } cleartext, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { log.Fatal(err) } m, err := manifest.Parse(cleartext) if err != nil { log.Fatal(err) } man = m // Show manifest data fmt.Print("Manifest headers:\n") for key, value := range man.Headers { fmt.Printf("\t%s: %s\n", key, value) } fmt.Print("Email parts in the manifest:\n") for _, part := range man.Parts { fmt.Printf("\t- Hash: %s\n", part.Hash) fmt.Printf("\t ID: %s\n", part.ID) if part.Filename != "" { fmt.Printf("\t Filename: %s\n", part.Filename) } } break } } rootReader = multipart.NewReader(bytes.NewReader(rootBody), params["boundary"]) for { part, err := rootReader.NextPart() if err == io.EOF { break } if err != nil { log.Fatal(err) } // Add the header as this library is weird header := "" for key, values := range part.Header { header += key + ": " + strings.Join(values, ", ") + "\n" } body, err := ioutil.ReadAll(part) if err != nil { log.Fatal(err) } body = append([]byte(header+"\n\n"), body...) // Parse the email email, err := mail.ReadMessage(bytes.NewReader(body)) if err != nil { log.Fatal(err) } mediaType, params, err := mime.ParseMediaType(email.Header.Get("content-type")) if err != nil { log.Print(email.Header.Get("content-type")) log.Fatal(err) } if mediaType == "multipart/alternative" { bodyReader := multipart.NewReader(bytes.NewReader(body), params["boundary"]) for { part, err := bodyReader.NextPart() if err == io.EOF { break } if err != nil { log.Fatal(err) } // Add the header as this library is weird header := "" for key, values := range part.Header { header += key + ": " + strings.Join(values, ", ") } body, err := ioutil.ReadAll(part) if err != nil { log.Fatal(err) } body = append([]byte(header+"\n\n"), body...) // Parse the part email, err := mail.ReadMessage(bytes.NewReader(body)) if err != nil { log.Fatal(err) } // Parse the content type mediaType, _, err := mime.ParseMediaType(email.Header.Get("content-type")) if err != nil { log.Fatal(err) } if mediaType == "application/pgp-encrypted" { block, err := armor.Decode(email.Body) if err != nil { log.Fatal(err) } body, err := ioutil.ReadAll(block.Body) if err != nil { log.Fatal(err) } md, err := openpgp.ReadMessage( bytes.NewReader(body), keyring, nil, nil, ) if err != nil { log.Fatal(err) } cleartext, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { log.Fatal(err) } // Find body definition var bodyPart *manifest.Part for _, part := range man.Parts { if part.ID == "body" { bodyPart = part } } bodyHash := sha256.Sum256(cleartext) if bodyPart.Hash != hex.EncodeToString(bodyHash[:]) { log.Fatal("Email's body has an invalid checksum") } fmt.Print("Email's body:\n") for _, line := range strings.Split(string(cleartext), "\n") { fmt.Printf("\t%s\n", line) } } } } else if mediaType != "application/x-pgp-manifest+json" { contentDisposition := email.Header.Get("Content-Disposition") filenameIndex := strings.Index(contentDisposition, `filename="`) if filenameIndex == -1 { continue } postFilename := contentDisposition[filenameIndex+10:] quoteIndex := strings.Index(postFilename, `"`) if quoteIndex == -1 { continue } filename := postFilename[:quoteIndex] extension := filepath.Ext(filename) if extension != ".pgp" { continue } id := filename[:len(filename)-len(extension)] // look up filename against the deps var part *manifest.Part for _, part2 := range man.Parts { if part2.ID == id { part = part2 } } if part == nil { continue } block, err := armor.Decode(email.Body) if err != nil { continue } body, err := ioutil.ReadAll(block.Body) if err != nil { log.Fatal(err) } md, err := openpgp.ReadMessage(bytes.NewReader(body), keyring, nil, nil) if err != nil { log.Fatal(err) } cleartext, err := ioutil.ReadAll(md.UnverifiedBody) if err != nil { log.Fatal(err) } bodyHash := sha256.Sum256(cleartext) if part.Hash != hex.EncodeToString(bodyHash[:]) { log.Fatal("Attachment's body has an invalid checksum") } fmt.Printf("Attachment %s:\n", id) fmt.Printf("\tFilename: %s\n", part.Filename) fmt.Printf("\tContent type: %s\n", part.ContentType) fmt.Print("\tBody:\n") for _, line := range strings.Split(string(cleartext), "\n") { fmt.Printf("\t\t%s\n", line) } } } }
func Decrypt(privateKeyFileName string, readPass readPasswordCallback, publicKeyFileName string, file string) (err error) { if filepath.Ext(file) != ".pgp" { return fmt.Errorf("quickpgp: filename to decrypt must end in .pgp") } var signer openpgp.EntityList if signer, err = readPublicKeyFile(publicKeyFileName); err != nil { return err } var recipient *openpgp.Entity if recipient, err = readPrivateKeyFile(privateKeyFileName, readPass); err != nil { return err } if recipient == nil { return fmt.Errorf("quickpgp: unable to read %s", privateKeyFileName) } var keyring openpgp.EntityList keyring = append(keyring, signer[0]) keyring = append(keyring, recipient) var cipherTextFile *os.File if cipherTextFile, err = os.Open(file); err != nil { return err } defer cipherTextFile.Close() var cipherText io.Reader if p, err := armor.Decode(cipherTextFile); err == nil { cipherText = p.Body } else { if _, err = cipherTextFile.Seek(0, 0); err != nil { return err } cipherText = cipherTextFile } var md *openpgp.MessageDetails if md, err = openpgp.ReadMessage(cipherText, keyring, nil, nil); err != nil { return err } var cwd string if cwd, err = os.Getwd(); err != nil { return err } var plainTextOutput *os.File if plainTextOutput, err = ioutil.TempFile(cwd, ".quickpgp."); err != nil { return err } var cleanExit bool defer func() { if !cleanExit { _ = os.Remove(plainTextOutput.Name()) } }() _, err = io.Copy(plainTextOutput, md.UnverifiedBody) if err != nil { return err } plainTextOutput.Close() if md.SignatureError != nil { return md.SignatureError } if md.Signature == nil { return openpgperrors.ErrUnknownIssuer } bareFilename := strings.TrimSuffix(file, filepath.Ext(file)) if len(md.LiteralData.FileName) != 0 && md.LiteralData.FileName != bareFilename { fmt.Fprintf(os.Stderr, "quickpgp: suggested filename \"%s\"\n", md.LiteralData.FileName) } var finalFilename string if _, err := os.Stat(bareFilename); os.IsNotExist(err) { finalFilename = bareFilename } else { finalFilename = fmt.Sprintf("%s.%X", bareFilename, uint32(md.SignedByKeyId&0xffffffff)) fmt.Fprintf(os.Stderr, "quickpgp: \"%s\" exists, writing to \"%s\"\n", bareFilename, finalFilename) } err = os.Rename(plainTextOutput.Name(), finalFilename) if err == nil { cleanExit = true } return err }