Example #1
0
		// it's likely a signature.
		sc.Type = CryptoMessageTypeAttachedSignature
	default:
		return false
	}
	sc.Format = CryptoMessageFormatPGP
	return true
}

func matchesSaltpackType(messageStart string, typeString string) bool {
	exp := "^\\s*BEGIN ([a-zA-Z0-9]+ )?SALTPACK " + typeString + "."
	match, err := regexp.MatchString(exp, messageStart)
	return match && (err == nil)
}

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 {
		// ErrUnexpectedEOF might just mean we read less than 100 bytes
		if err == io.ErrUnexpectedEOF && len(buf) > 0 {
Example #2
0
// 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)
		}
	}
}