int main()

in src/tools/wrap_with_imported_rsa_key.c [127:299]


int main(int argc, char *argv[])
{
    int opt;
    while( (opt = getopt(argc, argv, "l:p:s:k:i:o:h")) != -1 ) {
        switch (opt) {
            case 'l':
                p11SoName = optarg;
                break;
            case 'p':
                p11Pin = optarg;
                break;
            case 's':
                p11SlotId = atoi(optarg);
                break;
            case 'k':
                keyToWrap = atoi(optarg);
                break;
            case 'i':
                pubKeyName = optarg;
                break;
            case 'o':
                wrappedKeyName = optarg;
                break;
	    case 'h':
            default:
                usage(argv[0]);
                return -1;
        }
    }

    if (p11SlotId < 0 || keyToWrap < 0) {
        usage(argv[0]);
        return -1;
    }

    if (p11Pin == NULL) {
        fprintf(stderr, "Warning: No PKCS11 PIN specified, not calling C_Login\n");
    }

    /* Initialize OpenSSL LibCrypto */
    initialize_openssl();

    RSA *rsa = read_RSA_PUBKEY(pubKeyName);
    if (rsa == NULL) {
        return -1;
    }

    /* Get binary exponent and modulus for pub key */
    CK_ULONG keyExponentLen = BN_num_bytes(rsa->e);
    CK_BYTE *keyExponent = malloc(keyExponentLen);
    if (keyExponent == NULL) {
        fprintf(stderr, "Failed to allocate memory for exponent: %s\n", strerror(errno));
        return -1;
    }
    BN_bn2bin(rsa->e, keyExponent);

    CK_ULONG keyModulusLen = BN_num_bytes(rsa->n);
    CK_BYTE *keyModulus = malloc(keyModulusLen);
    if (keyModulus == NULL) {
        fprintf(stderr, "Failed to allocate memory for modulus: %s\n", strerror(errno));
        return -1;
    }
    BN_bn2bin(rsa->n, keyModulus);

    /* Free RSA struct */
    RSA_free(rsa);


    CK_RV rv;
    if (load_pkcs11(p11SoName) != 0) {
        return -1;
    }

    /* Initialize P11, create a session and login, if a PIN was supplied */
    rv = p11Func->C_Initialize(NULL);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call C_Initialize: %1$ld (0x%1$08lx)\n", rv);
        return -1;
    }

    CK_SESSION_HANDLE session;
    rv = p11Func->C_OpenSession(p11SlotId, CKF_SERIAL_SESSION, NULL, NULL, &session);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call C_OpenSession: %1$ld (0x%1$02lx)\n", rv);
        return -1;
    }

    if (p11Pin != NULL) {
        rv = p11Func->C_Login(session, CKU_USER, (CK_UTF8CHAR *)p11Pin, strlen(p11Pin));
        if (rv != CKR_OK) {
            fprintf(stderr, "Failed to call C_Login: %1$ld (0x%1$02lx)\n", rv);
            return -1;
        }
    }

    /* Import RSA Pub Key */
    CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
    CK_KEY_TYPE keyType = CKK_RSA;
    char *keyLabel = "Imported RSA Pub Key";
    CK_OBJECT_HANDLE wrappingKey;
    CK_ATTRIBUTE template[] = {
        { CKA_CLASS, &keyClass, sizeof(keyClass) },
        { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
        { CKA_TOKEN, &False, sizeof(False) },
        { CKA_LABEL, keyLabel, strlen(keyLabel) },
        { CKA_WRAP, &True, sizeof(True) },
        { CKA_PUBLIC_EXPONENT, keyExponent, keyExponentLen },
        { CKA_MODULUS, keyModulus, keyModulusLen }
    };
    size_t template_len = sizeof(template) / sizeof(CK_ATTRIBUTE);
    rv = p11Func->C_CreateObject(session, template, template_len, &wrappingKey);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call C_CreateObject: %1$ld (0x%1$02lx)\n", rv);
        return -1;
    }
    printf("wrappingKey Id: %ld\n", wrappingKey);

    /* Free key exponent and modulus now that they're imported */
    free(keyExponent);
    free(keyModulus);

    
    /* Wrap designated key using the pub key we imported */
    CK_RSA_PKCS_OAEP_PARAMS oaep_params = { CKM_SHA_1, CKG_MGF1_SHA1, CKZ_DATA_SPECIFIED, NULL, 0 };
    CK_MECHANISM mechanism = { CKM_RSA_PKCS_OAEP, &oaep_params, sizeof(oaep_params) };
    CK_BYTE *wrappedKey = NULL;
    CK_ULONG wrappedKeyLen;
    /* This WrapKey call gets how big wrappedKey buffer needs to be */
    rv = p11Func->C_WrapKey(session, &mechanism, wrappingKey, keyToWrap, wrappedKey, &wrappedKeyLen);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call first C_WrapKey: %1$ld (0x%1$02lx)\n", rv);
        return -1;
    }
    wrappedKey = malloc(wrappedKeyLen);
    if (wrappedKey == NULL) {
        fprintf(stderr, "Failed to allocate memory for wrapped key: %s\n", strerror(errno));
        return -1;
    }
    /* This actually wraps out the key */
    rv = p11Func->C_WrapKey(session, &mechanism, wrappingKey, keyToWrap, wrappedKey, &wrappedKeyLen);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call second C_WrapKey: %1$ld (0x%1$02lx)\n", rv);
        return -1;
    }

    /* Write wrapped key to a file */
    int fd = open(wrappedKeyName, O_WRONLY | O_CREAT | O_TRUNC, 0666);
    if (fd < 0) {
        fprintf(stderr, "Failed to open output file for wrapped key: %s\n", strerror(errno));
        return -1;
    }
    write(fd, wrappedKey, wrappedKeyLen);
    close(fd);

    free(wrappedKey);

    /* Cleanup PKCS11 layer */
    rv = p11Func->C_CloseSession(session);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call C_CloseSession: %1$ld (0x%1$02lx)\n", rv);
        return -1;
    }
    rv = p11Func->C_Finalize(NULL);
    if (rv != CKR_OK) {
        fprintf(stderr, "Failed to call C_Finalize: %1$ld (0x%1$02lx)\n", rv);
        return -1;
    }

    /* Cleanup OpenSSL */
    cleanup_openssl();

    return 0;
}