/*
- * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include "hx_locl.h"
-RCSID("$Id: cert.c 23457 2008-07-27 12:12:56Z lha $");
+RCSID("$Id$");
#include "crypto-headers.h"
#include <rtbl.h>
* the existans of a revokation method (OCSP, CRL) or not. Note that
* hx509_verify_path(), hx509_cms_verify_signed(), and other function
* call hx509_revoke_verify().
- *
+ *
* @param context hx509 context to change the flag for.
* @param flag zero, revokation method required, non zero missing
* revokation method ok
/**
* Free the context allocated by hx509_context_init().
- *
+ *
* @param context context to be freed.
*
* @ingroup hx509
/**
* Allocate and init an hx509 certificate object from the decoded
- * certificate `c´.
+ * certificate `c´.
*
* @param context A hx509 context.
* @param c
*/
int
-hx509_cert_init_data(hx509_context context,
+hx509_cert_init_data(hx509_context context,
const void *ptr,
size_t len,
hx509_cert *cert)
}
void
-_hx509_cert_set_release(hx509_cert cert,
+_hx509_cert_set_release(hx509_cert cert,
_hx509_cert_release_func release,
void *ctx)
{
/**
* Allocate an verification context that is used fo control the
- * verification process.
+ * verification process.
*
* @param context A hx509 context.
* @param ctx returns a pointer to a hx509_verify_ctx object.
c->max_depth = HX509_VERIFY_MAX_DEPTH;
*ctx = c;
-
+
return 0;
}
if (c->version == NULL || *c->version < 2 || c->extensions == NULL)
return NULL;
-
+
for (;*idx < c->extensions->len; (*idx)++) {
if (der_heim_oid_cmp(&c->extensions->val[*idx].extnID, oid) == 0)
return &c->extensions->val[(*idx)++];
}
static int
-find_extension_auth_key_id(const Certificate *subject,
+find_extension_auth_key_id(const Certificate *subject,
AuthorityKeyIdentifier *ai)
{
const Extension *e;
e = find_extension(subject, oid_id_x509_ce_authorityKeyIdentifier(), &i);
if (e == NULL)
return HX509_EXTENSION_NOT_FOUND;
-
- return decode_AuthorityKeyIdentifier(e->extnValue.data,
- e->extnValue.length,
+
+ return decode_AuthorityKeyIdentifier(e->extnValue.data,
+ e->extnValue.length,
ai, &size);
}
e = find_extension(issuer, oid_id_x509_ce_subjectKeyIdentifier(), &i);
if (e == NULL)
return HX509_EXTENSION_NOT_FOUND;
-
- return decode_SubjectKeyIdentifier(e->extnValue.data,
+
+ return decode_SubjectKeyIdentifier(e->extnValue.data,
e->extnValue.length,
si, &size);
}
static int
-find_extension_name_constraints(const Certificate *subject,
+find_extension_name_constraints(const Certificate *subject,
NameConstraints *nc)
{
const Extension *e;
e = find_extension(subject, oid_id_x509_ce_nameConstraints(), &i);
if (e == NULL)
return HX509_EXTENSION_NOT_FOUND;
-
- return decode_NameConstraints(e->extnValue.data,
- e->extnValue.length,
+
+ return decode_NameConstraints(e->extnValue.data,
+ e->extnValue.length,
nc, &size);
}
e = find_extension(cert, oid_id_x509_ce_subjectAltName(), i);
if (e == NULL)
return HX509_EXTENSION_NOT_FOUND;
-
- return decode_GeneralNames(e->extnValue.data,
+
+ return decode_GeneralNames(e->extnValue.data,
e->extnValue.length,
sa, &size);
}
e = find_extension(cert, oid_id_x509_ce_extKeyUsage(), &i);
if (e == NULL)
return HX509_EXTENSION_NOT_FOUND;
-
- return decode_ExtKeyUsage(e->extnValue.data,
+
+ return decode_ExtKeyUsage(e->extnValue.data,
e->extnValue.length,
eku, &size);
}
/**
* Return a list of subjectAltNames specified by oid in the
- * certificate. On error the
+ * certificate. On error the
*
* The returned list of octet string should be freed with
* hx509_free_octet_string_list().
for (j = 0; j < sa.len; j++) {
if (sa.val[j].element == choice_GeneralName_otherName &&
- der_heim_oid_cmp(&sa.val[j].u.otherName.type_id, oid) == 0)
+ der_heim_oid_cmp(&sa.val[j].u.otherName.type_id, oid) == 0)
{
ret = add_to_list(list, &sa.val[j].u.otherName.value);
if (ret) {
- hx509_set_error_string(context, 0, ret,
+ hx509_set_error_string(context, 0, ret,
"Error adding an exra SAN to "
"return list");
hx509_free_octet_string_list(list);
static int
-check_key_usage(hx509_context context, const Certificate *cert,
+check_key_usage(hx509_context context, const Certificate *cert,
unsigned flags, int req_present)
{
const Extension *e;
}
return 0;
}
-
+
ret = decode_KeyUsage(e->extnValue.data, e->extnValue.length, &ku, &size);
if (ret)
return ret;
*/
int
-_hx509_check_key_usage(hx509_context context, hx509_cert cert,
+_hx509_check_key_usage(hx509_context context, hx509_cert cert,
unsigned flags, int req_present)
{
return check_key_usage(context, _hx509_get_cert(cert), flags, req_present);
enum certtype { PROXY_CERT, EE_CERT, CA_CERT };
static int
-check_basic_constraints(hx509_context context, const Certificate *cert,
+check_basic_constraints(hx509_context context, const Certificate *cert,
enum certtype type, int depth)
{
BasicConstraints bc;
}
}
}
-
- ret = decode_BasicConstraints(e->extnValue.data,
+
+ ret = decode_BasicConstraints(e->extnValue.data,
e->extnValue.length, &bc,
&size);
if (ret)
SubjectKeyIdentifier si;
int ret_ai, ret_si, ret;
- ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
+ ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
&subject->tbsCertificate.issuer,
&diff);
if (ret)
return ret;
if (diff)
return diff;
-
+
memset(&ai, 0, sizeof(ai));
memset(&si, 0, sizeof(si));
goto out;
}
}
-
+
if (ai.keyIdentifier == NULL) {
Name name;
if (ai.authorityCertSerialNumber == NULL)
return -1;
- diff = der_heim_integer_cmp(ai.authorityCertSerialNumber,
+ diff = der_heim_integer_cmp(ai.authorityCertSerialNumber,
&issuer->tbsCertificate.serialNumber);
if (diff)
return diff;
if (ai.authorityCertIssuer->val[0].element != choice_GeneralName_directoryName)
return -1;
- name.element =
+ name.element =
ai.authorityCertIssuer->val[0].u.directoryName.element;
- name.u.rdnSequence =
+ name.u.rdnSequence =
ai.authorityCertIssuer->val[0].u.directoryName.u.rdnSequence;
- ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
+ ret = _hx509_name_cmp(&issuer->tbsCertificate.subject,
&name,
&diff);
if (ret)
int *self_signed)
{
int ret, diff;
- ret = _hx509_name_cmp(&cert->tbsCertificate.subject,
+ ret = _hx509_name_cmp(&cert->tbsCertificate.subject,
&cert->tbsCertificate.issuer, &diff);
*self_signed = (diff == 0);
if (ret)
time_t time_now,
hx509_certs trust_anchors,
hx509_path *path,
- hx509_certs pool,
+ hx509_certs pool,
hx509_cert current,
hx509_cert *parent)
{
*parent = NULL;
memset(&ai, 0, sizeof(ai));
-
+
_hx509_query_clear(&q);
if (!subject_null_p(current->data)) {
*/
static int
-is_proxy_cert(hx509_context context,
- const Certificate *cert,
+is_proxy_cert(hx509_context context,
+ const Certificate *cert,
ProxyCertInfo *rinfo)
{
ProxyCertInfo info;
return HX509_EXTENSION_NOT_FOUND;
}
- ret = decode_ProxyCertInfo(e->extnValue.data,
- e->extnValue.length,
+ ret = decode_ProxyCertInfo(e->extnValue.data,
+ e->extnValue.length,
&info,
&size);
if (ret) {
if (size != e->extnValue.length) {
free_ProxyCertInfo(&info);
hx509_clear_error_string(context);
- return HX509_EXTRA_DATA_AFTER_STRUCTURE;
+ return HX509_EXTRA_DATA_AFTER_STRUCTURE;
}
if (rinfo == NULL)
free_ProxyCertInfo(&info);
_hx509_path_free(hx509_path *path)
{
unsigned i;
-
+
for (i = 0; i < path->len; i++)
hx509_cert_free(path->val[i]);
free(path->val);
* The path includes a path from the top certificate to the anchor
* certificate.
*
- * The caller needs to free `path´ both on successful built path and
+ * The caller needs to free `path´ both on successful built path and
* failure.
*/
while (!certificate_is_anchor(context, anchors, current)) {
- ret = find_parent(context, time_now, anchors, path,
+ ret = find_parent(context, time_now, anchors, path,
pool, current, &parent);
hx509_cert_free(current);
if (ret)
}
}
- if ((flags & HX509_CALCULATE_PATH_NO_ANCHOR) &&
- path->len > 0 &&
+ if ((flags & HX509_CALCULATE_PATH_NO_ANCHOR) &&
+ path->len > 0 &&
certificate_is_anchor(context, anchors, path->val[path->len - 1]))
{
hx509_cert_free(path->val[path->len - 1]);
diff = der_heim_bit_string_cmp(&p->signatureValue, &q->signatureValue);
if (diff)
return diff;
- diff = _hx509_AlgorithmIdentifier_cmp(&p->signatureAlgorithm,
+ diff = _hx509_AlgorithmIdentifier_cmp(&p->signatureAlgorithm,
&q->signatureAlgorithm);
if (diff)
return diff;
int
hx509_cert_get_SPKI_AlgorithmIdentifier(hx509_context context,
- hx509_cert p,
+ hx509_cert p,
AlgorithmIdentifier *alg)
{
int ret;
return _hx509_private_key_private_decrypt(context,
ciphertext,
encryption_oid,
- p->private_key,
+ p->private_key,
cleartext);
}
if (c->len != n->len)
return HX509_NAME_CONSTRAINT_ERROR;
-
+
for (i = 0; i < n->len; i++) {
int diff, ret;
return ret;
}
return 0;
-}
+}
static int
match_general_name(const GeneralName *c, const GeneralName *n, int *match)
{
- /*
+ /*
* Name constraints only apply to the same name type, see RFC3280,
* 4.2.1.11.
*/
}
static int
-match_alt_name(const GeneralName *n, const Certificate *c,
+match_alt_name(const GeneralName *n, const Certificate *c,
int *same, int *match)
{
GeneralNames sa;
&& !subject_null_p(c))
{
GeneralName certname;
-
+
memset(&certname, 0, sizeof(certname));
certname.element = choice_GeneralName_directoryName;
- certname.u.directoryName.element =
+ certname.u.directoryName.element =
c->tbsCertificate.subject.element;
- certname.u.directoryName.u.rdnSequence =
+ certname.u.directoryName.u.rdnSequence =
c->tbsCertificate.subject.u.rdnSequence;
-
+
ret = match_general_name(&t->val[i].base, &certname, &name);
}
}
static int
-check_name_constraints(hx509_context context,
+check_name_constraints(hx509_context context,
const hx509_name_constraints *nc,
const Certificate *c)
{
ret = certificate_is_self_signed(context, c, &selfsigned);
if (ret)
goto out;
- if (selfsigned)
+ if (selfsigned)
selfsigned_depth++;
}
break;
case PROXY_CERT: {
- ProxyCertInfo info;
+ ProxyCertInfo info;
if (is_proxy_cert(context, c, &info) == 0) {
int j;
j = 0;
if (find_extension(c, oid_id_x509_ce_subjectAltName(), &j)) {
ret = HX509_PROXY_CERT_INVALID;
- hx509_set_error_string(context, 0, ret,
+ hx509_set_error_string(context, 0, ret,
"Proxy certificate have explicity "
"forbidden subjectAltName");
goto out;
j = 0;
if (find_extension(c, oid_id_x509_ce_issuerAltName(), &j)) {
ret = HX509_PROXY_CERT_INVALID;
- hx509_set_error_string(context, 0, ret,
+ hx509_set_error_string(context, 0, ret,
"Proxy certificate have explicity "
"forbidden issuerAltName");
goto out;
}
- /*
+ /*
* The subject name of the proxy certificate should be
* CN=XXX,<proxy issuer>, prune of CN and check if its
* the same over the whole chain of proxy certs and
}
j = proxy_issuer.u.rdnSequence.len;
- if (proxy_issuer.u.rdnSequence.len < 2
+ if (proxy_issuer.u.rdnSequence.len < 2
|| proxy_issuer.u.rdnSequence.val[j - 1].len > 1
|| der_heim_oid_cmp(&proxy_issuer.u.rdnSequence.val[j - 1].val[0].type,
oid_id_at_commonName()))
break;
} else {
- /*
+ /*
* Now we are done with the proxy certificates, this
* cert was an EE cert and we we will fall though to
* EE checking below.
*/
if (proxy_cert_depth) {
- ret = _hx509_name_cmp(&proxy_issuer,
+ ret = _hx509_name_cmp(&proxy_issuer,
&c->tbsCertificate.subject, &diff);
if (ret) {
hx509_set_error_string(context, 0, ret, "out of memory");
break;
}
- ret = check_basic_constraints(context, c, type,
+ ret = check_basic_constraints(context, c, type,
i - proxy_cert_depth - selfsigned_depth);
if (ret)
goto out;
-
+
/*
* Don't check the trust anchors expiration time since they
* are transported out of band, from RFC3820.
int parent = (i < path.len - 1) ? i + 1 : i;
ret = hx509_revoke_verify(context,
- ctx->revoke_ctx,
+ ctx->revoke_ctx,
certs,
ctx->time_now,
path.val[i],
hx509_hostname_type type,
const char *hostname,
const struct sockaddr *sa,
- /* XXX krb5_socklen_t */ int sa_size)
+ /* XXX krb5_socklen_t */ int sa_size)
{
GeneralNames san;
int ret, i, j;
int
_hx509_set_cert_attribute(hx509_context context,
- hx509_cert cert,
- const heim_oid *oid,
+ hx509_cert cert,
+ const heim_oid *oid,
const heim_octet_string *attr)
{
hx509_cert_attribute a;
if (hx509_cert_get_attribute(cert, oid) != NULL)
return 0;
- d = realloc(cert->attrs.val,
+ d = realloc(cert->attrs.val,
sizeof(cert->attrs.val[0]) * (cert->attrs.len + 1));
if (d == NULL) {
hx509_clear_error_string(context);
der_copy_octet_string(attr, &a->data);
der_copy_oid(oid, &a->oid);
-
+
cert->attrs.val[cert->attrs.len] = a;
cert->attrs.len++;
free_PKCS9_friendlyName(&n);
return NULL;
}
-
+
cert->friendlyname = malloc(n.val[0].length + 1);
if (cert->friendlyname == NULL) {
free_PKCS9_friendlyName(&n);
return NULL;
}
-
+
for (i = 0; i < n.val[0].length; i++) {
if (n.val[0].data[i] <= 0xff)
cert->friendlyname[i] = n.val[0].data[i] & 0xff;
int
hx509_query_match_issuer_serial(hx509_query *q,
- const Name *issuer,
+ const Name *issuer,
const heim_integer *serialNumber)
{
int ret;
}
if ((q->match & HX509_QUERY_MATCH_ISSUER_ID))
return 0;
- if ((q->match & HX509_QUERY_PRIVATE_KEY) &&
+ if ((q->match & HX509_QUERY_PRIVATE_KEY) &&
_hx509_cert_private_key(cert) == NULL)
return 0;
heim_octet_string os;
os.data = c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;
- os.length =
+ os.length =
c->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;
ret = _hx509_verify_signature(context,
return;
f = fopen(context->querystat, "r");
if (f == NULL) {
- fprintf(out, "No statistic file %s: %s.\n",
+ fprintf(out, "No statistic file %s: %s.\n",
context->querystat, strerror(errno));
return;
}
rk_cloexec_file(f);
-
+
for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) {
stats[i].index = i;
stats[i].stats = 0;
errx(1, "out of memory");
rtbl_set_separator (t, " ");
-
+
rtbl_add_column_by_id (t, 0, "Name", 0);
rtbl_add_column_by_id (t, 1, "Counter", 0);
for (i = 0; i < sizeof(stats)/sizeof(stats[0]); i++) {
char str[10];
- if (stats[i].index < sizeof(statname)/sizeof(statname[0]))
+ if (stats[i].index < sizeof(statname)/sizeof(statname[0]))
rtbl_add_column_entry_by_id (t, 0, statname[stats[i].index]);
else {
snprintf(str, sizeof(str), "%d", stats[i].index);
rtbl_format(t, out);
rtbl_destroy(t);
- fprintf(out, "\nQueries: multi %lu total %lu\n",
+ fprintf(out, "\nQueries: multi %lu total %lu\n",
multiqueries, totalqueries);
}
e = find_extension(cert, oid_id_x509_ce_keyUsage(), &i);
if (e == NULL)
return HX509_KU_CERT_MISSING;
-
+
ret = decode_KeyUsage(e->extnValue.data, e->extnValue.length, ku, &size);
if (ret)
return ret;
os->data = NULL;
os->length = 0;
- ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
+ ASN1_MALLOC_ENCODE(Certificate, os->data, os->length,
_hx509_get_cert(c), &size, ret);
if (ret) {
os->data = NULL;