func decrypt(sender, recipient *uid.Message, r io.Reader, recipientTemp *uid.KeyEntry, privateKey string, sign bool, chkMsg bool) error { // decrypt var res bytes.Buffer identities := []*uid.Message{recipient} input := base64.NewDecoder(r) version, preHeader, err := ReadFirstOuterHeader(input) if err != nil { return err } if version != Version { return errors.New("wrong version") } ms := memstore.New() if err := recipientTemp.SetPrivateKey(privateKey); err != nil { return err } ms.AddPrivateKeyEntry(recipientTemp) args := &DecryptArgs{ Writer: &res, Identities: identities, PreHeader: preHeader, Reader: input, Rand: cipher.RandReader, KeyStore: ms, } _, sig, err := Decrypt(args) if err != nil { return err } // do not compare messages when fuzzing, because messages have to be different! if chkMsg && res.String() != msgs.Message1 { return errors.New("messages differ") } if sign { contentHash := cipher.SHA512(res.Bytes()) decSig, err := base64.Decode(sig) if err != nil { return err } if len(decSig) != ed25519.SignatureSize { return errors.New("signature has wrong length") } var sigBuf [ed25519.SignatureSize]byte copy(sigBuf[:], decSig) if !ed25519.Verify(sender.PublicSigKey32(), contentHash, &sigBuf) { return errors.New("signature verification failed") } } return nil }
func (ce *CryptEngine) decrypt(w io.Writer, r io.Reader, statusfp *os.File) error { // retrieve all possible recipient identities from keyDB identities, err := ce.getRecipientIdentities() if err != nil { return err } // read pre-header r = base64.NewDecoder(r) version, preHeader, err := msg.ReadFirstOuterHeader(r) if err != nil { return err } // check version if version > msg.Version { return log.Errorf("cryptengine: newer message version, please update software") } if version < msg.Version { return log.Errorf("cryptengine: outdated message version, cannot process") } // decrypt message var senderID string var sig string args := &msg.DecryptArgs{ Writer: w, Identities: identities, PreHeader: preHeader, Reader: r, Rand: cipher.RandReader, KeyStore: ce, } senderID, sig, err = msg.Decrypt(args) if err != nil { // TODO: handle msg.ErrStatusError, should trigger a subsequent // encrypted message with StatusError return err } fmt.Fprintf(statusfp, "SENDERIDENTITY:\t%s\n", senderID) if sig != "" { fmt.Fprintf(statusfp, "SIGNATURE:\t%s\n", sig) } return nil }
func TestMaxMessageLength(t *testing.T) { alice := "*****@*****.**" aliceUID, err := uid.Create(alice, false, "", "", uid.Strict, hashchain.TestEntry, cipher.RandReader) if err != nil { t.Fatal(err) } bob := "*****@*****.**" bobUID, err := uid.Create(bob, false, "", "", uid.Strict, hashchain.TestEntry, cipher.RandReader) if err != nil { t.Fatal(err) } now := uint64(times.Now()) bobKI, _, privateKey, err := bobUID.KeyInit(1, now+times.Day, now-times.Day, false, "mute.berlin", "", "", cipher.RandReader) if err != nil { t.Fatal(err) } bobKE, err := bobKI.KeyEntryECDHE25519(bobUID.SigPubKey()) if err != nil { t.Fatal(err) } // create large message message, err := padding.Generate(MaxContentLength, cipher.RandReader) if err != nil { t.Fatal(err) } // encrypt message from Alice to Bob var encMsg bytes.Buffer aliceKeyStore := memstore.New() aliceKeyStore.AddPublicKeyEntry(bob, bobKE) encryptArgs := &EncryptArgs{ Writer: &encMsg, From: aliceUID, To: bobUID, SenderLastKeychainHash: hashchain.TestEntry, PrivateSigKey: aliceUID.PrivateSigKey64(), Reader: bytes.NewBuffer(message), Rand: cipher.RandReader, KeyStore: aliceKeyStore, } if _, err = Encrypt(encryptArgs); err != nil { t.Fatal(err) } // decrypt message from Alice to Bob var res bytes.Buffer bobIdentities := []*uid.Message{bobUID} input := base64.NewDecoder(&encMsg) version, preHeader, err := ReadFirstOuterHeader(input) if err != nil { t.Fatal(err) } if version != Version { t.Fatal("wrong version") } bobKeyStore := memstore.New() if err := bobKE.SetPrivateKey(privateKey); err != nil { t.Fatal(err) } bobKeyStore.AddPrivateKeyEntry(bobKE) decryptArgs := &DecryptArgs{ Writer: &res, Identities: bobIdentities, PreHeader: preHeader, Reader: input, Rand: cipher.RandReader, KeyStore: bobKeyStore, } _, _, err = Decrypt(decryptArgs) if err != nil { t.Fatal(err) } if res.String() != string(message) { t.Fatal("messages differ") } }