blob: 990247d9a5c4e4d2ac0141f372e50d0b0819ec99 [file] [log] [blame]
Jeff Thompson6c314bc2013-09-23 18:09:38 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson6c314bc2013-09-23 18:09:38 -070013 */
14
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080015#include "common.hpp"
16
17#include "sec-tpm-memory.hpp"
18#include "public-key.hpp"
19
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070020#include "openssl.hpp"
Junxiao Shi482ccc52014-03-31 13:05:24 -070021#include "cryptopp.hpp"
Jeff Thompson6c314bc2013-09-23 18:09:38 -070022
23using namespace std;
Jeff Thompson6c314bc2013-09-23 18:09:38 -070024
25namespace ndn {
26
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080027/**
28 * RsaPrivateKey is a simple class to hold an RSA private key.
29 */
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070030class SecTpmMemory::RsaPrivateKey
31{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080032public:
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070033 RsaPrivateKey(const uint8_t* keyDer, size_t keyDerLength)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080034 {
35 // Use a temporary pointer since d2i updates it.
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070036 const uint8_t* derPointer = keyDer;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070037 m_privateKey = d2i_RSAPrivateKey(NULL, &derPointer, keyDerLength);
38 if (!m_privateKey)
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080039 throw Error("RsaPrivateKey constructor: Error decoding private key DER");
40 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070041
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080042 ~RsaPrivateKey()
43 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070044 if (m_privateKey)
45 RSA_free(m_privateKey);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080046 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070047
48 rsa_st*
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080049 getPrivateKey()
50 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070051 return m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080052 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070053
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080054private:
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070055 rsa_st* m_privateKey;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080056};
57
Yingdi Yu87581582014-01-14 14:28:39 -080058SecTpmMemory::~SecTpmMemory()
Jeff Thompson6c314bc2013-09-23 18:09:38 -070059{
60}
61
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080062void
Yingdi Yu87581582014-01-14 14:28:39 -080063SecTpmMemory::setKeyPairForKeyName(const Name& keyName,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070064 const uint8_t* publicKeyDer, size_t publicKeyDerLength,
65 const uint8_t* privateKeyDer, size_t privateKeyDerLength)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070066{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070067 m_publicKeyStore[keyName.toUri()] = make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
68 m_privateKeyStore[keyName.toUri()] = make_shared<RsaPrivateKey>(privateKeyDer,
69 privateKeyDerLength);
Jeff Thompson6c314bc2013-09-23 18:09:38 -070070}
71
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070072void
Yingdi Yu87581582014-01-14 14:28:39 -080073SecTpmMemory::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -070074{
Yingdi Yu28fd32f2014-01-28 19:03:03 -080075 throw Error("SecTpmMemory::generateKeyPair not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -070076}
77
Yingdi Yu28fd32f2014-01-28 19:03:03 -080078void
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070079SecTpmMemory::deleteKeyPairInTpm(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -080080{
81 throw Error("SecTpmMemory::deleteKeyPairInTpm not implemented");
82}
83
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080084ConstBufferPtr
85SecTpmMemory::exportPrivateKeyPkcs1FromTpm(const Name& keyName)
86{
Yingdi Yu2e57a582014-02-20 23:34:43 -080087 return shared_ptr<Buffer>();
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080088}
89
90bool
91SecTpmMemory::importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
92{
Yingdi Yu2e57a582014-02-20 23:34:43 -080093 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -080094}
95
96bool
97SecTpmMemory::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
98{
Yingdi Yu2e57a582014-02-20 23:34:43 -080099 return false;
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800100}
101
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700102shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800103SecTpmMemory::getPublicKeyFromTpm(const Name& keyName)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700104{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700105 PublicKeyStore::iterator publicKey = m_publicKeyStore.find(keyName.toUri());
106 if (publicKey == m_publicKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800107 throw Error(string("MemoryPrivateKeyStorage: Cannot find public key ") + keyName.toUri());
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700108 return publicKey->second;
109}
110
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700111Block
112SecTpmMemory::signInTpm(const uint8_t* data, size_t dataLength,
Yingdi Yu2e57a582014-02-20 23:34:43 -0800113 const Name& keyName,
114 DigestAlgorithm digestAlgorithm)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700115{
116 if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800117 throw Error("Unsupported digest algorithm.");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700118
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700119 // Find the private key and sign.
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700120 PrivateKeyStore::iterator privateKey = m_privateKeyStore.find(keyName.toUri());
121 if (privateKey == m_privateKeyStore.end())
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800122 throw Error(string("MemoryPrivateKeyStorage: Cannot find private key ") + keyName.toUri());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700123
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800124 uint8_t digest[SHA256_DIGEST_LENGTH];
125 SHA256_CTX sha256;
126 SHA256_Init(&sha256);
127 SHA256_Update(&sha256, data, dataLength);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700128 SHA256_Final(digest,& sha256);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800129
Yingdi Yu2e57a582014-02-20 23:34:43 -0800130 BufferPtr signatureBuffer = make_shared<Buffer>();
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800131 signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700132
133 unsigned int signatureBitsLength;
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800134 if (!RSA_sign(NID_sha256, digest, sizeof(digest),
135 signatureBuffer->buf(),
136 &signatureBitsLength,
137 privateKey->second->getPrivateKey()))
138 {
139 throw Error("Error in RSA_sign");
140 }
141
142 return Block(Tlv::SignatureValue, signatureBuffer);
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::decryptInTpm(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::decrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700150}
151
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800152ConstBufferPtr
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700153SecTpmMemory::encryptInTpm(const uint8_t* data, size_t dataLength,
154 const Name& keyName, bool isSymmetric)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700155{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800156 throw Error("MemoryPrivateKeyStorage::encrypt not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700157}
158
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700159void
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800160SecTpmMemory::generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700161{
Alexander Afanasyev04b22a92014-01-05 22:40:17 -0800162 throw Error("MemoryPrivateKeyStorage::generateKey not implemented");
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700163}
164
165bool
Yingdi Yub4bb85a2014-01-16 10:11:04 -0800166SecTpmMemory::doesKeyExistInTpm(const Name& keyName, KeyClass keyClass)
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700167{
168 if (keyClass == KEY_CLASS_PUBLIC)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700169 return m_publicKeyStore.find(keyName.toUri()) != m_publicKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700170 else if (keyClass == KEY_CLASS_PRIVATE)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700171 return m_privateKeyStore.find(keyName.toUri()) != m_privateKeyStore.end();
Jeff Thompson6c314bc2013-09-23 18:09:38 -0700172 else
173 // KEY_CLASS_SYMMETRIC not implemented yet.
174 return false;
175}
176
Yingdi Yu4b752752014-02-18 12:24:03 -0800177bool
178SecTpmMemory::generateRandomBlock(uint8_t* res, size_t size)
179{
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700180 try
181 {
182 CryptoPP::AutoSeededRandomPool rng;
183 rng.GenerateBlock(res, size);
184 return true;
185 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700186 catch (CryptoPP::Exception& e)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700187 {
188 return false;
189 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800190}
191
Yingdi Yufc40d872014-02-18 12:56:04 -0800192} // namespace ndn