in src/tools/import_pub_key.c [105:174]
int main(int argc, char **argv) {
CK_RV rv;
CK_SESSION_HANDLE session;
int rc = 1;
struct import_args args = {0};
if (get_import_args(argc, argv, &args) < 0) {
return rc;
}
rv = pkcs11_initialize(args.library);
if (CKR_OK != rv) {
return rc;
}
rv = pkcs11_open_session(args.pin, &session);
if (CKR_OK != rv) {
return rc;
}
/* Read the pem file into an RSA struct to we can access the exponent and modulus */
RSA *key = read_RSA_PUBKEY(args.pem_file);
if (NULL==key) {
fprintf(stderr, "Could not read the RSA key\n");
return rc;
}
CK_ULONG pub_exp_len = BN_num_bytes(key->e);
CK_BYTE *pub_exp = malloc(pub_exp_len);
if (pub_exp == NULL) {
fprintf(stderr, "Failed to allocate memory for exponent: %s\n", strerror(errno));
return rc;
}
BN_bn2bin(key->e, pub_exp);
CK_ULONG modulus_len = BN_num_bytes(key->n);
CK_BYTE *modulus = malloc(modulus_len);
if (modulus == NULL) {
fprintf(stderr, "Failed to allocate memory for modulus: %s\n", strerror(errno));
return rc;
}
BN_bn2bin(key->n, modulus);
RSA_free(key);
/* Using the modulus and exponent from above, we can "import" the key by creating
* an object with the appropriate attributes.
*/
CK_OBJECT_HANDLE pub_key = CK_INVALID_HANDLE;
CK_OBJECT_CLASS pub_key_class = CKO_PUBLIC_KEY;
CK_KEY_TYPE key_type = CKK_RSA;
CK_ATTRIBUTE pub_tmpl[] = {
{CKA_KEY_TYPE, &key_type, sizeof(key_type)},
{CKA_CLASS, &pub_key_class, sizeof(pub_key_class)},
{CKA_MODULUS, modulus, modulus_len},
{CKA_PUBLIC_EXPONENT, pub_exp, pub_exp_len},
{CKA_TOKEN, &true_val, sizeof(CK_BBOOL)},
{CKA_WRAP, &true_val, sizeof(CK_BBOOL)}
};
rv = funcs->C_CreateObject(session, pub_tmpl, sizeof(pub_tmpl) / sizeof(CK_ATTRIBUTE), &pub_key);
if (CKR_OK != rv) {
fprintf(stderr, "Failed to create object %lu\n", rv);
return rc;
}
printf("Imported the public key as %lu\n", pub_key);
pkcs11_finalize_session(session);
return rv;
}