Exemple #1
0
static int
p11_list_keys(hx509_context context,
	      struct p11_module *p,
	      struct p11_slot *slot, 
	      CK_SESSION_HANDLE session,
	      hx509_lock lock,
	      hx509_certs *certs)
{
    struct hx509_collector *collector;
    CK_OBJECT_CLASS key_class;
    CK_ATTRIBUTE search_data[] = {
	{CKA_CLASS, NULL, 0},
    };
    CK_ATTRIBUTE query_data[3] = {
	{CKA_ID, NULL, 0},
	{CKA_VALUE, NULL, 0},
	{CKA_LABEL, NULL, 0}
    };
    int ret;

    search_data[0].pValue = &key_class;
    search_data[0].ulValueLen = sizeof(key_class);

    if (lock == NULL)
	lock = _hx509_empty_lock;

    ret = _hx509_collector_alloc(context, lock, &collector);
    if (ret)
	return ret;

    key_class = CKO_PRIVATE_KEY;
    ret = iterate_entries(context, p, slot, session,
			  search_data, 1,
			  query_data, 1,
			  collect_private_key, collector);
    if (ret)
	goto out;

    key_class = CKO_CERTIFICATE;
    ret = iterate_entries(context, p, slot, session,
			  search_data, 1,
			  query_data, 3,
			  collect_cert, collector);
    if (ret)
	goto out;

    ret = _hx509_collector_collect_certs(context, collector, &slot->certs);

out:
    _hx509_collector_free(collector);

    return ret;
}
Exemple #2
0
static int
file_init_common(hx509_context context,
		 hx509_certs certs, void **data, int flags,
		 const char *residue, hx509_lock lock, outformat format)
{
    char *p, *pnext;
    struct ks_file *f = NULL;
    hx509_private_key *keys = NULL;
    int ret;
    struct pem_ctx pem_ctx;

    pem_ctx.flags = flags;
    pem_ctx.c = NULL;

    *data = NULL;

    if (lock == NULL)
	lock = _hx509_empty_lock;

    f = calloc(1, sizeof(*f));
    if (f == NULL) {
	hx509_clear_error_string(context);
	return ENOMEM;
    }
    f->format = format;

    f->fn = strdup(residue);
    if (f->fn == NULL) {
	hx509_clear_error_string(context);
	ret = ENOMEM;
	goto out;
    }

    /*
     * XXX this is broken, the function should parse the file before
     * overwriting it
     */

    if (flags & HX509_CERTS_CREATE) {
	ret = hx509_certs_init(context, "MEMORY:ks-file-create",
			       0, lock, &f->certs);
	if (ret)
	    goto out;
	*data = f;
	return 0;
    }

    ret = _hx509_collector_alloc(context, lock, &pem_ctx.c);
    if (ret)
	goto out;

    for (p = f->fn; p != NULL; p = pnext) {
	FILE *f;

	pnext = strchr(p, ',');
	if (pnext)
	    *pnext++ = '\0';
	

	if ((f = fopen(p, "r")) == NULL) {
	    ret = ENOENT;
	    hx509_set_error_string(context, 0, ret,
				   "Failed to open PEM file \"%s\": %s",
				   p, strerror(errno));
	    goto out;
	}
	rk_cloexec_file(f);

	ret = hx509_pem_read(context, f, pem_func, &pem_ctx);
	fclose(f);		
	if (ret != 0 && ret != HX509_PARSING_KEY_FAILED)
	    goto out;
	else if (ret == HX509_PARSING_KEY_FAILED) {
	    size_t length;
	    void *ptr;
	    int i;

	    ret = rk_undumpdata(p, &ptr, &length);
	    if (ret) {
		hx509_clear_error_string(context);
		goto out;
	    }

	    for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) {
		ret = (*formats[i].func)(context, p, pem_ctx.c, NULL, ptr, length);
		if (ret == 0)
		    break;
	    }
	    rk_xfree(ptr);
	    if (ret)
		goto out;
	}
    }

    ret = _hx509_collector_collect_certs(context, pem_ctx.c, &f->certs);
    if (ret)
	goto out;

    ret = _hx509_collector_collect_private_keys(context, pem_ctx.c, &keys);
    if (ret == 0) {
	int i;

	for (i = 0; keys[i]; i++)
	    _hx509_certs_keys_add(context, f->certs, keys[i]);
	_hx509_certs_keys_free(context, keys);
    }

