Exemplo n.º 1
1
string RNEncryptor::encrypt(string plaintext, string password, RNCryptorSchema schemaVersion)
{
	this->configureSettings(schemaVersion);

	RNCryptorPayloadComponents components;
	components.schema = (char)schemaVersion;
	components.options = (char)this->options;
	components.salt = this->generateSalt();
	components.hmacSalt = this->generateSalt();
	components.iv = this->generateIv(this->ivLength);

	SecByteBlock key = this->generateKey(components.salt, password);

	switch (this->aesMode) {
		case MODE_CTR: {

			CTR_Mode<AES>::Encryption encryptor;
			encryptor.SetKeyWithIV((const byte *)key.data(), key.size(), (const byte *)components.iv.data());

			StringSource(plaintext, true,
				// StreamTransformationFilter adds padding as required.
				new StreamTransformationFilter(encryptor,
					new StringSink(components.ciphertext)
				)
			);

			break;
		}
		case MODE_CBC: {

			CBC_Mode<AES>::Encryption encryptor;
			encryptor.SetKeyWithIV(key.BytePtr(), key.size(), (const byte *)components.iv.data());

			StringSource(plaintext, true,
				// StreamTransformationFilter adds padding as required.
				new StreamTransformationFilter(encryptor,
					new StringSink(components.ciphertext)
				)
			);

			break;
		}
	}

	stringstream binaryData;
	binaryData << components.schema;
	binaryData << components.options;
	binaryData << components.salt;
	binaryData << components.hmacSalt;
	binaryData << components.iv;
	binaryData << components.ciphertext;

	std::cout << "Hex encoded: " << this->hex_encode(binaryData.str()) << std::endl;

	binaryData << this->generateHmac(components, password);

	return this->base64_encode(binaryData.str());
}
Exemplo n.º 2
0
void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile)
{
	SecByteBlock key = HexDecodeString(hexKey);
	SecByteBlock iv = HexDecodeString(hexIV);
	CTR_Mode<AES>::Encryption aes(key, key.size(), iv);
	FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile)));
}
Exemplo n.º 3
0
bool PEM_IsEncrypted(SecByteBlock& sb)
{
    SecByteBlock::iterator it = search(sb.begin(), sb.end(), SBB_PROC_TYPE.begin(), SBB_PROC_TYPE.end());
    if (it == sb.end()) return false;
    
    it = search(it + SBB_PROC_TYPE.size(), sb.end(), SBB_ENCRYPTED.begin(), SBB_ENCRYPTED.end());
    return it != sb.end();
}
Exemplo n.º 4
0
ECP::Point ECP::BERDecodePoint(BufferedTransformation &bt) const
{
	SecByteBlock str;
	BERDecodeOctetString(bt, str);
	Point P;
	if (!DecodePoint(P, str, str.size()))
		BERDecodeError();
	return P;
}
Exemplo n.º 5
0
std::string Converter::SecByteBlockToString(SecByteBlock data){
	Integer a;
	a.Decode(data.BytePtr(), data.SizeInBytes());
	//cout<< "ze secbyteblock do integera: "<<a<<endl;
	std::ostrstream oss;
	oss << std::hex << a;
	std::string s(oss.str());
	s = s.substr(0, 2*data.SizeInBytes()+1); //Do zapamiêtania. d³ugoœæ stringa z s wynosi 2*d³ugoœæ w bytach plus 1.
	return s;
}
Exemplo n.º 6
0
void PEM_StripEncapsulatedBoundary(BufferedTransformation& bt, const SecByteBlock& pre, const SecByteBlock& post)
{
    ByteQueue temp;
    SecByteBlock::const_iterator it;
    int n = 1, prePos = -1, postPos = -1;
    
    while(bt.AnyRetrievable() && n++)
    {
        SecByteBlock line, unused;
        PEM_ReadLine(bt, line, unused);
        
        // The write associated with an empty line must to occur. Otherwise, we loose the CR or LF
        //    in an ecrypted private key between the control fields and the encapsulated text.
        //if(line.empty())
        //    continue;
        
        it = Search(line, pre);
        if(it != line.end())
        {
            prePos = n;
            continue;
        }
        it = Search(line, post);
        if(it != line.end())
        {
            postPos = n;
            continue;
        }
        
        PEM_WriteLine(temp, line);
    }
    
    if(prePos == -1)
    {
        string msg = "PEM_StripEncapsulatedBoundary: '";
        msg += string((char*)pre.data(), pre.size()) + "' not found";
        throw InvalidDataFormat(msg);
    }
    
    if(postPos == -1)
    {
        string msg = "PEM_StripEncapsulatedBoundary: '";
        msg += string((char*)post.data(), post.size()) + "' not found";
        throw InvalidDataFormat(msg);
    }
    
    if(prePos > postPos)
        throw InvalidDataFormat("PEM_StripEncapsulatedBoundary: header boundary follows footer boundary");
    
    temp.TransferTo(bt);
}
Exemplo n.º 7
0
bool encryptFile(string filename, SecByteBlock key, byte* iv){
	ifstream file;
	file.open(filename);
	if(file.is_open()){
		string line;
		ofstream encFile;
		encFile.open("encText.txt", ios::app);
		CBC_Mode<AES>::Encryption enc;
		enc.SetKeyWithIV(key, key.size(), iv);
		while(getline(file, line)){
			string cipher;
			//cout << line << endl;
			StringSource ss(line, true, new StreamTransformationFilter(enc, new StringSink(cipher)));
			
			if(encFile.is_open()){
				encFile.write(cipher.c_str(), cipher.size());
				encFile << '\r\n';
			}
			else
				cout << "couldn't write" << endl;
			//cout << cipher << endl;
		}
		cout << "finished encrypting" << endl;
		encFile.close();
		file.close();
		return true;
	}
	else{
		cout << "Unable to open file." << endl;
		return false;
	}
}
Exemplo n.º 8
0
SecByteBlock Converter::encodeSecByteBlockWithLength(Integer key, int length)
{
    //int length = key.MinEncodedSize();
    byte * byteX;
    key.Encode(byteX, length);
    
    SecByteBlock pubKeyA;
    pubKeyA.Assign(byteX, length);

	std::cout<<"Key: " << key <<std::endl;
	std::cout<<"Decoded: " << decodeSecByteBlock(pubKeyA) <<std::endl;
    //check
    if (key != decodeSecByteBlock(pubKeyA))
        std::cout << "Error while encoding Integer to SecByteBlock" << std::endl;
    
    return pubKeyA;
}
Exemplo n.º 9
0
void InvertibleESIGNFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &param)
{
	int modulusSize = 1023*2;
	param.GetIntValue("ModulusSize", modulusSize) || param.GetIntValue("KeySize", modulusSize);

	if (modulusSize < 24)
		throw InvalidArgument("InvertibleESIGNFunction: specified modulus size is too small");

	if (modulusSize % 3 != 0)
		throw InvalidArgument("InvertibleESIGNFunction: modulus size must be divisible by 3");

	m_e = param.GetValueWithDefault("PublicExponent", Integer(32));

	if (m_e < 8)
		throw InvalidArgument("InvertibleESIGNFunction: public exponents less than 8 may not be secure");

	// VC70 workaround: putting these after primeParam causes overlapped stack allocation
	ConstByteArrayParameter seedParam;
	SecByteBlock seed;

	const Integer minP = Integer(204) << (modulusSize/3-8);
	const Integer maxP = Integer::Power2(modulusSize/3)-1;
	AlgorithmParameters primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME);

	if (param.GetValue("Seed", seedParam))
	{
		seed.resize(seedParam.size() + 4);
		memcpy(seed + 4, seedParam.begin(), seedParam.size());

		PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0);
		m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
		PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)1);
		m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
	}
	else
	{
		m_p.GenerateRandom(rng, primeParam);
		m_q.GenerateRandom(rng, primeParam);
	}

	m_n = m_p * m_p * m_q;

	CRYPTOPP_ASSERT(m_n.BitCount() == (unsigned int)modulusSize);
}
void
CertificateExtension::decode(CryptoPP::BufferedTransformation& in)
{
  using namespace CryptoPP;

  // Extension ::= SEQUENCE {
  //        extnID      OBJECT IDENTIFIER,
  //        critical    BOOLEAN DEFAULT FALSE,
  //        extnValue   OCTET STRING  }

  BERSequenceDecoder extension(in);
  {
    m_extensionId.decode(extension);
    BERDecodeUnsigned(extension, m_isCritical, BOOLEAN);

    // the extra copy operation can be optimized, but not trivial,
    // since the length is not known in advance
    SecByteBlock tmpBlock;
    BERDecodeOctetString(extension, tmpBlock);
    m_extensionValue.assign(tmpBlock.begin(), tmpBlock.end());
  }
  extension.MessageEnd();
}
Exemplo n.º 11
0
bool decryptFile(string filename, SecByteBlock key, byte* iv){
	ifstream file;
	file.open(filename);
	if(file.is_open()){
		string line;
		CBC_Mode<AES>::Decryption dec;
		dec.SetKeyWithIV(key, key.size(), iv);
		while(getline(file, line)){
			string plain;
			//cout << line << endl;
			StringSource ss(line, true, new StreamTransformationFilter(dec, new StringSink(plain)));
			//cout << plain << endl;
		}

		file.close();
		return true;
	}
	else{
		cout << "Unable to open file." << endl;
		return false;
	}
}
Exemplo n.º 12
0
void DL_PrivateKey_EC<EC>::BERDecodeKey2(BufferedTransformation &bt, bool parametersPresent, unsigned int size)
{
	BERSequenceDecoder seq(bt);
		word32 version;
		BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1);	// check version

		BERGeneralDecoder dec(seq, OCTET_STRING);
		if (!dec.IsDefiniteLength())
			BERDecodeError();
		Integer x;
		x.Decode(dec, dec.RemainingLength());
		dec.MessageEnd();
		if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
			BERDecodeError();
		if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
		{
			BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0);
			AccessGroupParameters().BERDecode(parameters);
			parameters.MessageEnd();
		}
		if (!seq.EndReached())
		{
			// skip over the public element
			SecByteBlock subjectPublicKey;
			unsigned int unusedBits;
			BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
			BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
			publicKey.MessageEnd();
			Element Q;
			if (!(unusedBits == 0 && GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size())))
				BERDecodeError();
		}
	seq.MessageEnd();

	SetPrivateExponent(x);
}
Exemplo n.º 13
0
int main()
{
    using namespace CryptoPP;

    AutoSeededRandomPool rng;

    DH                dhA;         //< Diffie-Hellman structure
    DH2               dh2A(dhA);   //< Diffie-Hellman structure
    SecByteBlock      sprivA;      //< static private key
    SecByteBlock      spubA;       //< static public key
    SecByteBlock      eprivA;      //< ephemeral private key
    SecByteBlock      epubA;       //< ephemeral public key
    SecByteBlock      sharedA;     //< shared key

    DH                dhB;         //< Diffie-Hellman structure
    DH2               dh2B(dhA);   //< Diffie-Hellman structure
    SecByteBlock      sprivB;      //< static private key
    SecByteBlock      spubB;       //< static public key
    SecByteBlock      eprivB;      //< ephemeral private key
    SecByteBlock      epubB;       //< ephemeral public key
    SecByteBlock      sharedB;     //< shared key

    std::cout << "Initializing DH parameters" << std::endl;;
    dhA.AccessCryptoParameters().GenerateRandomWithKeySize(rng,1024);
    dhB.AccessCryptoParameters().GenerateRandomWithKeySize(rng,1024);

    std::cout << "Generating Keys" << std::endl;;
    sprivA = SecByteBlock( dh2A.StaticPrivateKeyLength() );
    spubA  = SecByteBlock( dh2A.StaticPublicKeyLength() );
    eprivA = SecByteBlock( dh2A.EphemeralPrivateKeyLength() );
    epubA  = SecByteBlock( dh2A.EphemeralPublicKeyLength() );

    dh2A.GenerateStaticKeyPair(rng,sprivA,spubA);
    dh2A.GenerateEphemeralKeyPair(rng,eprivA, epubA);
    sharedA= SecByteBlock( dh2A.AgreedValueLength() );

    sprivB = SecByteBlock( dh2B.StaticPrivateKeyLength() );
    spubB  = SecByteBlock( dh2B.StaticPublicKeyLength() );
    eprivB = SecByteBlock( dh2B.EphemeralPrivateKeyLength() );
    epubB  = SecByteBlock( dh2B.EphemeralPublicKeyLength() );

    dh2B.GenerateStaticKeyPair(rng,sprivB,spubB);
    dh2B.GenerateEphemeralKeyPair(rng,eprivB, epubB);
    sharedB= SecByteBlock( dh2B.AgreedValueLength() );

    if(!dh2A.Agree(sharedA, sprivA, eprivA, spubB, epubB) )
        std::cerr << "A failed to agree " << std::endl;

    if(!dh2B.Agree(sharedB, sprivB, eprivB, spubA, epubA) )
        std::cerr << "B failed to agree " << std::endl;

    Integer sharedAOut, sharedBOut;
    sharedAOut.Decode(sharedA.BytePtr(), sharedA.SizeInBytes());
    sharedBOut.Decode(sharedB.BytePtr(), sharedB.SizeInBytes());

    std::cout << "shared secret:"
              << "\n A: " << std::hex << sharedAOut
              << "\n B: " << std::hex << sharedBOut
              << std::endl;

}
Exemplo n.º 14
0
int main(int argc, char* argv[])
{
	if (!((argc == 5 && strcmp(argv[1], "-e") == 0) || (argc == 4 && strcmp(argv[1], "-d") == 0))) {
        printf("To encrypt: %s -e <mp3 file> <key> <content id>\n"
               "To decrypt: %s -d <mp3 file> <key>\n",
               argv[0], argv[0]);
		exit(1);
	}
    const char * str_op = argv[1];
	const char * mp3_file_name = argv[2];
    const char * str_key = argv[3];
    const char * str_cid = ((argc == 5) ? argv[4] : NULL);

    if (strlen(mp3_file_name) < 4 || strcmp(&mp3_file_name[strlen(mp3_file_name) - 4], ".mp3") != 0) {
        printf("File must be \".mp3\".\n");
        exit(-1);
    }

    if (strlen(str_key) != 32) {
        printf("The key must be 16 bytes (32 hexachars) long.\n");
        exit(-1);
    }

    if (str_cid != NULL && strlen(str_cid) != 32) {
        printf("Content id must be 16 bytes (32 hexachars) long.\n");
        exit(-1);
    }

    for (int i = 0; i < 32; ++i) {
        if (!(str_key[i] >= '0' && str_key[i] <= '9' ||
              str_key[i] >= 'a' && str_key[i] <= 'f' ||
              str_key[i] >= 'A' && str_key[i] <= 'F')) {
            printf("The key must be hexadecimal.\n");
            exit(-1);
        }
        if (str_cid != NULL &&
            !(str_key[i] >= '0' && str_key[i] <= '9' ||
              str_key[i] >= 'a' && str_key[i] <= 'f' ||
              str_key[i] >= 'A' && str_key[i] <= 'F')) {
            printf("The key must be hexadecimal.\n");
            exit(-1);
        }
    }

	FILE * mp3_file;

	// Open the file
	mp3_file = fopen(mp3_file_name, "rb");
	if (mp3_file == NULL) {
		printf("MP3 file not found: \"%s\"\n", mp3_file_name);
	} else {
		printf("\n");

		// Get total mp3 file length
		long file_length = filelength(fileno(mp3_file));

		// Check for ID3v1 or ID3v1.1 header
		bool hasID3v1 = false;
		long id3v1_pos = file_length - 128;
		ID3v1 id3v1;
		if (file_length >= 128) {
			fseek(mp3_file, id3v1_pos, SEEK_SET);
			hasID3v1 = readID3v1(mp3_file, &id3v1) && checkID3v1(&id3v1);
		}

		// Check for ID3v2
		bool hasID3v2 = false;
		long id3v2_pos = 0;
		long id3v2_len = 0;
		if (file_length >= 10) {
			unsigned char id3v2_header[10];
			fseek(mp3_file, 0, SEEK_SET);
			if (fread(id3v2_header, 10, 1, mp3_file) == 1 && memcmp(id3v2_header, "ID3", 3) == 0) {
				hasID3v2 = true;
				id3v2_len = 10 + (((unsigned int)(id3v2_header[6])) << 21) +
				                 (((unsigned int)(id3v2_header[7])) << 14) +
				                 (((unsigned int)(id3v2_header[8])) <<  7) +
				                  ((unsigned int)(id3v2_header[9]));
				if (id3v2_header[5] & 0x10) id3v2_len += 10;
			}
		}

		// Check for Lyrics3 v1
		bool hasLyrics3v1 = false;
		long lyrics3v1_pos = 0;
		long lyrics3v1_len = 0;
		if (hasID3v1 && file_length >= 148) {
			char lyricsEnd[9];
			fseek(mp3_file, id3v1_pos - 9, SEEK_SET);
			if (fread(lyricsEnd, 9, 1, mp3_file) == 1 && memcmp(lyricsEnd, "LYRICSEND", 9) == 0) {
				// Found the end of a Lyrics3 field. Now, look backwards for LYRICSBEGIN.
				long maxLyricsLength = 11 + 5100;
				if (maxLyricsLength > file_length - 128 - 9) {
					maxLyricsLength = file_length - 128 - 9;
				}
				char * pLyrics = new char[maxLyricsLength];
				long searchPos = file_length - 128 - 9 - maxLyricsLength;
				fseek(mp3_file, searchPos, SEEK_SET);
				fread(pLyrics, maxLyricsLength, 1, mp3_file);
				char * pSearch = pLyrics;
				char * pPlace;
				do {
					pPlace = (char*)memchr(pSearch, 'L', maxLyricsLength - 11 + 1);
					if (memcmp(pPlace, "LYRICSBEGIN", 11) == 0) {
						hasLyrics3v1 = true;
						lyrics3v1_pos = searchPos + (pPlace - pLyrics);
						lyrics3v1_len = file_length - 128 - 9 - lyrics3v1_pos;
						break;
					} else {
						maxLyricsLength -= (long)(pPlace - pSearch) + 1;
						pSearch = pPlace + 1;
					}
				} while (pPlace != NULL);
				delete [] pLyrics;
			}
		}

		// Check for Lyrics3 v2
		bool hasLyrics3v2 = false;
		long lyrics3v2_pos = 0;
		long lyrics3v2_len = 0;
		if (hasID3v1 && file_length >= 148) {
			char lyricsEnd[9];
			fseek(mp3_file, id3v1_pos - 9, SEEK_SET);
			if (fread(lyricsEnd, 9, 1, mp3_file) == 1 && memcmp(lyricsEnd, "LYRICS200", 9) == 0) {
				// Found the end of a Lyrics3 field. Now, read the length of the lyrics.
				char lyricsLength[6];
				fseek(mp3_file, id3v1_pos - 9 - 6, SEEK_SET);
				if (fread(lyricsLength, 6, 1, mp3_file) == 1) {
					lyrics3v2_len = atol(lyricsLength);
					lyrics3v2_pos = id3v1_pos - 9 - 6 - lyrics3v2_len;
					// Confirm there's a LYRICSBEGIN tag.
					if (lyrics3v2_pos > 0) {
						char lyricsBegin[11];
						fseek(mp3_file, lyrics3v2_pos, SEEK_SET);
						if (fread(lyricsBegin, 11, 1, mp3_file) == 1 && memcmp(lyricsBegin, "LYRICSBEGIN", 11) == 0) {
							hasLyrics3v2 = true;
						}
					}
				}
			}
		}

		// Look for the first frame in the file
		fseek(mp3_file, 0, SEEK_SET);
		if (!synchronize(mp3_file)) {
			printf("Is this a real mp3 file?\n");
		} else {

			char * aes_file_name = new char[strlen(mp3_file_name) + 4 + 1];
			strcpy(aes_file_name, mp3_file_name);
			strcat(aes_file_name, ".aes");

			FILE * aes_file = fopen(aes_file_name, "wb");
			if (aes_file == NULL) {
				printf("Couldn't open the destination file \"%s\".\n", aes_file_name);
			} else {

				char buffer[4096];
				size_t nbToRead;
				size_t nbRead;

				// Save the current position (1st frame)
				long pos_1st_frame = ftell(mp3_file);
				fseek(mp3_file, 0, SEEK_SET);

				// Copy ID3v2
				if (hasID3v2) {
					long nbID3v2ToGo = id3v2_len;
					while (nbID3v2ToGo > 0) {
						nbToRead = ((nbID3v2ToGo >= sizeof(buffer)) ? sizeof(buffer) : nbID3v2ToGo);
						nbRead = fread(buffer, 1, nbToRead, mp3_file);
						fwrite(buffer, 1, nbRead, aes_file);
						nbID3v2ToGo -= (long)nbRead;
					}
				}

				byte iv_buf[16]; // The buffer for AES's IV.

				DoRM_Box dormBox;
				bool hasDoRMBox = false;
				fread(buffer, 1, 4, mp3_file);
				if (memcmp(buffer, "DoRM", 4) == 0) {
					// This is a protected file. Read the Dorm_Box e decrypt the file.
                    if (strcmp(str_op, "-e") == 0) {
                        printf("This file is already protected.\n");
                        fclose(aes_file);
                        unlink(aes_file_name);
                        delete [] aes_file_name;
                        fclose(mp3_file);
                        exit(-1);
                    }
					hasDoRMBox = true;
					fseek(mp3_file, -4, SEEK_CUR);
					fread(&dormBox, sizeof(DoRM_Box), 1, mp3_file);
					// Get the IV from the DoRM_Box.
					memcpy(iv_buf, dormBox.iv, 16);
				} else {
					// This is an unprotected file. Write the DoRM_Box and encrypt the file.
                    if (strcmp(str_op, "-d") == 0) {
                        printf("No DoRM box.\n");
                        fclose(aes_file);
                        unlink(aes_file_name);
                        delete [] aes_file_name;
                        fclose(mp3_file);
                        exit(-1);
                    }
					fseek(mp3_file, -4, SEEK_CUR);
					// Generate an IV (with no FFs)
					srand((unsigned)time(NULL));
					for (int i = 0; i < 16; ++i) {
						do { iv_buf[i] = rand(); } while (iv_buf[i] == 0xff);
					}
					// Write the DoRM box
					DoRM_Box dormBox;
					memcpy(dormBox.dorm, "DoRM", 4);
					memset(dormBox.version, 0, 2);
					memset(dormBox.reserved, 0, 2);
					size_t dormBoxLen = sizeof(DoRM_Box) - 10;
					dormBox.length[3] = (dormBoxLen & 0x0000007f);
					dormBox.length[2] = (dormBoxLen & 0x00003f80) >>  7;
					dormBox.length[1] = (dormBoxLen & 0x001fc000) >> 14;
					dormBox.length[0] = (dormBoxLen & 0x0fe00000) >> 21;
					unsigned dormProtId = 0x010000E0; // 0xE0000001 in big endian
					memcpy(dormBox.prot_id, &dormProtId, 4);
					//memset(dormBox.cid, 0, 16); // cid is 0 for now
                    for (int i = 0; i < 16; ++i) {
                        dormBox.cid[i] = (hex2bin(str_cid[i * 2 + 0]) << 4) |
                                         (hex2bin(str_cid[i * 2 + 1]));
                    }
					memcpy(dormBox.iv, iv_buf, 16);
					fwrite(&dormBox, sizeof(DoRM_Box), 1, aes_file);
				}

				// Instantiate AES
				SecByteBlock key = HexDecodeString(str_key);
				SecByteBlock iv(iv_buf, 16);
				OFB_Mode<AES>::Encryption aes(key, key.size(), iv);

				// Write whatever exists between ID3v2 and the 1st frame
				{
					long nbPreambleToGo = pos_1st_frame - id3v2_len - (hasDoRMBox ? sizeof(DoRM_Box) : 0);
					while (nbPreambleToGo > 0) {
						nbToRead = ((nbPreambleToGo >= sizeof(buffer)) ? sizeof(buffer) : nbPreambleToGo);
						nbRead = fread(buffer, 1, nbToRead, mp3_file);
						fwrite(buffer, 1, nbRead, aes_file);
						nbPreambleToGo -= (long)nbRead;
					}
				}
				assert(ftell(mp3_file) == pos_1st_frame);

				long last_pos = 0;
				size_t buf_size = 4096;
				char * pBuffer = new char[buf_size];
				int frame_length = 0;

				MP3Header mp3_header, mp3_nextHeader;
				for (;;) {
					for (;;) {
						last_pos = ftell(mp3_file);
						if (!readHeader(mp3_file, &mp3_header, true) ||
											!checkHeader(&mp3_header)) {
							fseek(mp3_file, last_pos, SEEK_SET);
							break;
						}
						frame_length = getFrameLength(&mp3_header);
						if (!(frame_length > 0)) break;

						// Check if the next header is correct. If not, don't
						// cipher this block. It may ruin some unsupported field.
						fseek(mp3_file, last_pos + frame_length, SEEK_SET);
						if (!readHeader(mp3_file, &mp3_nextHeader, true) || !checkHeader(&mp3_nextHeader)) break;

						fseek(mp3_file, last_pos, SEEK_SET);

						if (frame_length < 4) {
							break;
						} else {
							nbToRead = frame_length;
							if (nbToRead > buf_size) {
								delete [] pBuffer;
								pBuffer = new char[nbToRead];
							}
							nbRead = fread(pBuffer, 1, nbToRead, mp3_file);
                            if ((((*(int*)(void*)(&mp3_header)) ^ (*(int*)(void*)(&mp3_nextHeader))) & 0xFFFFFDFF) == 0) {
//printf(".");
    							aes.ProcessData(((byte *)pBuffer) + 4, ((const byte *)pBuffer) + 4, nbRead - 4);
                            } else {
//printf("-");
                            }
							fwrite(pBuffer, 1, nbRead, aes_file);
						}
					}

					// Did we get to the end of the file or to a known extension?
					if ((last_pos == file_length) ||
					    (hasID3v1 && (last_pos == id3v1_pos)) ||
					    (hasLyrics3v2 && (last_pos == lyrics3v2_pos)) ||
					    (hasLyrics3v1 && (last_pos == lyrics3v1_pos))) break;

					// Something odd happened. Either the file is broken or
					// it has some unknown extension. As I can't probe for
					// the existence of an unknown extension (that's forbidden
					// in my religion) I'll assume the file is broken and
					// try to resynchronize.
					if (!synchronize(mp3_file)) {
						fseek(mp3_file, last_pos, SEEK_SET);
						break;
					} else {

						// We managed to resynchronize. Let's save the broken
						// part in clear (!) and continue ciphering.
						long sync_pos = ftell(mp3_file);

						fseek(mp3_file, last_pos, SEEK_SET);
						long nbToGo = sync_pos - last_pos;
						while (nbToGo > 0) {
							nbToRead = (((unsigned)nbToGo > buf_size) ? buf_size : (unsigned)nbToGo);
							nbRead = fread(pBuffer, 1, nbToRead, mp3_file);
							fwrite(pBuffer, 1, nbRead, aes_file);
							if (nbRead < nbToRead) {
							printf("Error reading file.\n");
								goto exit;
							}
							nbToGo -= (long)nbRead;
						}
					}
				}
exit:
				long nbToGo = file_length - last_pos;
				nbToRead = buf_size;
				while (nbToGo > 0) {
					nbRead = fread(pBuffer, 1, nbToRead, mp3_file);
					fwrite(pBuffer, 1, nbRead, aes_file);
					if (nbToRead <= (unsigned)nbToGo && nbRead < nbToRead) {
					printf("Error reading file.\n");
						break;
					}
					nbToGo -= (long)nbRead;
				}

				delete [] pBuffer;
				fclose(aes_file);
			}

			if (aes_file_name != NULL) {
				delete [] aes_file_name;
				aes_file_name = NULL;
			}
		}
		fclose(mp3_file);
	}
	return 0;
}
Exemplo n.º 15
0
bool
SecTpm::importPrivateKeyPkcs5IntoTpm(const Name& keyName,
                                     const uint8_t* buf, size_t size,
                                     const std::string& passwordStr)
{
  using namespace CryptoPP;

  Oid pbes2Id;
  Oid pbkdf2Id;
  SecByteBlock saltBlock;
  uint32_t iterationCount;
  Oid pbes2encsId;
  SecByteBlock ivBlock;
  SecByteBlock encryptedDataBlock;

  try {
    // decode some decoding processes are not necessary for now,
    // because we assume only one encryption scheme.
    StringSource source(buf, size, true);

    // EncryptedPrivateKeyInfo ::= SEQUENCE {
    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
    //   encryptedData        OCTET STRING }
    BERSequenceDecoder encryptedPrivateKeyInfo(source);
    {
      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
      //   parameters     SEQUENCE {{PBES2-params}} }
      BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
      {
        pbes2Id.decode(encryptionAlgorithm);
        // PBES2-params ::= SEQUENCE {
        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
        BERSequenceDecoder pbes2Params(encryptionAlgorithm);
        {
          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
          //   parameters     SEQUENCE {{PBKDF2-params}} }
          BERSequenceDecoder pbes2KDFs(pbes2Params);
          {
            pbkdf2Id.decode(pbes2KDFs);
            // AlgorithmIdentifier ::= SEQUENCE {
            //   salt           OCTET STRING,
            //   iterationCount INTEGER (1..MAX),
            //   keyLength      INTEGER (1..MAX) OPTIONAL,
            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
            BERSequenceDecoder pbkdf2Params(pbes2KDFs);
            {
              BERDecodeOctetString(pbkdf2Params, saltBlock);
              BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
            }
            pbkdf2Params.MessageEnd();
          }
          pbes2KDFs.MessageEnd();

          // AlgorithmIdentifier ::= SEQUENCE {
          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
          //   parameters  OCTET STRING} {{iv}} }
          BERSequenceDecoder pbes2Encs(pbes2Params);
          {
            pbes2encsId.decode(pbes2Encs);
            BERDecodeOctetString(pbes2Encs, ivBlock);
          }
          pbes2Encs.MessageEnd();
        }
        pbes2Params.MessageEnd();
      }
      encryptionAlgorithm.MessageEnd();

      BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
    }
    encryptedPrivateKeyInfo.MessageEnd();
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
  size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
  byte derived[24] = {0};
  byte purpose = 0;

  try {
    keyGenerator.DeriveKey(derived, derivedLen,
                           purpose,
                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(),
                           saltBlock.BytePtr(), saltBlock.size(),
                           iterationCount);
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  //decrypt
  CBC_Mode< DES_EDE3 >::Decryption d;
  d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());

  OBufferStream privateKeyOs;
  try {
    StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true,
                                 new StreamTransformationFilter(d,  new FileSink(privateKeyOs)));
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  if (!importPrivateKeyPkcs8IntoTpm(keyName,
                                    privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
    return false;

  // determine key type
  StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true);

  KeyType publicKeyType = KeyType::NONE;
  SecByteBlock rawKeyBits;
  // PrivateKeyInfo ::= SEQUENCE {
  //   INTEGER,
  //   SEQUENCE,
  //   OCTECT STRING}
  BERSequenceDecoder privateKeyInfo(privateKeySource);
  {
    uint32_t versionNum;
    BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
    BERSequenceDecoder sequenceDecoder(privateKeyInfo);
    {
      Oid keyTypeOid;
      keyTypeOid.decode(sequenceDecoder);
      if (keyTypeOid == oid::RSA)
        publicKeyType = KeyType::RSA;
      else if (keyTypeOid == oid::ECDSA)
        publicKeyType = KeyType::EC;
      else
        return false; // Unsupported key type;
    }
  }


  // derive public key
  OBufferStream publicKeyOs;

  try {
    switch (publicKeyType) {
      case KeyType::RSA: {
        RSA::PrivateKey privateKey;
        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
        RSAFunction publicKey(privateKey);

        FileSink publicKeySink(publicKeyOs);
        publicKey.DEREncode(publicKeySink);
        publicKeySink.MessageEnd();
        break;
      }

      case KeyType::EC: {
        ECDSA<ECP, SHA256>::PrivateKey privateKey;
        privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());

        ECDSA<ECP, SHA256>::PublicKey publicKey;
        privateKey.MakePublicKey(publicKey);
        publicKey.AccessGroupParameters().SetEncodeAsOID(true);

        FileSink publicKeySink(publicKeyOs);
        publicKey.DEREncode(publicKeySink);
        publicKeySink.MessageEnd();
        break;
      }

      default:
        return false;
    }
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }

  if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
    return false;

  return true;
}
Exemplo n.º 16
0
const byte * CRYPTOPP_API GetActualMacAndLocation(unsigned int &macSize, unsigned int &fileLocation)
{
	macSize = (unsigned int)g_actualMac.size();
	fileLocation = g_macFileLocation;
	return g_actualMac;
}
Exemplo n.º 17
0
void CryptoSession::parseAuthenticate2Reply(const string &bobPacket)
{
  /* Alice verifies that the random string she sent bob is included in bobs msg */
  AutoSeededRandomPool rng(false,128);

  int len;
  Storage::sectionType s;

  StringSource pct(bobPacket,true,new Base64Decoder(new Gunzip));
  len = pct.MaxRetrievable();
  byte *tmp = new byte[len];
  pct.Get(tmp,len);
  Storage r;
  r.setData(len,tmp);

  s=r.readSection(0);
  Storage::sectionType s2 = r.readSection(1);

  /* verify signature */
  StringSource pubFile(peer.getPubkey().c_str(),true,new HexDecoder);
  RSASSA_PKCS1v15_SHA_Verifier pub(pubFile);

  if ((unsigned)s2.second.second!=pub.SignatureLength())
  {
    cout << "you puny earthling!\n";
    debug() << "Bleh!!" << endl;
  }
  SecByteBlock signature(pub.SignatureLength());
  signature.Assign(s2.second.first,s2.second.second);

  VerifierFilter *verifierFilter = new VerifierFilter(pub);
  verifierFilter->PutSignature(signature);
  StringSource f(s.second.first,s.second.second, true, verifierFilter);

  byte result = 0;
  f.Get(result);
  if (result != 1)
  {
    cout << "you deserve a horrible pimple on your nose\n";
    debug() << "Bleh!!" << endl;
  }
  else
    cout << "Signature verified\n";
  /* Alice now decrypts the signed packet */
  cout <<"Data : ";
  StringSource(s.second.first,s.second.second,true,new HexEncoder(new FileSink(cout)));
  cout << "\n";

  StringSource privFile(privKey, true, new HexDecoder);
  RSAES_OAEP_SHA_Decryptor priv(privFile);
  SecByteBlock buf;
  buf.Assign(s.second.first,s.second.second);
  byte *outstr = new byte[priv.MaxPlainTextLength()+1];
  unsigned messageLength = priv.Decrypt(buf,outstr);

  cout << messageLength << " " << s.second.second<< endl;

  Storage msg;
  msg.setData(messageLength,outstr);

  s=msg.readSection(0);
  cout << s.first << endl;
  if (s.first != IDENTITY)
  {
    cout << "you suck way too much!\n";
    debug() << "Bleh!!" << endl;
  }
  cout << s.second.first << endl;

  //  byte *sessionKey;
  //int sessionKeyLen;
  s=msg.readSection(1);
  if (s.first != RANDOMDATA)
  {
    cout << "you suck too much ass!\n";
    debug() << "Bleh!!" << endl;
  }
  int randomDataLen=s.second.second;
  byte *randomData=new byte[randomDataLen];
  memcpy(randomData,s.second.first,randomDataLen);

  cout <<"\nRandom data we sent: ";
  StringSource(randomData,randomDataLen,true,new HexEncoder(new FileSink(cout)));
  cout << "\n";

  // assert this str is equal to the random string we sent earlier.

  s = msg.readSection(2);
  if (s.first != SESSIONKEY2)
  {
    cout << "you suck way too much ass!\n";
    debug() << "Bleh!!" << endl;
  }
  sessionKey2Len=s.second.second;
  sessionKey2=new byte[sessionKey2Len];
  memcpy(sessionKey2,s.second.first,sessionKey2Len);

  cout <<"Sessionkey2: ";
  StringSource(sessionKey2,sessionKey2Len,true,new HexEncoder(new FileSink(cout)));
  cout << "\n";

  finalKeyLen=16;
  finalKey=new byte[finalKeyLen];
  for (int i=0;i<16;i++)
    finalKey[i] = sessionKey[i] ^ sessionKey2[i];

  s = msg.readSection(3);
  if (s.first != RANDOMDATA2)
  {
    cout << "you suck way too much donkey ass!\n";
    debug() << "Bleh!!" << endl;
  }
  cout << s.second.second << endl;
  int random2DataLen=s.second.second;
  byte *random2Data=new byte[random2DataLen];
  memcpy(random2Data,s.second.first,random2DataLen);

  cout <<"Random data we got from Bob: " << random2DataLen << endl;
  StringSource(random2Data,random2DataLen,true,new HexEncoder(new FileSink(cout)));
  cout << "\n\n";
  memcpy(random2,random2Data,16);
}
Exemplo n.º 18
0
size_t PEM_ReadLine(BufferedTransformation& source, SecByteBlock& line, SecByteBlock& ending)
{
    if(!source.AnyRetrievable())
    {
        line.New(0);
        ending.New(0);
        
        return 0;
    }
    
    ByteQueue temp;
    
    while(source.AnyRetrievable())
    {
        byte b;
        if(!source.Get(b))
            throw Exception(Exception::OTHER_ERROR, "PEM_ReadLine: failed to read byte");
        
        // LF ?
        if(b == '\n')
        {
            ending = LF;
            break;
        }
        
        // CR ?
        if(b == '\r')
        {
            // CRLF ?
            if(source.AnyRetrievable() && source.Peek(b))
            {
                if(b == '\n')
                {
                    source.Skip(1);
                    
                    ending = CRLF;
                    break;
                }
            }
            
            ending = CR;
            break;
        }
        
        // Not End-of-Line, accumulate it.
        temp.Put(b);
    }
    
    if(temp.AnyRetrievable())
    {
        line.Grow(temp.MaxRetrievable());
        temp.Get(line.data(), line.size());
    }
    else
    {
        line.New(0);
        ending.New(0);
    }
    
    // We return a line stripped of CRs and LFs. However, we return the actual number of
    //   of bytes processed, including the CR and LF. A return of 0 means nothing was read.
    //   A return of 1 means an empty line was read (CR or LF). A return of 2 could
    //   mean an empty line was read (CRLF), or could mean 1 character was read. In
    //   any case, line will hold whatever was parsed.
    return line.size() + ending.size();
}
Exemplo n.º 19
0
SecByteBlock::const_iterator Search(const SecByteBlock& source, const SecByteBlock& target)
{
    return search(source.begin(), source.end(), target.begin(), target.end());
}
Exemplo n.º 20
0
PEM_Type PEM_GetType(const SecByteBlock& sb)
{
    SecByteBlock::const_iterator it;
    
    it = Search(sb, SBB_PUBLIC_BEGIN);
    if(it != sb.end())
        return PEM_PUBLIC_KEY;
    
    // RSA key types
    it = Search(sb, SBB_RSA_PUBLIC_BEGIN);
    if(it != sb.end())
        return PEM_RSA_PUBLIC_KEY;
    
    it = Search(sb, SBB_RSA_PRIVATE_BEGIN);
    if(it != sb.end())
    {
        it = Search(sb, SBB_PROC_TYPE_ENC);
        if(it != sb.end())
            return PEM_RSA_ENC_PRIVATE_KEY;
        
        return PEM_RSA_PRIVATE_KEY;
    }
    
    // DSA key types
    it = Search(sb, SBB_DSA_PUBLIC_BEGIN);
    if(it != sb.end())
        return PEM_DSA_PUBLIC_KEY;
    
    it = Search(sb, SBB_DSA_PRIVATE_BEGIN);
    if(it != sb.end())
    {
        it = Search(sb, SBB_PROC_TYPE_ENC);
        if(it != sb.end())
            return PEM_DSA_ENC_PRIVATE_KEY;
        
        return PEM_DSA_PRIVATE_KEY;
    }
    
    // EC key types
    it = Search(sb, SBB_EC_PUBLIC_BEGIN);
    if(it != sb.end())
        return PEM_EC_PUBLIC_KEY;
    
    it = Search(sb, SBB_ECDSA_PUBLIC_BEGIN);
    if(it != sb.end())
        return PEM_ECDSA_PUBLIC_KEY;
    
    it = Search(sb, SBB_EC_PRIVATE_BEGIN);
    if(it != sb.end())
    {
        it = Search(sb, SBB_PROC_TYPE_ENC);
        if(it != sb.end())
            return PEM_EC_ENC_PRIVATE_KEY;
        
        return PEM_EC_PRIVATE_KEY;
    }
    
    // EC Parameters
    it = Search(sb, SBB_EC_PARAMETERS_BEGIN);
    if(it != sb.end())
        return PEM_EC_PARAMETERS;
    
    // DH Parameters
    it = Search(sb, SBB_DH_PARAMETERS_BEGIN);
    if(it != sb.end())
        return PEM_DH_PARAMETERS;
    
    // DSA Parameters
    it = Search(sb, SBB_DSA_PARAMETERS_BEGIN);
    if(it != sb.end())
        return PEM_DSA_PARAMETERS;
    
    // Certificate
    it = Search(sb, SBB_CERTIFICATE_BEGIN);
    if(it != sb.end())
        return PEM_CERTIFICATE;
    
    it = Search(sb, SBB_X509_CERTIFICATE_BEGIN);
    if(it != sb.end())
        return PEM_X509_CERTIFICATE;
    
    it = Search(sb, SBB_REQ_CERTIFICATE_BEGIN);
    if(it != sb.end())
        return PEM_REQ_CERTIFICATE;
    
    return PEM_UNSUPPORTED;
}
Exemplo n.º 21
0
int main()
{
    string key;
    unsigned int limit;
    int flag;

    cout << "Input key(32Byte from [0-9a-f]):";
    cin >> key;
    cout << "Input upper limit:";
    cin >> limit;

    StringSource ss(key, true, new HexDecoder);
    SecByteBlock bkey((size_t)ss.MaxRetrievable());
    ss.Get(bkey, bkey.size());

    ECB_Mode<AES>::Encryption aes(bkey, bkey.size());
    ECB_Mode<AES>::Encryption aes1(bkey, bkey.size());

    SecByteBlock *outputsbb;
    for(unsigned int i = 0; i < limit; i ++)
    {
        const byte *pi = (const byte *)&i;

        flag = 0;

        StreamTransformationFilter *stf = new StreamTransformationFilter(aes);
        StringSource outputss(pi, (size_t)sizeof(int)/sizeof(byte), true, stf);
        outputsbb = new SecByteBlock((size_t)outputss.MaxRetrievable());
        outputss.Get(*outputsbb, outputsbb->size());

        if(*((unsigned int *)(outputsbb->BytePtr())) < limit &&
                *((unsigned int *)(outputsbb->BytePtr()) + 4) == 0 &&
                *((unsigned int *)(outputsbb->BytePtr()) + 8) == 0 &&
                *((unsigned int *)(outputsbb->BytePtr()) + 12) == 0)
        {
            flag = 1;
        }


        while(!flag)
        {
            StreamTransformationFilter *stf1 = new StreamTransformationFilter(aes1);
            StringSource outputss1(*outputsbb, outputsbb->size(), true, stf1);
            delete outputsbb;
            outputsbb = new SecByteBlock((size_t)outputss1.MaxRetrievable());
            outputss1.Get(*outputsbb, outputsbb->size());

            if(*((unsigned int *)(outputsbb->BytePtr())) < limit &&
                    *((unsigned int *)(outputsbb->BytePtr()) + 4) == 0 &&
                    *((unsigned int *)(outputsbb->BytePtr()) + 8) == 0 &&
                    *((unsigned int *)(outputsbb->BytePtr()) + 12) == 0)
            {
                flag = 1;
                cout << i << ": " << *((unsigned int *)(outputsbb->BytePtr())) << endl;
            }
        }
        delete outputsbb;
    }

    return 0;
}
Exemplo n.º 22
0
void PEM_StripEncapsulatedHeader(BufferedTransformation& src, BufferedTransformation& dest, EncapsulatedHeader& header)
{
    if(!src.AnyRetrievable())
        return;
    
    SecByteBlock line, ending;
    size_t size = 0;
    
    // The first line *must* be Proc-Type. Ensure we read it before dropping into the loop.
    size = PEM_ReadLine(src, line, ending);
    if(size == 0 || line.empty())
        throw InvalidDataFormat("PEM_StripEncapsulatedHeader: failed to locate Proc-Type");
    
    SecByteBlock field = GetControlField(line);
    if(field.empty())
        throw InvalidDataFormat("PEM_StripEncapsulatedHeader: failed to locate Proc-Type");
    
    if(0 != CompareNoCase(field, SBB_PROC_TYPE))
        throw InvalidDataFormat("PEM_StripEncapsulatedHeader: failed to locate Proc-Type");
    
    line = GetControlFieldData(line);
    string tline(reinterpret_cast<const char*>(line.data()),line.size());
    
    PEM_ParseVersion(tline, header.m_version);
    if(header.m_version != "4")
        throw NotImplemented("PEM_StripEncapsulatedHeader: encryption version " + header.m_version + " not supported");
    
    PEM_ParseOperation(tline, header.m_operation);
    if(header.m_operation != "ENCRYPTED")
        throw NotImplemented("PEM_StripEncapsulatedHeader: operation " + header.m_operation + " not supported");
    
    // Next, we have to read until the first empty line
    while(true)
    {
        if(!src.AnyRetrievable()) break; // End Of Buffer
        
        size = PEM_ReadLine(src, line, ending);
        if(size == 0) break;        // End Of Buffer
        if(line.size() == 0) break; // size is non-zero; empty line
        
        field = GetControlField(line);
        if(0 == CompareNoCase(field, SBB_DEK_INFO))
        {
            line = GetControlFieldData(line);
            tline = string(reinterpret_cast<const char*>(line.data()),line.size());
            
            PEM_ParseAlgorithm(tline, header.m_algorithm);
            PEM_ParseIV(tline, header.m_iv);
            
            continue;
        }
        
        if(0 == CompareNoCase(field, SBB_CONTENT_DOMAIN))
        {
            // Silently ignore
            // Content-Domain: RFC822
            continue;
        }
        
        if(!field.empty())
        {
            const char* ptr = (char*)field.begin();
            size_t len = field.size();
            
            string m(ptr, len);
            throw NotImplemented("PEM_StripEncapsulatedHeader: " + m + " not supported");
        }
    }
    
    if(header.m_algorithm.empty())
        throw InvalidArgument("PEM_StripEncapsulatedHeader: no encryption algorithm");
    
    if(header.m_iv.empty())
        throw InvalidArgument("PEM_StripEncapsulatedHeader: no IV present");
    
    // After the empty line is the encapsulated text. Transfer it to the destination.
    src.TransferTo(dest);
}
Exemplo n.º 23
0
// Bob
void CryptoSession::parseAuthenticateReply(const string &alicePacket)
{

  AutoSeededRandomPool rng(false,128);

  int len;
  Storage::sectionType s;

  StringSource pct(alicePacket,true,new Base64Decoder(new Gunzip));
  len = pct.MaxRetrievable();
  byte *tmp = new byte[len];
  pct.Get(tmp,len);
  Storage r;
  r.setData(len,tmp);

  s=r.readSection(0);
  if (s.first != CERTIFICATE)
  {
    cout << "Corrupt packet\n";
    debug() << "Bleh!!" << endl;
  }
  /* Bob verifies the validity of the certificate */
  Certificate c(s.second.first,s.second.second);
  cout << "Version: "<< c.getVersion() << endl;
  cout << "Serial: "<< c.getSerial() << endl;
  cout << "Issuer: "<<  c.getIssuer() << endl;
  cout << "Subject: "<< c.getSubject() << endl;
  cout << "Pubkey Algorithm: "<< c.getPubkeyAlgorithm() << endl;
  cout << "Pubkey: "<< c.getPubkey() << endl;
  if (c.verify(""))
    cout << "Certificate verified!\n";
  else
    cout << "************ invalid certificate! **************\n";

  peer = c;

  /* Bob verifies her signature */
  s=r.readSection(1);
  Storage::sectionType s2 = r.readSection(2);

  StringSource pubFile(c.getPubkey().c_str(),true,new HexDecoder);
  RSASSA_PKCS1v15_SHA_Verifier pub(pubFile);

  if ((unsigned)s2.second.second!=pub.SignatureLength())
  {
    cout << "Alices signature is invalid\n";
    debug() << "Bleh!!" << endl;
  }
  SecByteBlock signature(pub.SignatureLength());
  signature.Assign(s2.second.first,s2.second.second);

  VerifierFilter *verifierFilter = new VerifierFilter(pub);
  verifierFilter->PutSignature(signature);
  StringSource f(s.second.first,s.second.second, true, verifierFilter);

  byte result = 0;
  f.Get(result);
  if (result != 1)
  {
    cout << "Alices signature is invalid\n";
    debug() << "Bleh!!" << endl;
  }

  /* Bob now decrypts the signed packet */
  cout <<"Data : ";
  StringSource(s.second.first,s.second.second,true,new HexEncoder(new FileSink(cout)));
  cout << "\n";

  StringSource privFile(privKey, true, new HexDecoder);
  RSAES_OAEP_SHA_Decryptor priv(privFile);
  SecByteBlock buf;
  buf.Assign(s.second.first,s.second.second);
  byte *outstr = new byte[priv.MaxPlainTextLength()+1];
  unsigned messageLength = priv.Decrypt(buf,outstr);

  cout << messageLength << " " << s.second.second<< endl;

  Storage msg;
  msg.setData(messageLength,outstr);

  s=msg.readSection(0);
  cout << s.first << endl;
  if (s.first != IDENTITY)
  {
    cout << "you suck too much!\n";
    debug() << "Bleh!!" << endl;
  }
  cout << s.second.first << endl;

  s=msg.readSection(1);
  if (s.first != SESSIONKEY)
  {
    cout << "you suck too much ass!\n";
    debug() << "Bleh!!" << endl;
  }
  sessionKeyLen=s.second.second;
  sessionKey=new byte[sessionKeyLen];
  memcpy(sessionKey,s.second.first,sessionKeyLen);

  cout <<"\nSessionkey : ";
  StringSource(sessionKey,sessionKeyLen,true,new HexEncoder(new FileSink(cout)));
  cout << "\n";

  s = msg.readSection(2);
  cout << s.first << endl;
  if (s.first != RANDOMDATA ||s.second.second != 16)
  {
    cout << "you suck too much ass!\n";
    debug() << "Bleh!!" << endl;
  }
  memcpy(random,s.second.first,16);
}
Exemplo n.º 24
0
//********************************************************************************************************
Integer Converter::decodeSecByteBlock(SecByteBlock key)
{
    Integer x;
    x.Decode(key.BytePtr(), key.SizeInBytes());
    return x;
}
Exemplo n.º 25
0
void PEM_NextObject(BufferedTransformation& src, BufferedTransformation& dest, bool trimTrailing)
{
    if(!src.AnyRetrievable())
        return;
    
    // We have four things to find:
    //   1. -----BEGIN (the leading begin)
    //   2. ----- (the trailing dashes)
    //   3. -----END (the leading end)
    //   4. ----- (the trailing dashes)
    
    // Once we parse something that purports to be PEM encoded, another routine
    //  will have to look for something particular, like a RSA key. We *will*
    //  inadvertently parse garbage, like -----BEGIN FOO BAR-----. It will
    //  be caught later when a PEM_Load routine is called.
    
    static const size_t BAD_IDX = PEM_INVALID;
    
    // We use iterators for the search. However, an interator is invalidated
    //  after each insert that grows the container. So we save indexes
    //  from begin() to speed up searching. On each iteration, we simply
    //  reinitialize them.
    SecByteBlock::const_iterator it;
    size_t idx1 = BAD_IDX, idx2 = BAD_IDX, idx3 = BAD_IDX, idx4 = BAD_IDX;
    
    // The idea is to read chunks in case there are multiple keys or
    //  paramters in a BufferedTransformation. So we use CopyTo to
    //  extract what we are interested in. We don't take anything
    //  out of the BufferedTransformation (yet).
    
    // We also use indexes because the iterator will be invalidated
    //   when we append to the ByteQueue. Even though the iterator
    //   is invalid, `accum.begin() + index` will be valid.
    
    // Reading 8 or 10 lines at a time is an optimization from testing
    //   against cacerts.pem. The file has 153 certs, so its a good test.
    // +2 to allow for CR + LF line endings. There's no guarantee a line
    //   will be present, or it will be RFC1421_LINE_BREAK in size.
    static const size_t READ_SIZE = (RFC1421_LINE_BREAK + 1) * 10;
    static const size_t REWIND = max(SBB_PEM_BEGIN.size(), SBB_PEM_END.size()) + 2;
    
    SecByteBlock accum;
    size_t idx = 0, next = 0;
    
    size_t available = src.MaxRetrievable();
    while(available)
    {
        // How much can we read?
        const size_t size = std::min(available, READ_SIZE);
        
        // Ideally, we would only scan the line we are reading. However,
        //   we need to rewind a bit in case a token spans the previous
        //   block and the block we are reading. But we can't rewind
        //   into a previous index. Once we find an index, the variable
        //   next is set to it. Hence the reason for the max()
        if(idx > REWIND)
        {
            const size_t x = idx - REWIND;
            next = max(next, x);
        }
        
#if 0
        // Next should be less than index by 10 or so
        std::cout << "  Index: " << idx << std::endl;
        std::cout << "   Next: " << next << std::endl;
#endif
        
        // We need a temp queue to use CopyRangeTo. We have to use it
        //   because there's no Peek that allows us to peek a range.
        ByteQueue tq;
        src.CopyRangeTo(tq, static_cast<lword>(idx), static_cast<lword>(size));
        
        const size_t offset = accum.size();
        accum.Grow(offset + size);
        tq.Get(accum.data() + offset, size);
        
        // Adjust sizes
        idx += size;
        available -= size;
        
        // Locate '-----BEGIN'
        if(idx1 == BAD_IDX)
        {
            it = search(accum.begin() + next, accum.end(), SBB_PEM_BEGIN.begin(), SBB_PEM_BEGIN.end());
            if(it == accum.end())
                continue;
            
            idx1 = it - accum.begin();
            next = idx1 + SBB_PEM_BEGIN.size();
        }
        
        // Locate '-----'
        if(idx2 == BAD_IDX && idx1 != BAD_IDX)
        {
            it = search(accum.begin() + next, accum.end(), SBB_PEM_TAIL.begin(), SBB_PEM_TAIL.end());
            if(it == accum.end())
                continue;
            
            idx2 = it - accum.begin();
            next = idx2 + SBB_PEM_TAIL.size();
        }
        
        // Locate '-----END'
        if(idx3 == BAD_IDX && idx2 != BAD_IDX)
        {
            it = search(accum.begin() + next, accum.end(), SBB_PEM_END.begin(), SBB_PEM_END.end());
            if(it == accum.end())
                continue;
            
            idx3 = it - accum.begin();
            next = idx3 + SBB_PEM_END.size();
        }
        
        // Locate '-----'
        if(idx4 == BAD_IDX && idx3 != BAD_IDX)
        {
            it = search(accum.begin() + next, accum.end(), SBB_PEM_TAIL.begin(), SBB_PEM_TAIL.end());
            if(it == accum.end())
                continue;
            
            idx4 = it - accum.begin();
            next = idx4 + SBB_PEM_TAIL.size();
        }
    }
    
    // Did we find `-----BEGIN XXX-----` (RFC 1421 calls this pre-encapsulated boundary)?
    if(idx1 == BAD_IDX || idx2 == BAD_IDX)
        throw InvalidDataFormat("PEM_NextObject: could not locate boundary header");
    
    // Did we find `-----END XXX-----` (RFC 1421 calls this post-encapsulated boundary)?
    if(idx3 == BAD_IDX || idx4 == BAD_IDX)
        throw InvalidDataFormat("PEM_NextObject: could not locate boundary footer");
    
    // *IF* the trailing '-----' occurred in the last 5 bytes in accum, then we might miss the
    // End of Line. We need to peek 2 more bytes if available and append them to accum.
    if(available >= 2)
    {
        ByteQueue tq;
        src.CopyRangeTo(tq, static_cast<lword>(idx), static_cast<lword>(2));
        
        const size_t offset = accum.size();
        accum.Grow(offset + 2);
        tq.Get(accum.data() + offset, 2);
    }
    else if(available == 1)
    {
        ByteQueue tq;
        src.CopyRangeTo(tq, static_cast<lword>(idx), static_cast<lword>(1));
        
        const size_t offset = accum.size();
        accum.Grow(offset + 1);
        tq.Get(accum.data() + offset, 1);
    }
    
    // Final book keeping
    const byte* ptr = accum.begin() + idx1;
    const size_t used = idx4 + SBB_PEM_TAIL.size();
    const size_t len = used - idx1;
    
    // Include one CR/LF if its available in the accumulator
    next = idx1 + len;
    size_t adjust = 0;
    if(next < accum.size())
    {
        byte c1 = accum[next];
        byte c2 = 0;
        
        if(next + 1 < accum.size())
            c2 = accum[next + 1];
        
        // Longest match first
        if(c1 == '\r' && c2 == '\n')
            adjust = 2;
        else if(c1 == '\r' || c1 == '\n')
            adjust = 1;
    }
    
    dest.Put(ptr, len + adjust);
    dest.MessageEnd();
    
    src.Skip(used + adjust);
    
    if(trimTrailing)
    {
        while (src.AnyRetrievable())
        {
            byte b;
            src.Peek(b);
            
            if(!isspace(b)) break;
            src.Skip(1);
        }
    }
}