Exemple #1
0
static int
load_crl(const char *path, time_t *t, CRLCertificateList *crl)
{
    size_t length, size;
    struct stat sb;
    void *data;
    int ret;

    memset(crl, 0, sizeof(*crl));

    ret = rk_undumpdata(path, &data, &length);
    if (ret)
	return ret;

    ret = stat(path, &sb);
    if (ret)
	return errno;

    *t = sb.st_mtime;

    ret = decode_CRLCertificateList(data, length, crl, &size);
    rk_xfree(data);
    if (ret)
	return ret;

    /* check signature is aligned */
    if (crl->signatureValue.length & 7) {
	free_CRLCertificateList(crl);
	return HX509_CRYPTO_SIG_INVALID_FORMAT;
    }
    return 0;
}
Exemple #2
0
void
_hx509_unmap_file_os(heim_octet_string *os)
{
    rk_xfree(os->data);
}
Exemple #3
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 #4
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;
}
Exemple #5
0
int
_hx509_request_parse(hx509_context context,
		     const char *path,
		     hx509_request *req)
{
    CertificationRequest r;
    CertificationRequestInfo *rinfo;
    hx509_name subject;
    size_t len, size;
    void *p;
    int ret;

    if (strncmp(path, "PKCS10:", 7) != 0) {
	hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION,
			       "unsupport type in %s", path);
	return HX509_UNSUPPORTED_OPERATION;
    }
    path += 7;

    /* XXX PEM request */

    ret = rk_undumpdata(path, &p, &len);
    if (ret) {
	hx509_set_error_string(context, 0, ret, "Failed to map file %s", path);
	return ret;
    }

    ret = decode_CertificationRequest(p, len, &r, &size);
    rk_xfree(p);
    if (ret) {
	hx509_set_error_string(context, 0, ret, "Failed to decode %s", path);
	return ret;
    }

    ret = _hx509_request_init(context, req);
    if (ret) {
	free_CertificationRequest(&r);
	return ret;
    }

    rinfo = &r.certificationRequestInfo;

    ret = _hx509_request_set_SubjectPublicKeyInfo(context, *req,
						  &rinfo->subjectPKInfo);
    if (ret) {
	free_CertificationRequest(&r);
	_hx509_request_free(req);
	return ret;
    }

    ret = _hx509_name_from_Name(&rinfo->subject, &subject);
    if (ret) {
	free_CertificationRequest(&r);
	_hx509_request_free(req);
	return ret;
    }
    ret = _hx509_request_set_name(context, *req, subject);
    hx509_name_free(&subject);
    free_CertificationRequest(&r);
    if (ret) {
	_hx509_request_free(req);
	return ret;
    }

    return 0;
}
Exemple #6
0
static int
load_ocsp(hx509_context context, struct revoke_ocsp *ocsp)
{
    OCSPBasicOCSPResponse basic;
    hx509_certs certs = NULL;
    size_t length;
    struct stat sb;
    void *data;
    int ret;

    ret = rk_undumpdata(ocsp->path, &data, &length);
    if (ret)
	return ret;

    ret = stat(ocsp->path, &sb);
    if (ret)
	return errno;

    ret = parse_ocsp_basic(data, length, &basic);
    rk_xfree(data);
    if (ret) {
	hx509_set_error_string(context, 0, ret,
			       "Failed to parse OCSP response");
	return ret;
    }

    if (basic.certs) {
	size_t i;

	ret = hx509_certs_init(context, "MEMORY:ocsp-certs", 0,
			       NULL, &certs);
	if (ret) {
	    free_OCSPBasicOCSPResponse(&basic);
	    return ret;
	}

	for (i = 0; i < basic.certs->len; i++) {
	    hx509_cert c;

	    ret = hx509_cert_init(context, &basic.certs->val[i], &c);
	    if (ret)
		continue;

	    ret = hx509_certs_add(context, certs, c);
	    hx509_cert_free(c);
	    if (ret)
		continue;
	}
    }

    ocsp->last_modfied = sb.st_mtime;

    free_OCSPBasicOCSPResponse(&ocsp->ocsp);
    hx509_certs_free(&ocsp->certs);
    hx509_cert_free(ocsp->signer);

    ocsp->ocsp = basic;
    ocsp->certs = certs;
    ocsp->signer = NULL;

    return 0;
}