示例#1
0
文件: softp11.c 项目: heimdal/heimdal
static CK_RV
add_certificate(const char *cert_file,
		const char *pin,
		char *id,
		char *label)
{
    hx509_certs certs;
    hx509_lock lock = NULL;
    int ret, flags = 0;

    struct foo foo;
    foo.id = id;
    foo.label = label;

    if (pin == NULL)
	flags |= HX509_CERTS_UNPROTECT_ALL;

    if (pin) {
	char *str;
	ret = asprintf(&str, "PASS:%s", pin);
	if (ret == -1 || !str) {
	    st_logf("failed to allocate memory\n");
	    return CKR_GENERAL_ERROR;
	}

	hx509_lock_init(context, &lock);
	hx509_lock_command_string(lock, str);

	memset(str, 0, strlen(str));
	free(str);
    }

    ret = hx509_certs_init(context, cert_file, flags, lock, &certs);
    if (ret) {
	st_logf("failed to open file %s\n", cert_file);
	return CKR_GENERAL_ERROR;
    }

    ret = hx509_certs_iter_f(context, certs, add_cert, &foo);
    hx509_certs_free(&certs);
    if (ret) {
	st_logf("failed adding certs from file %s\n", cert_file);
	return CKR_GENERAL_ERROR;
    }

    return CKR_OK;
}
示例#2
0
static int
file_store(hx509_context context,
	   hx509_certs certs, void *data, int flags, hx509_lock lock)
{
    struct ks_file *ksf = data;
    struct store_ctx sc;
    int ret;

    sc.f = fopen(ksf->fn, "w");
    if (sc.f == NULL) {
	hx509_set_error_string(context, 0, ENOENT,
			       "Failed to open file %s for writing");
	return ENOENT;
    }
    rk_cloexec_file(sc.f);
    sc.format = ksf->format;

    ret = hx509_certs_iter_f(context, ksf->certs, store_func, &sc);
    fclose(sc.f);
    return ret;
}
示例#3
0
文件: cms.c 项目: InvLim/heimdal
int
hx509_cms_create_signed(hx509_context context,
			int flags,
			const heim_oid *eContentType,
			const void *data, size_t length,
			const AlgorithmIdentifier *digest_alg,
			hx509_certs certs,
			hx509_peer_info peer,
			hx509_certs anchors,
			hx509_certs pool,
			heim_octet_string *signed_data)
{
    unsigned int i, j;
    hx509_name name;
    int ret;
    size_t size;
    struct sigctx sigctx;

    memset(&sigctx, 0, sizeof(sigctx));
    memset(&name, 0, sizeof(name));

    if (eContentType == NULL)
	eContentType = &asn1_oid_id_pkcs7_data;

    sigctx.digest_alg = digest_alg;
    sigctx.content.data = rk_UNCONST(data);
    sigctx.content.length = length;
    sigctx.eContentType = eContentType;
    sigctx.peer = peer;
    /**
     * Use HX509_CMS_SIGNATURE_ID_NAME to preferred use of issuer name
     * and serial number if possible. Otherwise subject key identifier
     * will preferred.
     */
    if (flags & HX509_CMS_SIGNATURE_ID_NAME)
	sigctx.cmsidflag = CMS_ID_NAME;
    else
	sigctx.cmsidflag = CMS_ID_SKI;

    /**
     * Use HX509_CMS_SIGNATURE_LEAF_ONLY to only request leaf
     * certificates to be added to the SignedData.
     */
    sigctx.leafonly = (flags & HX509_CMS_SIGNATURE_LEAF_ONLY) ? 1 : 0;

    /**
     * Use HX509_CMS_NO_CERTS to make the SignedData contain no
     * certificates, overrides HX509_CMS_SIGNATURE_LEAF_ONLY.
     */

    if ((flags & HX509_CMS_SIGNATURE_NO_CERTS) == 0) {
	ret = hx509_certs_init(context, "MEMORY:certs", 0, NULL, &sigctx.certs);
	if (ret)
	    return ret;
    }

    sigctx.anchors = anchors;
    sigctx.pool = pool;

    sigctx.sd.version = CMSVersion_v3;

    der_copy_oid(eContentType, &sigctx.sd.encapContentInfo.eContentType);

    /**
     * Use HX509_CMS_SIGNATURE_DETACHED to create detached signatures.
     */
    if ((flags & HX509_CMS_SIGNATURE_DETACHED) == 0) {
	ALLOC(sigctx.sd.encapContentInfo.eContent, 1);
	if (sigctx.sd.encapContentInfo.eContent == NULL) {
	    hx509_clear_error_string(context);
	    ret = ENOMEM;
	    goto out;
	}

	sigctx.sd.encapContentInfo.eContent->data = malloc(length);
	if (sigctx.sd.encapContentInfo.eContent->data == NULL) {
	    hx509_clear_error_string(context);
	    ret = ENOMEM;
	    goto out;
	}
	memcpy(sigctx.sd.encapContentInfo.eContent->data, data, length);
	sigctx.sd.encapContentInfo.eContent->length = length;
    }

    /**
     * Use HX509_CMS_SIGNATURE_NO_SIGNER to create no sigInfo (no
     * signatures).
     */
    if ((flags & HX509_CMS_SIGNATURE_NO_SIGNER) == 0) {
	ret = hx509_certs_iter_f(context, certs, sig_process, &sigctx);
	if (ret)
	    goto out;
    }

    if (sigctx.sd.signerInfos.len) {

	/*
	 * For each signerInfo, collect all different digest types.
	 */
	for (i = 0; i < sigctx.sd.signerInfos.len; i++) {
	    AlgorithmIdentifier *di =
		&sigctx.sd.signerInfos.val[i].digestAlgorithm;

	    for (j = 0; j < sigctx.sd.digestAlgorithms.len; j++)
		if (cmp_AlgorithmIdentifier(di, &sigctx.sd.digestAlgorithms.val[j]) == 0)
		    break;
	    if (j == sigctx.sd.digestAlgorithms.len) {
		ret = add_DigestAlgorithmIdentifiers(&sigctx.sd.digestAlgorithms, di);
		if (ret) {
		    hx509_clear_error_string(context);
		    goto out;
		}
	    }
	}
    }

    /*
     * Add certs we think are needed, build as part of sig_process
     */
    if (sigctx.certs) {
	ALLOC(sigctx.sd.certificates, 1);
	if (sigctx.sd.certificates == NULL) {
	    hx509_clear_error_string(context);
	    ret = ENOMEM;
	    goto out;
	}

	ret = hx509_certs_iter_f(context, sigctx.certs, cert_process, &sigctx);
	if (ret)
	    goto out;
    }

    ASN1_MALLOC_ENCODE(SignedData,
		       signed_data->data, signed_data->length,
		       &sigctx.sd, &size, ret);
    if (ret) {
	hx509_clear_error_string(context);
	goto out;
    }
    if (signed_data->length != size)
	_hx509_abort("internal ASN.1 encoder error");

out:
    hx509_certs_free(&sigctx.certs);
    free_SignedData(&sigctx.sd);

    return ret;
}
示例#4
0
static int
p12_store(hx509_context context,
	  hx509_certs certs, void *data, int flags, hx509_lock lock)
{
    struct ks_pkcs12 *p12 = data;
    PKCS12_PFX pfx;
    PKCS12_AuthenticatedSafe as;
    PKCS12_OctetString asdata;
    size_t size;
    int ret;

    memset(&as, 0, sizeof(as));
    memset(&pfx, 0, sizeof(pfx));

    ret = hx509_certs_iter_f(context, p12->certs, store_func, &as);
    if (ret)
	goto out;

    ASN1_MALLOC_ENCODE(PKCS12_AuthenticatedSafe, asdata.data, asdata.length,
		       &as, &size, ret);
    free_PKCS12_AuthenticatedSafe(&as);
    if (ret)
	return ret;

    ret = der_parse_hex_heim_integer("03", &pfx.version);
    if (ret) {
	free(asdata.data);
	goto out;
    }

    pfx.authSafe.content = calloc(1, sizeof(*pfx.authSafe.content));

    ASN1_MALLOC_ENCODE(PKCS12_OctetString,
		       pfx.authSafe.content->data,
		       pfx.authSafe.content->length,
		       &asdata, &size, ret);
    free(asdata.data);
    if (ret)
	goto out;

    ret = der_copy_oid(&asn1_oid_id_pkcs7_data, &pfx.authSafe.contentType);
    if (ret)
	goto out;

    ASN1_MALLOC_ENCODE(PKCS12_PFX, asdata.data, asdata.length,
		       &pfx, &size, ret);
    if (ret)
	goto out;

#if 0
    const struct _hx509_password *pw;

    pw = _hx509_lock_get_passwords(lock);
    if (pw != NULL) {
	pfx.macData = calloc(1, sizeof(*pfx.macData));
	if (pfx.macData == NULL) {
	    ret = ENOMEM;
	    hx509_set_error_string(context, 0, ret, "malloc out of memory");
	    return ret;
	}
	if (pfx.macData == NULL) {
	    free(asdata.data);
	    goto out;
	}
    }
    ret = calculate_hash(&aspath, pw, pfx.macData);
#endif

    rk_dumpdata(p12->fn, asdata.data, asdata.length);
    free(asdata.data);

out:
    free_PKCS12_AuthenticatedSafe(&as);
    free_PKCS12_PFX(&pfx);

    return ret;
}
示例#5
0
文件: revoke.c 项目: Henauxg/minix
int
hx509_ocsp_request(hx509_context context,
		   hx509_certs reqcerts,
		   hx509_certs pool,
		   hx509_cert signer,
		   const AlgorithmIdentifier *digest,
		   heim_octet_string *request,
		   heim_octet_string *nonce)
{
    OCSPRequest req;
    size_t size;
    int ret;
    struct ocsp_add_ctx ctx;
    Extensions *es;

    memset(&req, 0, sizeof(req));

    if (digest == NULL)
	digest = _hx509_crypto_default_digest_alg;

    ctx.req = &req.tbsRequest;
    ctx.certs = pool;
    ctx.digest = digest;
    ctx.parent = NULL;

    ret = hx509_certs_iter_f(context, reqcerts, add_to_req, &ctx);
    hx509_cert_free(ctx.parent);
    if (ret)
	goto out;

    if (nonce) {
	req.tbsRequest.requestExtensions =
	    calloc(1, sizeof(*req.tbsRequest.requestExtensions));
	if (req.tbsRequest.requestExtensions == NULL) {
	    ret = ENOMEM;
	    goto out;
	}

	es = req.tbsRequest.requestExtensions;

	es->val = calloc(es->len, sizeof(es->val[0]));
	if (es->val == NULL) {
	    ret = ENOMEM;
	    goto out;
	}
	es->len = 1;
	ret = der_copy_oid(&asn1_oid_id_pkix_ocsp_nonce, &es->val[0].extnID);
	if (ret) {
	    free_OCSPRequest(&req);
	    return ret;
	}

	es->val[0].extnValue.data = malloc(10);
	if (es->val[0].extnValue.data == NULL) {
	    ret = ENOMEM;
	    goto out;
	}
	es->val[0].extnValue.length = 10;

	ret = RAND_bytes(es->val[0].extnValue.data,
			 es->val[0].extnValue.length);
	if (ret != 1) {
	    ret = HX509_CRYPTO_INTERNAL_ERROR;
	    goto out;
	}
	ret = der_copy_octet_string(nonce, &es->val[0].extnValue);
	if (ret) {
	    ret = ENOMEM;
	    goto out;
	}
    }

    ASN1_MALLOC_ENCODE(OCSPRequest, request->data, request->length,
		       &req, &size, ret);
    free_OCSPRequest(&req);
    if (ret)
	goto out;
    if (size != request->length)
	_hx509_abort("internal ASN.1 encoder error");

    return 0;

out:
    free_OCSPRequest(&req);
    return ret;
}
示例#6
0
文件: revoke.c 项目: Henauxg/minix
int
hx509_crl_sign(hx509_context context,
	       hx509_cert signer,
	       hx509_crl crl,
	       heim_octet_string *os)
{
    const AlgorithmIdentifier *sigalg = _hx509_crypto_default_sig_alg;
    CRLCertificateList c;
    size_t size;
    int ret;
    hx509_private_key signerkey;

    memset(&c, 0, sizeof(c));

    signerkey = _hx509_cert_private_key(signer);
    if (signerkey == NULL) {
	ret = HX509_PRIVATE_KEY_MISSING;
	hx509_set_error_string(context, 0, ret,
			       "Private key missing for CRL signing");
	return ret;
    }

    c.tbsCertList.version = malloc(sizeof(*c.tbsCertList.version));
    if (c.tbsCertList.version == NULL) {
	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
	return ENOMEM;
    }

    *c.tbsCertList.version = 1;

    ret = copy_AlgorithmIdentifier(sigalg, &c.tbsCertList.signature);
    if (ret) {
	hx509_clear_error_string(context);
	goto out;
    }

    ret = copy_Name(&_hx509_get_cert(signer)->tbsCertificate.issuer,
		    &c.tbsCertList.issuer);
    if (ret) {
	hx509_clear_error_string(context);
	goto out;
    }

    c.tbsCertList.thisUpdate.element = choice_Time_generalTime;
    c.tbsCertList.thisUpdate.u.generalTime = time(NULL) - 24 * 3600;

    c.tbsCertList.nextUpdate = malloc(sizeof(*c.tbsCertList.nextUpdate));
    if (c.tbsCertList.nextUpdate == NULL) {
	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
	ret = ENOMEM;
	goto out;
    }

    {
	time_t next = crl->expire;
	if (next == 0)
	    next = time(NULL) + 24 * 3600 * 365;

	c.tbsCertList.nextUpdate->element = choice_Time_generalTime;
	c.tbsCertList.nextUpdate->u.generalTime = next;
    }

    c.tbsCertList.revokedCertificates =
	calloc(1, sizeof(*c.tbsCertList.revokedCertificates));
    if (c.tbsCertList.revokedCertificates == NULL) {
	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
	ret = ENOMEM;
	goto out;
    }
    c.tbsCertList.crlExtensions = NULL;

    ret = hx509_certs_iter_f(context, crl->revoked, add_revoked, &c.tbsCertList);
    if (ret)
	goto out;

    /* if not revoked certs, remove OPTIONAL entry */
    if (c.tbsCertList.revokedCertificates->len == 0) {
	free(c.tbsCertList.revokedCertificates);
	c.tbsCertList.revokedCertificates = NULL;
    }

    ASN1_MALLOC_ENCODE(TBSCRLCertList, os->data, os->length,
		       &c.tbsCertList, &size, ret);
    if (ret) {
	hx509_set_error_string(context, 0, ret, "failed to encode tbsCRL");
	goto out;
    }
    if (size != os->length)
	_hx509_abort("internal ASN.1 encoder error");


    ret = _hx509_create_signature_bitstring(context,
					    signerkey,
					    sigalg,
					    os,
					    &c.signatureAlgorithm,
					    &c.signatureValue);
    free(os->data);
    if (ret) {
	hx509_set_error_string(context, 0, ret, "Failed to sign CRL");
	goto out;
    }

    ASN1_MALLOC_ENCODE(CRLCertificateList, os->data, os->length,
		       &c, &size, ret);
    if (ret) {
	hx509_set_error_string(context, 0, ret, "failed to encode CRL");
	goto out;
    }
    if (size != os->length)
	_hx509_abort("internal ASN.1 encoder error");

    free_CRLCertificateList(&c);

    return 0;

out:
    free_CRLCertificateList(&c);
    return ret;
}
示例#7
0
文件: revoke.c 项目: Henauxg/minix
int
hx509_revoke_ocsp_print(hx509_context context, const char *path, FILE *out)
{
    struct revoke_ocsp ocsp;
    int ret;
    size_t i;

    if (out == NULL)
	out = stdout;

    memset(&ocsp, 0, sizeof(ocsp));

    ocsp.path = strdup(path);
    if (ocsp.path == NULL)
	return ENOMEM;

    ret = load_ocsp(context, &ocsp);
    if (ret) {
	free_ocsp(&ocsp);
	return ret;
    }

    fprintf(out, "signer: ");

    switch(ocsp.ocsp.tbsResponseData.responderID.element) {
    case choice_OCSPResponderID_byName: {
	hx509_name n;
	char *s;
	_hx509_name_from_Name(&ocsp.ocsp.tbsResponseData.responderID.u.byName, &n);
	hx509_name_to_string(n, &s);
	hx509_name_free(&n);
	fprintf(out, " byName: %s\n", s);
	free(s);
	break;
    }
    case choice_OCSPResponderID_byKey: {
	char *s;
	hex_encode(ocsp.ocsp.tbsResponseData.responderID.u.byKey.data,
		   ocsp.ocsp.tbsResponseData.responderID.u.byKey.length,
		   &s);
	fprintf(out, " byKey: %s\n", s);
	free(s);
	break;
    }
    default:
	_hx509_abort("choice_OCSPResponderID unknown");
	break;
    }

    fprintf(out, "producedAt: %s\n",
	    printable_time(ocsp.ocsp.tbsResponseData.producedAt));

    fprintf(out, "replies: %d\n", ocsp.ocsp.tbsResponseData.responses.len);

    for (i = 0; i < ocsp.ocsp.tbsResponseData.responses.len; i++) {
	const char *status;
	switch (ocsp.ocsp.tbsResponseData.responses.val[i].certStatus.element) {
	case choice_OCSPCertStatus_good:
	    status = "good";
	    break;
	case choice_OCSPCertStatus_revoked:
	    status = "revoked";
	    break;
	case choice_OCSPCertStatus_unknown:
	    status = "unknown";
	    break;
	default:
	    status = "element unknown";
	}

	fprintf(out, "\t%zu. status: %s\n", i, status);

	fprintf(out, "\tthisUpdate: %s\n",
		printable_time(ocsp.ocsp.tbsResponseData.responses.val[i].thisUpdate));
	if (ocsp.ocsp.tbsResponseData.responses.val[i].nextUpdate)
	    fprintf(out, "\tproducedAt: %s\n",
		    printable_time(ocsp.ocsp.tbsResponseData.responses.val[i].thisUpdate));

    }

    fprintf(out, "appended certs:\n");
    if (ocsp.certs)
	ret = hx509_certs_iter_f(context, ocsp.certs, hx509_ci_print_names, out);

    free_ocsp(&ocsp);
    return ret;
}