// Encrypt a message, and make sure recipients can decode it, and // non-recipients can't decode it. func TestSaltpackEncDec(t *testing.T) { senderKP, err := GenerateNaclDHKeyPair() if err != nil { t.Fatal(err) } var receiverKPs []NaclDHKeyPair var receiverPKs []NaclDHKeyPublic for i := 0; i < 12; i++ { kp, err := GenerateNaclDHKeyPair() if err != nil { t.Fatal(err) } receiverKPs = append(receiverKPs, kp) receiverPKs = append(receiverPKs, kp.Public) } nonReceiverKP, err := GenerateNaclDHKeyPair() if err != nil { t.Fatal(err) } message := "The Magic Words are Squeamish Ossifrage" var buf outputBuffer arg := SaltpackEncryptArg{ Source: strings.NewReader(message), Sink: &buf, Receivers: receiverPKs, Sender: senderKP, } if err := SaltpackEncrypt(G, &arg); err != nil { t.Fatal(err) } ciphertext := buf.String() if !strings.HasPrefix(ciphertext, saltpack.MakeArmorHeader(saltpack.MessageTypeEncryption, KeybaseSaltpackBrand)) { t.Errorf("ciphertext doesn't have header: %s", ciphertext) } if !strings.HasSuffix(ciphertext, saltpack.MakeArmorFooter(saltpack.MessageTypeEncryption, KeybaseSaltpackBrand)+".\n") { t.Errorf("ciphertext doesn't have footer: %s", ciphertext) } for _, key := range receiverKPs { buf.Reset() _, err = SaltpackDecrypt(G, strings.NewReader(ciphertext), &buf, key, nil) if err != nil { t.Fatal(err) } plaintext := buf.String() if plaintext != message { t.Errorf("expected %s, got %s", message, plaintext) } } // Sender is a non-recipient, too. nonReceiverKPs := []NaclDHKeyPair{nonReceiverKP, senderKP} for _, kp := range nonReceiverKPs { buf.Reset() _, err = SaltpackDecrypt(G, strings.NewReader(ciphertext), &buf, kp, nil) if err != saltpack.ErrNoDecryptionKey { t.Fatal(err) } } }
sc.Type = CryptoMessageTypeEncryption case 0x2: // Detached signature sc.Type = CryptoMessageTypeDetachedSignature case 0x4, 0x8: // Either a compressed message or just a one-pass signature type. In either case, // it's likely a signature. sc.Type = CryptoMessageTypeAttachedSignature default: return false } sc.Format = CryptoMessageFormatPGP return true } var encryptionArmorHeader = saltpack.MakeArmorHeader(saltpack.MessageTypeEncryption, KeybaseSaltpackBrand) var signedArmorHeader = saltpack.MakeArmorHeader(saltpack.MessageTypeAttachedSignature, KeybaseSaltpackBrand) var detachedArmorHeader = saltpack.MakeArmorHeader(saltpack.MessageTypeDetachedSignature, KeybaseSaltpackBrand) // ClassifyStream takes a stream reader in, and returns a likely classification // of that stream without consuming any data from it. It returns a reader that you // should read from instead, in addition to the classification. If classification // fails, there will be a `UnknownStreamError`, or additional EOF errors if the // stream ended beform classification could go. func ClassifyStream(r io.Reader) (sc StreamClassification, out io.Reader, err error) { peeker := NewStreamPeeker(r) var buf [100]byte var n int if n, err = peeker.Peek(buf[:]); err != nil { return sc, peeker, err }