void FilePrivateKeyStorage::generateKeyPair (const Name& keyName, const KeyParams& params) { if (doesKeyExist(keyName, KEY_CLASS_PUBLIC)) throw SecurityException("Public Key already exists"); if (doesKeyExist(keyName, KEY_CLASS_PRIVATE)) throw SecurityException("Private Key already exists"); Blob publicKeyDer; Blob privateKeyDer; if (params.getKeyType() == KEY_TYPE_RSA) { const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params); BIGNUM* exponent = 0; RSA* rsa = 0; exponent = BN_new(); if (BN_set_word(exponent, RSA_F4) == 1) { rsa = RSA_new(); if (RSA_generate_key_ex(rsa, rsaParams.getKeySize(), exponent, NULL) == 1) { // Encode the public key. int length = i2d_RSA_PUBKEY(rsa, NULL); publicKeyDer = Blob(ptr_lib::make_shared<vector<uint8_t> >(length), false); uint8_t* derPointer = const_cast<uint8_t*>(publicKeyDer.buf()); i2d_RSA_PUBKEY(rsa, &derPointer); // Encode the private key. length = i2d_RSAPrivateKey(rsa, NULL); vector<uint8_t> pkcs1PrivateKeyDer(length); derPointer = &pkcs1PrivateKeyDer[0]; i2d_RSAPrivateKey(rsa, &derPointer); privateKeyDer = encodePkcs8PrivateKey (pkcs1PrivateKeyDer, OID(RSA_ENCRYPTION_OID), ptr_lib::make_shared<DerNode::DerNull>()); } } BN_free(exponent); RSA_free(rsa); } else if (params.getKeyType() == KEY_TYPE_ECDSA) { const EcdsaKeyParams& ecdsaParams = static_cast<const EcdsaKeyParams&>(params); OID parametersOid; int curveId = -1; // Find the entry in EC_KEY_INFO. for (size_t i = 0 ; i < sizeof(EC_KEY_INFO) / sizeof(EC_KEY_INFO[0]); ++i) { if (EC_KEY_INFO[i].keySize == ecdsaParams.getKeySize()) { curveId = EC_KEY_INFO[i].curveId; parametersOid.setIntegerList (EC_KEY_INFO[i].oidIntegerList, EC_KEY_INFO[i].oidIntegerListLength); break; } } if (curveId == -1) throw SecurityException("Unsupported keySize for KEY_TYPE_ECDSA"); EC_KEY* ecKey = EC_KEY_new_by_curve_name(curveId); if (ecKey != NULL) { if (EC_KEY_generate_key(ecKey) == 1) { // Encode the public key. int length = i2d_EC_PUBKEY(ecKey, NULL); vector<uint8_t> opensslPublicKeyDer(length); uint8_t* derPointer = &opensslPublicKeyDer[0]; i2d_EC_PUBKEY(ecKey, &derPointer); // Convert the openssl style to ndn-cxx which has the simple AlgorithmIdentifier. // Find the bit string which is the second child. ptr_lib::shared_ptr<DerNode> parsedNode = DerNode::parse (&opensslPublicKeyDer[0], 0); const std::vector<ptr_lib::shared_ptr<DerNode> >& children = parsedNode->getChildren(); publicKeyDer = encodeSubjectPublicKeyInfo (OID(EC_ENCRYPTION_OID), ptr_lib::make_shared<DerNode::DerOid>(parametersOid), children[1]); // Encode the private key. EC_KEY_set_enc_flags(ecKey, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY); length = i2d_ECPrivateKey(ecKey, NULL); vector<uint8_t> pkcs1PrivateKeyDer(length); derPointer = &pkcs1PrivateKeyDer[0]; i2d_ECPrivateKey(ecKey, &derPointer); privateKeyDer = encodePkcs8PrivateKey (pkcs1PrivateKeyDer, OID(EC_ENCRYPTION_OID), ptr_lib::make_shared<DerNode::DerOid>(parametersOid)); } } EC_KEY_free(ecKey); } else throw SecurityException("Unsupported key type"); string keyUri = keyName.toUri(); string publicKeyFilePath = nameTransform(keyUri, ".pub"); string privateKeyFilePath = nameTransform(keyUri, ".pri"); ofstream publicKeyFile(publicKeyFilePath.c_str()); publicKeyFile << toBase64(publicKeyDer.buf(), publicKeyDer.size(), true); ofstream privateKeyFile(privateKeyFilePath.c_str()); privateKeyFile << toBase64(privateKeyDer.buf(), privateKeyDer.size(), true); ::chmod(publicKeyFilePath.c_str(), S_IRUSR | S_IRGRP | S_IROTH); ::chmod(privateKeyFilePath.c_str(), S_IRUSR); }