blob: 5e26be2f9e3b1ab6a86700737ce25682057304c6 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson6c314bc2013-09-23 18:09:38 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson6c314bc2013-09-23 18:09:38 -070022 */
23
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080024#include "common.hpp"
25
26#include "sec-tpm-memory.hpp"
27#include "public-key.hpp"
28
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070029#include "openssl.hpp"
Junxiao Shi482ccc52014-03-31 13:05:24 -070030#include "cryptopp.hpp"
Jeff Thompson6c314bc2013-09-23 18:09:38 -070031
32using namespace std;
Jeff Thompson6c314bc2013-09-23 18:09:38 -070033
34namespace ndn {
35
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080036/**
37 * RsaPrivateKey is a simple class to hold an RSA private key.
38 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070039class SecTpmMemory::RsaPrivateKey
40{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080041public:
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070042 RsaPrivateKey(const uint8_t* keyDer, size_t keyDerLength)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080043 {
44 // Use a temporary pointer since d2i updates it.
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070045 const uint8_t* derPointer = keyDer;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070046 m_privateKey = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength);
47 if (!m_privateKey)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080048 throw Error("RsaPrivateKey constructor: Error decoding private key DER");
49 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070050
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080051 ~RsaPrivateKey()
52 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070053 if (m_privateKey)
54 RSA_free(m_privateKey);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080055 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070056
57 rsa_st*
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080058 getPrivateKey()
59 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070060 return m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080061 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070062
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080063private:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070064 rsa_st* m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080065};
66
Yingdi Yu87581582014-01-14 14:28:39 -080067SecTpmMemory::~SecTpmMemory()
Jeff Thompson6c314bc2013-09-23 18:09:38 -070068{
69}
70
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080071void
Yingdi Yu87581582014-01-14 14:28:39 -080072SecTpmMemory::setKeyPairForKeyName(const Name& keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070073 const uint8_t* publicKeyDer, size_t publicKeyDerLength,
74 const uint8_t* privateKeyDer, size_t privateKeyDerLength)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070075{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070076 m_publicKeyStore[keyName.toUri()] = make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
77 m_privateKeyStore[keyName.toUri()] = make_shared<RsaPrivateKey>(privateKeyDer,
78 privateKeyDerLength);
Jeff Thompson6c314bc2013-09-23 18:09:38 -070079}
80
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070081void
Yingdi Yu87581582014-01-14 14:28:39 -080082SecTpmMemory::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070083{
Yingdi Yu28fd32f2014-01-28 19:03:03 -080084 throw Error("SecTpmMemory::generateKeyPair not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -070085}
86
Yingdi Yu28fd32f2014-01-28 19:03:03 -080087void
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070088SecTpmMemory::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -080089{
90 throw Error("SecTpmMemory::deleteKeyPairInTpm not implemented");
91}
92
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080093ConstBufferPtr
94SecTpmMemory::exportPrivateKeyPkcs1FromTpm(const Name& keyName)
95{
Yingdi Yu2e57a582014-02-20 23:34:43 -080096 return shared_ptr<Buffer>();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080097}
98
99bool
100SecTpmMemory::importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
101{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800102 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800103}
104
105bool
106SecTpmMemory::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
107{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800108 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800109}
110
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700111shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800112SecTpmMemory::getPublicKeyFromTpm(const Name& keyName)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700113{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700114 PublicKeyStore::iterator publicKey = m_publicKeyStore.find(keyName.toUri());
115 if (publicKey == m_publicKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800116 throw Error(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri());
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700117 return publicKey->second;
118}
119
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700120Block
121SecTpmMemory::signInTpm(const uint8_t* data, size_t dataLength,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800122 const Name& keyName,
123 DigestAlgorithm digestAlgorithm)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700124{
125 if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800126 throw Error("Unsupported digest algorithm.");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700127
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700128 // Find the private key and sign.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700129 PrivateKeyStore::iterator privateKey = m_privateKeyStore.find(keyName.toUri());
130 if (privateKey == m_privateKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800131 throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700132
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800133 uint8_t digest[SHA256_DIGEST_LENGTH];
134 SHA256_CTX sha256;
135 SHA256_Init(&sha256);
136 SHA256_Update(&sha256, data, dataLength);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700137 SHA256_Final(digest,& sha256);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800138
Yingdi Yu2e57a582014-02-20 23:34:43 -0800139 BufferPtr signatureBuffer = make_shared<Buffer>();
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800140 signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700141
142 unsigned int signatureBitsLength;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800143 if (!RSA_sign(NID_sha256, digest, sizeof(digest),
144 signatureBuffer->buf(),
145 &signatureBitsLength,
146 privateKey->second->getPrivateKey()))
147 {
148 throw Error("Error in RSA_sign");
149 }
150
151 return Block(Tlv::SignatureValue, signatureBuffer);
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700152}
153
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800154ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700155SecTpmMemory::decryptInTpm(const uint8_t* data, size_t dataLength,
156 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700157{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800158 throw Error("MemoryPrivateKeyStorage::decrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700159}
160
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800161ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700162SecTpmMemory::encryptInTpm(const uint8_t* data, size_t dataLength,
163 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700164{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800165 throw Error("MemoryPrivateKeyStorage::encrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700166}
167
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700168void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800169SecTpmMemory::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700170{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800171 throw Error("MemoryPrivateKeyStorage::generateKey not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700172}
173
174bool
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800175SecTpmMemory::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700176{
177 if (keyClass == KEY_CLASS_PUBLIC)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700178 return m_publicKeyStore.find(keyName.toUri()) != m_publicKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700179 else if (keyClass == KEY_CLASS_PRIVATE)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700180 return m_privateKeyStore.find(keyName.toUri()) != m_privateKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700181 else
182 // KEY_CLASS_SYMMETRIC not implemented yet.
183 return false;
184}
185
Yingdi Yu4b752752014-02-18 12:24:03 -0800186bool
187SecTpmMemory::generateRandomBlock(uint8_t* res, size_t size)
188{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700189 try
190 {
191 CryptoPP::AutoSeededRandomPool rng;
192 rng.GenerateBlock(res, size);
193 return true;
194 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700195 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700196 {
197 return false;
198 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800199}
200
Yingdi Yufc40d872014-02-18 12:56:04 -0800201} // namespace ndn