blob: 3475aa41080b1878531272cc08d69dab5f85e200 [file] [log] [blame]
Jeff Thompson6c314bc2013-09-23 18:09:38 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -08008#include "common.hpp"
9
10#include "sec-tpm-memory.hpp"
11#include "public-key.hpp"
12
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070013#include "openssl.hpp"
Junxiao Shi482ccc52014-03-31 13:05:24 -070014#include "cryptopp.hpp"
Jeff Thompson6c314bc2013-09-23 18:09:38 -070015
16using namespace std;
Jeff Thompson6c314bc2013-09-23 18:09:38 -070017
18namespace ndn {
19
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080020/**
21 * RsaPrivateKey is a simple class to hold an RSA private key.
22 */
Yingdi Yu87581582014-01-14 14:28:39 -080023class SecTpmMemory::RsaPrivateKey {
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080024public:
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070025 RsaPrivateKey(const uint8_t* keyDer, size_t keyDerLength)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080026 {
27 // Use a temporary pointer since d2i updates it.
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070028 const uint8_t* derPointer = keyDer;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070029 m_privateKey = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength);
30 if (!m_privateKey)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080031 throw Error("RsaPrivateKey constructor: Error decoding private key DER");
32 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070033
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080034 ~RsaPrivateKey()
35 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070036 if (m_privateKey)
37 RSA_free(m_privateKey);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080038 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070039
40 rsa_st*
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080041 getPrivateKey()
42 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070043 return m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080044 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070045
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080046private:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070047 rsa_st* m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080048};
49
Yingdi Yu87581582014-01-14 14:28:39 -080050SecTpmMemory::~SecTpmMemory()
Jeff Thompson6c314bc2013-09-23 18:09:38 -070051{
52}
53
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080054void
Yingdi Yu87581582014-01-14 14:28:39 -080055SecTpmMemory::setKeyPairForKeyName(const Name& keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070056 const uint8_t* publicKeyDer, size_t publicKeyDerLength,
57 const uint8_t* privateKeyDer, size_t privateKeyDerLength)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070058{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070059 m_publicKeyStore[keyName.toUri()] = make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
60 m_privateKeyStore[keyName.toUri()] = make_shared<RsaPrivateKey>(privateKeyDer,
61 privateKeyDerLength);
Jeff Thompson6c314bc2013-09-23 18:09:38 -070062}
63
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070064void
Yingdi Yu87581582014-01-14 14:28:39 -080065SecTpmMemory::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070066{
Yingdi Yu28fd32f2014-01-28 19:03:03 -080067 throw Error("SecTpmMemory::generateKeyPair not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -070068}
69
Yingdi Yu28fd32f2014-01-28 19:03:03 -080070void
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070071SecTpmMemory::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -080072{
73 throw Error("SecTpmMemory::deleteKeyPairInTpm not implemented");
74}
75
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080076ConstBufferPtr
77SecTpmMemory::exportPrivateKeyPkcs1FromTpm(const Name& keyName)
78{
Yingdi Yu2e57a582014-02-20 23:34:43 -080079 return shared_ptr<Buffer>();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080080}
81
82bool
83SecTpmMemory::importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
84{
Yingdi Yu2e57a582014-02-20 23:34:43 -080085 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080086}
87
88bool
89SecTpmMemory::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
90{
Yingdi Yu2e57a582014-02-20 23:34:43 -080091 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080092}
93
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070094shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -080095SecTpmMemory::getPublicKeyFromTpm(const Name& keyName)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070096{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070097 PublicKeyStore::iterator publicKey = m_publicKeyStore.find(keyName.toUri());
98 if (publicKey == m_publicKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080099 throw Error(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri());
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700100 return publicKey->second;
101}
102
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700103Block
104SecTpmMemory::signInTpm(const uint8_t* data, size_t dataLength,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800105 const Name& keyName,
106 DigestAlgorithm digestAlgorithm)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700107{
108 if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800109 throw Error("Unsupported digest algorithm.");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700110
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700111 // Find the private key and sign.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700112 PrivateKeyStore::iterator privateKey = m_privateKeyStore.find(keyName.toUri());
113 if (privateKey == m_privateKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800114 throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700115
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800116 uint8_t digest[SHA256_DIGEST_LENGTH];
117 SHA256_CTX sha256;
118 SHA256_Init(&sha256);
119 SHA256_Update(&sha256, data, dataLength);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700120 SHA256_Final(digest,& sha256);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800121
Yingdi Yu2e57a582014-02-20 23:34:43 -0800122 BufferPtr signatureBuffer = make_shared<Buffer>();
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800123 signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700124
125 unsigned int signatureBitsLength;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800126 if (!RSA_sign(NID_sha256, digest, sizeof(digest),
127 signatureBuffer->buf(),
128 &signatureBitsLength,
129 privateKey->second->getPrivateKey()))
130 {
131 throw Error("Error in RSA_sign");
132 }
133
134 return Block(Tlv::SignatureValue, signatureBuffer);
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700135}
136
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800137ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700138SecTpmMemory::decryptInTpm(const uint8_t* data, size_t dataLength,
139 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700140{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800141 throw Error("MemoryPrivateKeyStorage::decrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700142}
143
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800144ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700145SecTpmMemory::encryptInTpm(const uint8_t* data, size_t dataLength,
146 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700147{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800148 throw Error("MemoryPrivateKeyStorage::encrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700149}
150
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700151void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800152SecTpmMemory::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700153{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800154 throw Error("MemoryPrivateKeyStorage::generateKey not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700155}
156
157bool
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800158SecTpmMemory::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700159{
160 if (keyClass == KEY_CLASS_PUBLIC)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700161 return m_publicKeyStore.find(keyName.toUri()) != m_publicKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700162 else if (keyClass == KEY_CLASS_PRIVATE)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700163 return m_privateKeyStore.find(keyName.toUri()) != m_privateKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700164 else
165 // KEY_CLASS_SYMMETRIC not implemented yet.
166 return false;
167}
168
Yingdi Yu4b752752014-02-18 12:24:03 -0800169bool
170SecTpmMemory::generateRandomBlock(uint8_t* res, size_t size)
171{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700172 try
173 {
174 CryptoPP::AutoSeededRandomPool rng;
175 rng.GenerateBlock(res, size);
176 return true;
177 }
178 catch (const CryptoPP::Exception& e)
179 {
180 return false;
181 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800182}
183
Yingdi Yufc40d872014-02-18 12:56:04 -0800184} // namespace ndn