Пример #1
0
int
hx509_peer_info_set_cert(hx509_peer_info peer,
			 hx509_cert cert)
{
    if (peer->cert)
	hx509_cert_free(peer->cert);
    peer->cert = hx509_cert_ref(cert);
    return 0;
}
Пример #2
0
static int
mem_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c)
{
    struct mem_data *mem = data;
    hx509_cert *val;

    val = realloc(mem->certs.val,
		  (mem->certs.len + 1) * sizeof(mem->certs.val[0]));
    if (val == NULL)
	return ENOMEM;

    mem->certs.val = val;
    mem->certs.val[mem->certs.len] = hx509_cert_ref(c);
    mem->certs.len++;

    return 0;
}
Пример #3
0
static int
mem_iter(hx509_context contexst,
	 hx509_certs certs,
	 void *data,
	 void *cursor,
	 hx509_cert *cert)
{
    unsigned long *iter = cursor;
    struct mem_data *mem = data;

    if (*iter >= mem->certs.len) {
	*cert = NULL;
	return 0;
    }

    *cert = hx509_cert_ref(mem->certs.val[*iter]);
    (*iter)++;
    return 0;
}
Пример #4
0
static int HX509_LIB_CALL
add_cert(hx509_context hxctx, void *ctx, hx509_cert cert)
{
    static char empty[] = "";
    struct foo *foo = (struct foo *)ctx;
    struct st_object *o = NULL;
    CK_OBJECT_CLASS type;
    CK_BBOOL bool_true = CK_TRUE;
    CK_BBOOL bool_false = CK_FALSE;
    CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
    CK_KEY_TYPE key_type;
    CK_MECHANISM_TYPE mech_type;
    CK_RV ret = CKR_GENERAL_ERROR;
    int hret;
    heim_octet_string cert_data, subject_data, issuer_data, serial_data;

    st_logf("adding certificate\n");

    serial_data.data = NULL;
    serial_data.length = 0;
    cert_data = subject_data = issuer_data = serial_data;

    hret = hx509_cert_binary(hxctx, cert, &cert_data);
    if (hret)
	goto out;

    {
	    hx509_name name;

	    hret = hx509_cert_get_issuer(cert, &name);
	    if (hret)
		goto out;
	    hret = hx509_name_binary(name, &issuer_data);
	    hx509_name_free(&name);
	    if (hret)
		goto out;

	    hret = hx509_cert_get_subject(cert, &name);
	    if (hret)
		goto out;
	    hret = hx509_name_binary(name, &subject_data);
	    hx509_name_free(&name);
	    if (hret)
		goto out;
    }

    {
	AlgorithmIdentifier alg;

	hret = hx509_cert_get_SPKI_AlgorithmIdentifier(context, cert, &alg);
	if (hret) {
	    ret = CKR_DEVICE_MEMORY;
	    goto out;
	}

	key_type = CKK_RSA; /* XXX */

	free_AlgorithmIdentifier(&alg);
    }


    type = CKO_CERTIFICATE;
    o = add_st_object();
    if (o == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto out;
    }

    o->cert = hx509_cert_ref(cert);

    add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));
    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, foo->label, strlen(foo->label));

    add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
    add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));

    add_object_attribute(o, 0, CKA_SUBJECT, subject_data.data, subject_data.length);
    add_object_attribute(o, 0, CKA_ISSUER, issuer_data.data, issuer_data.length);
    add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data.data, serial_data.length);
    add_object_attribute(o, 0, CKA_VALUE, cert_data.data, cert_data.length);
    add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));

    st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));

    type = CKO_PUBLIC_KEY;
    o = add_st_object();
    if (o == NULL) {
	ret = CKR_DEVICE_MEMORY;
	goto out;
    }
    o->cert = hx509_cert_ref(cert);

    add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));
    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, foo->label, strlen(foo->label));

    add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
    add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
    add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */
    add_object_attribute(o, 0, CKA_END_DATE, empty, 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.data, subject_data.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(hxctx, o, key_type, cert);

    st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));

    if (hx509_cert_have_private_key(cert)) {
	CK_FLAGS flags;

	type = CKO_PRIVATE_KEY;

        /* Note to static analyzers: `o' is still referred to via globals */
	o = add_st_object();
	if (o == NULL) {
	    ret = CKR_DEVICE_MEMORY;
	    goto out;
	}
	o->cert = hx509_cert_ref(cert);

	add_object_attribute(o, 0, CKA_CLASS, &type, sizeof(type));
	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, foo->label, strlen(foo->label));

	add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
	add_object_attribute(o, 0, CKA_ID, foo->id, strlen(foo->id));
	add_object_attribute(o, 0, CKA_START_DATE, empty, 1); /* XXX */
	add_object_attribute(o, 0, CKA_END_DATE, empty, 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.data, subject_data.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(hxctx, o, key_type, cert);
    }

    ret = CKR_OK;
 out:
    if (ret != CKR_OK) {
	st_logf("something went wrong when adding cert!\n");

	/* XXX wack o */;
    }
    hx509_xfree(cert_data.data);
    hx509_xfree(serial_data.data);
    hx509_xfree(issuer_data.data);
    hx509_xfree(subject_data.data);

    /* Note to static analyzers: `o' is still referred to via globals */
    return 0;
}
Пример #5
0
static int
add_to_req(hx509_context context, void *ptr, hx509_cert cert)
{
    struct ocsp_add_ctx *ctx = ptr;
    OCSPInnerRequest *one;
    hx509_cert parent = NULL;
    Certificate *p, *c = _hx509_get_cert(cert);
    heim_octet_string os;
    int ret;
    hx509_query q;
    void *d;

    d = realloc(ctx->req->requestList.val,
		sizeof(ctx->req->requestList.val[0]) *
		(ctx->req->requestList.len + 1));
    if (d == NULL)
	return ENOMEM;
    ctx->req->requestList.val = d;

    one = &ctx->req->requestList.val[ctx->req->requestList.len];
    memset(one, 0, sizeof(*one));

    _hx509_query_clear(&q);

    q.match |= HX509_QUERY_FIND_ISSUER_CERT;
    q.subject = c;

    ret = hx509_certs_find(context, ctx->certs, &q, &parent);
    if (ret)
	goto out;

    if (ctx->parent) {
	if (hx509_cert_cmp(ctx->parent, parent) != 0) {
	    ret = HX509_REVOKE_NOT_SAME_PARENT;
	    hx509_set_error_string(context, 0, ret,
				   "Not same parent certifate as "
				   "last certificate in request");
	    goto out;
	}
    } else
	ctx->parent = hx509_cert_ref(parent);

    p = _hx509_get_cert(parent);

    ret = copy_AlgorithmIdentifier(ctx->digest, &one->reqCert.hashAlgorithm);
    if (ret)
	goto out;

    ret = _hx509_create_signature(context,
				  NULL,
				  &one->reqCert.hashAlgorithm,
				  &c->tbsCertificate.issuer._save,
				  NULL,
				  &one->reqCert.issuerNameHash);
    if (ret)
	goto out;

    os.data = p->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
    os.length =
	p->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;

    ret = _hx509_create_signature(context,
				  NULL,
				  &one->reqCert.hashAlgorithm,
				  &os,
				  NULL,
				  &one->reqCert.issuerKeyHash);
    if (ret)
	goto out;

    ret = copy_CertificateSerialNumber(&c->tbsCertificate.serialNumber,
				       &one->reqCert.serialNumber);
    if (ret)
	goto out;

    ctx->req->requestList.len++;
out:
    hx509_cert_free(parent);
    if (ret) {
	free_OCSPInnerRequest(one);
	memset(one, 0, sizeof(*one));
    }

    return ret;
}
Пример #6
0
static int
verify_crl(hx509_context context,
	   hx509_revoke_ctx ctx,
	   CRLCertificateList *crl,
	   time_t time_now,
	   hx509_certs certs,
	   hx509_cert parent)
{
    hx509_cert signer;
    hx509_query q;
    time_t t;
    int ret;

    t = _hx509_Time2time_t(&crl->tbsCertList.thisUpdate);
    if (t > time_now) {
	hx509_set_error_string(context, 0, HX509_CRL_USED_BEFORE_TIME,
			       "CRL used before time");
	return HX509_CRL_USED_BEFORE_TIME;
    }

    if (crl->tbsCertList.nextUpdate == NULL) {
	hx509_set_error_string(context, 0, HX509_CRL_INVALID_FORMAT,
			       "CRL missing nextUpdate");
	return HX509_CRL_INVALID_FORMAT;
    }

    t = _hx509_Time2time_t(crl->tbsCertList.nextUpdate);
    if (t < time_now) {
	hx509_set_error_string(context, 0, HX509_CRL_USED_AFTER_TIME,
			       "CRL used after time");
	return HX509_CRL_USED_AFTER_TIME;
    }

    _hx509_query_clear(&q);

    /*
     * If it's the signer have CRLSIGN bit set, use that as the signer
     * cert for the certificate, otherwise, search for a certificate.
     */
    if (_hx509_check_key_usage(context, parent, 1 << 6, FALSE) == 0) {
	signer = hx509_cert_ref(parent);
    } else {
	q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
	q.match |= HX509_QUERY_KU_CRLSIGN;
	q.subject_name = &crl->tbsCertList.issuer;

	ret = hx509_certs_find(context, certs, &q, &signer);
	if (ret) {
	    hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
				   "Failed to find certificate for CRL");
	    return ret;
	}
    }

    ret = _hx509_verify_signature_bitstring(context,
					    signer,
					    &crl->signatureAlgorithm,
					    &crl->tbsCertList._save,
					    &crl->signatureValue);
    if (ret) {
	hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
			       "CRL signature invalid");
	goto out;
    }

    /*
     * If signer is not CA cert, need to check revoke status of this
     * CRL signing cert too, this include all parent CRL signer cert
     * up to the root *sigh*, assume root at least hve CERTSIGN flag
     * set.
     */
    while (_hx509_check_key_usage(context, signer, 1 << 5, TRUE)) {
	hx509_cert crl_parent;

	_hx509_query_clear(&q);

	q.match = HX509_QUERY_MATCH_SUBJECT_NAME;
	q.match |= HX509_QUERY_KU_CRLSIGN;
	q.subject_name = &_hx509_get_cert(signer)->tbsCertificate.issuer;

	ret = hx509_certs_find(context, certs, &q, &crl_parent);
	if (ret) {
	    hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
				   "Failed to find parent of CRL signer");
	    goto out;
	}

	ret = hx509_revoke_verify(context,
				  ctx,
				  certs,
				  time_now,
				  signer,
				  crl_parent);
	hx509_cert_free(signer);
	signer = crl_parent;
	if (ret) {
	    hx509_set_error_string(context, HX509_ERROR_APPEND, ret,
				   "Failed to verify revoke "
				   "status of CRL signer");
	    goto out;
	}
    }

out:
    hx509_cert_free(signer);

    return ret;
}