Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
static CK_RV
func_not_supported(void)
{
	gpkcs11_log("function not supported\n");
	return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 5
0
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;
}