void loadRSAPriKey(RSA::PrivateKey& key, const char* filename){
  ByteQueue byte;
  FileSource file(filename, true, new Base64Decoder);
  file.TransferTo(byte);
  byte.MessageEnd();
  key.Load(byte);
}
// EGPublicKey::Dump
// Streaming method.  Outputs key to specfied stream.  Outputs key length followed
// by each factor of the key.
void
EGPublicKey::Dump(std::ostream& os) const
{
	// Output KeyLen followed by P, G, and Y
	try
	{
		ByteQueue aQueue;
		aQueue.Put(mKey, mKeyLen);
		aQueue.Close();

		Integer            p, q, g, y;
		BERSequenceDecoder aDecoder(aQueue);
		p.BERDecode(aDecoder);
		q.BERDecode(aDecoder);
		g.BERDecode(aDecoder);
		y.BERDecode(aDecoder);
		os << "(Len=" << mKeyLen << " P=" << p << " Q=" << q << " G=" << g
		   << " Y=" << y << ')';
	}
	catch (Exception& anEx)
	{
		WDBG_AH("EGPublicKey::Dump Caught CryptoLib exception: " << anEx.what());
		os << "(EGPublicKey Exception: " << anEx.what() << ')';
	}
}
Esempio n. 3
0
void ByteQueue::pop(ByteQueue& data) {
  uint32_t total = data.size() <= buf.size() ? data.size() : buf.size();
  if (!total)
    return;
  memcpy(data.ptr(), (const void*)&buf[0], total);
  buf.erase(buf.begin(), buf.begin() + total);
  data.resize(total);
}
Esempio n. 4
0
 QByteArray CppGetByteArray(const CryptoMaterial &cm)
 {
   ByteQueue queue;
   cm.Save(queue);
   QByteArray data(queue.CurrentSize(), 0);
   queue.Get(reinterpret_cast<byte *>(data.data()), data.size());
   return data;
 }
