コード例 #1
0
ファイル: pkcs11d.c プロジェクト: zhulianhai/pkcs11
int main(int argc, char **argv)
{
    CK_ULONG          nslots;
    CK_SLOT_ID        *pslots = NULL;
    CK_FUNCTION_LIST  *funcs = NULL;
    CK_UTF8CHAR_PTR   opt_pin = NULL;
    CK_ULONG          opt_pin_len = 0;
    CK_RV             rc;
    CK_ULONG          opt_slot = -1;
    CK_SESSION_HANDLE h_session;
    char *opt_module = NULL, *opt_dir = NULL;
    /* struct sockaddr_un sockaddr; */
    int long_optind = 0;
    int fd, verbose = 0;
    key_id_t *rsa_keys, *ec_keys;
    CK_ULONG rsa_len = 0, ec_len = 0, i;

    init_crypto();

    while (1) {
        char c = getopt_long(argc, argv, "d:hp:s:m:v",
                             options, &long_optind);
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                opt_dir = optarg;
                break;
            case 'p':
                opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg);
                if(opt_pin) {
                    opt_pin_len = strlen(optarg);
                }
                break;
            case 's':
                opt_slot = (CK_SLOT_ID) atoi(optarg);
                break;
            case 'm':
                opt_module = optarg;
                break;
            case 'v':
                verbose = 1;
                break;
            case 'h':
            default:
                print_usage_and_die(app_name, options, option_help);
        }
    }

    rc = pkcs11_load_init(opt_module, opt_dir, stderr, &funcs);
    if (rc != CKR_OK) {
        return rc;
    }

    rc = pkcs11_get_slots(funcs, stderr, &pslots, &nslots);
    if (rc != CKR_OK) {
        return rc;
    }

    if(opt_slot == -1) {
        if(nslots < 1) {
            /* No slots */
            return -1;
        } else {
            opt_slot = pslots[0];
        }
    } else {
        /* Check selected slot is in pslots */
    }

    fprintf(stderr, "Slot: %ld\n", opt_slot);
    rc = pkcs11_login_session(funcs, stderr, opt_slot, &h_session,
                              CK_TRUE, CKU_USER, opt_pin, opt_pin_len);
    if (rc != CKR_OK) {
        show_error(stderr, "Login", rc);
        return rc;
    }
    
    load_keys(funcs, h_session, CKK_RSA, &rsa_keys, &rsa_len);
    load_keys(funcs, h_session, CKK_EC,  &ec_keys,  &ec_len);


    /* fd = nw_unix_server("pkcs11d.sock", &sockaddr, 0, 0, 0, 64); */
    /* close(fd); */
    fd = nw_tcp_server(1234, 0, 64);
    
    do {
        struct sockaddr address;
        socklen_t a_len = sizeof(address);
        int s = accept(fd, &address, &a_len);
        BIO *b = BIO_new_socket(s, BIO_NOCLOSE);
        BIO *buf = BIO_new(BIO_f_buffer());
        b = BIO_push(buf, b);
        char buffer[4096], sig[4096], keyid[KEY_ID_SIZE + 1];
        int l, slen = 0, plen = 0;
        CK_KEY_TYPE type;
        CK_ATTRIBUTE_TYPE operation;
        EVP_PKEY *pkey = NULL;

        l = BIO_gets(b, buffer, sizeof(buffer));
        if(l <= 0) {
            fprintf(stderr, "Error reading query line\n");
            goto end;
        }

        if(strncmp(buffer, "POST /sign/rsa/", 15) == 0) {
            memcpy(keyid, buffer + 15, KEY_ID_SIZE - 1);
            type = CKK_RSA;
            operation = CKA_SIGN;
        } else if(strncmp(buffer, "POST /decrypt/rsa/", 18) == 0) {
            memcpy(keyid, buffer + 18, KEY_ID_SIZE - 1);
            type = CKK_RSA;
            operation = CKA_DECRYPT;
        } else if(strncmp(buffer, "POST /sign/ec/", 14) == 0) {
            memcpy(keyid, buffer + 14, KEY_ID_SIZE - 1);
            type = CKK_EC;
            operation = CKA_SIGN;
        } else {
            goto end;
        }
        keyid[KEY_ID_SIZE] = '\0';

        l = BIO_gets(b, buffer, sizeof(buffer));
        if((l <= 0) || strncmp(buffer, "Content-Length: ", 16) != 0) {
            fprintf(stderr, "Invalid content length line = %s\n", buffer);
            goto end;
        }
        plen = atoi(buffer + 16);
        l = BIO_gets(b, buffer, sizeof(buffer));
        l = BIO_read(b, buffer, plen);
        if(l < plen) {
            fprintf(stderr, "Error reading payload\n");
            goto end;
        }


        if(type == CKK_RSA) {
            for(i = 0; (i < rsa_len) && (pkey == NULL); i++) {
                if(strncmp(rsa_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) {
                    pkey = rsa_keys[i].key;
                }
            }
        } else if(type == CKK_EC) {
            for(i = 0; (i < ec_len) && (pkey == NULL); i++) {
                if(strncmp(ec_keys[i].id, keyid, KEY_ID_SIZE - 1) == 0) {
                    pkey = ec_keys[i].key;
                }
            }
        }
        if(pkey == NULL) {
            fprintf(stderr, "Key not found\n");
            goto end;
        } else if(verbose) {
            fprintf(stderr, "Key '%s'found\n", keyid);
        }
        
        if(type == CKK_RSA && operation == CKA_SIGN) {
            if(verbose) {
                fprintf(stderr, "RSA signature operation requested\n");
            }
            l = RSA_private_encrypt(plen, (unsigned char *)buffer, (unsigned char *)sig,
                                    EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING);
        } else if(type == CKK_RSA && operation == CKA_DECRYPT) {
            if(verbose) {
                fprintf(stderr, "RSA decryption operation requested\n");
            }
            l = RSA_private_decrypt(plen, (unsigned char *)buffer, (unsigned char *)sig,
                                    EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING);
        } else if (type == CKK_EC && operation == CKA_SIGN) {
            unsigned char *ptr = (unsigned char *)sig;
            ECDSA_SIG *s = ECDSA_do_sign((unsigned char *)buffer, plen, EVP_PKEY_get1_EC_KEY(pkey));
            l = i2d_ECDSA_SIG(s, &ptr);
            ECDSA_SIG_free(s);
        } else {
            if(verbose) {
                fprintf(stderr, "Invalid operation requested\n");
            }
            goto end;
        }

        slen = l;
        if(l <= 0) {
            if(verbose) {
                fprintf(stderr, "Error unsuccessful\n");
            }
            goto end;
        } else if(verbose) {
            fprintf(stderr, "Operation successful\n");
        }

        BIO_printf(b, "200 Ok\r\n");
        BIO_printf(b, "Content-Length: %d\r\n\r\n", slen);

        l = BIO_write(b, sig, slen);
        BIO_flush(b);

        i= 0;
        /*
        for(i = 0; i < rsa_len; i++) {
            BIO_write(b, rsa_keys[i].id, KEY_ID_SIZE);
            BIO_write(b, "\n", 1);
            PEM_write_bio_RSAPrivateKey(b, EVP_PKEY_get1_RSA(rsa_keys[i].key), NULL, NULL, 0, NULL, NULL);
        }
        for(i = 0; i < ec_len; i++) {
            BIO_write(b, ec_keys[i].id, KEY_ID_SIZE);
            BIO_write(b, "\n", 1);
            PEM_write_bio_ECPrivateKey(b, EVP_PKEY_get1_EC_KEY(ec_keys[i].key), NULL, NULL, 0, NULL, NULL);
        }
        */


    end:
        close(s);
        BIO_free(b);
    } while(1);

    close(fd);

    if(opt_pin) {
        funcs->C_CloseAllSessions(opt_slot);
        free(opt_pin);
    }

    rc = funcs->C_Finalize(NULL);
    if (rc != CKR_OK) {
        show_error(stderr, "C_Finalize", rc);
        return rc;
    }
    
    return rc;
}
コード例 #2
0
ファイル: clean.c プロジェクト: zhulianhai/pkcs11
int clean(int argc, char **argv)
{
    CK_UTF8CHAR_PTR   opt_pin = NULL;
    CK_ULONG          opt_pin_len = 0;
    CK_RV             rc;
    CK_ULONG          nslots, opt_slot = -1;
    CK_SLOT_ID        *pslots = NULL;
    CK_SESSION_HANDLE h_session;
    char *opt_module = NULL, *opt_dir = NULL;
    int long_optind = 0, rw = 0, destroy = 0, i;
    char c;

    while (1) {
        c = getopt_long(argc, argv, "hrd:p:s:m:", options, &long_optind);
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                opt_dir = optarg;
                break;
            case 'p':
                opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg);
                if(opt_pin) {
                    opt_pin_len = strlen(optarg);
                }
                break;
            case 's':
                opt_slot = (CK_SLOT_ID) atoi(optarg);
                break;
            case 'm':
                opt_module = optarg;
                break;
            case 'r':
                rw = 1;
                break;
            case 'h':
            default:
                print_usage_and_die(app_name, options, option_help);
        }
    }

    rc = pkcs11_load_init(opt_module, opt_dir, stdout, &funcs);
    if (rc != CKR_OK) {
        return rc;
    }

    rc = pkcs11_get_slots(funcs, stdout, &pslots, &nslots);
    if (rc != CKR_OK) {
        return rc;
    }

    if(opt_slot != -1) {
        /* TODO: Look in pslots */
        pslots = &opt_slot;
        nslots = 1;
    } else {
        if(nslots == 1) {
            opt_slot = pslots[0];
        } else {
            fprintf(stdout, "Found %ld slots, use --slot parameter to choose.\n", nslots);
            exit(-1);
        }
    }

    rc = pkcs11_login_session(funcs, stdout, opt_slot, &h_session,
                              CK_TRUE, CKU_USER, opt_pin, opt_pin_len);
    free(opt_pin);
    if (rc != CKR_OK) {
        return rc;
    }

    CK_OBJECT_CLASS pkey = CKO_PRIVATE_KEY;
    CK_ATTRIBUTE search_all[] =
    {
        { CKA_CLASS, &pkey, sizeof(pkey)}
    };
    CK_OBJECT_HANDLE all_keys[65536];
    CK_ULONG key_count = sizeof(all_keys) / sizeof(CK_OBJECT_HANDLE);

    rc = funcs->C_FindObjectsInit(h_session, search_all, 1);
    if (rc != CKR_OK) {
        show_error(stdout, "C_FindObjectsInit", rc);
        return rc;
    }

    rc = funcs->C_FindObjects(h_session, all_keys, key_count, &key_count);
    if (rc != CKR_OK) {
        show_error(stdout, "C_FindObjects", rc);
        return rc;
    }

    rc = funcs->C_FindObjectsFinal(h_session);
    if (rc != CKR_OK) {
        show_error(stdout, "C_FindObjectsFinal", rc);
        return rc;
    }

    fprintf(stdout, "Found %lu private keys\n", key_count);

    for(i = 0; i < key_count; i++) {
        CK_BYTE id[32];
        CK_OBJECT_CLASS crt = CKO_CERTIFICATE;
        CK_ATTRIBUTE search_crt[] = {
            { CKA_ID, &id, 32 },
            { CKA_CLASS, &crt, sizeof(crt)}
        };
        CK_OBJECT_HANDLE h_crt;
        CK_ULONG crt_count = 1;

        rc = funcs->C_GetAttributeValue(h_session, all_keys[i], search_crt, 1);
        if (rc != CKR_OK) {
            show_error(stdout, "C_GetAttributeValue", rc);
            return rc;
        }

        fprintf(stdout, "Handling key #%d with handle 0x%lx\n", i, all_keys[i]);
        dump_generic(stdout, "Key ID", id, search_crt[0].ulValueLen);

        rc = funcs->C_FindObjectsInit(h_session, search_crt, 2);
        if (rc != CKR_OK) {
            show_error(stdout, "C_FindObjectsInit", rc);
            return rc;
        }

        rc = funcs->C_FindObjects(h_session, &h_crt, 1, &crt_count);
        if (rc != CKR_OK) {
            show_error(stdout, "C_FindObjects", rc);
            return rc;
        }

        rc = funcs->C_FindObjectsFinal(h_session);
        if (rc != CKR_OK) {
            show_error(stdout, "C_FindObjectsFinal", rc);
            return rc;
        }

        if(crt_count == 0) {
            CK_OBJECT_CLASS pub = CKO_PUBLIC_KEY;
            CK_ATTRIBUTE search_pub[] = {
                { CKA_ID, &id, search_crt[0].ulValueLen },
                { CKA_CLASS, &pub, sizeof(pub)}
            };
            CK_OBJECT_HANDLE h_pub;
            CK_ULONG pub_count = 1;

            fprintf(stdout, "Didn't find matching certificate. Now looking for public key.\n");

            rc = funcs->C_FindObjectsInit(h_session, search_pub, 2);
            if (rc != CKR_OK) {
                show_error(stdout, "C_FindObjectsInit", rc);
                return rc;
            }

            rc = funcs->C_FindObjects(h_session, &h_pub, 1, &pub_count);
            if (rc != CKR_OK) {
                show_error(stdout, "C_FindObjects", rc);
                return rc;
            }

            rc = funcs->C_FindObjectsFinal(h_session);
            if (rc != CKR_OK) {
                show_error(stdout, "C_FindObjectsFinal", rc);
                return rc;
            }

            if(pub_count == 0) {
                fprintf(stdout, "Didn't find matching public key. Skipping\n");
            } else {
                if(!rw) {
                    fprintf(stdout, "Read-only mode: Found candidate private key and public key with handles 0x%lx 0x%lx\n",
                           all_keys[i], h_pub);
                } else {
                    fprintf(stdout, "Deleting private key and public key with handles 0x%lx 0x%lx\n", all_keys[i], h_pub);

                    rc = funcs->C_DestroyObject(h_session, all_keys[i]);
                    if (rc != CKR_OK) {
                        show_error(stdout, "C_DestroyObject", rc);
                    }

                    rc = funcs->C_DestroyObject(h_session, h_pub);
                    if (rc != CKR_OK) {
                        show_error(stdout, "C_DestroyObject", rc);
                    }
                    destroy += 2;
                }
            }
        } else {
            fprintf(stdout, "Found matching certificate\n");
        }

    }

    pkey = CKO_SECRET_KEY;
    rc = funcs->C_FindObjectsInit(h_session, search_all, 1);
    if (rc != CKR_OK) {
        show_error(stdout, "C_FindObjectsInit", rc);
        return rc;
    }

    key_count = sizeof(all_keys) / sizeof(CK_OBJECT_HANDLE);
    rc = funcs->C_FindObjects(h_session, all_keys, key_count, &key_count);
    if (rc != CKR_OK) {
        show_error(stdout, "C_FindObjects", rc);
        return rc;
    }

    rc = funcs->C_FindObjectsFinal(h_session);
    if (rc != CKR_OK) {
        show_error(stdout, "C_FindObjectsFinal", rc);
        return rc;
    }

    fprintf(stdout, "Found %lu secret keys\n", key_count);

    for(i = 0; i < key_count; i++) {
        rc = funcs->C_DestroyObject(h_session, all_keys[i]);
        if (rc != CKR_OK) {
            show_error(stdout, "C_DestroyObject", rc);
        }
        destroy += 1;
    }

    if(destroy > 0) {
        fprintf(stdout, "\nDeleted %d objects\n", destroy);
    }

    rc = pkcs11_close(stdout, funcs, h_session);
    return rc;
}
コード例 #3
0
ファイル: keygen.c プロジェクト: mbrossard/pkcs11
int keygen(int argc, char **argv)
{
    CK_ULONG          nslots, keysize;
    CK_SLOT_ID        *pslots = NULL;
    CK_FUNCTION_LIST  *funcs = NULL;
    CK_SESSION_HANDLE h_session;
    CK_BYTE_PTR       opt_label = NULL;
    CK_UTF8CHAR_PTR   opt_pin = NULL;
    CK_ULONG          opt_pin_len = 0;
    CK_ULONG          opt_slot = -1;
    CK_RV             rc;
    char *opt_module = NULL, *opt_dir = NULL;
    char *gen_param = NULL, *tmp;
    int long_optind = 0;
    int genkey = 0;
    char c;

    init_crypto();

    while (1) {
        c = getopt_long(argc, argv, "d:hl:p:s:k:m:",
                        options, &long_optind);
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                opt_dir = optarg;
                break;
            case 'l':
                opt_label = (CK_BYTE_PTR)optarg;
                break;
            case 'p':
                opt_pin = (CK_UTF8CHAR_PTR) strdup(optarg);
                if(opt_pin) {
                    opt_pin_len = strlen(optarg);
                }
                break;
            case 's':
                opt_slot = (CK_SLOT_ID) atoi(optarg);
                break;
            case 'm':
                opt_module = optarg;
                break;
            case 'k':
                gen_param = optarg;
                genkey = 1;
                break;
            case 'h':
            default:
                print_usage_and_die(app_name, options, option_help);
        }
    }

    if(!genkey) {
        print_usage_and_die(app_name, options, option_help);
    }

    rc = pkcs11_load_init(opt_module, opt_dir, stdout, &funcs);
    if (rc != CKR_OK) {
        return rc;
    }

    rc = pkcs11_get_slots(funcs, stdout, &pslots, &nslots);
    if (rc != CKR_OK) {
        return rc;
    }

    if(opt_slot != -1) {
        CK_ULONG i = 0;
        while (i < nslots && pslots[i] != opt_slot) {
            i++;
        }
        if (i == nslots) {
            fprintf(stderr, "Unknown slot '%lu'\n", opt_slot);
            return -1;            
        }
    } else {
        if(nslots == 1) {
            opt_slot = pslots[0];
        } else {
            fprintf(stdout, "Found %ld slots, use --slot parameter to choose.\n", nslots);
            exit(-1);
        }
    }

    rc = pkcs11_login_session(funcs, stdout, opt_slot, &h_session,
                              CK_TRUE, CKU_USER, opt_pin, opt_pin_len);
    free(opt_pin);
    if (rc != CKR_OK) {
        return rc;
    }

    fprintf(stdout, "Generating key with param '%s'\n", gen_param);
    keysize = strtol(gen_param, &tmp, 10);
    if(gen_param != tmp) {
        fprintf(stdout, "Generating RSA key with size %ld\n", keysize);
        rc = generateRsaKeyPair(funcs, h_session, keysize, opt_label);
    } else if(strncmp(gen_param, "gost", 4) == 0) {
        fprintf(stdout, "Generating GOST R34.10-2001 key (%s) in slot %ld\n",
                gen_param, opt_slot);
        rc = generateGostKeyPair(funcs, h_session, gen_param, opt_label);
    } else if((strncmp(gen_param, "secp", 4) == 0) ||
              (strncmp(gen_param, "nistp", 5) == 0) ||
              (strncmp(gen_param, "prime", 5) == 0) ||
              (strncmp(gen_param, "ansiX9", 6) == 0)) {
        CK_BBOOL full;
        rc = ecdsaNeedsEcParams(funcs, opt_slot, &full);
        if(rc == CKR_OK) {
            fprintf(stdout, "Generating ECDSA key with curve '%s' "
                    "in slot %ld with %s\n", gen_param, opt_slot,
                    full ? "EC Parameters" : "Named Curve");
            rc = generateEcdsaKeyPair(funcs, h_session, gen_param, full, opt_label);
        }
    } else if(strncmp(gen_param, "aes", 3) == 0) {
        if(strcmp(gen_param, "aes256") == 0) {
            fprintf(stdout, "Generating 256-bit AES key in slot %ld\n", opt_slot);
            generateKey(funcs, h_session, CKK_AES, CKM_AES_KEY_GEN, 256 / 8, opt_label);
        } else if(strcmp(gen_param, "aes192") == 0) {
            fprintf(stdout, "Generating 192-bit AES key in slot %ld\n", opt_slot);
            generateKey(funcs, h_session, CKK_AES, CKM_AES_KEY_GEN, 192 /8, opt_label);
        } else if((strcmp(gen_param, "aes128") == 0) ||
                  (strcmp(gen_param, "aes") == 0)) {
            fprintf(stdout, "Generating 128-bit AES key in slot %ld\n", opt_slot);
            generateKey(funcs, h_session, CKK_AES, CKM_AES_KEY_GEN, 128 / 8, opt_label);
        } else {
            fprintf(stdout, "Unknown key type '%s'\n", gen_param);
            return -1;
        }
    } else if(strncmp(gen_param, "des3", 4) == 0) {
        fprintf(stdout, "Generating 3DES key in slot %ld\n", opt_slot);
        generateKey(funcs, h_session, CKK_DES3, CKM_DES3_KEY_GEN, 0, opt_label);
    } else {
        fprintf(stdout, "Unknown key type '%s'\n", gen_param);
        return -1;
    }

    rc = pkcs11_close(stdout, funcs, h_session);
    return rc;
}