| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */ |
| /** |
| * Copyright (C) 2013 Regents of the University of California. |
| * @author: Jeff Thompson <jefft0@remap.ucla.edu> |
| * See COPYING for copyright and distribution information. |
| */ |
| |
| #include "common.hpp" |
| |
| #include "sec-tpm-memory.hpp" |
| #include "public-key.hpp" |
| |
| #include "openssl.hpp" |
| #include "cryptopp.hpp" |
| |
| using namespace std; |
| |
| namespace ndn { |
| |
| /** |
| * RsaPrivateKey is a simple class to hold an RSA private key. |
| */ |
| class SecTpmMemory::RsaPrivateKey { |
| public: |
| RsaPrivateKey(const uint8_t* keyDer, size_t keyDerLength) |
| { |
| // Use a temporary pointer since d2i updates it. |
| const uint8_t* derPointer = keyDer; |
| m_privateKey = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength); |
| if (!m_privateKey) |
| throw Error("RsaPrivateKey constructor: Error decoding private key DER"); |
| } |
| |
| ~RsaPrivateKey() |
| { |
| if (m_privateKey) |
| RSA_free(m_privateKey); |
| } |
| |
| rsa_st* |
| getPrivateKey() |
| { |
| return m_privateKey; |
| } |
| |
| private: |
| rsa_st* m_privateKey; |
| }; |
| |
| SecTpmMemory::~SecTpmMemory() |
| { |
| } |
| |
| void |
| SecTpmMemory::setKeyPairForKeyName(const Name& keyName, |
| const uint8_t* publicKeyDer, size_t publicKeyDerLength, |
| const uint8_t* privateKeyDer, size_t privateKeyDerLength) |
| { |
| m_publicKeyStore[keyName.toUri()] = make_shared<PublicKey>(publicKeyDer, publicKeyDerLength); |
| m_privateKeyStore[keyName.toUri()] = make_shared<RsaPrivateKey>(privateKeyDer, |
| privateKeyDerLength); |
| } |
| |
| void |
| SecTpmMemory::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) |
| { |
| throw Error("SecTpmMemory::generateKeyPair not implemented"); |
| } |
| |
| void |
| SecTpmMemory::deleteKeyPairInTpm(const Name& keyName) |
| { |
| throw Error("SecTpmMemory::deleteKeyPairInTpm not implemented"); |
| } |
| |
| ConstBufferPtr |
| SecTpmMemory::exportPrivateKeyPkcs1FromTpm(const Name& keyName) |
| { |
| return shared_ptr<Buffer>(); |
| } |
| |
| bool |
| SecTpmMemory::importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) |
| { |
| return false; |
| } |
| |
| bool |
| SecTpmMemory::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size) |
| { |
| return false; |
| } |
| |
| shared_ptr<PublicKey> |
| SecTpmMemory::getPublicKeyFromTpm(const Name& keyName) |
| { |
| PublicKeyStore::iterator publicKey = m_publicKeyStore.find(keyName.toUri()); |
| if (publicKey == m_publicKeyStore.end()) |
| throw Error(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri()); |
| return publicKey->second; |
| } |
| |
| Block |
| SecTpmMemory::signInTpm(const uint8_t* data, size_t dataLength, |
| const Name& keyName, |
| DigestAlgorithm digestAlgorithm) |
| { |
| if (digestAlgorithm != DIGEST_ALGORITHM_SHA256) |
| throw Error("Unsupported digest algorithm."); |
| |
| // Find the private key and sign. |
| PrivateKeyStore::iterator privateKey = m_privateKeyStore.find(keyName.toUri()); |
| if (privateKey == m_privateKeyStore.end()) |
| throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri()); |
| |
| uint8_t digest[SHA256_DIGEST_LENGTH]; |
| SHA256_CTX sha256; |
| SHA256_Init(&sha256); |
| SHA256_Update(&sha256, data, dataLength); |
| SHA256_Final(digest,& sha256); |
| |
| BufferPtr signatureBuffer = make_shared<Buffer>(); |
| signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey())); |
| |
| unsigned int signatureBitsLength; |
| if (!RSA_sign(NID_sha256, digest, sizeof(digest), |
| signatureBuffer->buf(), |
| &signatureBitsLength, |
| privateKey->second->getPrivateKey())) |
| { |
| throw Error("Error in RSA_sign"); |
| } |
| |
| return Block(Tlv::SignatureValue, signatureBuffer); |
| } |
| |
| ConstBufferPtr |
| SecTpmMemory::decryptInTpm(const uint8_t* data, size_t dataLength, |
| const Name& keyName, bool isSymmetric) |
| { |
| throw Error("MemoryPrivateKeyStorage::decrypt not implemented"); |
| } |
| |
| ConstBufferPtr |
| SecTpmMemory::encryptInTpm(const uint8_t* data, size_t dataLength, |
| const Name& keyName, bool isSymmetric) |
| { |
| throw Error("MemoryPrivateKeyStorage::encrypt not implemented"); |
| } |
| |
| void |
| SecTpmMemory::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) |
| { |
| throw Error("MemoryPrivateKeyStorage::generateKey not implemented"); |
| } |
| |
| bool |
| SecTpmMemory::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass) |
| { |
| if (keyClass == KEY_CLASS_PUBLIC) |
| return m_publicKeyStore.find(keyName.toUri()) != m_publicKeyStore.end(); |
| else if (keyClass == KEY_CLASS_PRIVATE) |
| return m_privateKeyStore.find(keyName.toUri()) != m_privateKeyStore.end(); |
| else |
| // KEY_CLASS_SYMMETRIC not implemented yet. |
| return false; |
| } |
| |
| bool |
| SecTpmMemory::generateRandomBlock(uint8_t* res, size_t size) |
| { |
| try |
| { |
| CryptoPP::AutoSeededRandomPool rng; |
| rng.GenerateBlock(res, size); |
| return true; |
| } |
| catch (const CryptoPP::Exception& e) |
| { |
| return false; |
| } |
| } |
| |
| } // namespace ndn |