Esempio n. 5
0
void initRSA() {
    string pubkey = base64_decode(string(serverPublicKey));
    ByteQueue tmp;
    for (int i = 0; i < pubkey.size(); i++)
        tmp.Put((byte)pubkey[i]);

    serverPub = new RSA::PublicKey;
    serverPub->Load(tmp);

    encryptor = new RSAES_OAEP_SHA_Encryptor(*serverPub);
}
Esempio n. 6
0
static bool DecodeFromFile(const char* filename, RSA::PrivateKey& key)
{
	try {
		ByteQueue queue;
		FileSource file(filename, true);
		file.TransferTo(queue);
		queue.MessageEnd();
		key.BERDecodePrivateKey(queue, false, queue.MaxRetrievable());
		return key.Validate(rng, 3);
	} catch (...) {
		return false;
	}
}
Esempio n. 7
0
void CAuthenticationProfileImpl::sendPublicKey(RSA::PublicKey publicKey)
{
   LOG4CPLUS_TRACE_METHOD(msLogger, __PRETTY_FUNCTION__ );
   ByteQueue queue;
   publicKey.Save(queue);
   UInt32 queueSize = queue.CurrentSize();
   UInt8* outgoingData = new UInt8[queueSize + 1];
   outgoingData[0] = static_cast<UInt8>(SEND_PUBLIC_KEY);
   queue.Get(outgoingData + 1, queueSize);
   LOG4CPLUS_INFO(msLogger, "***** " + convertIntegerToString(queueSize + 1) + " bytes sent");
   iviLink::Channel::sendBuffer(mChannelID, outgoingData, queueSize + 1);
   delete[] outgoingData;
}
// EGPublicKey::AllocateSig
// Allocates the mSigP member if needed.  Feeds binary rep of key into the
// ElGamalVerifier class from Crypto++.
void
EGPublicKey::AllocateSig() const
{
	WTRACE("EGPublicKey::AllocateSig");
	if (! mSigP)
	{
		WDBG_LL("EGPublicKey::AllocateSig Allocating crypt object.");
		ByteQueue aQueue;
		aQueue.Put(mKey, mKeyLen);
		aQueue.Close();
		mSigP = new ElGamalVerifier(aQueue);
	}
}
Esempio n. 9
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);
}
Esempio n. 10
0
void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
{
	std::string s1 = GetRequiredDatum(data, name), s2;
	ByteQueue q;

	while (!s1.empty())
	{
		while (s1[0] == ' ')
		{
			s1 = s1.substr(1);
			if (s1.empty())
				goto end;	// avoid invalid read if s1 is empty
		}

		int repeat = 1;
		if (s1[0] == 'r')
		{
			repeat = atoi(s1.c_str()+1);
			s1 = s1.substr(s1.find(' ')+1);
		}

		s2 = ""; // MSVC 6 doesn't have clear();

		if (s1[0] == '\"')
		{
			s2 = s1.substr(1, s1.find('\"', 1)-1);
			s1 = s1.substr(s2.length() + 2);
		}
		else if (s1.substr(0, 2) == "0x")
		{
			StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
			s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
		}
		else
		{
			StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
			s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
		}

		while (repeat--)
		{
			q.Put((const byte *)s2.data(), s2.size());
			RandomizedTransfer(q, target, false);
		}
	}

end:
	RandomizedTransfer(q, target, true);
}
Esempio n. 11
0
void UDPSocket::send(const Address& address, const ByteQueue& data) {
#ifdef _WIN32
  SOCKADDR_IN servaddr;
  memset((void*)&servaddr, 0, sizeof(SOCKADDR_IN));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = address.ip;
  servaddr.sin_port = address.port;
  sendto(sd, (const char*)data.ptr(), data.size(), 0, (SOCKADDR*)&servaddr, sizeof(SOCKADDR_IN));
#else
  sockaddr_in servaddr;
  memset(&servaddr, 0, sizeof(sockaddr_in));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = address.ip;
  servaddr.sin_port = address.port;
  sendto(sd, data.ptr(), data.size(), 0, (const sockaddr*)&servaddr, sizeof(sockaddr_in));
#endif
}
// EGPublicKey::Encrypt
// Encrypts a block of data of the specified length using ElGamal encryption for this
// key.  Returns allocated block/len of encrypted data.
EGPublicKey::CryptReturn
EGPublicKey::Encrypt(const void* theMsgP, unsigned long theLen) const
{
	WTRACE("EGPublicKey::Encrypt");

	// Sanity check
	if ((! theMsgP) || (theLen == 0))
	{
		WDBG_LM("EGPublicKey::Encrypt No data to encrypt");
		return CryptReturn(NULL,0);
	}

	try
	{
		// Allocate crypt object if needed
		AllocateCrypt();

		// Encrypt the data
		ByteQueue aQueue;
		EncryptData(aQueue, reinterpret_cast<const unsigned char*>(theMsgP), theLen);

		// Build return
		WDBG_LL("EGPublicKey::Encrypt Building return values.");
		unsigned long anOutLen = aQueue.MaxRetrieveable();
		if (anOutLen == 0)
		{
			WDBG_LM("EGPublicKey::Encrypt Encrypt failed, no data.");
			return CryptReturn(NULL, 0);
		}

		auto_ptr<unsigned char> anOutP(new unsigned char [anOutLen]);
		aQueue.Get(anOutP.get(), anOutLen);

		WDBG_LM("EGPublicKey::Encrypt Encrypted, out block len=" << anOutLen);
		return CryptReturn(anOutP.release(), anOutLen);
	}
	catch (Exception& anEx)
	{
		// Little trick here, construct a CryptException to auto log the failure!
		WDBG_AH("EGPublicKey::Encrypt Caught CryptoLib exception: " << anEx.what());
#ifndef _WONCRYPT_NOEXCEPTIONS
		WONCrypt::CryptException aLog(WONCommon::ExCryptoLib, __LINE__, __FILE__, anEx.what());
#endif
		return CryptReturn(NULL,0);
	}
}
Esempio n. 13
0
ByteQueue UDPSocket::recv(Address& address) {
  ByteQueue data;
#ifdef _WIN32
  fd_set fds;
  timeval timeout;
  FD_ZERO(&fds);
  FD_SET(sd, &fds);
  timeout.tv_sec = 0;
  timeout.tv_usec = 0;
  if (select(0, &fds, nullptr, nullptr, &timeout) > 0) {
    SOCKADDR_IN addr;
    int addrsize = sizeof(SOCKADDR_IN);
    data.resize(maxlen);
    data.resize(uint32_t(recvfrom(SOCKET(sd), (char*)data.ptr(), maxlen, 0, (SOCKADDR*)&addr, &addrsize)));
    address = Address(addr.sin_addr.S_un.S_addr, addr.sin_port);
  }
#else
  fd_set fds;
  timeval timeout;
  FD_ZERO(&fds);
  FD_SET(sd, &fds);
  timeout.tv_sec = 0;
  timeout.tv_usec = 0;
  if (select(sd + 1, &fds, nullptr, nullptr, &timeout) > 0) {
    sockaddr_in addr;
    socklen_t addrsize = sizeof(sockaddr_in);
    data.resize(maxlen);
    data.resize(uint32_t(recvfrom(sd, data.ptr(), maxlen, 0, (sockaddr*)&addr, &addrsize)));
    address = Address(addr.sin_addr.s_addr, addr.sin_port);
  }
#endif
  return data;
}
// EGPublicKey::CopyFromPrivateKey
// Copies public key from a private key.  Existing key (if any) is replaced.  This
// method takes the binary rep of the private key and drops the private portion
// to generate the public key.
void
EGPublicKey::CopyFromPrivateKey(const EGPrivateKey& theKeyR)
{
	ClearLocal();

	try
	{
		ByteQueue aPrivQueue;
		aPrivQueue.Put(theKeyR.GetKey(), theKeyR.GetKeyLen());
		aPrivQueue.Close();

		ElGamalVerifier aKey(aPrivQueue);
		ByteQueue       aPubQueue;
		aKey.DEREncode(aPubQueue);
		aPubQueue.Close();

		AllocKeyBuf(aPubQueue.MaxRetrieveable());
		aPubQueue.Get(mKey, mKeyLen);
	}
	catch (Exception& anEx)
	{
		WDBG_AH("EGPublicKey::CopyFromPrivateKey Caught CryptoLib exception: " << anEx.what());
#ifndef _WONCRYPT_NOEXCEPTIONS
		throw WONCrypt::CryptException(WONCommon::ExCryptoLib, __LINE__, __FILE__, anEx.what());
#else
		Invalidate();
#endif
	}
}
extern "C" int rsa_pss_sign(const char *key_file, const unsigned char *msg,
			int len, unsigned char *sig_buf, unsigned char *modulus_buf)
{
	try {
		AutoSeededRandomPool rng;
		FileSource file(key_file, true);
		RSA::PrivateKey key;
		ByteQueue bq;

		// Load the key
		file.TransferTo(bq);
		bq.MessageEnd();
		key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable());

		// Write the modulus
		Integer mod = key.GetModulus();
		// error check
		if (mod.ByteCount() != RCM_RSA_MODULUS_SIZE)
			throw std::length_error("incorrect rsa key modulus length");
		for (int i = 0; i < mod.ByteCount(); i++)
			modulus_buf[i] = mod.GetByte(i);

		// Sign the message
		RSASS<PSS, SHA256>::Signer signer(key);
		size_t length = signer.MaxSignatureLength();
		SecByteBlock signature(length);

		length = signer.SignMessage(rng, msg, len, signature);

		// Copy in reverse order
		for (int i = 0; i < length; i++)
			sig_buf[length - i - 1] = signature[i];
	}
	catch(const CryptoPP::Exception& e) {
		cerr << e.what() << endl;
		return 1;
	}
	catch(std::length_error& le) {
		cerr << "Error: " << le.what() << endl;
		return 1;
	}

	return 0;
}
Esempio n. 16
0
void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target)
{
	std::string s1 = GetRequiredDatum(data, name), s2;

	while (!s1.empty())
	{
		while (s1[0] == ' ')
			s1 = s1.substr(1);

		int repeat = 1;
		if (s1[0] == 'r')
		{
			repeat = atoi(s1.c_str()+1);
			s1 = s1.substr(s1.find(' ')+1);
		}
		
		s2 = ""; // MSVC 6 doesn't have clear();

		if (s1[0] == '\"')
		{
			s2 = s1.substr(1, s1.find('\"', 1)-1);
			s1 = s1.substr(s2.length() + 2);
		}
		else if (s1.substr(0, 2) == "0x")
		{
			StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
			s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
		}
		else
		{
			StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2)));
			s1 = s1.substr(STDMIN(s1.find(' '), s1.length()));
		}

		ByteQueue q;
		while (repeat--)
		{
			q.Put((const byte *)s2.data(), s2.size());
			if (q.MaxRetrievable() > 4*1024 || repeat == 0)
				q.TransferTo(target);
		}
	}
}
extern "C" int rsa_pss_sign_file(const char *key_file, const char *msg_file,
			unsigned char *sig_buf)
{
	try {
		AutoSeededRandomPool rng;
		FileSource file(key_file, true);
		RSA::PrivateKey key;
		ByteQueue bq;

		// Load the key
		file.TransferTo(bq);
		bq.MessageEnd();
		key.BERDecodePrivateKey(bq, false, bq.MaxRetrievable());

		// Sign the message
		RSASS<PSS, SHA256>::Signer signer(key);
		string signature;
		FileSource src(msg_file, true,
			new SignerFilter(rng, signer,
					new StringSink(signature)));
		int length = signature.length();
		// error check
		if (length != RCM_RSA_SIG_SIZE)
			throw std::length_error("incorrect rsa key length");

		// Copy in reverse order
		for (int i = 0; i < length; i++)
			sig_buf[length - i - 1] = signature[i];
	}
	catch(const CryptoPP::Exception& e) {
		cerr << e.what() << endl;
		return 1;
	}
	catch(std::length_error& le) {
		cerr << "Error: " << le.what() << endl;
		return 1;
	}

	return 0;
}
Esempio n. 18
0
bool ByteQueue::operator==(const ByteQueue &rhs) const
{
	const unsigned long currentSize = CurrentSize();

	if (currentSize != rhs.CurrentSize())
		return false;

	for (unsigned long i = 0; i<currentSize; i++)
		if ((*this)[i] != rhs[i])
			return false;

	return true;
}
// EGPublicKey::AllocateCrypt
// Allocates the mCryptP member if needed.  Manually decodes binary rep into factors
// and feeds appropriate factor to the ElGamalEncryptor class from Crypto++.
void
EGPublicKey::AllocateCrypt() const
{
	WTRACE("EGPublicKey::AllocateCrypt");
	if (! mCryptP)
	{
		WDBG_LL("EGPublicKey::AllocateCrypt Allocating crypt object.");
		ByteQueue aQueue;
		aQueue.Put(mKey, mKeyLen);
		aQueue.Close();

		// *HACK*
		// Manually build the ElGamalEncryptor object.  See notes at
		// top of this file.
		Integer p, q, g, y;
		BERSequenceDecoder seq(aQueue);
		p.BERDecode(seq);
		q.BERDecode(seq);
		g.BERDecode(seq);
		y.BERDecode(seq);
		mCryptP = new ElGamalEncryptor(p, g, y);
	}
}
Esempio n. 20
0
  CppRsaPublicKeyImpl::CppRsaPublicKeyImpl(const QByteArray &data, bool seed) :
    m_public_key(new RSA::PublicKey())
  {
    if(seed) {
      RSA::PrivateKey key;
      CryptoRandom rand(data);
      key.GenerateRandomWithKeySize(GetCppRandom(rand),
          RsaPrivateKey::DefaultKeySize());
      m_public_key.reset(new RSA::PublicKey(key));
    } else {
      ByteQueue queue;
      queue.Put2(reinterpret_cast<const byte *>(data.data()), data.size(), 0, true);

      try {
        m_public_key->Load(queue);
      } catch (std::exception &e) {
        qWarning() << "In CppRsaPublicKey: " << e.what();
        m_valid = false;
        return;
      }
    }
    m_valid = true;
  }
