From fc236266f7931cde83c5c136a0a4e0246ab018e0 Mon Sep 17 00:00:00 2001
From: tomsmeding <tom.smeding@gmail.com>
Date: Sat, 8 Oct 2016 22:21:24 +0200
Subject: Add envelope application using the crypto lib

---
 envelope/Makefile |  30 +++++++++++++++++
 envelope/envelope | Bin 0 -> 116616 bytes
 envelope/main.cpp |  97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 envelope/Makefile
 create mode 100755 envelope/envelope
 create mode 100644 envelope/main.cpp

diff --git a/envelope/Makefile b/envelope/Makefile
new file mode 100644
index 0000000..06b0419
--- /dev/null
+++ b/envelope/Makefile
@@ -0,0 +1,30 @@
+CXX = g++
+CXXFLAGS = -Wall -Wextra -std=c++0x -fwrapv
+LDFLAGS =
+ifneq ($(DEBUG),)
+	CXXFLAGS += -g
+else
+	CXXFLAGS += -O2
+endif
+ifeq ($(shell uname),Linux)
+	LDFLAGS += -lbsd
+endif
+
+BIN = envelope
+
+
+.PHONY: all clean remake
+
+all: $(BIN)
+
+clean:
+	rm -rf $(BIN) *.o *.dSYM
+
+remake: clean all
+
+
+$(BIN): $(patsubst %.cpp,%.o,$(wildcard *.cpp)) ../cryptolib.a
+	$(CXX) -o $@ $^ $(LDFLAGS)
+
+%.o: %.cpp $(wildcard *.h)
+	$(CXX) $(CXXFLAGS) -c -o $@ $<
diff --git a/envelope/envelope b/envelope/envelope
new file mode 100755
index 0000000..50b479f
Binary files /dev/null and b/envelope/envelope differ
diff --git a/envelope/main.cpp b/envelope/main.cpp
new file mode 100644
index 0000000..49b41ff
--- /dev/null
+++ b/envelope/main.cpp
@@ -0,0 +1,97 @@
+#include <iostream>
+#include <cstdlib>
+#include "../base64.h"
+#include "../envelope.h"
+
+using namespace std;
+
+const char *progname="envelope";
+
+void usage(){
+	cerr<<"Usage: "                                                                         <<endl
+	    <<"   "<<progname<<" -k <keylength>   Generate a key with the given number of bits" <<endl
+	    <<"   "<<progname<<" -e <pubkey>      Encrypt text on standard input"               <<endl
+	    <<"   "<<progname<<" -d <privkey>     Decrypt text on standard input"               <<endl
+	                                                                                        <<endl
+	    <<"The program first encrypts the plaintext using 256-bit AES CBC with a randomly"  <<endl
+	    <<"generated key, and then encrypts the key using RSA, with the specified key."     <<endl
+	    <<"All RSA keys are encoded in base64 in an internal format."                       <<endl
+	                                                                                        <<endl
+	    <<"The <keylength> used for RSA key generation is the number of bits in the"        <<endl
+	    <<"modulus. Advised for security is at least 2048, but that might take a while to"  <<endl
+	    <<"generate (be patient...). (Note: duration of key generation has *absolutely no*" <<endl
+	    <<"meaning as to the strength of the key.) There is no restriction to powers of two"<<endl
+	    <<"in the key length (or any other special class of numbers), but stay above 512,"  <<endl
+	    <<"or the AES key might not fit."                                                   <<endl
+	                                                                                        <<endl
+	    <<"  -k  The public and private keys are printed on standard output, separated by"  <<endl
+	    <<"      newlines. Comments are on standard error."                                 <<endl
+	    <<"  -e  Text to encrypt is expected on standard input; the public key of the"      <<endl
+	    <<"      recipient is a command-line argument. Encrypted text is in base64 on"      <<endl
+	    <<"      standard output."                                                          <<endl
+	    <<"  -d  Text to decrypt is expected on standard input, in the base64 form that is" <<endl
+	    <<"      outputted by the -e function. your private key is a command-line argument."<<endl
+	    <<"      Decrypted text is on standard output."                                     <<endl;
+}
+
+void mode_keygen(int keylength){
+	if(keylength<512){
+		cerr<<"Key length too small, please specify length >= 512"<<endl;
+		exit(1);
+	}
+	if(keylength>8192){
+		cerr<<"Key length too large, please specify length <= 8192"<<endl;
+		exit(1);
+	}
+	pair<RSA::Key,RSA::Key> keyset=RSA::genkeys(keylength);
+	cerr<<"Public key:"<<endl;
+	cout<<RSA::exportKey(keyset.first)<<endl;
+	cerr<<"Private key:"<<endl;
+	cout<<RSA::exportKey(keyset.second)<<endl;
+}
+
+void mode_encrypt(const string &pubkeyrepr){
+	RSA::Key key(RSA::importKey(pubkeyrepr));
+	string data;
+	char buf[1024];
+	while(cin){
+		cin.read(buf,sizeof(buf));
+		int nread=cin.gcount();
+		if(nread==0)continue;
+		data.append(buf,nread);
+	}
+	cout<<Base64::encode(Envelope::encrypt(data,key))<<endl;
+}
+
+void mode_decrypt(const string &privkeyrepr){
+	RSA::Key key(RSA::importKey(privkeyrepr));
+	string data;
+	char buf[1024];
+	while(cin){
+		cin.read(buf,sizeof(buf));
+		int nread=cin.gcount();
+		if(nread==0)continue;
+		data.append(buf,nread);
+	}
+	cout<<Envelope::decrypt(Base64::decode(data),key)<<flush;
+}
+
+int main(int argc,char **argv){
+	if(argc==3&&strcmp(argv[1],"-k")==0){
+		char *endp;
+		int keylength=strtol(argv[2],&endp,10);
+		if(!argv[2][0]||*endp){
+			cerr<<"Invalid number '"<<argv[2]<<"'"<<endl;
+			usage();
+			return 1;
+		}
+		mode_keygen(keylength);
+	} else if(argc==3&&strcmp(argv[1],"-e")==0){
+		mode_encrypt(argv[2]);
+	} else if(argc==3&&strcmp(argv[1],"-d")==0){
+		mode_decrypt(argv[2]);
+	} else {
+		usage();
+		return 1;
+	}
+}
-- 
cgit v1.2.3-70-g09d2