blob: 56f8ba7b8a5a9fea65c184297a3c44ce7e0f4ed7 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu04020922014-01-22 12:46:53 -08002/**
Davide Pesavento41abef82016-08-08 07:41:59 +02003 * Copyright (c) 2013-2016 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.
Yingdi Yu04020922014-01-22 12:46:53 -080020 */
21
Yingdi Yuf56c68f2014-04-24 21:50:13 -070022#include "security/sec-tpm-file.hpp"
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080023#include "security/key-chain.hpp"
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070024#include "security/v1/cryptopp.hpp"
Yingdi Yu04020922014-01-22 12:46:53 -080025
Yingdi Yuf56c68f2014-04-24 21:50:13 -070026#include "util/time.hpp"
27
Yingdi Yu41546342014-11-30 23:37:53 -080028#include <boost/filesystem.hpp>
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070029#include <boost/lexical_cast.hpp>
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070030#include "boost-test.hpp"
31
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -080032namespace ndn {
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070033namespace security {
Spyridon Mastorakis429634f2015-02-19 17:35:33 -080034namespace tests {
Yingdi Yu04020922014-01-22 12:46:53 -080035
Spyridon Mastorakis429634f2015-02-19 17:35:33 -080036BOOST_AUTO_TEST_SUITE(SecuritySecTpmFile)
Yingdi Yu04020922014-01-22 12:46:53 -080037
Yingdi Yu7036ce22014-06-19 18:53:37 -070038BOOST_AUTO_TEST_CASE(Delete)
Yingdi Yu28fd32f2014-01-28 19:03:03 -080039{
40 SecTpmFile tpm;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070041
Yingdi Yu5e96e002014-04-23 18:32:15 -070042 Name keyName("/TestSecTpmFile/Delete/ksk-" +
Yingdi Yu7036ce22014-06-19 18:53:37 -070043 boost::lexical_cast<std::string>(time::toUnixTimestamp(time::system_clock::now())));
44 RsaKeyParams params(2048);
45 BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, params));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070046
Yingdi Yu99b2a002015-08-12 12:47:44 -070047 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), true);
48 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), true);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070049
Yingdi Yu28fd32f2014-01-28 19:03:03 -080050 tpm.deleteKeyPairInTpm(keyName);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070051
Yingdi Yu99b2a002015-08-12 12:47:44 -070052 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
53 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
Yingdi Yu28fd32f2014-01-28 19:03:03 -080054}
55
Yingdi Yu7036ce22014-06-19 18:53:37 -070056BOOST_AUTO_TEST_CASE(SignVerify)
Yingdi Yu04020922014-01-22 12:46:53 -080057{
58 SecTpmFile tpm;
59
Yingdi Yu5e96e002014-04-23 18:32:15 -070060 Name keyName("/TestSecTpmFile/SignVerify/ksk-" +
Yingdi Yu7036ce22014-06-19 18:53:37 -070061 boost::lexical_cast<std::string>(time::toUnixTimestamp(time::system_clock::now())));
62 RsaKeyParams params(2048);
63 BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, params));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070064
Yingdi Yu04020922014-01-22 12:46:53 -080065 Data data("/tmp/test/1");
66 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
67
Yingdi Yu2e57a582014-02-20 23:34:43 -080068 Block sigBlock;
Yingdi Yu5e96e002014-04-23 18:32:15 -070069 BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content),
Yingdi Yu99b2a002015-08-12 12:47:44 -070070 keyName, DigestAlgorithm::SHA256));
Alexander Afanasyev2fa59392016-07-29 17:24:23 -070071 shared_ptr<v1::PublicKey> publicKey;
Yingdi Yu7036ce22014-06-19 18:53:37 -070072 BOOST_CHECK_NO_THROW(publicKey = tpm.getPublicKeyFromTpm(keyName));
Yingdi Yu04020922014-01-22 12:46:53 -080073
Yingdi Yu2e57a582014-02-20 23:34:43 -080074 try
75 {
76 using namespace CryptoPP;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070077
Yingdi Yu7036ce22014-06-19 18:53:37 -070078 RSA::PublicKey rsaPublicKey;
Yingdi Yu2e57a582014-02-20 23:34:43 -080079 ByteQueue queue;
Yingdi Yu7036ce22014-06-19 18:53:37 -070080 queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
81 rsaPublicKey.Load(queue);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070082
Yingdi Yu7036ce22014-06-19 18:53:37 -070083 RSASS<PKCS1v15, SHA256>::Verifier verifier(rsaPublicKey);
Yingdi Yu2e57a582014-02-20 23:34:43 -080084 bool result = verifier.VerifyMessage(content, sizeof(content),
Yingdi Yu5e96e002014-04-23 18:32:15 -070085 sigBlock.value(), sigBlock.value_size());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070086
Yingdi Yu2e57a582014-02-20 23:34:43 -080087 BOOST_CHECK_EQUAL(result, true);
88 }
Yingdi Yu5e96e002014-04-23 18:32:15 -070089 catch (CryptoPP::Exception& e)
Yingdi Yu2e57a582014-02-20 23:34:43 -080090 {
91 BOOST_CHECK(false);
92 }
Yingdi Yu04020922014-01-22 12:46:53 -080093
Yingdi Yu28fd32f2014-01-28 19:03:03 -080094 tpm.deleteKeyPairInTpm(keyName);
Yingdi Yu04020922014-01-22 12:46:53 -080095}
96
Yingdi Yu7036ce22014-06-19 18:53:37 -070097BOOST_AUTO_TEST_CASE(RandomGenerator)
Yingdi Yu4b752752014-02-18 12:24:03 -080098{
99 SecTpmFile tpm;
100
Davide Pesavento41abef82016-08-08 07:41:59 +0200101 constexpr size_t scale = 1000;
102 constexpr size_t size = 256 * scale;
103 auto block = unique_ptr<uint8_t[]>{new uint8_t[size]};
104 tpm.generateRandomBlock(block.get(), size);
Yingdi Yu4b752752014-02-18 12:24:03 -0800105
Davide Pesavento41abef82016-08-08 07:41:59 +0200106 std::map<uint8_t, size_t> counter;
107 for (size_t i = 0; i < size; i++) {
108 counter[block[i]] += 1;
109 }
Yingdi Yu4b752752014-02-18 12:24:03 -0800110
Davide Pesavento41abef82016-08-08 07:41:59 +0200111 double dev = 0.0;
112 for (uint8_t i = 0; i < 255; i++) {
113 dev += static_cast<double>((counter[i] - scale) * (counter[i] - scale)) / (scale * scale);
114 }
115 dev /= 256;
Yingdi Yu4b752752014-02-18 12:24:03 -0800116
Davide Pesavento41abef82016-08-08 07:41:59 +0200117 BOOST_CHECK_CLOSE(dev, 0.001, 100);
Yingdi Yu4b752752014-02-18 12:24:03 -0800118}
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800119
Yingdi Yu7036ce22014-06-19 18:53:37 -0700120BOOST_AUTO_TEST_CASE(ImportExportKey)
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800121{
122 using namespace CryptoPP;
123
Yingdi Yu7036ce22014-06-19 18:53:37 -0700124 std::string imported =
125"MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIIJzwsbTIVqgCAggAMBQGCCqG"
126"SIb3DQMHBAiEsSKdgGkCEQSCBMjaYsEeHM/EPzGNDAPaSxE1ASKxjyNkXEVPQbtGx/ju1PlQ"
127"QakTCzPpia8ziVGihrVfuacHrxxbLh+ufNZtbVVsv9kGQL2g15BN2Nic8VqyTxplKrduFkEb"
128"eOipqu627gb6eTsrSj7kubXfs/w9OAdhRZFaEc7I/S6rcPUaDai4i3O03VuvuTOrzZL/unhD"
129"CDzOa3pr2aUQlO/5Pck6GbSYL1/4aW/fB7djZrZAjsGPTqIYpPa16oWlrzsILQ4650Zlvdn8"
130"feh6elTrA4qy6RljZfhIHxzGAeuGbVVLT7zavs01y+QE88sxPpeZ0RGtlVxCYp+xoB5hOO/x"
131"Xm3n0r+HVIaBV9rHLuUSUiHVAtzwuOj/XKh7YBNXeF58lcv8Npsx10etrPuV5hRQelYirKo1"
132"QbT+Aq7sLdWI09eGClDHjvRgw54lCFEUAVUFLxhBnzfVUfw/UiR2SheixH+c7cY3gOOvSMQh"
133"1oL9Omii4S6yhzfbD3hRN/wBKC0NgiIOLRR+Ti0mEEbTxYQrVcHC9rpRcnr1fFAiQvOXrOw0"
134"HyxsbnOeYpoURgLJmUyItPi09xUMCHwUPZ/sI6aG5eRqVUGgcYaQib7MBbGG/D2PlWaKZx1w"
135"iEYtYUI7rrc7Qc2ltp4i1u46ZLtSOxUi8kM7qK2Yp1AOtcWFlGn0XBXpGsHanZRzs8KzfDjQ"
136"OPmRIuFXFmuJweqUGmg6c8P3wHYueenB4oowYELYaDwmmV96obXMG5hbsKne5kcem875d6K+"
137"hL2QzjAl+na4tUZyXYXDdUO2lgTT8IItujBn6c+b8vDcZ24NcYyWPHHb16J4uvKi/6Zb245g"
138"/N0NC6hB43KE+2F0BH0eyXRzCnen6AjF8nvx/wgYrXsFlsU47P8gaL1e7V6QECkY4vIk6//b"
139"LINmpcgZoAv23fgjvYYTMfS/IyPsooS5DJarbHzbsgAWOuqP2ewYulrKqLi0vaUyoErRedQC"
140"8J5p9c4KF56++ameiwxbyKnDynHIIFCOM8eamLnDH4VvU9E2mtfZxmi8kWDWx/NhKEK9zbQv"
141"WuaGDpOysgPK4myTp2QGQNQDvBB92gMcrVTcY//3OGHSXeJrkUfDKLOUDyz7ROghEt1vpRTL"
142"j9Xdbm/01O/0MLBqyXDY119b1qAVVY7Y2CxRIRFdw2V76INWNIwPi46t/VUGwMBGmEux8S8+"
143"79Mv7UyGhKvSUr88pWCS1KdSz1HhN1VWjDvyXPyg96+SecpZMwXCdkUCLdLdD3/8rJLt7wS5"
144"3K5/1V4sacds8GHx7NckhQ/KV0VDlUEFuaOCS4Sd3XXetXs4IFSqtKH+Rn0jX7d8Igcw7X2b"
145"eaV1gxOVquDEwLDT5+wXURw96ahq0caL/4YfoBUQIOQ6HGtPTWJz1Yax0pGu9F30VEY/ObrK"
146"L/B6peJKfqhQGJ+MObqOiP6yHBZH75EImLAkksSVmREdNVjwWkz9D9vzPoAnmP8sQ3/NZarB"
147"Ak+ynQjc19t+CCecPrS2Tlh0cJZkHRiGFF7J5a3ci7yBvg3HfD86AXMRBQuSG1UG8TrzC6BK"
148"+qIQ8DWecQwBMZ3nv/Flo2Fejd/G4/wWe6ObMytC5SB8pJNOq9ri0Ff6Zh3rPrwaSv1PPgFJ"
149"GOw=";
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800150
Yingdi Yu7036ce22014-06-19 18:53:37 -0700151 std::string decoded;
Yingdi Yu5e96e002014-04-23 18:32:15 -0700152 BOOST_CHECK_NO_THROW(StringSource source(imported,
153 true,
Yingdi Yu7036ce22014-06-19 18:53:37 -0700154 new Base64Decoder(new StringSink(decoded))));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800155
156 SecTpmFile tpm;
157
Yingdi Yu5e96e002014-04-23 18:32:15 -0700158 Name keyName("/TestSecTpmFile/ImportKey/ksk-" +
Yingdi Yu7036ce22014-06-19 18:53:37 -0700159 boost::lexical_cast<std::string>(time::toUnixTimestamp(time::system_clock::now())));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800160
Yingdi Yu99b2a002015-08-12 12:47:44 -0700161 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
162 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700163
Yingdi Yu5e96e002014-04-23 18:32:15 -0700164 BOOST_REQUIRE_NO_THROW(
165 tpm.importPrivateKeyPkcs5IntoTpm(keyName,
166 reinterpret_cast<const uint8_t*>(decoded.c_str()),
167 decoded.size(),
168 "1234"));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800169
Yingdi Yu99b2a002015-08-12 12:47:44 -0700170 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), true);
171 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), true);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800172
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700173 shared_ptr<v1::PublicKey> publicKey;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700174 BOOST_CHECK_NO_THROW(publicKey = tpm.getPublicKeyFromTpm(keyName));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800175
176 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
Yingdi Yu2e57a582014-02-20 23:34:43 -0800177 Block sigBlock;
Yingdi Yu5e96e002014-04-23 18:32:15 -0700178 BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700179 keyName, DigestAlgorithm::SHA256));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800180
Yingdi Yu2e57a582014-02-20 23:34:43 -0800181 try
182 {
183 using namespace CryptoPP;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700184
Yingdi Yu7036ce22014-06-19 18:53:37 -0700185 RSA::PublicKey rsaPublicKey;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800186 ByteQueue queue;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700187 queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
188 rsaPublicKey.Load(queue);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700189
Yingdi Yu7036ce22014-06-19 18:53:37 -0700190 RSASS<PKCS1v15, SHA256>::Verifier verifier(rsaPublicKey);
191 bool isVerified = verifier.VerifyMessage(content, sizeof(content),
192 sigBlock.value(), sigBlock.value_size());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700193
Yingdi Yu7036ce22014-06-19 18:53:37 -0700194 BOOST_CHECK_EQUAL(isVerified, true);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800195 }
Yingdi Yu5e96e002014-04-23 18:32:15 -0700196 catch (CryptoPP::Exception& e)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800197 {
198 BOOST_CHECK(false);
199 }
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800200
Yingdi Yu2e57a582014-02-20 23:34:43 -0800201 ConstBufferPtr exported;
Yingdi Yu5e96e002014-04-23 18:32:15 -0700202 BOOST_CHECK_NO_THROW(exported = tpm.exportPrivateKeyPkcs5FromTpm(keyName, "5678"));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800203
204 tpm.deleteKeyPairInTpm(keyName);
205
Yingdi Yu99b2a002015-08-12 12:47:44 -0700206 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
207 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800208
Yingdi Yu5e96e002014-04-23 18:32:15 -0700209 BOOST_REQUIRE(tpm.importPrivateKeyPkcs5IntoTpm(keyName, exported->buf(), exported->size(),
210 "5678"));
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700211
Yingdi Yu99b2a002015-08-12 12:47:44 -0700212 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), true);
213 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), true);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700214
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800215 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Yingdi Yu2e57a582014-02-20 23:34:43 -0800216 Block sigBlock2;
Yingdi Yu5e96e002014-04-23 18:32:15 -0700217 BOOST_CHECK_NO_THROW(sigBlock2 = tpm.signInTpm(content2, sizeof(content2),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700218 keyName, DigestAlgorithm::SHA256));
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800219
Yingdi Yu2e57a582014-02-20 23:34:43 -0800220 try
221 {
222 using namespace CryptoPP;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700223
Yingdi Yu7036ce22014-06-19 18:53:37 -0700224 RSA::PublicKey rsaPublicKey;
Yingdi Yu2e57a582014-02-20 23:34:43 -0800225 ByteQueue queue;
Yingdi Yu7036ce22014-06-19 18:53:37 -0700226 queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
227 rsaPublicKey.Load(queue);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800228
Yingdi Yu7036ce22014-06-19 18:53:37 -0700229 RSASS<PKCS1v15, SHA256>::Verifier verifier(rsaPublicKey);
230 bool isVerified = verifier.VerifyMessage(content2, sizeof(content2),
231 sigBlock2.value(), sigBlock2.value_size());
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700232
Yingdi Yu7036ce22014-06-19 18:53:37 -0700233 BOOST_CHECK_EQUAL(isVerified, true);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800234 }
Yingdi Yu5e96e002014-04-23 18:32:15 -0700235 catch (CryptoPP::Exception& e)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800236 {
237 BOOST_CHECK(false);
238 }
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700239
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800240 tpm.deleteKeyPairInTpm(keyName);
241
Yingdi Yu99b2a002015-08-12 12:47:44 -0700242 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
243 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
Yingdi Yu8dceb1d2014-02-18 12:45:10 -0800244}
245
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700246BOOST_AUTO_TEST_CASE(EcdsaSigning)
247{
248 SecTpmFile tpm;
249
250 Name keyName("/TestSecTpmFile/EcdsaSigning/ksk-" +
251 boost::lexical_cast<std::string>(time::toUnixTimestamp(time::system_clock::now())));
252 EcdsaKeyParams params;
253 BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, params));
254
255 Data data("/TestSecTpmFile/EcdsaSigning/Data/1");
256 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
257
258 Block sigBlock;
259 BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700260 keyName, DigestAlgorithm::SHA256));
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700261
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700262 shared_ptr<v1::PublicKey> pubkeyPtr;
Yingdi Yuc8f883c2014-06-20 23:25:22 -0700263 BOOST_CHECK_NO_THROW(pubkeyPtr = tpm.getPublicKeyFromTpm(keyName));
264
265 try
266 {
267 using namespace CryptoPP;
268
269 ECDSA<ECP, SHA256>::PublicKey publicKey;
270 ByteQueue queue;
271 queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
272 publicKey.Load(queue);
273
274 uint8_t buffer[64];
275 size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
276 sigBlock.value(), sigBlock.value_size(), DSA_DER);
277
278 ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
279 bool result = verifier.VerifyMessage(content, sizeof(content),
280 buffer, usedSize);
281
282 BOOST_CHECK_EQUAL(result, true);
283 }
284 catch (CryptoPP::Exception& e)
285 {
286 BOOST_CHECK(false);
287 }
288
289 tpm.deleteKeyPairInTpm(keyName);
290}
291
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700292
293BOOST_AUTO_TEST_CASE(ImportExportEcdsaKey)
294{
295 using namespace CryptoPP;
296
297 std::string imported =
298 "MIGMMEAGCSqGSIb3DQEFDTAzMBsGCSqGSIb3DQEFDDAOBAhqkJiLfzFWtQICCAAw"
299 "FAYIKoZIhvcNAwcECJ1HLtP8OZC6BEgNv9OH2mZdbkxvqTVlRBkUqPbbP3580OG6"
300 "f0htqWSRppcb4IEKYfuPt2qPCYKL2GcAN2pU3eJqhiM7LFTSFaxgBRFozzIwusk=";
301
302 std::string decoded;
303 BOOST_CHECK_NO_THROW(StringSource source(imported,
304 true,
305 new Base64Decoder(new StringSink(decoded))));
306
307 SecTpmFile tpm;
308
309 Name keyName("/TestSecTpmFile/ImportExportEcdsaKey/ksk-" +
310 boost::lexical_cast<std::string>(time::toUnixTimestamp(time::system_clock::now())));
311
Yingdi Yu99b2a002015-08-12 12:47:44 -0700312 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
313 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700314
315 BOOST_REQUIRE_NO_THROW(
316 tpm.importPrivateKeyPkcs5IntoTpm(keyName,
317 reinterpret_cast<const uint8_t*>(decoded.c_str()),
318 decoded.size(),
319 "5678"));
320
Yingdi Yu99b2a002015-08-12 12:47:44 -0700321 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), true);
322 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), true);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700323
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700324 shared_ptr<v1::PublicKey> publicKey;
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700325 BOOST_CHECK_NO_THROW(publicKey = tpm.getPublicKeyFromTpm(keyName));
326
327 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
328 Block sigBlock;
329 BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700330 keyName, DigestAlgorithm::SHA256));
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700331
332 try
333 {
334 using namespace CryptoPP;
335
336 ECDSA<ECP, SHA256>::PublicKey ecdsaPublicKey;
337 ByteQueue queue;
338 queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
339 ecdsaPublicKey.Load(queue);
340
341 uint8_t buffer[64];
342 size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
343 sigBlock.value(), sigBlock.value_size(), DSA_DER);
344
345 ECDSA<ECP, SHA256>::Verifier verifier(ecdsaPublicKey);
346 bool isVerified = verifier.VerifyMessage(content, sizeof(content),
347 buffer, usedSize);
348
349 BOOST_CHECK_EQUAL(isVerified, true);
350 }
351 catch (CryptoPP::Exception& e)
352 {
353 BOOST_CHECK(false);
354 }
355
356 ConstBufferPtr exported;
357 BOOST_CHECK_NO_THROW(exported = tpm.exportPrivateKeyPkcs5FromTpm(keyName, "1234"));
358
359 tpm.deleteKeyPairInTpm(keyName);
360
Yingdi Yu99b2a002015-08-12 12:47:44 -0700361 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
362 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700363
364 BOOST_REQUIRE(tpm.importPrivateKeyPkcs5IntoTpm(keyName, exported->buf(), exported->size(),
365 "1234"));
366
Yingdi Yu99b2a002015-08-12 12:47:44 -0700367 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), true);
368 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), true);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700369
370 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
371 Block sigBlock2;
372 BOOST_CHECK_NO_THROW(sigBlock2 = tpm.signInTpm(content2, sizeof(content2),
Yingdi Yu99b2a002015-08-12 12:47:44 -0700373 keyName, DigestAlgorithm::SHA256));
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700374
375 try
376 {
377 using namespace CryptoPP;
378
379 ECDSA<ECP, SHA256>::PublicKey ecdsaPublicKey;
380 ByteQueue queue;
381 queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
382 ecdsaPublicKey.Load(queue);
383
384 uint8_t buffer[64];
385 size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
386 sigBlock2.value(), sigBlock2.value_size(),
387 DSA_DER);
388
389 ECDSA<ECP, SHA256>::Verifier verifier(ecdsaPublicKey);
390 bool isVerified = verifier.VerifyMessage(content2, sizeof(content2),
391 buffer, usedSize);
392
393 BOOST_CHECK_EQUAL(isVerified, true);
394
395 }
396 catch (CryptoPP::Exception& e)
397 {
398 BOOST_CHECK(false);
399 }
400
401 tpm.deleteKeyPairInTpm(keyName);
402
Yingdi Yu99b2a002015-08-12 12:47:44 -0700403 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PRIVATE), false);
404 BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KeyClass::PUBLIC), false);
Yingdi Yu9d9d5992014-06-25 12:25:16 -0700405}
406
Yingdi Yu04020922014-01-22 12:46:53 -0800407BOOST_AUTO_TEST_SUITE_END()
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -0800408
Spyridon Mastorakis429634f2015-02-19 17:35:33 -0800409} // namespace tests
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700410} // namespace security
Alexander Afanasyev0abb2da2014-01-30 18:07:57 -0800411} // namespace ndn