Esempio n. 21
0
bool ByteQueue::operator==(const ByteQueue &rhs) const
{
	const lword currentSize = CurrentSize();

	if (currentSize != rhs.CurrentSize())
		return false;

	Walker walker1(*this), walker2(rhs);
	byte b1, b2;

	while (walker1.Get(b1) && walker2.Get(b2))
		if (b1 != b2)
			return false;

	return true;
}
Esempio n. 22
0
bool ValidateRSA()
{
	cout << "\nRSA validation suite running...\n\n";

	byte out[100], outPlain[100];
	bool pass = true, fail;

	{
		static const char plain[] = "Everyone gets Friday off.";
		byte *signature = (byte *)
			"\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
			"\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
			"\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
			"\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1";

		FileSource keys("TestData/rsa512a.dat", true, new HexDecoder);
		Weak::RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys);
		Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);

		size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out);
		fail = !VerifyBufsEqual(signature, out, 64);
		pass = pass && !fail;

		cout << (fail ? "FAILED    " : "passed    ");
		cout << "signature check against test vector\n";

		fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
		pass = pass && !fail;

		cout << (fail ? "FAILED    " : "passed    ");
		cout << "verification check against test vector\n";

		out[10]++;
		fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength);
		pass = pass && !fail;

		cout << (fail ? "FAILED    " : "passed    ");
		cout << "invalid signature verification\n";
	}
	{
		FileSource keys("TestData/rsa1024.dat", true, new HexDecoder);
		RSAES_PKCS1v15_Decryptor rsaPriv(keys);
		RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv);

		pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
	}
	{
		RSAES<OAEP<SHA> >::Decryptor rsaPriv(GlobalRNG(), 512);
		RSAES<OAEP<SHA> >::Encryptor rsaPub(rsaPriv);

		pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
	}
	{
		byte *plain = (byte *)
			"\x54\x85\x9b\x34\x2c\x49\xea\x2a";
		byte *encrypted = (byte *)
			"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
			"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
			"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
			"\x62\x51";
		byte *oaepSeed = (byte *)
			"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
			"\xf0\x6c\xb5\x8f";
		ByteQueue bq;
		bq.Put(oaepSeed, 20);
		FixedRNG rng(bq);

		FileSource privFile("TestData/rsa400pv.dat", true, new HexDecoder);
		FileSource pubFile("TestData/rsa400pb.dat", true, new HexDecoder);
		RSAES_OAEP_SHA_Decryptor rsaPriv;
		rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0);
		RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);

		memset(out, 0, 50);
		memset(outPlain, 0, 8);
		rsaPub.Encrypt(rng, plain, 8, out);
		DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain);
		fail = !result.isValidCoding || (result.messageLength!=8) || !VerifyBufsEqual(out, encrypted, 50) || !VerifyBufsEqual(plain, outPlain, 8);
		pass = pass && !fail;

		cout << (fail ? "FAILED    " : "passed    ");
		cout << "PKCS 2.0 encryption and decryption\n";
	}

	return pass;
}
Esempio n. 23
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();
}
Esempio n. 24
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);
        }
    }
}
Esempio n. 25
0
void CAuthenticationProfileImpl::onBufferReceived(const iviLink::Channel::tChannelId channel, Buffer const& buffer)
{
   LOG4CPLUS_TRACE_METHOD(msLogger, __PRETTY_FUNCTION__);
   LOG4CPLUS_TRACE(msLogger, "CBuffer write position = "+convertIntegerToString(buffer.getWritePosition())
         + "; CBuffer size = " + convertIntegerToString(buffer.getSize()) +
         "; Channel = "+ convertIntegerToString(channel));

   assert(this);

   UInt8 *incomingData = buffer.getBuffer();
   int read_size = buffer.getSize();

   LOG4CPLUS_INFO(msLogger, "Procedure ID = " + convertIntegerToString(incomingData[0]));

   if(incomingData[0] == SEND_ENCRYPTED_PIN)
   {
      LOG4CPLUS_INFO(msLogger, "Encrypted PIN received");
      string encryptedPIN((char*)(incomingData + 1), read_size - 1);
      LOG4CPLUS_INFO(msLogger, "Engrypted PIN length = " + convertIntegerToString(encryptedPIN.length()));
      LOG4CPLUS_INFO(msLogger, "Encrypted PIN  = " + encryptedPIN);
      string decryptedRemotePIN = CRSAEncryptDecrypt::decrypt(encryptedPIN, CRSAEncryptDecrypt::getPrivateKey(mpAppCallbacks->getInternalPath()));
      LOG4CPLUS_INFO(msLogger, "Decrypted remote PIN = " + decryptedRemotePIN);

      mpAppCallbacks->gotPIN(decryptedRemotePIN[0] - '0',
                             decryptedRemotePIN[1] - '0',
                             decryptedRemotePIN[2] - '0',
                             decryptedRemotePIN[3] - '0');

   }
   else if(incomingData[0] == SEND_PUBLIC_KEY)
   {
      LOG4CPLUS_INFO(msLogger, "PublicKey received");
      UInt8* keyBytes = new UInt8[read_size - 1];
      memcpy(keyBytes, incomingData + 1, read_size - 1);
      ByteQueue queue;
      queue.Put(keyBytes, read_size - 1);
      remoteHostPublicKey.Load(queue);
   }
   else if(incomingData[0] == SEND_UID)
   {
      LOG4CPLUS_INFO(msLogger, "Remote UID received");
      string uid((char*)(incomingData + 1), read_size - 1);
      LOG4CPLUS_INFO(msLogger, "UID = " + uid);
      mRemoteUID = iviLink::BaseUid(uid);

      if(mpTrustList->isKnownUid(mRemoteUID))
      {
          LOG4CPLUS_INFO(msLogger, "Remote UID is known");

          remoteUIDIsChecked = true;
          remoteUIDIsOK = true;

          sendYourUIDIsKnow();
          validateUIDs();
      }
      else
      {
         LOG4CPLUS_INFO(msLogger, "Remote UID is unknown");

         remoteUIDIsChecked = true;
         remoteUIDIsOK = false;

         sendYourUIDIsUnknown();
         validateUIDs();
      }
   }
   else if(incomingData[0] == YOUR_UID_IS_OK)
   {
      localUIDIsChecked = true;
      localUIDIsOK = true;

      validateUIDs();
   }
   else if(incomingData[0] == YOUR_UID_IS_NOK)
   {
      localUIDIsChecked = true;
      localUIDIsOK = false;
      validateUIDs();
   }
   else if(incomingData[0] == READY_TO_EXIT)
   {
      mpAppCallbacks->onReadyToExit();
   }
}
Esempio n. 26
0
Block
SecTpmFile::signInTpm(const uint8_t* data, size_t dataLength,
                      const Name& keyName, DigestAlgorithm digestAlgorithm)
{
  string keyURI = keyName.toUri();

  if (!doesKeyExistInTpm(keyName, KeyClass::PRIVATE))
    BOOST_THROW_EXCEPTION(Error("private key doesn't exist"));

  try {
    using namespace CryptoPP;
    AutoSeededRandomPool rng;

    // Read public key
    shared_ptr<v1::PublicKey> pubkeyPtr;
    pubkeyPtr = getPublicKeyFromTpm(keyName);

    switch (pubkeyPtr->getKeyType()) {
      case KeyType::RSA: {
        // Read private key
        ByteQueue bytes;
        FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
                        true, new Base64Decoder);
        file.TransferTo(bytes);
        bytes.MessageEnd();
        RSA::PrivateKey privateKey;
        privateKey.Load(bytes);

        // Sign message
        switch (digestAlgorithm) {
          case DigestAlgorithm::SHA256: {
            RSASS<PKCS1v15, SHA256>::Signer signer(privateKey);

            OBufferStream os;
            StringSource(data, dataLength,
                         true,
                         new SignerFilter(rng, signer, new FileSink(os)));

            return Block(tlv::SignatureValue, os.buf());
          }

          default:
            BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
        }
      }

      case KeyType::EC: {
        // Read private key
        ByteQueue bytes;
        FileSource file(m_impl->transformName(keyURI, ".pri").string().c_str(),
                        true, new Base64Decoder);
        file.TransferTo(bytes);
        bytes.MessageEnd();

        // Sign message
        switch (digestAlgorithm) {
          case DigestAlgorithm::SHA256: {
            ECDSA<ECP, SHA256>::PrivateKey privateKey;
            privateKey.Load(bytes);
            ECDSA<ECP, SHA256>::Signer signer(privateKey);

            OBufferStream os;
            StringSource(data, dataLength,
                         true,
                         new SignerFilter(rng, signer, new FileSink(os)));

            uint8_t buf[200];
            size_t bufSize = DSAConvertSignatureFormat(buf, sizeof(buf), DSA_DER,
                                                       os.buf()->buf(), os.buf()->size(),
                                                       DSA_P1363);

            shared_ptr<Buffer> sigBuffer = make_shared<Buffer>(buf, bufSize);

            return Block(tlv::SignatureValue, sigBuffer);
          }

          default:
            BOOST_THROW_EXCEPTION(Error("Unsupported digest algorithm"));
        }
      }

      default:
        BOOST_THROW_EXCEPTION(Error("Unsupported key type"));
    }
  }
  catch (const CryptoPP::Exception& e) {
    BOOST_THROW_EXCEPTION(Error(e.what()));
  }
}
Esempio n. 27
0
bool RSAValidate()
{
	cout << "\nRSA validation suite running...\n\n";

	byte out[100], outPlain[100];
	unsigned int outLen;
	bool pass = true, fail;

	try
	{
		{
			char *plain = "Everyone gets Friday off.";
			byte *signature = (byte *)
				"\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84"
				"\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21"
				"\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b"
				"\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1";
			LC_RNG rng(765);

			FileSource keys("rsa512a.dat", true, new HexDecoder);
			RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys);
			RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv);

			rsaPriv.SignMessage(rng, (byte *)plain, strlen(plain), out);
			fail = memcmp(signature, out, 64) != 0;
			pass = pass && !fail;

			cout << (fail ? "FAILED    " : "passed    ");
			cout << "signature check against test vector\n";

			fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out);
			pass = pass && !fail;

			cout << (fail ? "FAILED    " : "passed    ");
			cout << "verification check against test vector\n";

			out[10]++;
			fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out);
			pass = pass && !fail;

			cout << (fail ? "FAILED    " : "passed    ");
			cout << "invalid signature verification\n";
		}
		{
			FileSource keys("rsa512.dat", true, new HexDecoder);
			RSAES_PKCS1v15_Decryptor rsaPriv(keys);
			RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv);

			pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass;
		}
		{
			byte *plain = (byte *)
				"\x54\x85\x9b\x34\x2c\x49\xea\x2a";
			byte *encrypted = (byte *)
				"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
				"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
				"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
				"\x62\x51";
			byte *oaepSeed = (byte *)
				"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2"
				"\xf0\x6c\xb5\x8f";
			ByteQueue bq;
			bq.Put(oaepSeed, 20);
			FixedRNG rng(bq);

			FileSource privFile("rsa400pv.dat", true, new HexDecoder);
			FileSource pubFile("rsa400pb.dat", true, new HexDecoder);
			RSAES_OAEP_SHA_Decryptor rsaPriv(privFile);
			RSAES_OAEP_SHA_Encryptor rsaPub(pubFile);

			memset(out, 0, 50);
			memset(outPlain, 0, 8);
			rsaPub.Encrypt(rng, plain, 8, out);
			outLen = rsaPriv.Decrypt(encrypted, outPlain);
			fail = (outLen!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8);
			pass = pass && !fail;

			cout << (fail ? "FAILED    " : "passed    ");
			cout << "PKCS 2.0 encryption and decryption\n";
		}
	}
	catch (BERDecodeErr)
	{
		cout << "FAILED    Error decoding RSA key\n";
		pass = false;
	}

	return pass;
}
Esempio n. 28
0
bool
Validator::verifySignature(const uint8_t* buf,
                           const size_t size,
                           const Signature& sig,
                           const v1::PublicKey& key)
{
  try {
    using namespace CryptoPP;

    switch (sig.getType()) {
      case tlv::SignatureSha256WithRsa: {
        if (key.getKeyType() != KeyType::RSA)
          return false;

        RSA::PublicKey publicKey;
        ByteQueue queue;

        queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
        publicKey.Load(queue);

        RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
        return verifier.VerifyMessage(buf, size,
                                      sig.getValue().value(), sig.getValue().value_size());
      }

      case tlv::SignatureSha256WithEcdsa: {
        if (key.getKeyType() != KeyType::EC)
          return false;

        ECDSA<ECP, SHA256>::PublicKey publicKey;
        ByteQueue queue;

        queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
        publicKey.Load(queue);

        ECDSA<ECP, SHA256>::Verifier verifier(publicKey);

        uint32_t length = 0;
        StringSource src(key.get().buf(), key.get().size(), true);
        BERSequenceDecoder subjectPublicKeyInfo(src);
        {
          BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
          {
            Oid algorithm;
            algorithm.decode(algorithmInfo);

            Oid curveId;
            curveId.decode(algorithmInfo);

            if (curveId == SECP256R1)
              length = 256;
            else if (curveId == SECP384R1)
              length = 384;
            else
              return false;
          }
        }

        switch (length) {
          case 256: {
            uint8_t buffer[64];
            size_t usedSize = DSAConvertSignatureFormat(buffer, sizeof(buffer), DSA_P1363,
                                                        sig.getValue().value(),
                                                        sig.getValue().value_size(),
                                                        DSA_DER);
            return verifier.VerifyMessage(buf, size, buffer, usedSize);
          }

          case 384: {
            uint8_t buffer[96];
            size_t usedSize = DSAConvertSignatureFormat(buffer, sizeof(buffer), DSA_P1363,
                                                        sig.getValue().value(),
                                                        sig.getValue().value_size(),
                                                        DSA_DER);
            return verifier.VerifyMessage(buf, size, buffer, usedSize);
          }

          default:
            return false;
        }
      }

      default:
        // Unsupported sig type
        return false;
    }
  }
  catch (const CryptoPP::Exception& e) {
    return false;
  }
}