out:
    if (ret == 0)
	*data = f;
    else {
	if (f->fn)
	    free(f->fn);
	free(f);
    }
    if (pem_ctx.c)
	_hx509_collector_free(pem_ctx.c);

    return ret;
}
Exemple #3
0
static int
p12_init(hx509_context context,
	 hx509_certs certs, void **data, int flags,
	 const char *residue, hx509_lock lock)
{
    struct ks_pkcs12 *p12;
    size_t len;
    void *buf;
    PKCS12_PFX pfx;
    PKCS12_AuthenticatedSafe as;
    int ret;
    size_t i;
    struct hx509_collector *c;

    *data = NULL;

    if (lock == NULL)
	lock = _hx509_empty_lock;

    ret = _hx509_collector_alloc(context, lock, &c);
    if (ret)
	return ret;

    p12 = calloc(1, sizeof(*p12));
    if (p12 == NULL) {
	ret = ENOMEM;
	hx509_set_error_string(context, 0, ret, "out of memory");
	goto out;
    }

    p12->fn = strdup(residue);
    if (p12->fn == NULL) {
	ret = ENOMEM;
	hx509_set_error_string(context, 0, ret, "out of memory");
	goto out;
    }

    if (flags & HX509_CERTS_CREATE) {
	ret = hx509_certs_init(context, "MEMORY:ks-file-create",
			       0, lock, &p12->certs);
	if (ret == 0)
	    *data = p12;
	goto out;
    }

    ret = rk_undumpdata(residue, &buf, &len);
    if (ret) {
	hx509_clear_error_string(context);
	goto out;
    }

    ret = decode_PKCS12_PFX(buf, len, &pfx, NULL);
    rk_xfree(buf);
    if (ret) {
	hx509_set_error_string(context, 0, ret,
			       "Failed to decode the PFX in %s", residue);
	goto out;
    }

    if (der_heim_oid_cmp(&pfx.authSafe.contentType, &asn1_oid_id_pkcs7_data) != 0) {
	free_PKCS12_PFX(&pfx);
	ret = EINVAL;
	hx509_set_error_string(context, 0, ret,
			       "PKCS PFX isn't a pkcs7-data container");
	goto out;
    }

    if (pfx.authSafe.content == NULL) {
	free_PKCS12_PFX(&pfx);
	ret = EINVAL;
	hx509_set_error_string(context, 0, ret,
			       "PKCS PFX missing data");
	goto out;
    }

    {
	heim_octet_string asdata;

	ret = decode_PKCS12_OctetString(pfx.authSafe.content->data,
					pfx.authSafe.content->length,
					&asdata,
					NULL);
	free_PKCS12_PFX(&pfx);
	if (ret) {
	    hx509_clear_error_string(context);
	    goto out;
	}
	ret = decode_PKCS12_AuthenticatedSafe(asdata.data,
					      asdata.length,
					      &as,
					      NULL);
	der_free_octet_string(&asdata);
	if (ret) {
	    hx509_clear_error_string(context);
	    goto out;
	}
    }

    for (i = 0; i < as.len; i++)
	parse_pkcs12_type(context,
			  c,
			  &as.val[i].contentType,
			  as.val[i].content->data,
			  as.val[i].content->length,
			  NULL);

    free_PKCS12_AuthenticatedSafe(&as);

    ret = _hx509_collector_collect_certs(context, c, &p12->certs);
    if (ret == 0)
	*data = p12;

out:
    _hx509_collector_free(c);

    if (ret && p12) {
	if (p12->fn)
	    free(p12->fn);
	if (p12->certs)
	    hx509_certs_free(&p12->certs);
	free(p12);
    }

    return ret;
}