diff options
| -rw-r--r-- | envelope.cpp | 52 | 
1 files changed, 9 insertions, 43 deletions
diff --git a/envelope.cpp b/envelope.cpp index 4971358..abf6e8f 100644 --- a/envelope.cpp +++ b/envelope.cpp @@ -14,8 +14,12 @@ using namespace std;  namespace Envelope{ +	// Envelope format: [AES encrypted data | RSA encrypted AES key | length of AES key] +	// The encrypted AES key is in big-endian format, as is the length tag. The length tag +	// is an unsigned 16-bit integer. +  	bool safeKey(const string &key){ -		//checks against keys 0 and 1, because they don't undergo change in RSA +		//checks against keys 0 and 1, because they don't undergo change in RSA enryption  		int i;  		for(i=0;i<(int)key.size();i++)if(key[i]!=0)break;  		if(i==(int)key.size())return false; //key is 0 @@ -30,36 +34,20 @@ namespace Envelope{  		do {  			for(int i=0;i<keylen;i++)*(uint32_t*)&aeskey[4*i]=crng.get();  		} while(!safeKey(aeskey)); -#ifdef DEBUG -		cerr<<"decrkey="<<Base64::encode(aeskey)<<endl; -#endif  		string payload(AES::encrypt(data,aeskey,AES::AES_256_CBC)); -#ifdef DEBUG -		cerr<<"payload="<<Base64::encode(payload)<<endl; -#endif  		Bigint rsadata;  		for(int i=0;i<(int)aeskey.size();i++){ -			if(i!=0)rsadata<<=8; +			if(i!=0)rsadata<<=8; //we see aeskey as being in big-endian format  			rsadata+=(uint8_t)aeskey[i];  		} -#ifdef DEBUG -		cerr<<"rsadata="<<rsadata<<endl; -		cerr<<"pubkey = {"<<pubkey.mod<<" , "<<pubkey.exp<<'}'<<endl; -#endif  		Bigint res(RSA::encrypt(rsadata,pubkey)); -#ifdef DEBUG -		cerr<<"rsaencr="<<res<<endl; -#endif -		vector<uint8_t> bytes; //bytes in little-endian order (so, reverse!) +		vector<uint8_t> bytes; //bytes in little-endian order (so, reversed!)  		while(res!=0){  			bytes.push_back(res.lowdigits()&0xff);  			res>>=8;  		} -#ifdef DEBUG -		cerr<<"encrkey="<<Base64::encode(string(bytes.rbegin(),bytes.rend()))<<endl; -#endif  		payload.reserve(payload.size()+bytes.size()+2);  		for(int i=bytes.size()-1;i>=0;i--)payload.push_back(bytes[i]); //append in big-endian order again @@ -70,38 +58,22 @@ namespace Envelope{  	}  	string decrypt(const string &data,const RSA::Key &privkey){ -#ifdef DEBUG -		cerr<<"=== DECRYPT ==="<<endl; -#endif  		if(data.size()<2)throw invalid_argument("Envelope data length invalid");  		int encrkeylen=((uint16_t)(uint8_t)data[data.size()-2]<<8)+(uint8_t)data.back();  		assert(encrkeylen<(1<<16)); -#ifdef DEBUG -		cerr<<"encrkeylen="<<encrkeylen<<endl; -#endif  		if((int)data.size()<encrkeylen+2)throw invalid_argument("Envelope key format invalid");  		string encrkey(encrkeylen,'\0'); //in big-endian  		for(int i=0;i<encrkeylen;i++){  			encrkey[i]=data[data.size()-2-encrkeylen+i];  		} -#ifdef DEBUG -		cerr<<"encrkey="<<Base64::encode(encrkey)<<endl; -#endif  		Bigint rsadata;  		for(int i=0;i<encrkeylen;i++){ -			if(i!=0)rsadata<<=8; +			if(i!=0)rsadata<<=8; //encrkey is also in big-endian  			rsadata+=(uint8_t)encrkey[i];  		} -#ifdef DEBUG -		cerr<<"rsaencr="<<rsadata<<endl; -		cerr<<"privkey = {"<<privkey.mod<<" , "<<privkey.exp<<'}'<<endl; -#endif  		Bigint res(RSA::decrypt(rsadata,privkey)); -#ifdef DEBUG -		cerr<<"rsadata="<<res<<endl; -#endif  		vector<uint8_t> bytes; //bytes in little-endian order  		for(int i=0;i<32;i++){ //32 is the number of bytes in a 256-bit AES key (256/8=32) @@ -112,14 +84,8 @@ namespace Envelope{  			throw invalid_argument("Envelope RSA private key incorrect");  		}  		string decrkey(bytes.size(),'\0'); -		for(int i=0;i<(int)bytes.size();i++)decrkey[bytes.size()-1-i]=bytes[i]; -#ifdef DEBUG -		cerr<<"decrkey="<<Base64::encode(decrkey)<<endl; -#endif +		for(int i=0;i<(int)bytes.size();i++)decrkey[bytes.size()-1-i]=bytes[i]; //save in decrkey in big-endian order again -#ifdef DEBUG -		cerr<<"payload="<<Base64::encode(data.substr(0,data.size()-2-encrkeylen))<<endl; -#endif  		try {  			return AES::decrypt(data.substr(0,data.size()-2-encrkeylen),decrkey,AES::AES_256_CBC);  		} catch(invalid_argument){  | 
