security: Enable exporting/importing ECDSA key
Change-Id: I58f722337f26cad4eb6a3c83d883814efc4ed8df
Refs: #1660
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 f3a782bc..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;