static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { EC_KEY *ec_key; unsigned char *ep, *p; int eplen, ptype; void *pval; unsigned int tmp_flags, old_flags; ec_key = pkey->pkey.ec; if (!eckey_param2type(&ptype, &pval, ec_key)) { ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); return 0; } /* set the private key */ /* do not include the parameters in the SEC1 private key * see PKCS#11 12.11 */ old_flags = EC_KEY_get_enc_flags(ec_key); tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; EC_KEY_set_enc_flags(ec_key, tmp_flags); eplen = i2d_ECPrivateKey(ec_key, NULL); if (!eplen) { EC_KEY_set_enc_flags(ec_key, old_flags); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } ep = (unsigned char *) OPENSSL_malloc(eplen); if (!ep) { EC_KEY_set_enc_flags(ec_key, old_flags); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); return 0; } p = ep; if (!i2d_ECPrivateKey(ec_key, &p)) { EC_KEY_set_enc_flags(ec_key, old_flags); OPENSSL_free(ep); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } /* restore old encoding flags */ EC_KEY_set_enc_flags(ec_key, old_flags); if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, ptype, pval, ep, eplen)) return 0; return 1; }
// Constructors OSSLECPrivateKey::OSSLECPrivateKey() { eckey = EC_KEY_new(); // For PKCS#8 encoding EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); }
OSSLECPrivateKey::OSSLECPrivateKey(const EC_KEY* inECKEY) { eckey = EC_KEY_new(); // For PKCS#8 encoding EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); setFromOSSL(inECKEY); }
ndn_Error ndn_EcPublicKey_encode (const struct ndn_EcPublicKey *self, int includeParameters, uint8_t *encoding, size_t *encodingLength) { if (includeParameters) EC_KEY_set_enc_flags(self->publicKey, 0); else EC_KEY_set_enc_flags (self->publicKey, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY); int result = i2d_EC_PUBKEY(self->publicKey, encoding ? &encoding : 0); if (result < 0) return NDN_ERROR_Error_encoding_key; *encodingLength = result; return NDN_ERROR_success; }
static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { EC_KEY ec_key = *(pkey->pkey.ec); uint8_t *ep, *p; int eplen, ptype; void *pval; unsigned int old_flags; if (!eckey_param2type(&ptype, &pval, &ec_key)) { ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); return 0; } /* set the private key */ /* do not include the parameters in the SEC1 private key * see PKCS#11 12.11 */ old_flags = EC_KEY_get_enc_flags(&ec_key); EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); eplen = i2d_ECPrivateKey(&ec_key, NULL); if (!eplen) { ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } ep = malloc(eplen); if (ep == NULL) { ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); return 0; } p = ep; if (!i2d_ECPrivateKey(&ec_key, &p)) { free(ep); ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); return 0; } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, ptype, pval, ep, eplen)) return 0; return 1; }
static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) { EC_KEY *ec_key; const EC_GROUP *group; unsigned char *p, *pp; int nid, i, ret = 0; unsigned int tmp_flags, old_flags; ec_key = pkey->pkey.ec; if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS); return 0; } /* set the ec parameters OID */ if (p8->pkeyalg->algorithm) ASN1_OBJECT_free(p8->pkeyalg->algorithm); p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey); /* set the ec parameters */ if (p8->pkeyalg->parameter) { ASN1_TYPE_free(p8->pkeyalg->parameter); p8->pkeyalg->parameter = NULL; } if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return 0; } if (EC_GROUP_get_asn1_flag(group) && (nid = EC_GROUP_get_curve_name(group))) { /* we have a 'named curve' => just set the OID */ p8->pkeyalg->parameter->type = V_ASN1_OBJECT; p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid); } else /* explicit parameters */ { if ((i = i2d_ECParameters(ec_key, NULL)) == 0) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); return 0; } if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return 0; } pp = p; if (!i2d_ECParameters(ec_key, &pp)) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); OPENSSL_free(p); return 0; } p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; if ((p8->pkeyalg->parameter->value.sequence = ASN1_STRING_new()) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB); OPENSSL_free(p); return 0; } ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i); OPENSSL_free(p); } /* set the private key */ /* do not include the parameters in the SEC1 private key * see PKCS#11 12.11 */ old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec); tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags); i = i2d_ECPrivateKey(pkey->pkey.ec, NULL); if (!i) { EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); return 0; } p = (unsigned char *) OPENSSL_malloc(i); if (!p) { EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return 0; } pp = p; if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp)) { EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); OPENSSL_free(p); return 0; } /* restore old encoding flags */ EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); switch(p8->broken) { case PKCS8_OK: p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); if (!p8->pkey->value.octet_string || !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string, (const void *)p, i)) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); } else ret = 1; break; case PKCS8_NO_OCTET: /* RSA specific */ case PKCS8_NS_DB: /* DSA specific */ case PKCS8_EMBEDDED_PARAM: /* DSA specific */ default: EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR); } OPENSSL_cleanse(p, (size_t)i); OPENSSL_free(p); return ret; }
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); }