security: Enable exporting/importing ECDSA key
Change-Id: I58f722337f26cad4eb6a3c83d883814efc4ed8df
Refs: #1660
diff --git a/src/encoding/oid.cpp b/src/encoding/oid.cpp
index 511ff6c..1e623a5 100644
--- a/src/encoding/oid.cpp
+++ b/src/encoding/oid.cpp
@@ -28,11 +28,13 @@
#include <sstream>
-using namespace std;
-using namespace CryptoPP;
-
namespace ndn {
+using std::string;
+using std::vector;
+
+static const int OID_MAGIC_NUMBER = 40;
+
OID::OID(const char* oid)
{
construct(oid);
@@ -64,9 +66,10 @@
}
}
-string OID::toString() const
+string
+OID::toString() const
{
- ostringstream convert;
+ std::ostringstream convert;
for (vector<int>::const_iterator it = m_oid.begin(); it != m_oid.end(); ++it) {
if (it != m_oid.begin())
@@ -83,28 +86,29 @@
vector<int>::const_iterator i = m_oid.begin();
vector<int>::const_iterator j = oid.m_oid.begin();
- for (; i != m_oid.end () && j != oid.m_oid.end (); i++, j++) {
+ for (; i != m_oid.end() && j != oid.m_oid.end(); i++, j++) {
if (*i != *j)
return false;
}
- if (i == m_oid.end () && j == oid.m_oid.end ())
- return true;
- else
- return false;
+ return (i == m_oid.end() && j == oid.m_oid.end()); // keep parenthesis for readability.
}
inline void
-EncodeValue(BufferedTransformation& bt, word32 v)
+encodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32 v)
{
- for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
- bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
- bt.Put((byte)(v & 0x7f));
+ using namespace CryptoPP;
+
+ for (unsigned int i = RoundUpToMultipleOf(STDMAX(7U, BitPrecision(v)), 7U) - 7; i != 0; i -= 7)
+ bt.Put(static_cast<byte>(0x80 | ((v >> i) & 0x7f)));
+ bt.Put(static_cast<byte>(v & 0x7f));
}
inline size_t
-DecodeValue(BufferedTransformation& bt, word32& v)
+decodeValue(CryptoPP::BufferedTransformation& bt, CryptoPP::word32& v)
{
+ using namespace CryptoPP;
+
v = 0;
size_t i = 0;
while (true)
@@ -113,11 +117,11 @@
if (!bt.Get(b))
BERDecodeError();
i++;
- if (v >> (8*sizeof(v) - 7)) // v about to overflow
+ if (v >> (8 * sizeof(v) - 7)) // v about to overflow
BERDecodeError();
v <<= 7;
v += b & 0x7f;
- if (!(b & 0x80))
+ if ((b & 0x80) == 0)
return i;
}
}
@@ -125,12 +129,14 @@
void
OID::encode(CryptoPP::BufferedTransformation& out) const
{
+ using namespace CryptoPP;
+
BOOST_ASSERT(m_oid.size() >= 2);
ByteQueue temp;
- temp.Put(byte(m_oid[0] * 40 + m_oid[1]));
+ temp.Put(byte(m_oid[0] * OID_MAGIC_NUMBER + m_oid[1]));
for (size_t i = 2; i < m_oid.size(); i++)
- EncodeValue(temp, m_oid[i]);
+ encodeValue(temp, m_oid[i]);
out.Put(OBJECT_IDENTIFIER);
DERLengthEncode(out, temp.CurrentSize());
@@ -140,6 +146,8 @@
void
OID::decode(CryptoPP::BufferedTransformation& in)
{
+ using namespace CryptoPP;
+
byte b;
if (!in.Get(b) || b != OBJECT_IDENTIFIER)
BERDecodeError();
@@ -153,13 +161,13 @@
length--;
m_oid.resize(2);
- m_oid[0] = b / 40;
- m_oid[1] = b % 40;
+ m_oid[0] = b / OID_MAGIC_NUMBER;
+ m_oid[1] = b % OID_MAGIC_NUMBER;
while (length > 0)
{
word32 v;
- size_t valueLen = DecodeValue(in, v);
+ size_t valueLen = decodeValue(in, v);
if (valueLen > length)
BERDecodeError();
m_oid.push_back(v);
@@ -167,4 +175,11 @@
}
}
+namespace oid {
+const OID RSA("1.2.840.113549.1.1.1");
+const OID ECDSA("1.2.840.10045.2.1");
+
+const OID ATTRIBUTE_NAME("2.5.4.41");
+}
+
} // namespace ndn
diff --git a/src/encoding/oid.hpp b/src/encoding/oid.hpp
index 7da47a6..d5f99ca 100644
--- a/src/encoding/oid.hpp
+++ b/src/encoding/oid.hpp
@@ -35,14 +35,17 @@
class OID
{
public:
- OID ()
+ OID()
{
}
+ explicit
OID(const char* oid);
+ explicit
OID(const std::string& oid);
+ explicit
OID(const std::vector<int>& oid)
: m_oid(oid)
{
@@ -55,19 +58,22 @@
}
void
- setIntegerList(const std::vector<int>& value){
+ setIntegerList(const std::vector<int>& value)
+ {
m_oid = value;
}
std::string
toString() const;
- bool operator == (const OID& oid) const
+ bool
+ operator==(const OID& oid) const
{
return equal(oid);
}
- bool operator != (const OID& oid) const
+ bool
+ operator!=(const OID& oid) const
{
return !equal(oid);
}
@@ -90,6 +96,15 @@
std::vector<int> m_oid;
};
+namespace oid {
+//crypto algorithm
+extern const OID RSA;
+extern const OID ECDSA;
+
+//certificate entries
+extern const OID ATTRIBUTE_NAME;
+}
+
}
#endif // NDN_ENCODING_OID_HPP
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index 9c5e000..5118468 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -274,8 +274,7 @@
if (subjectDescription.empty())
{
- // OID 2.5.4.41 is the oid of subject name.
- CertificateSubjectDescription subjectName("2.5.4.41", keyName.getPrefix(-1).toUri());
+ CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
certificate->addSubjectDescription(subjectName);
}
else
@@ -333,9 +332,10 @@
certificate->setName(certificateName);
certificate->setNotBefore(time::system_clock::now());
- certificate->setNotAfter(time::system_clock::now() + time::days(7300)/* ~20 years*/);
+ certificate->setNotAfter(time::system_clock::now() + time::days(7300)); // ~20 years
certificate->setPublicKeyInfo(*pubKey);
- certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+ certificate->addSubjectDescription(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
+ keyName.toUri()));
certificate->encode();
selfSign(*certificate);
diff --git a/src/security/public-key.cpp b/src/security/public-key.cpp
index bed8f81..801fe6c 100644
--- a/src/security/public-key.cpp
+++ b/src/security/public-key.cpp
@@ -29,9 +29,6 @@
namespace ndn {
-static OID RSA_OID("1.2.840.113549.1.1.1");
-static OID ECDSA_OID("1.2.840.10045.2.1");
-
PublicKey::PublicKey()
: m_type(KEY_TYPE_NULL)
{
@@ -91,9 +88,9 @@
OID algorithm;
algorithm.decode(algorithmInfo);
- if (algorithm == RSA_OID)
+ if (algorithm == oid::RSA)
m_type = KEY_TYPE_RSA;
- else if (algorithm == ECDSA_OID)
+ else if (algorithm == oid::ECDSA)
m_type = KEY_TYPE_ECDSA;
else
throw Error("Only RSA/ECDSA public keys are supported for now (" +
diff --git a/src/security/sec-tpm-osx.cpp b/src/security/sec-tpm-osx.cpp
index f3a782b..b805d4e 100644
--- a/src/security/sec-tpm-osx.cpp
+++ b/src/security/sec-tpm-osx.cpp
@@ -535,6 +535,8 @@
throw Error("Private key [" + keyName.toUri() + "] does not exist in OSX Keychain");
}
+ shared_ptr<PublicKey> publicKey = getPublicKeyFromTpm(keyName);
+
CFReleaser<CFDataRef> exportedKey;
OSStatus res = SecItemExport(privateKey.get(),
kSecFormatOpenSSL,
@@ -555,11 +557,40 @@
return shared_ptr<Buffer>();
}
- OBufferStream pkcs1Os;
- FileSink sink(pkcs1Os);
-
uint32_t version = 0;
- OID algorithm("1.2.840.113549.1.1.1"); // "RSA encryption"
+ OID algorithm;
+ bool hasParameters = false;
+ OID algorithmParameter;
+ switch (publicKey->getKeyType()) {
+ case KEY_TYPE_RSA:
+ {
+ algorithm = oid::RSA; // "RSA encryption"
+ hasParameters = false;
+ break;
+ }
+ case KEY_TYPE_ECDSA:
+ {
+ // "ECDSA encryption"
+ StringSource src(publicKey->get().buf(), publicKey->get().size(), true);
+ BERSequenceDecoder subjectPublicKeyInfo(src);
+ {
+ BERSequenceDecoder algorithmInfo(subjectPublicKeyInfo);
+ {
+ algorithm.decode(algorithmInfo);
+ algorithmParameter.decode(algorithmInfo);
+ }
+ }
+ hasParameters = true;
+ break;
+ }
+ default:
+ throw Error("Unsupported key type" +
+ boost::lexical_cast<std::string>(publicKey->getKeyType()));
+ }
+
+ OBufferStream pkcs8Os;
+ FileSink sink(pkcs8Os);
+
SecByteBlock rawKeyBits;
// PrivateKeyInfo ::= SEQUENCE {
// version INTEGER,
@@ -571,7 +602,10 @@
DERSequenceEncoder privateKeyAlgorithm(privateKeyInfo);
{
algorithm.encode(privateKeyAlgorithm);
- DEREncodeNull(privateKeyAlgorithm);
+ if (hasParameters)
+ algorithmParameter.encode(privateKeyAlgorithm);
+ else
+ DEREncodeNull(privateKeyAlgorithm);
}
privateKeyAlgorithm.MessageEnd();
DEREncodeOctetString(privateKeyInfo,
@@ -580,7 +614,7 @@
}
privateKeyInfo.MessageEnd();
- return pkcs1Os.buf();
+ return pkcs8Os.buf();
}
#ifdef __GNUC__
@@ -598,8 +632,6 @@
using namespace CryptoPP;
StringSource privateKeySource(buf, size, true);
- uint32_t tmpNum;
- OID tmpOID;
SecByteBlock rawKeyBits;
// PrivateKeyInfo ::= SEQUENCE {
// INTEGER,
@@ -607,11 +639,24 @@
// OCTECT STRING}
BERSequenceDecoder privateKeyInfo(privateKeySource);
{
- BERDecodeUnsigned<uint32_t>(privateKeyInfo, tmpNum, INTEGER);
+ uint32_t versionNum;
+ BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
BERSequenceDecoder sequenceDecoder(privateKeyInfo);
{
- tmpOID.decode(sequenceDecoder);
- BERDecodeNull(sequenceDecoder);
+ OID keyTypeOID;
+ keyTypeOID.decode(sequenceDecoder);
+
+ if (keyTypeOID == oid::RSA)
+ BERDecodeNull(sequenceDecoder);
+ else if (keyTypeOID == oid::ECDSA)
+ {
+ OID parameterOID;
+ parameterOID.decode(sequenceDecoder);
+ }
+ else
+ return false; // Unsupported key type;
+
+
}
BERDecodeOctetString(privateKeyInfo, rawKeyBits);
}
diff --git a/src/security/sec-tpm.cpp b/src/security/sec-tpm.cpp
index 3191095..97adf7a 100644
--- a/src/security/sec-tpm.cpp
+++ b/src/security/sec-tpm.cpp
@@ -66,6 +66,7 @@
e.SetKeyWithIV(derived, derivedLen, iv);
ConstBufferPtr pkcs8PrivateKey = exportPrivateKeyPkcs8FromTpm(keyName);
+
if (!static_cast<bool>(pkcs8PrivateKey))
throw Error("Cannot export the private key, #1");
@@ -233,7 +234,6 @@
return false;
}
-
PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
byte derived[24] = {0};
@@ -271,23 +271,70 @@
privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
return false;
+ //determine key type
+ StringSource privateKeySource(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size(), true);
+
+ KeyType publicKeyType = KEY_TYPE_NULL;
+ SecByteBlock rawKeyBits;
+ // PrivateKeyInfo ::= SEQUENCE {
+ // INTEGER,
+ // SEQUENCE,
+ // OCTECT STRING}
+ BERSequenceDecoder privateKeyInfo(privateKeySource);
+ {
+ uint32_t versionNum;
+ BERDecodeUnsigned<uint32_t>(privateKeyInfo, versionNum, INTEGER);
+ BERSequenceDecoder sequenceDecoder(privateKeyInfo);
+ {
+ OID keyTypeOID;
+ keyTypeOID.decode(sequenceDecoder);
+ if (keyTypeOID == oid::RSA)
+ publicKeyType = KEY_TYPE_RSA;
+ else if (keyTypeOID == oid::ECDSA)
+ publicKeyType = KEY_TYPE_ECDSA;
+ else
+ return false; // Unsupported key type;
+ }
+ }
+
+
//derive public key
OBufferStream publicKeyOs;
- try
- {
- RSA::PrivateKey privateKey;
- privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
- RSAFunction publicKey(privateKey);
+ try {
+ switch (publicKeyType) {
+ case KEY_TYPE_RSA:
+ {
+ RSA::PrivateKey privateKey;
+ privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
+ RSAFunction publicKey(privateKey);
- FileSink publicKeySink(publicKeyOs);
- publicKey.DEREncode(publicKeySink);
- publicKeySink.MessageEnd();
- }
- catch (CryptoPP::Exception& e)
- {
+ FileSink publicKeySink(publicKeyOs);
+ publicKey.DEREncode(publicKeySink);
+ publicKeySink.MessageEnd();
+ break;
+ }
+ case KEY_TYPE_ECDSA:
+ {
+ ECDSA<ECP, SHA256>::PrivateKey privateKey;
+ privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
+
+ ECDSA<ECP, SHA256>::PublicKey publicKey;
+ privateKey.MakePublicKey(publicKey);
+ publicKey.AccessGroupParameters().SetEncodeAsOID(true);
+
+ FileSink publicKeySink(publicKeyOs);
+ publicKey.DEREncode(publicKeySink);
+ publicKeySink.MessageEnd();
+ break;
+ }
+ default:
return false;
}
+ }
+ catch (CryptoPP::Exception& e) {
+ return false;
+ }
if (!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
return false;
diff --git a/tests/unit-tests/security/test-encode-decode-certificate.cpp b/tests/unit-tests/security/test-encode-decode-certificate.cpp
index 2577509..f8cc0fb 100644
--- a/tests/unit-tests/security/test-encode-decode-certificate.cpp
+++ b/tests/unit-tests/security/test-encode-decode-certificate.cpp
@@ -92,7 +92,8 @@
certificate.setNotAfter(time::fromUnixTimestamp(time::milliseconds(1388100174000LL)));
// subject
- certificate.addSubjectDescription(CertificateSubjectDescription("2.5.4.41", "TEST NAME"));
+ certificate.addSubjectDescription(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
+ "TEST NAME"));
// publicKeyInfo
ndn::PublicKey key(PUBLIC_KEY, sizeof(PUBLIC_KEY));
@@ -113,7 +114,8 @@
}
seq.MessageEnd();
- certificate.addExtension(CertificateExtension("1.3.6.1.5.32.1", true,
+ //create a randome extension
+ certificate.addExtension(CertificateExtension(OID("1.3.6.1.5.32.1"), true,
reinterpret_cast<const uint8_t*>(extenstionValue.c_str()),
extenstionValue.size()));
});
diff --git a/tests/unit-tests/security/test-sec-tpm-file.cpp b/tests/unit-tests/security/test-sec-tpm-file.cpp
index c25a40b..0b900ed 100644
--- a/tests/unit-tests/security/test-sec-tpm-file.cpp
+++ b/tests/unit-tests/security/test-sec-tpm-file.cpp
@@ -289,6 +289,122 @@
tpm.deleteKeyPairInTpm(keyName);
}
+
+BOOST_AUTO_TEST_CASE(ImportExportEcdsaKey)
+{
+ using namespace CryptoPP;
+
+ std::string imported =
+ "MIGMMEAGCSqGSIb3DQEFDTAzMBsGCSqGSIb3DQEFDDAOBAhqkJiLfzFWtQICCAAw"
+ "FAYIKoZIhvcNAwcECJ1HLtP8OZC6BEgNv9OH2mZdbkxvqTVlRBkUqPbbP3580OG6"
+ "f0htqWSRppcb4IEKYfuPt2qPCYKL2GcAN2pU3eJqhiM7LFTSFaxgBRFozzIwusk=";
+
+ std::string decoded;
+ BOOST_CHECK_NO_THROW(StringSource source(imported,
+ true,
+ new Base64Decoder(new StringSink(decoded))));
+
+ SecTpmFile tpm;
+
+ Name keyName("/TestSecTpmFile/ImportExportEcdsaKey/ksk-" +
+ boost::lexical_cast<std::string>(time::toUnixTimestamp(time::system_clock::now())));
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
+
+ BOOST_REQUIRE_NO_THROW(
+ tpm.importPrivateKeyPkcs5IntoTpm(keyName,
+ reinterpret_cast<const uint8_t*>(decoded.c_str()),
+ decoded.size(),
+ "5678"));
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), true);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
+
+ shared_ptr<PublicKey> publicKey;
+ BOOST_CHECK_NO_THROW(publicKey = tpm.getPublicKeyFromTpm(keyName));
+
+ const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
+ Block sigBlock;
+ BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content),
+ keyName, DIGEST_ALGORITHM_SHA256));
+
+ try
+ {
+ using namespace CryptoPP;
+
+ ECDSA<ECP, SHA256>::PublicKey ecdsaPublicKey;
+ ByteQueue queue;
+ queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
+ ecdsaPublicKey.Load(queue);
+
+ uint8_t buffer[64];
+ size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
+ sigBlock.value(), sigBlock.value_size(), DSA_DER);
+
+ ECDSA<ECP, SHA256>::Verifier verifier(ecdsaPublicKey);
+ bool isVerified = verifier.VerifyMessage(content, sizeof(content),
+ buffer, usedSize);
+
+ BOOST_CHECK_EQUAL(isVerified, true);
+ }
+ catch (CryptoPP::Exception& e)
+ {
+ BOOST_CHECK(false);
+ }
+
+ ConstBufferPtr exported;
+ BOOST_CHECK_NO_THROW(exported = tpm.exportPrivateKeyPkcs5FromTpm(keyName, "1234"));
+
+ tpm.deleteKeyPairInTpm(keyName);
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
+
+ BOOST_REQUIRE(tpm.importPrivateKeyPkcs5IntoTpm(keyName, exported->buf(), exported->size(),
+ "1234"));
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), true);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
+
+ const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
+ Block sigBlock2;
+ BOOST_CHECK_NO_THROW(sigBlock2 = tpm.signInTpm(content2, sizeof(content2),
+ keyName, DIGEST_ALGORITHM_SHA256));
+
+ try
+ {
+ using namespace CryptoPP;
+
+ ECDSA<ECP, SHA256>::PublicKey ecdsaPublicKey;
+ ByteQueue queue;
+ queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
+ ecdsaPublicKey.Load(queue);
+
+ uint8_t buffer[64];
+ size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
+ sigBlock2.value(), sigBlock2.value_size(),
+ DSA_DER);
+
+ ECDSA<ECP, SHA256>::Verifier verifier(ecdsaPublicKey);
+ bool isVerified = verifier.VerifyMessage(content2, sizeof(content2),
+ buffer, usedSize);
+
+ BOOST_CHECK_EQUAL(isVerified, true);
+
+ }
+ catch (CryptoPP::Exception& e)
+ {
+ BOOST_CHECK(false);
+ }
+
+ tpm.deleteKeyPairInTpm(keyName);
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace ndn
diff --git a/tests/unit-tests/security/test-sec-tpm-osx.cpp b/tests/unit-tests/security/test-sec-tpm-osx.cpp
index 3b28c66..a7d1d80 100644
--- a/tests/unit-tests/security/test-sec-tpm-osx.cpp
+++ b/tests/unit-tests/security/test-sec-tpm-osx.cpp
@@ -25,6 +25,7 @@
#include "util/time.hpp"
#include <boost/lexical_cast.hpp>
+#include <Availability.h>
#include "boost-test.hpp"
@@ -177,9 +178,14 @@
}
tpm.deleteKeyPairInTpm(keyName);
- // This is some problem related to Mac OS Key chain, and we will fix it later.
- // BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == false);
- // BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
+ // This is some problem related to Mac OS Key chain.
+ // On OSX 10.8, we cannot delete imported keys, but there is no such problem on OSX 10.9.
+#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_9
+ BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == false);
+ BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
+#endif
+#endif
}
BOOST_AUTO_TEST_CASE(NonExistingKey)
@@ -246,6 +252,82 @@
tpm.deleteKeyPairInTpm(keyName);
}
+
+BOOST_AUTO_TEST_CASE(ExportImportEcdsaKey)
+{
+ using namespace CryptoPP;
+
+ SecTpmOsx tpm;
+
+ Name keyName("/TestSecTpmOsx/ExportImportEcdsaKey/ksk-" +
+ boost::lexical_cast<std::string>(
+ time::toUnixTimestamp(time::system_clock::now()).count()));
+
+ EcdsaKeyParams params;
+ BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, params));
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), true);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
+
+ ConstBufferPtr exported;
+ BOOST_CHECK_NO_THROW(exported = tpm.exportPrivateKeyPkcs5FromTpm(keyName, "1234"));
+
+ shared_ptr<PublicKey> publicKey;
+ BOOST_REQUIRE_NO_THROW(publicKey = tpm.getPublicKeyFromTpm(keyName));
+
+ tpm.deleteKeyPairInTpm(keyName);
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
+
+ BOOST_REQUIRE(tpm.importPrivateKeyPkcs5IntoTpm(keyName,
+ exported->buf(), exported->size(),
+ "1234"));
+
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
+ BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), true);
+
+ const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
+ Block sigBlock;
+ BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content),
+ keyName, DIGEST_ALGORITHM_SHA256));
+
+ try
+ {
+ using namespace CryptoPP;
+
+ ECDSA<ECP, SHA256>::PublicKey ecdsaPublicKey;
+ ByteQueue queue;
+ queue.Put(reinterpret_cast<const byte*>(publicKey->get().buf()), publicKey->get().size());
+ ecdsaPublicKey.Load(queue);
+
+ uint8_t buffer[64];
+ size_t usedSize = DSAConvertSignatureFormat(buffer, 64, DSA_P1363,
+ sigBlock.value(), sigBlock.value_size(),
+ DSA_DER);
+
+ ECDSA<ECP, SHA256>::Verifier verifier(ecdsaPublicKey);
+ bool isVerified = verifier.VerifyMessage(content, sizeof(content),
+ buffer, usedSize);
+
+ BOOST_CHECK_EQUAL(isVerified, true);
+ }
+ catch (CryptoPP::Exception& e)
+ {
+ BOOST_CHECK(false);
+ }
+
+ tpm.deleteKeyPairInTpm(keyName);
+ // This is some problem related to Mac OS Key chain.
+ // On OSX 10.8, we cannot delete imported keys, but there is no such problem on OSX 10.9.
+#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_9
+ BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == false);
+ BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == false);
+#endif
+#endif
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace ndn
diff --git a/tools/ndnsec-cert-gen.hpp b/tools/ndnsec-cert-gen.hpp
index c2b0333..264dfab 100644
--- a/tools/ndnsec-cert-gen.hpp
+++ b/tools/ndnsec-cert-gen.hpp
@@ -105,10 +105,10 @@
}
std::vector<CertificateSubjectDescription> subjectDescription;
- subjectDescription.push_back(CertificateSubjectDescription("2.5.4.41", subjectName));
+ subjectDescription.push_back(CertificateSubjectDescription(oid::ATTRIBUTE_NAME, subjectName));
tokenizer<escaped_list_separator<char> > subjectInfoItems
- (subjectInfo, escaped_list_separator<char> ("\\", " \t", "'\""));
+ (subjectInfo, escaped_list_separator<char>("\\", " \t", "'\""));
tokenizer<escaped_list_separator<char> >::iterator it =
subjectInfoItems.begin();
@@ -126,7 +126,7 @@
std::string value = *it;
- subjectDescription.push_back(CertificateSubjectDescription(oid, value));
+ subjectDescription.push_back(CertificateSubjectDescription(OID(oid), value));
it++;
}