CK_RV C_Initialize(CK_VOID_PTR a) { CK_C_INITIALIZE_ARGS_PTR args = a; gpkcs11_log("Initialize\n"); int i; CK_RV ret; DIR *dir = NULL; struct dirent *file; char *label, *cadir; if (a != NULL_PTR) { gpkcs11_log("\tCreateMutex:\t%p\n", args->CreateMutex); gpkcs11_log("\tDestroyMutext\t%p\n", args->DestroyMutex); gpkcs11_log("\tLockMutext\t%p\n", args->LockMutex); gpkcs11_log("\tUnlockMutext\t%p\n", args->UnlockMutex); gpkcs11_log("\tFlags\t%04x\n", (unsigned int)args->flags); } ret = gpkcs11_init_token(IGTF_MODULE_VERSION, "IGTF Approved Anchors", &gpkcs11_soft_token); if (ret) return ret; /* prevent from asking for a pin */ gpkcs11_soft_token.flags.login_done = 1; cadir = getenv("X509_CERT_DIR"); if (cadir == NULL) cadir = "/etc/grid-security/certificates"; chdir(cadir); dir = opendir(cadir); if (dir == NULL) { gpkcs11_log("Failed to open cert dir: %s\n", strerror(errno)); return CKR_FUNCTION_FAILED; } i = 1; while ((file = readdir(dir))) { if (file->d_name == NULL || strlen(file->d_name) != 10 || strcmp(file->d_name + 8, ".0") != 0) continue; asprintf(&label, "IGTF CA #%d", i++); gpkcs11_add_credentials(label, file->d_name, NULL, label, 1); free(label); } closedir(dir); return CKR_OK; }
CK_RV get_myproxy_creds(char *server, char *username, char *password, char **creds) { myproxy_socket_attrs_t *socket_attrs = NULL; myproxy_request_t *client_request = NULL; myproxy_response_t *server_response = NULL; char *request_buffer = NULL; char creds_file[MAXPATHLEN]; int ret, requestlen; verror_clear(); socket_attrs = malloc(sizeof(*socket_attrs)); if (socket_attrs == NULL) { ret = CKR_DEVICE_MEMORY; goto end; } memset(socket_attrs, 0, sizeof(*socket_attrs)); client_request = malloc(sizeof(*client_request)); if (client_request == NULL) { ret = CKR_DEVICE_MEMORY; goto end; } memset(client_request, 0, sizeof(*client_request)); server_response = malloc(sizeof(*server_response)); if (server_response == NULL) { ret = CKR_DEVICE_MEMORY; goto end; } memset(server_response, 0, sizeof(*server_response)); socket_attrs->psport = MYPROXY_SERVER_PORT; socket_attrs->pshost = strdup(server); if (socket_attrs->pshost == NULL) { ret = CKR_DEVICE_MEMORY; goto end; } ret = myproxy_init_client(socket_attrs); if (ret < 0) { gpkcs11_log("Error contacting MyProxy server %s: %s\n", socket_attrs->pshost, verror_get_string()); ret = CKR_GENERAL_ERROR; goto end; } GSI_SOCKET_allow_anonymous(socket_attrs->gsi_socket, 1); ret = myproxy_authenticate_init(socket_attrs, NULL); if (ret < 0) { gpkcs11_log("Error authenticating MyProxy server %s: %s\n", socket_attrs->pshost, verror_get_string()); ret = CKR_GENERAL_ERROR; goto end; } client_request->version = strdup(MYPROXY_VERSION); client_request->command_type = MYPROXY_RETRIEVE_CERT; strncpy(client_request->passphrase, password, sizeof(client_request->passphrase)); client_request->username = strdup(username); requestlen = myproxy_serialize_request_ex(client_request, &request_buffer); if (requestlen < 0) { gpkcs11_log("Error preparing MyProxy request: %s\n", verror_get_string()); ret = CKR_GENERAL_ERROR; goto end; } ret = myproxy_send(socket_attrs, request_buffer, requestlen); free(request_buffer); if (ret < 0) { gpkcs11_log("Error sending MyProxy request: %s\n", verror_get_string()); ret = CKR_GENERAL_ERROR; goto end; } ret = myproxy_recv_response_ex(socket_attrs, server_response, client_request); if (ret != 0) { gpkcs11_log("Error receiving MyProxy response: %s\n", verror_get_string()); ret = CKR_GENERAL_ERROR; goto end; } ret = myproxy_accept_credentials(socket_attrs, creds_file, sizeof(creds_file)); if (ret < 0) { gpkcs11_log("Error receiving credentials: %s\n", verror_get_string()); ret = CKR_GENERAL_ERROR; goto end; } *creds = strdup(creds_file); if (*creds == NULL) { ret = CKR_DEVICE_MEMORY; goto end; } ret = 0; end: if (socket_attrs && socket_attrs->socket_fd) close(socket_attrs->socket_fd); myproxy_free(socket_attrs, client_request, server_response); verror_clear(); return ret; }
CK_RV gpkcs11_add_credentials(char *label, const char *cert_file, const char *private_key_file, char *id, int anchor) { struct gpkcs11_st_object *o = NULL; CK_BBOOL bool_true = CK_TRUE; CK_BBOOL bool_false = CK_FALSE; CK_OBJECT_CLASS c; CK_CERTIFICATE_TYPE cert_type = CKC_X_509; CK_KEY_TYPE key_type; CK_MECHANISM_TYPE mech_type; CK_RV ret = CKR_GENERAL_ERROR; void *subject_data = NULL; size_t subject_length; X509 *cert, *proxy_cert = NULL; EVP_PKEY *public_key; FILE *f = NULL; size_t id_len = strlen(id); f = fopen(cert_file, "r"); if (f == NULL) { gpkcs11_log("failed to open file %s\n", cert_file); return CKR_GENERAL_ERROR; } while (1) { cert = PEM_read_X509(f, NULL, NULL, NULL); if (cert == NULL) { if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) break; ret = CKR_GENERAL_ERROR; goto out; } if (proxy_cert == NULL) proxy_cert = cert; ret = gpkcs11_add_certificate(label, cert, id, anchor); if (ret) goto out; } public_key = X509_get_pubkey(proxy_cert); switch (EVP_PKEY_type(public_key->type)) { case EVP_PKEY_RSA: key_type = CKK_RSA; break; case EVP_PKEY_DSA: key_type = CKK_DSA; break; default: /* XXX */ break; } OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length, X509_get_subject_name(proxy_cert), ret); if (ret) goto out; if (private_key_file) { CK_FLAGS flags; FILE *f; o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->type = STO_T_PRIVATE_KEY; o->u.private_key.file = strdup(private_key_file); o->u.private_key.key = NULL; o->u.private_key.cert = proxy_cert; c = CKO_PRIVATE_KEY; add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false)); add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); add_object_attribute(o, 0, CKA_ID, id, id_len); add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); mech_type = CKM_RSA_X_509; add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true)); flags = 0; add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags)); add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false)); add_pubkey_info(o, key_type, public_key); f = fopen(private_key_file, "r"); if (f == NULL) { gpkcs11_log("failed to open private key\n"); return CKR_GENERAL_ERROR; } o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL); fclose(f); if (o->u.private_key.key == NULL) { gpkcs11_log("failed to read private key a startup\n"); /* don't bother with this failure for now, fix it at C_Login time */; } else { /* XXX verify keytype */ if (key_type == CKK_RSA) RSA_set_method(o->u.private_key.key->pkey.rsa, RSA_PKCS1_SSLeay()); if (X509_check_private_key(proxy_cert, o->u.private_key.key) != 1) { EVP_PKEY_free(o->u.private_key.key); o->u.private_key.key = NULL; gpkcs11_log("private key doesn't verify\n"); } else { gpkcs11_log("private key usable\n"); gpkcs11_soft_token.flags.login_done = 1; } } } ret = CKR_OK; out: if (ret != CKR_OK) { gpkcs11_log("something went wrong when adding cert!\n"); /* XXX wack o */; } if (f) fclose(f); return ret; }
static CK_RV func_not_supported(void) { gpkcs11_log("function not supported\n"); return CKR_FUNCTION_NOT_SUPPORTED; }
CK_RV gpkcs11_add_certificate(char *label, X509 *cert, char *id, int anchor) { struct gpkcs11_st_object *o = NULL; void *cert_data = NULL; size_t cert_length; void *subject_data = NULL; size_t subject_length; void *issuer_data = NULL; size_t issuer_length; void *serial_data = NULL; size_t serial_length; EVP_PKEY *public_key; unsigned char sha1[SHA_DIGEST_LENGTH]; CK_TRUST trust_ca = CKT_NSS_TRUSTED_DELEGATOR; int ret; CK_BBOOL bool_true = CK_TRUE; CK_BBOOL bool_false = CK_FALSE; CK_OBJECT_CLASS c; CK_CERTIFICATE_TYPE cert_type = CKC_X_509; CK_KEY_TYPE key_type; CK_MECHANISM_TYPE mech_type; size_t id_len = strlen(id); OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret); if (ret) goto out; OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length, X509_get_issuer_name(cert), ret); if (ret) goto out; OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length, X509_get_subject_name(cert), ret); if (ret) goto out; OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length, X509_get_serialNumber(cert), ret); if (ret) goto out; gpkcs11_log("done parsing, adding to internal structure\n"); o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->type = STO_T_CERTIFICATE; o->u.cert = cert; public_key = X509_get_pubkey(o->u.cert); switch (EVP_PKEY_type(public_key->type)) { case EVP_PKEY_RSA: key_type = CKK_RSA; break; case EVP_PKEY_DSA: key_type = CKK_DSA; break; default: /* XXX */ break; } c = CKO_CERTIFICATE; add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type)); add_object_attribute(o, 0, CKA_ID, id, id_len); add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length); add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length); add_object_attribute(o, 0, CKA_VALUE, cert_data, cert_length); if (anchor) add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); else add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false)); gpkcs11_log("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o)); if (anchor) { o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->type = STO_T_NETSCAPE_TRUST; c = CKO_NETSCAPE_TRUST; add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); add_object_attribute(o, 0, CKA_LABEL, "IGTF CA Trust", 13); add_object_attribute(o, 0, CKA_ID, id, id_len); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length); add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length); EVP_Digest(cert_data, cert_length, sha1, NULL, EVP_sha1(), NULL); add_object_attribute(o, 0, CKA_CERT_SHA1_HASH, sha1, sizeof(sha1)); add_object_attribute(o, 0, CKA_TRUST_SERVER_AUTH, &trust_ca, sizeof(trust_ca)); add_object_attribute(o, 0, CKA_TRUST_CLIENT_AUTH, &trust_ca, sizeof(trust_ca)); add_object_attribute(o, 0, CKA_TRUST_CODE_SIGNING, &trust_ca, sizeof(trust_ca)); add_object_attribute(o, 0, CKA_TRUST_EMAIL_PROTECTION, &trust_ca, sizeof(trust_ca)); gpkcs11_log("add Netscape trust object: %lx\n", (unsigned long)OBJECT_ID(o)); } o = add_st_object(); if (o == NULL) { ret = CKR_DEVICE_MEMORY; goto out; } o->type = STO_T_PUBLIC_KEY; o->u.public_key = public_key; c = CKO_PUBLIC_KEY; add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c)); add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LABEL, label, strlen(label)); add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type)); add_object_attribute(o, 0, CKA_ID, id, id_len); add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */ add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */ add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false)); mech_type = CKM_RSA_X_509; add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type)); add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length); add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false)); add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true)); add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true)); add_pubkey_info(o, key_type, public_key); gpkcs11_log("add key ok: %lx\n", (unsigned long)OBJECT_ID(o)); ret = CKR_OK; out: free(cert_data); free(serial_data); free(issuer_data); free(subject_data); return ret; }