func SerializeKeys(entity *openpgp.Entity) (privKeyArmor, pubKeyArmor string, err error) { // First serialize the private parts. // NOTE: need to call this in order to initialize the newly created entities, // otherwise entity.Serialize() will fail // https://code.google.com/p/go/issues/detail?id=6483 b := bytes.NewBuffer(nil) w, _ := armor.Encode(b, openpgp.PrivateKeyType, nil) err = entity.SerializePrivate(w, nil) if err != nil { return "", "", err } w.Close() privKeyArmor = b.String() // Serialize the public key. b.Reset() w, _ = armor.Encode(b, openpgp.PublicKeyType, nil) err = entity.Serialize(w) if err != nil { return "", "", err } w.Close() pubKeyArmor = b.String() return }
func GenerateKeyPair(name, desc, email string) (pubkey, privkey []byte, fp string, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("GenerateKeyPair() -> %v", e) } }() // generate a private key ent, err := openpgp.NewEntity(name, desc, email, nil) if err != nil { panic(err) } // serialize the private key pkbuf := bytes.NewBuffer(nil) err = ent.SerializePrivate(pkbuf, nil) if err != nil { panic(err) } buf := bytes.NewBuffer(nil) ewrbuf, err := armor.Encode(buf, openpgp.PrivateKeyType, nil) if err != nil { panic(err) } _, err = ewrbuf.Write(pkbuf.Bytes()) if err != nil { panic(err) } ewrbuf.Close() privkey = buf.Bytes() // serialize the public key pkbuf = bytes.NewBuffer(nil) err = ent.Serialize(pkbuf) if err != nil { panic(err) } buf = bytes.NewBuffer(nil) ewrbuf, err = armor.Encode(buf, openpgp.PublicKeyType, nil) if err != nil { panic(err) } _, err = ewrbuf.Write(pkbuf.Bytes()) if err != nil { panic(err) } ewrbuf.Close() pubkey = buf.Bytes() // validate the public key and obtain a fingerprint from it fp, err = LoadArmoredPubKey(pubkey) if err != nil { panic(err) } return }
func ArmorPubKey(pubkey []byte) (armoredPubKey []byte, err error) { var pubkeybuf bytes.Buffer // Load PGP public key el, err := openpgp.ReadArmoredKeyRing(bytes.NewBuffer(pubkey)) if err != nil { panic(err) } // serialize entities into io.Reader err = el[0].Serialize(&pubkeybuf) if err != nil { panic(err) } armoredbuf := bytes.NewBuffer(nil) ewrbuf, err := armor.Encode(armoredbuf, openpgp.PublicKeyType, nil) if err != nil { panic(err) } _, err = ewrbuf.Write(pubkeybuf.Bytes()) if err != nil { panic(err) } ewrbuf.Close() armoredPubKey = armoredbuf.Bytes() return }
// KeyringToArmoredPubKeys reads all public keys from a keyring and returned their armored format // into map of keys indexed by key fingerprint func KeyringToArmoredPubKeys(keyring io.ReadCloser) (armoredkeys map[string][]byte, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("KeyringToArmoredPubKeys() -> %v", e) } }() els, err := openpgp.ReadArmoredKeyRing(keyring) if err != nil { panic(err) } for _, el := range els { fingerprint := hex.EncodeToString(el.PrimaryKey.Fingerprint[:]) var pubkeybuf bytes.Buffer err = el.Serialize(&pubkeybuf) if err != nil { panic(err) } armoredbuf := bytes.NewBuffer(nil) ewrbuf, err := armor.Encode(armoredbuf, openpgp.PublicKeyType, nil) if err != nil { panic(err) } _, err = ewrbuf.Write(pubkeybuf.Bytes()) if err != nil { panic(err) } ewrbuf.Close() armoredkeys[fingerprint] = armoredbuf.Bytes() } return }
func ExportKey(key, filename string) error { entity, err := findKey(key) if err != nil { return err } f, err := os.Create(filename) if err != nil { return err } defer f.Close() w, err := armor.Encode(f, openpgp.PublicKeyType, nil) if err != nil { return err } err = entity.Serialize(w) if err != nil { return err } err = w.Close() if err != nil { return err } return nil }
// Encrypt the provided bytes for the provided encryption // keys recipients. Returns the encrypted content bytes. func Encrypt(d []byte, encryptionKeys *openpgp.EntityList) ([]byte, error) { var buffer *bytes.Buffer = &bytes.Buffer{} var armoredWriter io.WriteCloser var cipheredWriter io.WriteCloser var err error // Create an openpgp armored cipher writer pointing on our // buffer armoredWriter, err = armor.Encode(buffer, "PGP MESSAGE", nil) if err != nil { return nil, NewPgpError(ERR_ENCRYPTION_ENCODING, fmt.Sprintf("Can't make armor: %v", err)) } // Create an encrypted writer using the provided encryption keys cipheredWriter, err = openpgp.Encrypt(armoredWriter, *encryptionKeys, nil, nil, nil) if err != nil { return nil, NewPgpError(ERR_ENCRYPTION_ENCRYPT, fmt.Sprintf("Error encrypting: %v", err)) } // Write (encrypts on the fly) the provided bytes to // cipheredWriter _, err = cipheredWriter.Write(d) if err != nil { return nil, NewPgpError(ERR_ENCRYPTION_ENCRYPT, fmt.Sprintf("Error copying encrypted content: %v", err)) } cipheredWriter.Close() armoredWriter.Close() return buffer.Bytes(), nil }
// NewEntity creates a new entity. It doesn't provide an option for comments. func NewEntity(name, email, outFile string) (ne *openpgp.Entity, err error) { ne, err = openpgp.NewEntity(name, "", email, DefaultConfig) if err != nil { return } out, err := os.Create(outFile) if err != nil { ne = nil return } hdr := map[string]string{ "Version": fmt.Sprintf("Keybase Go client (OpenPGP version %s)", Version), } keyOut, err := armor.Encode(out, openpgp.PrivateKeyType, hdr) if err != nil { ne = nil return } defer func() { keyOut.Close() out.Close() }() err = ne.SerializePrivate(keyOut, DefaultConfig) if err != nil { ne = nil return } return }
func (d *dashEscaper) Close() (err error) { if !d.atBeginningOfLine { if err = d.buffered.WriteByte(lf); err != nil { return } } sig := new(packet.Signature) sig.SigType = packet.SigTypeText sig.PubKeyAlgo = d.privateKey.PubKeyAlgo sig.Hash = d.hashType sig.CreationTime = d.config.Now() sig.IssuerKeyId = &d.privateKey.KeyId if err = sig.Sign(d.h, d.privateKey, d.config); err != nil { return } out, err := armor.Encode(d.buffered, "PGP SIGNATURE", nil) if err != nil { return } if err = sig.Serialize(out); err != nil { return } if err = out.Close(); err != nil { return } if err = d.buffered.Flush(); err != nil { return } return }
// Export writes out the named public key, or all public keys if keyID // is empty. The result is an ASCII-armoured public key. func (keyRing *KeyRing) Export(keyID string) (armoured string, err error) { buf := new(bytes.Buffer) blockType := openpgp.PublicKeyType blockHeaders := map[string]string{ "Version": fmt.Sprintf("Keybase Go client (OpenPGP version %s)", Version), } armourBuffer, err := armor.Encode(buf, blockType, blockHeaders) if err != nil { return } if keyID != "" { e, ok := keyRing.Entities[strings.ToLower(keyID)] if !ok { err = ErrKeyNotFound return } e.Serialize(armourBuffer) } else { if len(keyRing.Entities) == 0 { err = ErrKeyNotFound return } for _, e := range keyRing.Entities { e.Serialize(armourBuffer) } } armourBuffer.Close() armoured = string(buf.Bytes()) return }
func encryptMail(e Envelope, keys openpgp.EntityList) (*bytes.Buffer, error) { var err error var contenttype string var buffer *bytes.Buffer var armored io.WriteCloser var crypter io.WriteCloser buffer = bytes.NewBuffer(nil) armored, err = armor.Encode(buffer, "PGP MESSAGE", nil) if err != nil { return buffer, err } crypter, err = openpgp.Encrypt(armored, keys, nil, nil, nil) if err != nil { return buffer, err } contenttype = e.Mail.Header.Get("Content-Type") if contenttype == "" { contenttype = "text/plain" } fmt.Fprintf(crypter, "Content-Type: %s\n\n", contenttype) io.Copy(crypter, e.Mail.Body) crypter.Close() armored.Close() return buffer, nil }
func encryptWith(m *Message, pubkeys openpgp.EntityList, signingEntity *openpgp.Entity, passphrase string) *EncryptStatus { if len(pubkeys) == 0 { return createEncryptFailure("no recipient keys") } buffer := new(bytes.Buffer) ar, err := armor.Encode(buffer, "PGP MESSAGE", nil) if err != nil { return createEncryptFailure("error encoding output message: " + err.Error()) } if signingEntity.PrivateKey == nil { return createEncryptFailure("signing key has no private key") } if signingEntity != nil && isSigningKeyLocked(signingEntity, passphrase) { return &EncryptStatus{Code: StatusFailedPassphraseNeeded} } w, err := openpgp.Encrypt(ar, pubkeys, signingEntity, nil, openpgpConfig) if err != nil { return createEncryptFailure("encryption operation failed: " + err.Error()) } bodyPart := createBodyMimePart(m) w.Write(bodyPart.rawContent) w.Close() ar.Close() buffer.WriteString("\n") err = writeEncryptedMimeBody(m, buffer.Bytes()) if err != nil { return createEncryptFailure(err.Error()) } if signingEntity != nil { return &EncryptStatus{Code: StatusSignedAndEncrypted, Message: m} } else { return &EncryptStatus{Code: StatusEncryptedOnly, Message: m} } }
// Sign signs the given message. func (keyRing *KeyRing) Sign(message []byte, keyID string) (sig []byte, err error) { err = keyRing.Unlock(keyID) if err != nil { return } signer := keyRing.Entities[strings.ToLower(keyID)] buf := new(bytes.Buffer) hdr := map[string]string{ "Version": fmt.Sprintf("Keybase Go client (OpenPGP version %s)", Version), } armourBuf, err := armor.Encode(buf, "PGP MESSAGE", hdr) if err != nil { return } opSig := &packet.OnePassSignature{ SigType: packet.SigTypeBinary, Hash: crypto.SHA1, PubKeyAlgo: packet.PubKeyAlgoRSA, KeyId: signer.PrimaryKey.KeyId, IsLast: true, } err = opSig.Serialize(armourBuf) if err != nil { return } literalPacket, err := newLiteralDataPacket(message, "", uint32(time.Now().Unix())) if err != nil { return } _, err = armourBuf.Write(literalPacket) if err != nil { return } sigPacket := &packet.Signature{ SigType: packet.SigTypeBinary, IssuerKeyId: &signer.PrimaryKey.KeyId, PubKeyAlgo: packet.PubKeyAlgoRSA, Hash: crypto.SHA1, CreationTime: time.Now(), } h := sha1.New() h.Write(message) err = sigPacket.Sign(h, signer.PrivateKey, nil) if err != nil { return } err = sigPacket.Serialize(armourBuf) if err != nil { return } armourBuf.Close() sig = buf.Bytes() return }
func main() { w, _ := armor.Encode(os.Stdout, "PGP MESSAGE", nil) plaintext, _ := openpgp.SymmetricallyEncrypt(w, []byte("golang"), nil) fmt.Fprintf(plaintext, "Hello from golang.\n") plaintext.Close() w.Close() fmt.Print("\n") }
func WriteArmoredPackets(w io.Writer, root PacketRecord) error { armw, err := armor.Encode(w, openpgp.PublicKeyType, nil) defer armw.Close() if err != nil { return err } return WritePackets(armw, root) }
func armoredDetachSign(w io.Writer, signer *Entity, message io.Reader, sigType packet.SignatureType, config *packet.Config) (err error) { out, err := armor.Encode(w, SignatureType, nil) if err != nil { return } err = detachSign(out, signer, message, sigType, config) if err != nil { return } return out.Close() }
func main() { ent, err := openpgp.NewEntity("bob", "Bob's key", "*****@*****.**", nil) if err != nil { panic(err) } pkbuf := bytes.NewBuffer(nil) err = ent.SerializePrivate(pkbuf, nil) if err != nil { panic(err) } buf := bytes.NewBuffer(nil) ewrbuf, err := armor.Encode(buf, "PGP PRIVATE KEY BLOCK", nil) if err != nil { panic(err) } _, err = ewrbuf.Write(pkbuf.Bytes()) if err != nil { panic(err) } ewrbuf.Close() fmt.Printf("%s\n", buf.Bytes()) // serialize the public key pkbuf = bytes.NewBuffer(nil) err = ent.Serialize(pkbuf) if err != nil { panic(err) } buf = bytes.NewBuffer(nil) ewrbuf, err = armor.Encode(buf, openpgp.PublicKeyType, nil) if err != nil { panic(err) } _, err = ewrbuf.Write(pkbuf.Bytes()) if err != nil { panic(err) } ewrbuf.Close() fmt.Printf("%s\n", buf.Bytes()) }
func exportArmoredKey(e *openpgp.Entity, header string, writeKey func(io.Writer) error) (string, error) { b := &bytes.Buffer{} w, err := armor.Encode(b, header, map[string]string{}) if err != nil { return "", err } err = writeKey(w) if err != nil { return "", err } w.Close() return b.String(), nil }
func main() { pubRingFile, _ := os.Open("/home/brad/.gnupg/pubring.gpg") pubRing, _ := openpgp.ReadKeyRing(pubRingFile) privRingFile, _ := os.Open("/home/brad/.gnupg/secring.gpg") privRing, _ := openpgp.ReadKeyRing(privRingFile) myPrivateKey := getKeyByEmail(privRing, "*****@*****.**") theirPublicKey := getKeyByEmail(pubRing, "*****@*****.**") w, _ := armor.Encode(os.Stdout, "PGP MESSAGE", nil) plaintext, _ := openpgp.Encrypt(w, []*openpgp.Entity{theirPublicKey}, myPrivateKey, nil) fmt.Fprintf(plaintext, "Hello from golang.\n") plaintext.Close() w.Close() fmt.Printf("\n") }
func ArmoredPublicKey(entity *openpgp.Entity) (string, error) { var buf bytes.Buffer wc, err := armor.Encode(&buf, openpgp.PublicKeyType, nil) if err != nil { return "", err } err = entity.PrivateKey.PublicKey.Serialize(wc) if err != nil { return "", err } wc.Close() if !bytes.HasSuffix(buf.Bytes(), newlineBytes) { buf.WriteString("\n") } return buf.String(), nil }
func SignText(entity *openpgp.Entity, text string) string { /* The armored signature from above can be verified in javascript like so: ```javascript sig = openpgp.read_message(sig_armored) pk = openpgp.read_publicKey(pubkey_armored) sig[0].signature.verify("some message", {obj:pk[0]}) ``` */ b := bytes.NewBuffer(nil) w, _ := armor.Encode(b, openpgp.SignatureType, nil) err := openpgp.DetachSign(w, entity, strings.NewReader(text), nil) if err != nil { panic(err) } w.Close() return b.String() }
//PubEntToAsciiArmor creates ASscii Armor from pubEnt of type openpgp.Entity func PubEntToAsciiArmor(pubEnt openpgp.Entity) (asciiEntity string, err error) { gotWriter := bytes.NewBuffer(nil) wr, errEncode := armor.Encode(gotWriter, openpgp.PublicKeyType, nil) if errEncode != nil { // fmt.Println("Encoding Armor ", errEncode.Error()) err = errEncode return } errSerial := pubEnt.Serialize(wr) if errSerial != nil { // fmt.Println("Serializing PubKey ", errSerial.Error()) } errClosing := wr.Close() if errClosing != nil { // fmt.Println("Closing writer ", errClosing.Error()) } asciiEntity = gotWriter.String() return }
func encryptForUsers(plaintext string, addrs []string) string { keys := make([]*openpgp.Entity, 0) for _, addr := range addrs { token := strings.Split(addr, "@")[0] user := LoadUser(token) if user == nil { // we've already told the SMTP sender that those // recipients don't exist on this server continue } entity, err := ReadEntity(user.PublicKey) if err != nil { panic(err) } keys = append(keys, entity) } if len(keys) == 0 { log.Printf("Warning: not encrypting incoming mail--unrecognized recipients") return plaintext } log.Printf("Encrypting plaintext for %s, found %d keys\n", strings.Join(addrs, ","), len(keys)) cipherBuffer := new(bytes.Buffer) w, err := armor.Encode(cipherBuffer, "PGP MESSAGE", nil) if err != nil { panic(err) } plainWriter, err := openpgp.Encrypt(w, keys, nil, nil, nil) if err != nil { panic(err) } plainWriter.Write([]byte(plaintext)) plainWriter.Close() w.Close() ciphertext := cipherBuffer.String() return ciphertext }
func encrypt(s string) string { buf := &bytes.Buffer{} wa, err := armor.Encode(buf, "PGP MESSAGE", nil) if err != nil { log.Fatalf("Can't make armor: %v", err) } w, err := openpgp.Encrypt(wa, encryptKeys, nil, nil, nil) if err != nil { log.Fatalf("Error encrypting: %v", err) } _, err = io.Copy(w, strings.NewReader(s)) if err != nil { log.Fatalf("Error encrypting: %v", err) } w.Close() wa.Close() return buf.String() }
func Encrypt(encryptionKeys *openpgp.EntityList, s string) []byte { buf := &bytes.Buffer{} wa, err := armor.Encode(buf, "PGP MESSAGE", nil) if err != nil { NewPgpError(ERR_ENCRYPTION_ENCODING, fmt.Sprintf("Can't make armor: %v", err)) } w, err := openpgp.Encrypt(wa, *encryptionKeys, nil, nil, nil) if err != nil { NewPgpError(ERR_ENCRYPTION_ENCRYPT, fmt.Sprintf("Error encrypting: %v", err)) } _, err = io.Copy(w, strings.NewReader(s)) if err != nil { log.Fatalf("Error copying encrypted content: %v", err) } w.Close() wa.Close() return buf.Bytes() }
/* * Client upload data received. * @param data []byte - uploaded document data * @return bool - post-processing successful? */ func PostprocessUploadData(data []byte) bool { logger.Println(logger.INFO, "[sid.upload] Client upload received") logger.Println(logger.DBG_ALL, "[sid.upload] Client upload data:\n"+string(data)) baseName := uploadPath + "/" + CreateId(16) // check if we use a shared secret scheme if reviewer == nil { // no: store content unencrypted. fname := baseName + ".document" wrt, err := os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { logger.Printf(logger.ERROR, "[sid.upload] Can't create document file '%s'\n", fname) return false } // write content and close file wrt.Write(data) wrt.Close() } else { // yes: use shared secret scheme to store upload in encrypted form. var ( err error engine cipher.Block = nil wrt io.WriteCloser = nil ct io.WriteCloser = nil pt io.WriteCloser = nil ) //----------------------------------------------------------------- // setup AES-256 for encryption //----------------------------------------------------------------- key := crypto.RandBytes(32) if engine, err = aes.NewCipher(key); err != nil { // should not happen at all; epic fail if it does logger.Println(logger.ERROR, "[sid.upload] Failed to setup AES cipher!") return false } bs := engine.BlockSize() iv := crypto.RandBytes(bs) enc := cipher.NewCFBEncrypter(engine, iv) logger.Println(logger.DBG_ALL, "[sid.upload] key:\n"+hex.Dump(key)) logger.Println(logger.DBG_ALL, "[sid.upload] IV:\n"+hex.Dump(iv)) //----------------------------------------------------------------- // encrypt client document into file //----------------------------------------------------------------- // open file for output fname := baseName + ".document.aes256" if wrt, err = os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666); err != nil { logger.Printf(logger.ERROR, "[sid.upload] Can't create document file '%s'\n", fname) return false } // write iv first wrt.Write(iv) // encrypt binary data for the document logger.Println(logger.DBG_ALL, "[sid.upload] AES256 in:\n"+hex.Dump(data)) enc.XORKeyStream(data, data) logger.Println(logger.DBG_ALL, "[sid.upload] AES256 out:\n"+hex.Dump(data)) // write to file wrt.Write(data) wrt.Close() //----------------------------------------------------------------- // create shares from secret //----------------------------------------------------------------- secret := new(big.Int).SetBytes(key) n := len(reviewer) shares := crypto.Split(secret, prime, n, treshold) recipient := make([]*openpgp.Entity, 1) for i, ent := range reviewer { // generate filename based on key id id := strconv.FormatUint(ent.PrimaryKey.KeyId&0xFFFFFFFF, 16) fname = baseName + "." + strings.ToUpper(id) + ".gpg" // create file for output if wrt, err = os.OpenFile(fname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666); err != nil { logger.Printf(logger.ERROR, "[sid.upload] Can't create share file '%s'\n", fname) continue } // create PGP armorer if ct, err = armor.Encode(wrt, "PGP MESSAGE", nil); err != nil { logger.Printf(logger.ERROR, "[sid.upload] Can't create armorer: %s\n", err.Error()) wrt.Close() continue } // encrypt share to file recipient[0] = ent if pt, err = openpgp.Encrypt(ct, recipient, nil, nil, nil); err != nil { logger.Printf(logger.ERROR, "[sid.upload] Can't create encrypter: %s\n", err.Error()) ct.Close() wrt.Close() continue } pt.Write([]byte(shares[i].P.String() + "\n")) pt.Write([]byte(shares[i].X.String() + "\n")) pt.Write([]byte(shares[i].Y.String() + "\n")) pt.Close() ct.Close() wrt.Close() } } // report success return true }