blob: 393a21786b11b6f2a073b1fb58e9cdda662b7b45 [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 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070023class SecTpmMemory::RsaPrivateKey
24{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080025public:
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070026 RsaPrivateKey(const uint8_t* keyDer, size_t keyDerLength)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080027 {
28 // Use a temporary pointer since d2i updates it.
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070029 const uint8_t* derPointer = keyDer;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070030 m_privateKey = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength);
31 if (!m_privateKey)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080032 throw Error("RsaPrivateKey constructor: Error decoding private key DER");
33 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070034
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080035 ~RsaPrivateKey()
36 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070037 if (m_privateKey)
38 RSA_free(m_privateKey);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080039 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070040
41 rsa_st*
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080042 getPrivateKey()
43 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070044 return m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080045 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070046
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080047private:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070048 rsa_st* m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080049};
50
Yingdi Yu87581582014-01-14 14:28:39 -080051SecTpmMemory::~SecTpmMemory()
Jeff Thompson6c314bc2013-09-23 18:09:38 -070052{
53}
54
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080055void
Yingdi Yu87581582014-01-14 14:28:39 -080056SecTpmMemory::setKeyPairForKeyName(const Name& keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070057 const uint8_t* publicKeyDer, size_t publicKeyDerLength,
58 const uint8_t* privateKeyDer, size_t privateKeyDerLength)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070059{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070060 m_publicKeyStore[keyName.toUri()] = make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
61 m_privateKeyStore[keyName.toUri()] = make_shared<RsaPrivateKey>(privateKeyDer,
62 privateKeyDerLength);
Jeff Thompson6c314bc2013-09-23 18:09:38 -070063}
64
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070065void
Yingdi Yu87581582014-01-14 14:28:39 -080066SecTpmMemory::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070067{
Yingdi Yu28fd32f2014-01-28 19:03:03 -080068 throw Error("SecTpmMemory::generateKeyPair not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -070069}
70
Yingdi Yu28fd32f2014-01-28 19:03:03 -080071void
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070072SecTpmMemory::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -080073{
74 throw Error("SecTpmMemory::deleteKeyPairInTpm not implemented");
75}
76
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080077ConstBufferPtr
78SecTpmMemory::exportPrivateKeyPkcs1FromTpm(const Name& keyName)
79{
Yingdi Yu2e57a582014-02-20 23:34:43 -080080 return shared_ptr<Buffer>();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080081}
82
83bool
84SecTpmMemory::importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
85{
Yingdi Yu2e57a582014-02-20 23:34:43 -080086 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080087}
88
89bool
90SecTpmMemory::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
91{
Yingdi Yu2e57a582014-02-20 23:34:43 -080092 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080093}
94
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070095shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -080096SecTpmMemory::getPublicKeyFromTpm(const Name& keyName)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070097{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070098 PublicKeyStore::iterator publicKey = m_publicKeyStore.find(keyName.toUri());
99 if (publicKey == m_publicKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800100 throw Error(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri());
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700101 return publicKey->second;
102}
103
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700104Block
105SecTpmMemory::signInTpm(const uint8_t* data, size_t dataLength,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800106 const Name& keyName,
107 DigestAlgorithm digestAlgorithm)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700108{
109 if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800110 throw Error("Unsupported digest algorithm.");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700111
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700112 // Find the private key and sign.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700113 PrivateKeyStore::iterator privateKey = m_privateKeyStore.find(keyName.toUri());
114 if (privateKey == m_privateKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800115 throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700116
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800117 uint8_t digest[SHA256_DIGEST_LENGTH];
118 SHA256_CTX sha256;
119 SHA256_Init(&sha256);
120 SHA256_Update(&sha256, data, dataLength);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700121 SHA256_Final(digest,& sha256);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800122
Yingdi Yu2e57a582014-02-20 23:34:43 -0800123 BufferPtr signatureBuffer = make_shared<Buffer>();
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800124 signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700125
126 unsigned int signatureBitsLength;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800127 if (!RSA_sign(NID_sha256, digest, sizeof(digest),
128 signatureBuffer->buf(),
129 &signatureBitsLength,
130 privateKey->second->getPrivateKey()))
131 {
132 throw Error("Error in RSA_sign");
133 }
134
135 return Block(Tlv::SignatureValue, signatureBuffer);
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700136}
137
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800138ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700139SecTpmMemory::decryptInTpm(const uint8_t* data, size_t dataLength,
140 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700141{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800142 throw Error("MemoryPrivateKeyStorage::decrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700143}
144
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800145ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700146SecTpmMemory::encryptInTpm(const uint8_t* data, size_t dataLength,
147 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700148{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800149 throw Error("MemoryPrivateKeyStorage::encrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700150}
151
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700152void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800153SecTpmMemory::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700154{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800155 throw Error("MemoryPrivateKeyStorage::generateKey not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700156}
157
158bool
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800159SecTpmMemory::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700160{
161 if (keyClass == KEY_CLASS_PUBLIC)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700162 return m_publicKeyStore.find(keyName.toUri()) != m_publicKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700163 else if (keyClass == KEY_CLASS_PRIVATE)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700164 return m_privateKeyStore.find(keyName.toUri()) != m_privateKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700165 else
166 // KEY_CLASS_SYMMETRIC not implemented yet.
167 return false;
168}
169
Yingdi Yu4b752752014-02-18 12:24:03 -0800170bool
171SecTpmMemory::generateRandomBlock(uint8_t* res, size_t size)
172{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700173 try
174 {
175 CryptoPP::AutoSeededRandomPool rng;
176 rng.GenerateBlock(res, size);
177 return true;
178 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700179 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700180 {
181 return false;
182 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800183}
184
Yingdi Yufc40d872014-02-18 12:56:04 -0800185} // namespace ndn