Initial revision

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15716 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-07-24 16:59:14 +00:00
parent c3bf2d966b
commit 0a70228c08
22 changed files with 9914 additions and 0 deletions

52
lib/hx509/Makefile.am Normal file
View File

@@ -0,0 +1,52 @@
# $Id$
include $(top_srcdir)/Makefile.am.common
lib_LTLIBRARIES = libhx509.la
libhx509_la_LDFLAGS = -version-info 1:0:0
BUILT_SOURCES = hx509_err.c hx509_err.h
libhx509_la_LIBADD = ../asn1/libasn1.la
libhx509_la_CPPFLAGS = -I$(srcdir)/ref $(INCLUDE_des)
libhx509_la_SOURCES = \
cert.c \
cms.c \
crypto.c \
file.c \
hx509.h \
hx509_err.c \
hx509_err.h \
keyset.c \
ks_mem.c \
ks_file.c \
ks_null.c \
ks_p12.c \
lock.c \
name.c \
p11.c \
print.c
$(libhx509_la_OBJECTS): $(srcdir)/hx509-protos.h $(srcdir)/hx509-private.h
$(srcdir)/hx509-protos.h:
cd $(srcdir) && perl ../../cf/make-proto.pl -E HX509_LIB_FUNCTION -q -P comment -o hx509-protos.h $(libhx509_la_SOURCES) || rm -f hx509-protos.h
$(srcdir)/hx509-private.h:
cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p hx509-private.h $(libhx509_la_SOURCES) || rm -f hx509-private.h
include_HEADERS = hx509.h hx509-protos.h hx509_err.h
noinst_PROGRAMS = hxtool
hxtool_SOURCES = hxtool.c
hxtool_CPPFLAGS = $(INCLUDE_des)
hxtool_LDADD = libhx509.la $(LIB_roken) ../sl/libsl.la $(LIB_des)
hxtool_LDFLAGS = -pthread
EXTRA_DIST = hx509_err.et
CLEANFILES = hx509_err.c hx509_err.h

1232
lib/hx509/cert.c Normal file

File diff suppressed because it is too large Load Diff

1010
lib/hx509/cms.c Normal file

File diff suppressed because it is too large Load Diff

1312
lib/hx509/crypto.c Normal file

File diff suppressed because it is too large Load Diff

84
lib/hx509/file.c Normal file
View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2005 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$");
int
_hx509_map_file(const char *fn, void **data, size_t *length)
{
struct stat sb;
size_t len;
ssize_t l;
int ret;
void *d;
int fd;
*data = NULL;
*length = 0;
fd = open(fn, O_RDONLY);
if (fd < 0)
return errno;
if (fstat(fd, &sb) < 0) {
ret = errno;
close(fd);
return ret;
}
len = sb.st_size;
d = malloc(len);
if (d == NULL) {
close(fd);
return ENOMEM;
}
l = read(fd, d, len);
close(fd);
if (l < 0 || l != len) {
free(d);
return EINVAL;
}
*data = d;
*length = len;
return 0;
}
void
_hx509_unmap_file(void *data, size_t len)
{
free(data);
}

77
lib/hx509/hx509.h Normal file
View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2004 - 2005 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.
*/
/* $Id$ */
typedef struct hx509_verify_ctx_data *hx509_verify_ctx;
typedef struct hx509_certs_data *hx509_certs;
typedef struct hx509_cert_data *hx509_cert;
typedef struct hx509_cert_attribute_data *hx509_cert_attribute;
typedef struct hx509_validate_ctx_data *hx509_validate_ctx;
typedef struct hx509_name_data *hx509_name;
typedef void * hx509_cursor;
typedef struct hx509_lock_data *hx509_lock;
typedef struct hx509_private_key *hx509_private_key;
/* current unused */
typedef struct hx509_crypto_data *hx509_crypto;
typedef struct hx509_digest_data *hx509_digest;
typedef void (*hx509_vprint_func)(void *, const char *, va_list);
enum {
HX509_VALIDATE_F_VALIDATE = 1,
HX509_VALIDATE_F_VERBOSE = 2
};
struct hx509_cert_attribute_data {
heim_oid oid;
heim_octet_string data;
};
typedef enum {
HX509_PROMPT_TYPE_PASSWORD = 0x1,
HX509_PROMPT_TYPE_QUESTION = 0x2,
HX509_PROMPT_TYPE_CONFIRMATION = 0x4
} hx509_prompt_type;
typedef struct hx509_prompt {
const char *prompt;
int hidden;
hx509_prompt_type type;
heim_octet_string *reply;
} hx509_prompt;
typedef int (*hx509_prompter_fct)(void *, const hx509_prompt *);
#include <hx509-protos.h>

49
lib/hx509/hx509_err.et Normal file
View File

@@ -0,0 +1,49 @@
#
# Error messages for the hx509 library
#
# This might look like a com_err file, but is not
#
id "$Id$"
error_table hx
prefix HX509
error_code BAD_TIMEFORMAT, "ASN.1 failed call to system time library"
error_code EXTENSION_NOT_FOUND, "Extension not found"
error_code NO_PATH, "Certification path not found"
error_code PARENT_NOT_CA, "Parent certificate is not a CA"
error_code CA_PATH_TOO_DEEP, "CA path too deep"
error_code SIG_ALG_NO_SUPPORTED, "Signature algorithm not supported"
error_code SIG_ALG_DONT_MATCH_KEY_ALG, "Signature algorithm doesn't match certificate key"
error_code CERT_USED_BEFORE_TIME, "Certificate used before it became valid"
error_code CERT_USED_AFTER_TIME, "Certificate used after it became invalid"
error_code PRIVATE_KEY_MISSING, "Private key required for the operation is missing"
error_code ALG_NOT_SUPP, "Algorithm not supported"
error_code ISSUER_NOT_FOUND, "Issuer couldn't be found"
error_code VERIFY_CONSTRAINTS, "Error verifing constraints"
error_code RANGE, "Number too large"
error_code NAME_CONSTRAINT_ERROR, "Error while verifing name constraints"
error_code PATH_TOO_LONG, "Path is too long, failed to find valid anchor"
index 32
prefix HX509_CMS
error_code FAILED_CREATE_SIGATURE, "Failed to create signature"
error_code MISSING_SIGNER_DATA, "Missing signer data"
error_code SIGNER_NOT_FOUND, "Couldn't find signers certificate"
error_code NO_DATA_AVAILABLE, "No data to perform the operation on"
error_code INVALID_DATA, "Data in the message is invalid"
error_code PADDING_ERROR, "Padding in the message invalid"
error_code NO_RECIPIENT_CERTIFICATE, "Couldn't find recipient certificate"
error_code DATA_OID_MISMATCH, "Mismatch bewteen signed type and unsigned type"
index 64
prefix HX509_CRYPTO
error_code INTERNAL_ERROR, "Internal error in the crypto engine"
error_code EXTERNAL_ERROR, "External error in the crypto engine"
error_code SIGNATURE_MISSING, "Signature missing for data"
error_code BAD_SIGNATURE, "Signature is not valid"
error_code SIG_NO_CONF, "Sigature doesn't provide confidentiality"
error_code SIG_INVALID_FORMAT, "Invalid format on signature"
error_code OID_MISMATCH, "Mismatch bewteen oids"
end

126
lib/hx509/hx_locl.h Normal file
View File

@@ -0,0 +1,126 @@
/*
* Copyright (c) 2004 - 2005 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.
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <assert.h>
#include <stdarg.h>
#include <err.h>
#include <getarg.h>
#include <base64.h>
#include <roken.h>
#include <heim_asn1.h>
#include <rfc2459_asn1.h>
#include <cms_asn1.h>
#include <pkcs8_asn1.h>
#include <pkcs9_asn1.h>
#include <pkcs12_asn1.h>
#include <asn1_err.h>
#include <der.h>
struct hx509_query_data;
typedef struct hx509_query_data hx509_query;
struct hx509_keyset_ops;
#include <hx509.h>
#include <hx509-private.h>
#include <hx509_err.h>
#define HX509_CERTS_FIND_SERIALNUMBER 1
#define HX509_CERTS_FIND_ISSUER 2
#define HX509_CERTS_FIND_SUBJECT 4
#define HX509_CERTS_FIND_ISSUER_KEY_ID 8
#define HX509_CERTS_FIND_SUBJECT_KEY_ID 16
struct hx509_name_data {
Name der_name;
};
typedef struct hx509_path {
size_t len;
hx509_cert *val;
} hx509_path;
struct hx509_query_data {
int match;
#define HX509_QUERY_FIND_ISSUER_CERT 0x001
#define HX509_QUERY_MATCH_SERIALNUMBER 0x002
#define HX509_QUERY_MATCH_ISSUER_NAME 0x004
#define HX509_QUERY_MATCH_SUBJECT_NAME 0x008
#define HX509_QUERY_MATCH_SUBJECT_ID 0x010
#define HX509_QUERY_MATCH_ISSUER_ID 0x020
#define HX509_QUERY_PRIVATE_KEY 0x040
#define HX509_QUERY_ANCHOR 0x080
#define HX509_QUERY_MATCH_CERTIFICATE 0x100
#define HX509_QUERY_MATCH_LOCAL_KEY_ID 0x200
#define HX509_QUERY_NO_MATCH_PATH 0x400
#define HX509_QUERY_MASK 0x7ff
Certificate *subject;
Certificate *certificate;
heim_integer *serial;
heim_octet_string *subject_id;
heim_octet_string *local_key_id;
Name *issuer_name;
Name *subject_name;
hx509_path *path;
};
struct hx509_keyset_ops {
char *name;
int flags;
int (*init)(hx509_certs, void **, int, const char *, hx509_lock);
int (*free)(hx509_certs, void *);
int (*add)(hx509_certs, void *, hx509_cert);
int (*query)(hx509_certs, void *, const hx509_query *, hx509_cert *);
int (*iter_start)(hx509_certs, void *, void **);
int (*iter)(hx509_certs, void *, void *, hx509_cert *);
int (*iter_end)(hx509_certs, void *, void *);
};
struct _hx509_password {
size_t len;
char **val;
};
extern hx509_lock _hx509_empty_lock;

549
lib/hx509/hxtool.c Normal file
View File

@@ -0,0 +1,549 @@
/*
* Copyright (c) 2004 - 2005 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$");
#include <sl.h>
static int version_flag;
static int help_flag;
struct getargs args[] = {
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
int num_args = sizeof(args) / sizeof(args[0]);
static void
usage(int code)
{
arg_printusage(args, num_args, NULL, "command");
exit(code);
}
static int
cms_verify_sd(int argc, char **argv)
{
int ret;
hx509_verify_ctx ctx = NULL;
heim_oid type;
heim_octet_string c;
hx509_certs signers = NULL;
hx509_certs anchors = NULL;
ssize_t sz;
void *p;
int fd;
argc--;
argv++;
if (argc < 2)
errx(1, "argc < 2");
printf("cms verify signed data\n");
fd = open(argv[0], O_RDONLY, 0);
if (fd < 0)
err(1, "open %s", argv[0]);
p = malloc(10000);
if (p == NULL)
;
sz = read(fd, p, 10000);
if (sz < 0)
err(1, "read");
close(fd);
ret = hx509_verify_init_ctx(&ctx);
argc--;
argv++;
ret = hx509_certs_init("MEMORY:cms-anchors", 0, NULL, &anchors);
while (argc > 0) {
ret = hx509_certs_append(anchors, argv[0]);
if (ret)
errx(1, "hx509_certs_append: %d", ret);
argc--;
argv++;
}
hx509_verify_attach_anchors(ctx, anchors);
ret = hx509_cms_verify_signed(ctx, p, sz, &type, &c, &signers);
if (ret)
errx(1, "hx509_cms_verify_signed: %d", ret);
printf("signers:\n");
hx509_certs_iter(signers, hx509_ci_print_names, stdout);
hx509_certs_free(&anchors);
hx509_certs_free(&signers);
return 0;
}
static int
cms_create_sd(int argc, char **argv)
{
const heim_oid *contentType;
heim_octet_string o;
hx509_query q;
hx509_lock lock;
hx509_certs s;
hx509_cert cert;
ssize_t sz;
void *p;
int fd;
int ret;
contentType = oid_id_pkcs7_data();
argc--;
argv++;
if (argc < 3)
errx(1, "argc < 3");
printf("cms create signed data\n");
hx509_lock_init(&lock);
hx509_lock_add_password(lock, "foobar");
fd = open(argv[0], O_RDONLY, 0);
if (fd < 0)
err(1, "open %s", argv[0]);
p = malloc(10000);
if (p == NULL)
;
sz = read(fd, p, 10000);
if (sz < 0)
err(1, "read");
close(fd);
ret = hx509_certs_init(argv[2], 0, lock, &s);
if (ret)
errx(1, "hx509_certs_init: %d", ret);
_hx509_query_clear(&q);
q.match |= HX509_QUERY_PRIVATE_KEY;
ret = _hx509_certs_find(s, &q, &cert);
if (ret)
errx(1, "hx509_certs_find: %d", ret);
ret = hx509_cms_create_signed_1(contentType,
p,
sz,
NULL,
cert,
&o);
if (ret)
errx(1, "hx509_cms_create_signed: %d", ret);
fd = open(argv[1], O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0)
err(1, "open %s", argv[1]);
write(fd, o.data, o.length);
close(fd);
hx509_lock_free(lock);
return 0;
}
static int
cms_unenvelope(int argc, char **argv)
{
heim_oid contentType = { 0, NULL };
heim_octet_string o;
hx509_certs certs;
ssize_t sz;
void *p;
int fd;
int ret;
hx509_lock lock;
argc--;
argv++;
if (argc != 3)
errx(1, "argc != 3");
printf("cms unenvelope data\n");
hx509_lock_init(&lock);
hx509_lock_add_password(lock, "foobar");
fd = open(argv[1], O_RDONLY, 0);
if (fd < 0)
err(1, "open %s", argv[1]);
p = malloc(10000);
if (p == NULL)
;
sz = read(fd, p, 10000);
if (sz < 0)
err(1, "read");
close(fd);
ret = hx509_certs_init("MEMORY:cert-store", 0, NULL, &certs);
ret = hx509_certs_init(argv[0], 0, lock, &certs);
if (ret)
errx(1, "hx509_certs_init: %d", ret);
ret = hx509_cms_unenvelope(certs, p, sz, &contentType, &o);
if (ret)
errx(1, "hx509_cms_unenvelope: %d", ret);
fd = open(argv[2], O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0)
err(1, "open %s", argv[2]);
write(fd, o.data, o.length);
close(fd);
hx509_lock_free(lock);
return 0;
}
static int
cms_create_enveloped(int argc, char **argv)
{
heim_octet_string o;
heim_oid contentType = { 0, NULL };
hx509_query q;
hx509_certs certs;
hx509_cert cert;
int ret;
ssize_t sz;
void *p;
int fd;
argc--;
argv++;
if (argc != 3)
errx(1, "argc ! = 3");
printf("cms create enveloped\n");
fd = open(argv[0], O_RDONLY, 0);
if (fd < 0)
err(1, "open %s", argv[0]);
p = malloc(10000);
if (p == NULL)
;
sz = read(fd, p, 10000);
if (sz < 0)
err(1, "read");
close(fd);
ret = hx509_certs_init(argv[2], 0, NULL, &certs);
if (ret)
errx(1, "hx509_certs_init: %d", ret);
_hx509_query_clear(&q);
ret = _hx509_certs_find(certs, &q, &cert);
if (ret)
errx(1, "hx509_certs_find: %d", ret);
ret = hx509_cms_envelope_1(cert, p, sz, NULL, &contentType, &o);
if (ret)
errx(1, "hx509_cms_unenvelope: %d", ret);
fd = open(argv[1], O_WRONLY|O_TRUNC|O_CREAT, 0644);
if (fd < 0)
err(1, "open %s", argv[1]);
write(fd, o.data, o.length);
close(fd);
return 0;
}
static int
validate_print_f(void *ctx, hx509_cert c)
{
hx509_validate_cert(ctx, c);
return 0;
}
static int
validate_print(int argc, char **argv, int flags)
{
hx509_validate_ctx ctx;
hx509_certs certs;
hx509_lock lock;
argc--;
argv++;
if (argc < 1)
errx(1, "argc");
hx509_lock_init(&lock);
hx509_lock_add_password(lock, "foobar");
hx509_validate_ctx_init(&ctx);
hx509_validate_ctx_set_print(ctx, hx509_print_stdout, stdout);
hx509_validate_ctx_add_flags(ctx, flags);
while(argc--) {
int ret;
ret = hx509_certs_init(argv[0], 0, lock, &certs);
if (ret)
errx(1, "hx509_certs_init");
hx509_certs_iter(certs, validate_print_f, ctx);
hx509_certs_free(&certs);
argv++;
}
hx509_validate_ctx_free(ctx);
hx509_lock_free(lock);
return 0;
}
static int
pcert_print(int argc, char **argv)
{
return validate_print(argc, argv, HX509_VALIDATE_F_VERBOSE);
}
static int
pcert_validate(int argc, char **argv)
{
return validate_print(argc, argv, HX509_VALIDATE_F_VALIDATE);
}
struct verify {
hx509_verify_ctx ctx;
hx509_certs chain;
};
static int
verify_f(void *ctx, hx509_cert c)
{
struct verify *v = ctx;
int ret;
ret = hx509_verify_path(v->ctx, c, v->chain);
if (ret)
printf("verify_path returned %d\n", ret);
else
printf("path ok\n");
return 0;
}
static int
pcert_verify(int argc, char **argv)
{
hx509_certs anchors, chain, certs;
hx509_verify_ctx ctx;
struct verify v;
int ret;
argc--;
argv++;
ret = hx509_verify_init_ctx(&ctx);
ret = hx509_certs_init("MEMORY:anchors", 0, NULL, &anchors);
ret = hx509_certs_init("MEMORY:chain", 0, NULL, &chain);
ret = hx509_certs_init("MEMORY:certs", 0, NULL, &certs);
if (argc < 1)
errx(1, "argc");
while(argc--) {
char *s = *argv++;
if (strncmp(s, "chain:", 6) == 0) {
s += 6;
ret = hx509_certs_append(chain, s);
if (ret)
errx(1, "hx509_certs_append: chain: %d", ret);
} else if (strncmp(s, "anchor:", 7) == 0) {
s += 7;
ret = hx509_certs_append(anchors, s);
if (ret)
errx(1, "hx509_certs_append: anchor: %d", ret);
} else if (strncmp(s, "cert:", 5) == 0) {
s += 5;
ret = hx509_certs_append(certs, s);
if (ret)
errx(1, "hx509_certs_append: certs: %d", ret);
} else {
errx(1, "unknown option to verify: `%s'\n", s);
}
}
hx509_verify_attach_anchors(ctx, anchors);
v.ctx = ctx;
v.chain = chain;
hx509_certs_iter(certs, verify_f, &v);
hx509_certs_free(&anchors);
hx509_certs_free(&certs);
hx509_certs_free(&chain);
return 0;
}
static int
pcert_pkcs11(int argc, char **argv)
{
int ret;
argc--;
argv++;
if (argc < 1)
errx(1, "argc");
ret = hx509_keyset_init(argv[0], NULL);
if (ret) {
printf("hx509_keyset_init: %d\n", ret);
return 0;
}
return 0;
}
static int help(int, char **);
static SL_cmd cmds[] = {
{ "cms-create-sd",
cms_create_sd,
"in-file out-file cert ...",
"create signed data"
},
{ "cms-verify-sd",
cms_verify_sd,
"file cert ...",
"verify signed data"
},
{ "cms-unenvelope",
cms_unenvelope,
"cert key in-file out-file",
"unenvelope data"
},
{ "cms-create-envelope",
cms_create_enveloped,
"cert in-file out-file",
"envelope data"
},
{ "print",
pcert_print,
"cert ...",
"print certificates"
},
{ "validate",
pcert_validate,
"cert ...",
"validate certificates"
},
{ "verify",
pcert_verify,
"cert:foo chain:cert1 chain:cert2 anchor:anchor1 anchor:anchor2",
"verify certificates"
},
{ "pkcs11",
pcert_pkcs11,
"...",
"deal with pkcs11 devices"
},
{ "help", help, "help" },
{ "?" },
{ NULL }
};
int
help(int argc, char **argv)
{
sl_help(cmds, argc, argv);
return 0;
}
int
main(int argc, char **argv)
{
int ret, optidx = 0;
setprogname (argv[0]);
if(getarg(args, num_args, argc, argv, &optidx))
usage(1);
if(help_flag)
usage(0);
if(version_flag) {
print_version(NULL);
exit(0);
}
argv += optidx;
argc -= optidx;
if (argc == 0)
usage(1);
ret = sl_command(cmds, argc, argv);
if(ret == -1)
warnx ("unrecognized command: %s", argv[0]);
return 0;
}

281
lib/hx509/keyset.c Normal file
View File

@@ -0,0 +1,281 @@
/*
* Copyright (c) 2004 - 2005 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$");
static struct hx509_keyset_ops **ks_ops;
static int ks_num_ops;
struct hx509_certs_data {
struct hx509_keyset_ops *ops;
void *ops_data;
};
static struct hx509_keyset_ops *
_hx509_ks_type(const char *type)
{
int i;
for (i = 0; i < ks_num_ops; i++)
if (strcasecmp(type, ks_ops[i]->name) == 0)
return ks_ops[i];
return NULL;
}
void
_hx509_ks_register(struct hx509_keyset_ops *ops)
{
struct hx509_keyset_ops **val;
if (_hx509_ks_type(ops->name))
return;
val = realloc(ks_ops, (ks_num_ops + 1) * sizeof(ks_ops[0]));
if (val == NULL)
return;
val[ks_num_ops] = ops;
ks_ops = val;
ks_num_ops++;
}
int
hx509_certs_init(const char *name, int flags,
hx509_lock lock, hx509_certs *certs)
{
struct hx509_keyset_ops *ops;
const char *residue;
hx509_certs c;
char *type;
int ret;
*certs = NULL;
if (ks_ops == NULL) {
_hx509_ks_mem_register();
_hx509_ks_file_register();
_hx509_ks_pkcs12_register();
}
residue = strchr(name, ':');
if (residue) {
type = strndup(name, residue - name);
residue++;
if (residue[0] == '\0')
residue = NULL;
} else {
type = strdup("MEMORY");
residue = name;
}
if (type == NULL)
return ENOMEM;
ops = _hx509_ks_type(type);
free(type);
if (ops == NULL)
return ENOENT;
c = calloc(1, sizeof(*c));
if (c == NULL)
return ENOMEM;
c->ops = ops;
ret = (*ops->init)(c, &c->ops_data, flags, residue, lock);
if (ret) {
free(c);
return ENOMEM;
}
*certs = c;
return 0;
}
void
hx509_certs_free(hx509_certs *certs)
{
(*(*certs)->ops->free)(*certs, (*certs)->ops_data);
free(*certs);
*certs = NULL;
}
int
hx509_certs_start_seq(hx509_certs certs, hx509_cursor cursor)
{
int ret;
if (certs->ops->iter_start == NULL)
return ENOENT;
ret = (*certs->ops->iter_start)(certs, certs->ops_data, cursor);
if (ret)
return ret;
return 0;
}
int
hx509_certs_next_cert(hx509_certs certs, hx509_cursor cursor,
hx509_cert *cert)
{
*cert = NULL;
return (*certs->ops->iter)(certs, certs->ops_data, cursor, cert);
}
int
hx509_certs_end_seq(hx509_certs certs, hx509_cursor cursor)
{
(*certs->ops->iter_end)(certs, certs->ops_data, cursor);
return 0;
}
int
hx509_certs_iter(hx509_certs certs, int (*fn)(void *, hx509_cert), void *ctx)
{
hx509_cursor cursor;
hx509_cert c;
int ret;
ret = hx509_certs_start_seq(certs, &cursor);
if (ret)
return ret;
while (1) {
ret = hx509_certs_next_cert(certs, cursor, &c);
if (ret)
break;
if (c == NULL)
break;
ret = (*fn)(ctx, c);
hx509_cert_free(c);
if (ret)
break;
}
hx509_certs_end_seq(certs, cursor);
return 0;
}
int
hx509_ci_print_names(void *ctx, hx509_cert c)
{
Certificate *cert;
hx509_name n;
char *str;
cert = _hx509_get_cert(c);
_hx509_name_from_Name(&cert->tbsCertificate.subject, &n);
hx509_name_to_string(n, &str);
hx509_name_free(&n);
fprintf(ctx, "%s\n", str);
free(str);
return 0;
}
int
hx509_certs_add(hx509_certs certs, hx509_cert cert)
{
if (certs->ops->add == NULL)
return ENOENT;
return (*certs->ops->add)(certs, certs->ops_data, cert);
}
int
_hx509_certs_find(hx509_certs certs, const hx509_query *q, hx509_cert *r)
{
hx509_cursor cursor;
hx509_cert c;
int ret, found = 0;
*r = NULL;
if (certs->ops->query)
return (*certs->ops->query)(certs, certs->ops_data, q, r);
ret = hx509_certs_start_seq(certs, &cursor);
if (ret)
return ret;
while (1) {
ret = hx509_certs_next_cert(certs, cursor, &c);
if (ret)
break;
if (c == NULL)
break;
found = _hx509_query_match_cert(q, c);
if (found) {
*r = c;
break;
}
hx509_cert_free(c);
}
hx509_certs_end_seq(certs, cursor);
if (!found)
return ENOENT;
return 0;
}
static int
certs_merge_func(void *ctx, hx509_cert c)
{
return hx509_certs_add((hx509_certs)ctx, c);
}
int
hx509_certs_merge(hx509_certs to, hx509_certs from)
{
return hx509_certs_iter(from, certs_merge_func, to);
}
int
hx509_certs_append(hx509_certs to, const char *name)
{
hx509_certs s;
int ret;
ret = hx509_certs_init(name, 0, NULL, &s);
if (ret)
return ret;
ret = hx509_certs_merge(to, s);
hx509_certs_free(&s);
return ret;
}

233
lib/hx509/ks_file.c Normal file
View File

@@ -0,0 +1,233 @@
/*
* Copyright (c) 2005 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$");
static int
parse_certificate(const char *fn, int use_pem, Certificate *t)
{
char buf[1024];
void *data = NULL;
size_t size, len = 0;
int in_cert = 0;
FILE *f;
int i, ret;
memset(t, 0, sizeof(*t));
if ((f = fopen(fn, "r")) == NULL)
return ENOENT;
if (use_pem) {
while (fgets(buf, sizeof(buf), f) != NULL) {
char *p;
i = strcspn(buf, "\n");
if (buf[i] == '\n') buf[i--] = '\0';
if (buf[i] == '\r') buf[i--] = '\0';
if (i == 26
&& strcmp("-----BEGIN CERTIFICATE-----", buf) == 0)
{
in_cert = 1;
continue;
} else if (i == 24 &&
strcmp("-----END CERTIFICATE-----", buf) == 0)
{
in_cert = 0;
continue;
}
if (in_cert == 0)
continue;
p = malloc(i);
i = base64_decode(buf, p);
data = erealloc(data, len + i);
memcpy(((char *)data) + len, p, i);
free(p);
len += i;
}
} else {
while((i = fread(buf, 1, sizeof(buf), f)) > 0) {
data = erealloc(data, len + i);
memcpy(((char *)data) + len, buf, i);
len += i;
}
}
fclose(f);
if (data == NULL)
return 1;
if (data && in_cert) {
free(data);
return 1;
}
ret = decode_Certificate(data, len, t, &size);
free(data);
if (ret != 0) {
return 1;
}
return 0;
}
static int
file_init(hx509_certs certs, void **data, int flags,
const char *residue, hx509_lock lock)
{
char *certfn, *keyfn, *friendlyname = NULL;
hx509_cert cert;
*data = NULL;
certfn = strdup(residue);
if (certfn == NULL)
return ENOMEM;
keyfn = strchr(certfn, ',');
if (keyfn) {
*keyfn++ = '\0';
friendlyname = strchr(keyfn, ',');
if (friendlyname)
*friendlyname++ = '\0';
}
{
Certificate t;
int ret;
ret = parse_certificate(certfn, 1, &t);
if (ret)
ret = parse_certificate(certfn, 0, &t);
if (ret) {
free(certfn);
return ret;
}
ret = hx509_cert_init(&t, &cert);
free_Certificate(&t);
if (ret) {
free(certfn);
return ret;
}
}
if (keyfn) {
int ret;
ret = _hx509_cert_assign_private_key_file(cert, lock, keyfn);
if (ret) {
hx509_cert_free(cert);
free(certfn);
return ret;
}
}
if (friendlyname) {
int ret;
ret = hx509_cert_set_friendly_name(cert, friendlyname);
if (ret) {
hx509_cert_free(cert);
free(certfn);
return ret;
}
}
free(certfn);
*data = cert;
return 0;
}
static int
file_free(hx509_certs certs, void *data)
{
hx509_cert_free(data);
return 0;
}
static int
file_iter_start(hx509_certs certs, void *data, void **cursor)
{
int *i;
i = malloc(sizeof(*i));
if (i == NULL)
return ENOMEM;
*i = 0;
*cursor = i;
return 0;
}
static int
file_iter(hx509_certs certs, void *data, void *iter, hx509_cert *cert)
{
int *i = iter;
if (*i != 0)
return 0;
*cert = hx509_cert_ref((hx509_cert)data);
(*i)++;
return 0;
}
static int
file_iter_end(hx509_certs certs,
void *data,
void *cursor)
{
free(cursor);
return 0;
}
static struct hx509_keyset_ops keyset_file = {
"FILE",
0,
file_init,
file_free,
NULL,
NULL,
file_iter_start,
file_iter,
file_iter_end
};
void
_hx509_ks_file_register(void)
{
_hx509_ks_register(&keyset_file);
}

150
lib/hx509/ks_mem.c Normal file
View File

@@ -0,0 +1,150 @@
/*
* Copyright (c) 2005 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$");
struct mem_data {
char *name;
unsigned long len;
hx509_cert *val;
};
static int
mem_init(hx509_certs certs, void **data, int flags,
const char *residue, hx509_lock lock)
{
struct mem_data *mem;
mem = calloc(1, sizeof(*mem));
if (mem == NULL)
return ENOMEM;
if (residue == NULL || residue[0] == '\0')
residue = "anonymous";
mem->name = strdup(residue);
if (mem->name == NULL) {
free(mem);
return ENOMEM;
}
*data = mem;
return 0;
}
static int
mem_free(hx509_certs certs, void *data)
{
struct mem_data *mem = data;
unsigned long i;
for (i = 0; i < mem->len; i++)
hx509_cert_free(mem->val[i]);
free(mem->val);
free(mem->name);
free(mem);
return 0;
}
static int
mem_add(hx509_certs certs, void *data, hx509_cert c)
{
struct mem_data *mem = data;
hx509_cert *val;
val = realloc(mem->val, (mem->len + 1) * sizeof(mem->val[0]));
if (val == NULL)
return ENOMEM;
mem->val = val;
mem->val[mem->len] = hx509_cert_ref(c);
mem->len++;
return 0;
}
static int
mem_iter_start(hx509_certs certs, void *data, void **cursor)
{
unsigned long *iter = malloc(sizeof(*iter));
if (iter == NULL)
return ENOMEM;
*iter = 0;
*cursor = iter;
return 0;
}
static int
mem_iter(hx509_certs certs,
void *data,
void *cursor,
hx509_cert *cert)
{
unsigned long *iter = cursor;
struct mem_data *mem = data;
if (*iter >= mem->len)
return ENOENT;
*cert = hx509_cert_ref(mem->val[*iter]);
(*iter)++;
return 0;
}
static int
mem_iter_end(hx509_certs certs,
void *data,
void *cursor)
{
free(cursor);
return 0;
}
static struct hx509_keyset_ops keyset_mem = {
"MEMORY",
0,
mem_init,
mem_free,
mem_add,
NULL,
mem_iter_start,
mem_iter,
mem_iter_end
};
void
_hx509_ks_mem_register(void)
{
_hx509_ks_register(&keyset_mem);
}

89
lib/hx509/ks_null.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* Copyright (c) 2005 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$");
static int
null_init(hx509_certs certs, void **data, int flags,
const char *residue, hx509_lock lock)
{
*data = NULL;
return 0;
}
static int
null_free(hx509_certs certs, void *data)
{
assert(data == NULL);
return 0;
}
static int
null_iter_start(hx509_certs certs, void *data, void **cursor)
{
*cursor = NULL;
return 0;
}
static int
null_iter(hx509_certs certs, void *data, void *iter, hx509_cert *cert)
{
*cert = NULL;
return ENOENT;
}
static int
null_iter_end(hx509_certs certs,
void *data,
void *cursor)
{
assert(cursor == NULL);
return 0;
}
struct hx509_keyset_ops keyset_null = {
"NULL",
0,
null_init,
null_free,
NULL,
NULL,
null_iter_start,
null_iter,
null_iter_end
};

526
lib/hx509/ks_p12.c Normal file
View File

@@ -0,0 +1,526 @@
/*
* Copyright (c) 2004 - 2005 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$");
struct ks_pkcs12 {
hx509_certs certs;
};
struct private_key {
AlgorithmIdentifier alg;
heim_octet_string data;
heim_octet_string localKeyId;
};
struct collector {
hx509_lock lock;
hx509_certs unenvelop_certs;
hx509_certs certs;
struct {
struct private_key **data;
size_t len;
} val;
};
typedef int (*collector_func)(struct collector *, const void *, size_t,
const PKCS12_Attributes *);
struct type {
const heim_oid * (*oid)(void);
collector_func func;
};
static int
parse_pkcs12_type(struct collector *, const heim_oid *,
const void *, size_t, const PKCS12_Attributes *);
static const PKCS12_Attribute *
find_attribute(const PKCS12_Attributes *attrs, const heim_oid *oid)
{
int i;
if (attrs == NULL)
return NULL;
for (i = 0; i < attrs->len; i++)
if (heim_oid_cmp(oid, &attrs->val[i].attrId) == 0)
return &attrs->val[i];
return NULL;
}
static int
ShroudedKeyBag_parser(struct collector *c, const void *data, size_t length,
const PKCS12_Attributes *attrs)
{
struct private_key *key;
const PKCS12_Attribute *attr;
PKCS8EncryptedPrivateKeyInfo pk;
PKCS8PrivateKeyInfo ki;
heim_octet_string content;
const struct _hx509_password *pw;
int i;
int ret;
printf("pkcs8ShroudedKeyBag\n");
memset(&pk, 0, sizeof(pk));
attr = find_attribute(attrs, oid_id_pkcs_9_at_localKeyId());
if (attr == NULL) {
printf("no localKeyId, ignoreing private key\n");
return 0;
}
ret = decode_PKCS8EncryptedPrivateKeyInfo(data, length, &pk, NULL);
if (ret) {
printf("PKCS8EncryptedPrivateKeyInfo returned %d\n", ret);
return ret;
}
pw = _hx509_lock_get_passwords(c->lock);
ret = HX509_CRYPTO_INTERNAL_ERROR;
for (i = 0; i < pw->len; i++) {
ret = _hx509_pbe_decrypt(pw->val[i],
&pk.encryptionAlgorithm,
&pk.encryptedData,
&content);
if (ret == 0)
break;
}
free_PKCS8EncryptedPrivateKeyInfo(&pk);
if (ret) {
printf("decrypt encryped failed %d\n", ret);
return ret;
}
ret = decode_PKCS8PrivateKeyInfo(content.data, content.length,
&ki, NULL);
free_octet_string(&content);
if (ret) {
printf("PKCS8PrivateKeyInfo returned %d\n", ret);
return ret;
}
key = malloc(sizeof(*key));
if (key == NULL) {
free_PKCS8PrivateKeyInfo(&ki);
return ENOMEM;
}
copy_AlgorithmIdentifier(&ki.privateKeyAlgorithm, &key->alg);
copy_octet_string(&ki.privateKey, &key->data);
copy_octet_string(&attr->attrValues, &key->localKeyId);
free_PKCS8PrivateKeyInfo(&ki);
{
void *d;
d = realloc(c->val.data, (c->val.len + 1) * sizeof(c->val.data[0]));
if (d == NULL) {
abort();
}
c->val.data = d;
c->val.data[c->val.len] = key;
c->val.len++;
}
return 0;
}
static int
certBag_parser(struct collector *c, const void *data, size_t length,
const PKCS12_Attributes *attrs)
{
heim_octet_string os;
Certificate t;
hx509_cert cert;
PKCS12_CertBag cb;
int ret;
printf("certBag\n");
ret = decode_PKCS12_CertBag(data, length, &cb, NULL);
if (ret)
return ret;
{
char *str;
hx509_oid_sprint(&cb.certType, &str);
printf("oid: %s\n", str);
}
ret = decode_PKCS12_OctetString(cb.certValue.data,
cb.certValue.length,
&os,
NULL);
free_PKCS12_CertBag(&cb);
if (ret) {
printf("failed with %d\n", ret);
return 1;
}
ret = decode_Certificate(os.data, os.length, &t, NULL);
free_octet_string(&os);
if (ret) {
printf("failed with %d\n", ret);
return 1;
}
printf("cert parsed ok\n");
ret = hx509_cert_init(&t, &cert);
free_Certificate(&t);
if (ret) {
return ret;
}
ret = hx509_certs_add(c->certs, cert);
if (ret) {
hx509_cert_free(cert);
return ret;
}
{
const PKCS12_Attribute *attr;
const heim_oid * (*oids[])(void) = {
oid_id_pkcs_9_at_localKeyId, oid_id_pkcs_9_at_friendlyName
};
int i;
for (i = 0; i < sizeof(oids)/sizeof(oids[0]); i++) {
const heim_oid *oid = (*(oids[i]))();
attr = find_attribute(attrs, oid);
if (attr)
_hx509_set_cert_attribute(cert, oid, &attr->attrValues);
}
}
{
const char *s = hx509_cert_get_friendly_name(cert);
printf("cert name: %s\n", s ? s : "no name set");
}
return 0;
}
static int
parse_safe_content(struct collector *c, const unsigned char *p, size_t len)
{
PKCS12_SafeContents sc;
int ret, i;
memset(&sc, 0, sizeof(sc));
ret = decode_PKCS12_SafeContents(p, len, &sc, NULL);
if (ret)
return ret;
for (i = 0; i < sc.len ; i++)
parse_pkcs12_type(c,
&sc.val[i].bagId,
sc.val[i].bagValue.data,
sc.val[i].bagValue.length,
sc.val[i].bagAttributes);
free_PKCS12_SafeContents(&sc);
return 0;
}
static int
safeContent_parser(struct collector *c, const void *data, size_t length,
const PKCS12_Attributes *attrs)
{
heim_octet_string os;
int ret;
printf("safeContent\n");
ret = decode_PKCS12_OctetString(data, length, &os, NULL);
if (ret)
return 1;
ret = parse_safe_content(c, os.data, os.length);
free_octet_string(&os);
return ret;
};
static int
encryptedData_parser(struct collector *c, const void *data, size_t length,
const PKCS12_Attributes *attrs)
{
heim_octet_string content;
heim_oid contentType;
int ret;
memset(&contentType, 0, sizeof(contentType));
ret = hx509_cms_decrypt_encrypted(c->lock,
data, length,
&contentType,
&content);
if (ret)
printf("decrypt encryped failed %d\n", ret);
else {
if (content.length == 0) {
printf("no content in encryped data\n");
} else if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) == 0) {
ret = parse_safe_content(c, content.data, content.length);
if (ret)
printf("parse_safe_content failed with %d\n", ret);
}
}
return 0;
}
static int
envelopedData_parser(struct collector *c, const void *data, size_t length,
const PKCS12_Attributes *attrs)
{
heim_octet_string content;
heim_oid contentType;
int ret;
memset(&contentType, 0, sizeof(contentType));
ret = hx509_cms_unenvelope(c->unenvelop_certs,
data, length,
&contentType,
&content);
if (ret)
printf("unenveloped failed %d\n", ret);
else {
if (content.length == 0) {
printf("no content enveloped data\n");
} else if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) == 0) {
ret = parse_safe_content(c, content.data, content.length);
if (ret)
printf("parse_safe_content failed with %d\n", ret);
}
}
return 0;
}
struct type bagtypes[] = {
{ oid_id_pkcs12_pkcs8ShroudedKeyBag, ShroudedKeyBag_parser },
{ oid_id_pkcs12_certBag, certBag_parser },
{ oid_id_pkcs7_data, safeContent_parser },
{ oid_id_pkcs7_encryptedData, encryptedData_parser },
{ oid_id_pkcs7_envelopedData, envelopedData_parser }
};
static int
parse_pkcs12_type(struct collector *c, const heim_oid *oid,
const void *data, size_t length,
const PKCS12_Attributes *attrs)
{
int i;
for (i = 0; i < sizeof(bagtypes)/sizeof(bagtypes[0]); i++) {
if (heim_oid_cmp((*bagtypes[i].oid)(), oid) == 0) {
(*bagtypes[i].func)(c, data, length, attrs);
return 0;
}
}
return 1;
}
static int
p12_init(hx509_certs certs, void **data, int flags,
const char *residue, hx509_lock lock)
{
size_t len;
void *buf;
PKCS12_PFX pfx;
PKCS12_AuthenticatedSafe as;
int ret, i;
struct collector c;
*data = NULL;
if (lock == NULL)
lock = _hx509_empty_lock;
ret = _hx509_map_file(residue, &buf, &len);
if (ret)
return ret;
ret = decode_PKCS12_PFX(buf, len, &pfx, NULL);
_hx509_unmap_file(buf, len);
if (ret)
return ret;
if (heim_oid_cmp(&pfx.authSafe.contentType, oid_id_pkcs7_data()) != 0) {
free_PKCS12_PFX(&pfx);
ret = EINVAL;
goto out;
}
if (pfx.authSafe.content == NULL) {
free_PKCS12_PFX(&pfx);
ret = EINVAL;
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)
goto out;
ret = decode_PKCS12_AuthenticatedSafe(asdata.data,
asdata.length,
&as,
NULL);
free_octet_string(&asdata);
if (ret)
goto out;
}
c.lock = lock;
hx509_certs_init("MEMORY:dummy", 0, NULL, &c.unenvelop_certs);
c.val.data = NULL;
c.val.len = 0;
hx509_certs_init("MEMORY:pkcs12-store", 0, NULL, &c.certs);
for (i = 0; i < as.len; i++) {
parse_pkcs12_type(&c,
&as.val[i].contentType,
as.val[i].content->data,
as.val[i].content->length,
NULL);
}
free_PKCS12_AuthenticatedSafe(&as);
printf("found %d private keys\n", c.val.len);
for (i = 0; i < c.val.len; i++) {
hx509_cert cert;
hx509_query q;
_hx509_query_clear(&q);
q.match |= HX509_QUERY_MATCH_LOCAL_KEY_ID;
q.local_key_id = &c.val.data[i]->localKeyId;
ret = _hx509_certs_find(c.certs, &q, &cert);
if (ret == 0) {
hx509_private_key key;
ret = _hx509_parse_private_key(&c.val.data[i]->alg.algorithm,
c.val.data[i]->data.data,
c.val.data[i]->data.length,
&key);
if (ret == 0)
_hx509_cert_assign_key(cert, key);
else
printf("failed to parse key: %d\n", ret);
hx509_cert_free(cert);
}
free_octet_string(&c.val.data[i]->localKeyId);
free_octet_string(&c.val.data[i]->data);
free_AlgorithmIdentifier(&c.val.data[i]->alg);
free(c.val.data[i]);
}
free(c.val.data);
{
struct ks_pkcs12 *p12;
p12 = malloc(sizeof(*p12));
if (p12 == NULL) {
abort();
}
memset(p12, 0, sizeof(*p12));
p12->certs = c.certs;
*data = p12;
}
ret = 0;
out:
return ret;
}
static int
p12_free(hx509_certs certs, void *data)
{
struct ks_pkcs12 *p12 = data;
hx509_certs_free(&p12->certs);
free(p12);
return 0;
}
static int
p12_iter_start(hx509_certs certs, void *data, void **cursor)
{
struct ks_pkcs12 *p12 = data;
return hx509_certs_start_seq(p12->certs, cursor);
}
static int
p12_iter(hx509_certs certs, void *data, void *cursor, hx509_cert *cert)
{
struct ks_pkcs12 *p12 = data;
return hx509_certs_next_cert(p12->certs, cursor, cert);
}
static int
p12_iter_end(hx509_certs certs,
void *data,
void *cursor)
{
struct ks_pkcs12 *p12 = data;
return hx509_certs_end_seq(p12->certs, cursor);
}
static struct hx509_keyset_ops keyset_pkcs12 = {
"PKCS12",
0,
p12_init,
p12_free,
NULL,
NULL,
p12_iter_start,
p12_iter,
p12_iter_end
};
void
_hx509_ks_pkcs12_register(void)
{
_hx509_ks_register(&keyset_pkcs12);
}

187
lib/hx509/lock.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2005 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$");
struct hx509_lock_data {
struct _hx509_password password;
hx509_certs certs;
hx509_prompter_fct *prompt;
void *prompt_data;
};
static struct hx509_lock_data empty_lock_data = {
{ 0, NULL }
};
hx509_lock _hx509_empty_lock = &empty_lock_data;
/*
*
*/
int
hx509_lock_init(hx509_lock *lock)
{
hx509_lock l;
int ret;
*lock = NULL;
l = calloc(1, sizeof(*l));
if (l == NULL)
return ENOMEM;
ret = hx509_certs_init("MEMORY:locks-internal", 0, NULL, &l->certs);
if (ret) {
free(l);
return ret;
}
*lock = l;
return 0;
}
int
hx509_lock_add_password(hx509_lock lock, const char *password)
{
void *d;
char *s;
s = strdup(password);
if (s == NULL)
return ENOMEM;
d = realloc(lock->password.val,
(lock->password.len + 1) * sizeof(lock->password.val[0]));
if (d == NULL) {
free(s);
return ENOMEM;
}
lock->password.val = d;
lock->password.val[lock->password.len] = s;
lock->password.len++;
return 0;
}
const struct _hx509_password *
_hx509_lock_get_passwords(hx509_lock lock)
{
return &lock->password;
}
void
hx509_lock_reset_passwords(hx509_lock lock)
{
int i;
for (i = 0; i < lock->password.len; i++)
free(lock->password.val[i]);
free(lock->password.val);
lock->password.val = NULL;
lock->password.len = 0;
}
int
hx509_lock_add_cert(hx509_lock lock, hx509_cert cert)
{
return hx509_certs_add(lock->certs, cert);
}
int
hx509_lock_add_certs(hx509_lock lock, hx509_certs certs)
{
return hx509_certs_merge(lock->certs, certs);
}
void
hx509_lock_reset_certs(hx509_lock lock)
{
hx509_certs certs = lock->certs;
int ret;
ret = hx509_certs_init("MEMORY:locks-internal", 0, NULL, &lock->certs);
if (ret == 0)
hx509_certs_free(&certs);
else
lock->certs = certs;
}
int
_hx509_lock_find_cert(hx509_lock lock, const hx509_query *q, hx509_cert *c)
{
*c = NULL;
return 0;
}
int
hx509_lock_set_prompter(hx509_lock lock, hx509_prompter_fct *prompt)
{
lock->prompt = prompt;
return 0;
}
int
hx509_lock_set_prompter_data(hx509_lock lock, void *data)
{
lock->prompt_data = data;
return 0;
}
void
hx509_lock_reset_promper(hx509_lock lock)
{
lock->prompt = NULL;
lock->prompt_data = NULL;
}
int
hx509_lock_prompt(hx509_lock lock, hx509_prompt *prompt)
{
if (lock->prompt == NULL) {
strlcpy(prompt->reply->data, "", prompt->reply->length);
return 0;
}
return (*lock->prompt)(lock->prompt_data, prompt);
}
void
hx509_lock_free(hx509_lock lock)
{
hx509_certs_free(&lock->certs);
hx509_lock_reset_passwords(lock);
memset(lock, 0, sizeof(*lock));
free(lock);
}

322
lib/hx509/name.c Normal file
View File

@@ -0,0 +1,322 @@
/*
* Copyright (c) 2004 - 2005 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$");
/*
* name parsing from rfc2253
* fix so parsing rfc1779 works too
* rfc3280
*/
#define oid_enc(n) { sizeof(n)/sizeof(n[0]), n }
static unsigned country_num[] = { 2, 5, 4, 6 };
static heim_oid country_oid = oid_enc(country_num);
static unsigned organizationName_num[] = { 2, 5, 4, 10 };
static heim_oid organizationName_oid = oid_enc(organizationName_num);
static unsigned commonName_num[] = { 2, 5, 4, 3 };
static heim_oid commonName_oid = oid_enc(commonName_num);
static unsigned localityName_num[] = { 2, 5, 4, 7 };
static heim_oid localityName_oid = oid_enc(localityName_num);
static unsigned email_num[] = { 1, 2, 840, 113549, 1, 9, 1 };
static heim_oid email_oid = oid_enc(email_num);
static unsigned uid_num[] = { 0, 9, 2342, 19200300, 100, 1, 1 };
static heim_oid uid_oid = oid_enc(uid_num);
static const struct {
char *n;
heim_oid *o;
} no[] = {
{ "C", &country_oid },
{ "CN", &commonName_oid },
{ "O", &organizationName_oid },
{ "L", &localityName_oid },
{ "Email", &email_oid },
{ "UID", &uid_oid }
};
static char *
quote_string(const char *f, size_t len, size_t *rlen)
{
size_t i, j, tolen;
const unsigned char *from = f;
unsigned char *to;
tolen = len * 3 + 1;
to = malloc(tolen);
if (to == NULL)
return NULL;
for (i = 0, j = 0; i < len; i++) {
if (from[i] == ' ' && i + 1 < len)
to[j++] = from[i];
else if (from[i] == ',' || from[i] == '=' || from[i] == '+' ||
from[i] == '<' || from[i] == '>' || from[i] == '#' ||
from[i] == ';' || from[i] == ' ')
{
to[j++] = '\\';
to[j++] = from[i];
} else if (from[i] >= 32 && from[i] <= 127) {
to[j++] = from[i];
} else {
int l = snprintf(&to[j], tolen - j - 1,
"#%02x", (unsigned int)from[i]);
j += l;
}
}
to[j] = '\0';
*rlen = j;
return to;
}
static int
append_string(char **str, size_t *total_len, char *ss, size_t len, int quote)
{
char *s, *qs;
if (quote)
qs = quote_string(ss, len, &len);
else
qs = ss;
s = realloc(*str, len + *total_len + 1);
if (s == NULL)
abort();
memcpy(s + *total_len, qs, len);
if (qs != ss)
free(qs);
s[*total_len + len] = '\0';
*str = s;
*total_len += len;
return 0;
}
static char *
oidtostring(const heim_oid *type)
{
char *s = NULL, *ss;
size_t i, total_len = 0;
for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {
if (heim_oid_cmp(no[i].o, type) == 0)
return strdup(no[i].n);
}
for (i = 0; i < type->length; i++) {
asprintf(&ss, "%u", type->components[i]);
append_string(&s, &total_len, ss, strlen(ss), 0);
if (i + 1 < type->length)
append_string(&s, &total_len, ".", 1, 0);
}
return s;
}
int
hx509_name_to_string(const hx509_name name, char **str)
{
const Name *n = &name->der_name;
ssize_t total_len = 0;
int i, j;
*str = strdup("");
if (*str == NULL)
return ENOMEM;
for (i = 0 ; i < n->u.rdnSequence.len; i++) {
char *ss;
int len;
for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {
DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value;
char *oidname;
oidname = oidtostring(&n->u.rdnSequence.val[i].val[j].type);
switch(ds->element) {
case choice_DirectoryString_ia5String:
ss = ds->u.ia5String;
break;
case choice_DirectoryString_printableString:
ss = ds->u.ia5String;
break;
case choice_DirectoryString_utf8String:
ss = ds->u.ia5String;
break;
#if 0
case choice_DirectoryString_bmpstring:
ss = ds->u.bmpstring;
break;
#endif
default:
abort();
}
append_string(str, &total_len, oidname, strlen(oidname), 0);
free(oidname);
append_string(str, &total_len, "=", 1, 0);
len = strlen(ss);
append_string(str, &total_len, ss, len, 1);
if (j + 1 < n->u.rdnSequence.val[i].len)
append_string(str, &total_len, "+", 1, 0);
}
if (i + 1 < n->u.rdnSequence.len)
append_string(str, &total_len, ", ", 2, 0);
}
return 0;
}
/*
* XXX this function is broken, it needs to compare code points, not
* bytes.
*/
int
_hx509_name_ds_cmp(const DirectoryString *ds1, const DirectoryString *ds2)
{
int c;
c = ds1->element - ds2->element;
if (c)
return c;
switch(ds1->element) {
case choice_DirectoryString_ia5String:
c = strcmp(ds1->u.ia5String, ds2->u.ia5String);
break;
case choice_DirectoryString_teletexString:
c = heim_octet_string_cmp(&ds1->u.teletexString,
&ds2->u.teletexString);
break;
case choice_DirectoryString_printableString:
c = strcmp(ds1->u.printableString, ds2->u.printableString);
break;
case choice_DirectoryString_utf8String:
c = strcmp(ds1->u.utf8String, ds2->u.utf8String);
break;
case choice_DirectoryString_universalString:
c = heim_universal_string_cmp(&ds1->u.universalString,
&ds2->u.universalString);
break;
case choice_DirectoryString_bmpString:
c = heim_bmp_string_cmp(&ds1->u.bmpString,
&ds2->u.bmpString);
break;
default:
return 1;
}
return 0;
}
int
_hx509_name_cmp(const Name *n1, const Name *n2)
{
int i, j, c;
c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;
if (c)
return c;
for (i = 0 ; i < n1->u.rdnSequence.len; i++) {
c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;
if (c)
return c;
for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {
c = heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,
&n1->u.rdnSequence.val[i].val[j].type);
if (c)
return c;
c = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,
&n2->u.rdnSequence.val[i].val[j].value);
if (c)
return c;
}
}
return 0;
}
int
_hx509_name_from_Name(const Name *n, hx509_name *name)
{
int ret;
*name = calloc(1, sizeof(**name));
if (*name == NULL)
return ENOMEM;
ret = copy_Name(n, &(*name)->der_name);
if (ret) {
free(*name);
*name = NULL;
}
return ret;
}
static int
hx509_der_parse_name(const void *data, size_t length, hx509_name *name)
{
int ret;
Name n;
*name = NULL;
ret = decode_Name(data, length, &n, NULL);
if (ret)
return ret;
return _hx509_name_from_Name(&n, name);
}
void
hx509_name_free(hx509_name *name)
{
free_Name(&(*name)->der_name);
memset(*name, 0, sizeof(**name));
free(*name);
*name = NULL;
}
int
hx509_parse_name(const void *data, size_t length, char **str)
{
hx509_name name;
int ret;
ret = hx509_der_parse_name(data, length, &name);
if (ret)
return ret;
ret = hx509_name_to_string(name, str);
hx509_name_free(&name);
return ret;
}

576
lib/hx509/p11.c Normal file
View File

@@ -0,0 +1,576 @@
/*
* Copyright (c) 2004 - 2005 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$");
/* http://developer.netscape.com/support/faqs/pkcs_11.html */
#include <openssl/ui.h>
#include <dlfcn.h>
#include "pkcs11u.h"
#include "pkcs11.h"
typedef struct hx509_security_device_data *hx509_security_device;
typedef struct hx509_keyset_data *hx509_keyset;
struct p11_slot {
int flags;
#define P11_SESSION 1
#define P11_LOGIN_REQ 2
#define P11_LOGIN_DONE 4
CK_SESSION_HANDLE session;
CK_SLOT_ID id;
CK_BBOOL token;
char *name;
char *pin;
};
struct hx509_security_device_data {
int refcount;
void *handle;
CK_FUNCTION_LIST_PTR funcs;
CK_ULONG num_slots;
struct p11_slot *slots;
int selected_slot; /* XXX */
};
#define P11SESSION(module) ((module)->slots[(module)->selected_slot].session)
#define P11FUNC(module,f,args) (*(module)->funcs->C_##f)args
struct hx509_keyset_data {
hx509_security_device device;
hx509_certs certs;
};
typedef struct hx509_key_data *hx509_key;
static int
hx509_p11_load_module(const char *fn, hx509_security_device *module)
{
CK_C_GetFunctionList getFuncs;
hx509_security_device p;
int ret;
*module = NULL;
p = calloc(1, sizeof(*p));
if (p == NULL)
return ENOMEM;
p->selected_slot = 0;
p->handle = dlopen(fn, RTLD_NOW);
if (p->handle == NULL) {
ret = EINVAL; /* XXX */
goto out;
}
getFuncs = dlsym(p->handle, "C_GetFunctionList");
if (getFuncs == NULL) {
ret = EINVAL;
goto out;
}
ret = (*getFuncs)(&p->funcs);
if (ret) {
ret = EINVAL;
goto out;
}
ret = P11FUNC(p, Initialize, (NULL_PTR));
if (ret != CKR_OK) {
ret = EINVAL;
goto out;
}
{
CK_INFO info;
ret = P11FUNC(p, GetInfo, (&info));
if (ret != CKR_OK) {
ret = EINVAL;
goto out;
}
printf("module information:\n");
printf("version: %04x.%04x\n",
(unsigned int)info.cryptokiVersion.major,
(unsigned int)info.cryptokiVersion.minor);
printf("manufacturer: %.*s\n",
(int)sizeof(info.manufacturerID) - 1,
info.manufacturerID);
printf("flags: 0x%04x\n", (unsigned int)info.flags);
printf("library description: %.*s\n",
(int)sizeof(info.libraryDescription) - 1,
info.libraryDescription);
printf("version: %04x.%04x\n",
(unsigned int)info.libraryVersion.major,
(unsigned int)info.libraryVersion.minor);
}
ret = P11FUNC(p, GetSlotList, (FALSE, NULL, &p->num_slots));
if (ret) {
ret = EINVAL;
goto out;
}
printf("num slots: %ld\n", (long)p->num_slots);
{
CK_SLOT_ID_PTR slot_ids;
int i, j;
slot_ids = malloc(p->num_slots * sizeof(*slot_ids));
if (slot_ids == NULL) {
ret = ENOMEM;
goto out;
}
ret = P11FUNC(p, GetSlotList, (FALSE, slot_ids, &p->num_slots));
if (ret) {
free(slot_ids);
ret = EINVAL;
goto out;
}
p->slots = calloc(p->num_slots, sizeof(p->slots[0]));
if (p->slots == NULL) {
free(slot_ids);
ret = ENOMEM;
goto out;
}
for (i = 0; i < p->num_slots; i++) {
CK_SLOT_INFO slot_info;
CK_TOKEN_INFO token_info;
printf("slot %d = id %d\n", i, (int)slot_ids[i]);
p->slots[i].id = slot_ids[i];
ret = P11FUNC(p, GetSlotInfo, (slot_ids[i], &slot_info));
if (ret)
continue;
for (j = sizeof(slot_info.slotDescription) - 1; j > 0; j--) {
char c = slot_info.slotDescription[j];
if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\0')
continue;
j++;
break;
}
asprintf(&p->slots[i].name, "%.*s (slot %d)",
j, slot_info.slotDescription, i);
printf("description: %s\n", p->slots[i].name);
printf("manufacturer: %.*s\n",
(int)sizeof(slot_info.manufacturerID),
slot_info.manufacturerID);
if ((slot_info.flags & CKF_TOKEN_PRESENT) == 0) {
printf("no token present\n");
continue;
}
ret = P11FUNC(p, GetTokenInfo, (slot_ids[i], &token_info));
if (ret)
continue;
printf("token present\n");
printf("label: %.*s\n",
(int)sizeof(token_info.label),
token_info.label);
printf("manufacturer: %.*s\n",
(int)sizeof(token_info.manufacturerID),
token_info.manufacturerID);
printf("model: %.*s\n",
(int)sizeof(token_info.model),
token_info.model);
printf("serialNumber: %.*s\n",
(int)sizeof(token_info.serialNumber),
token_info.serialNumber);
printf("flags: 0x%04x\n", (unsigned int)token_info.flags);
printf("slotinfo.flags 0x%x & 0x%x = 0x%x\n",
(int)slot_info.flags, (int)CKF_LOGIN_REQUIRED,
(int)(slot_info.flags & CKF_LOGIN_REQUIRED));
if (token_info.flags & CKF_LOGIN_REQUIRED) {
printf("login required\n");
p->slots[i].flags |= P11_LOGIN_REQ;
}
}
}
*module = p;
return 0;
out:
if (p->slots)
free(p->slots);
if (p->handle)
dlclose(p->handle);
free(p);
return ret;
}
static int
p11_get_session(hx509_security_device module, const char *conf, int slot)
{
CK_RV ret;
module->selected_slot = slot;
if (slot >= module->num_slots)
return EINVAL;
if (module->slots[slot].flags & P11_SESSION)
return EINVAL; /* XXX */
ret = P11FUNC(module, OpenSession, (module->slots[slot].id,
CKF_SERIAL_SESSION,
NULL,
NULL,
&module->slots[slot].session));
if (ret != CKR_OK)
return EINVAL;
module->slots[slot].flags |= P11_SESSION;
if ((module->slots[slot].flags & P11_LOGIN_REQ) &&
(module->slots[slot].flags & P11_LOGIN_DONE) == 0) {
char pin[20];
char *prompt;
module->slots[slot].flags |= P11_LOGIN_DONE;
asprintf(&prompt, "PIN code for %s: ", module->slots[slot].name);
if (UI_UTIL_read_pw_string(pin, sizeof(pin), prompt, 0)) {
printf("no pin");
goto out;
}
free(prompt);
ret = P11FUNC(module, Login,
(P11SESSION(module), CKU_USER, "3962", 4));
if (ret != CKR_OK)
printf("login failed\n");
else
module->slots[slot].pin = strdup(pin);
out:;
}
return 0;
}
static int
p11_put_session(hx509_security_device module, int slot)
{
int ret;
if (module->slots[slot].flags & P11_SESSION)
return EINVAL;
ret = P11FUNC(module, CloseSession, (module->slots[slot].session));
if (ret != CKR_OK)
return EINVAL;
return 0;
}
static int
iterate_entries(hx509_security_device module, hx509_certs ks,
CK_ATTRIBUTE *search_data, int num_search_data,
CK_ATTRIBUTE *query, int num_query,
int (*func)(void *, CK_ATTRIBUTE *, int), void *ptr)
{
CK_OBJECT_HANDLE object;
CK_ULONG object_count;
int ret, i;
printf("current slot: %d\n", module->selected_slot);
ret = P11FUNC(module, FindObjectsInit,
(P11SESSION(module), search_data, num_search_data));
if (ret != CKR_OK) {
return -1;
}
while (1) {
ret = P11FUNC(module, FindObjects,
(P11SESSION(module), &object, 1, &object_count));
if (ret != CKR_OK) {
return -1;
}
printf("object count = %d\n", (int)object_count);
if (object_count == 0)
break;
for (i = 0; i < num_query; i++)
query[i].pValue = NULL;
ret = P11FUNC(module, GetAttributeValue,
(P11SESSION(module), object, query, num_query));
if (ret != CKR_OK) {
return -1;
}
for (i = 0; i < num_query; i++) {
printf("id %d len = %d\n", i, (int)query[i].ulValueLen);
query[i].pValue = malloc(query[i].ulValueLen);
if (query[i].pValue == NULL) {
ret = ENOMEM;
goto out;
}
}
ret = P11FUNC(module, GetAttributeValue,
(P11SESSION(module), object, query, num_query));
if (ret != CKR_OK) {
ret = -1;
goto out;
}
ret = (*func)(ptr, query, num_query);
if (ret)
goto out;
for (i = 0; i < num_query; i++) {
if (query[i].pValue)
free(query[i].pValue);
query[i].pValue = NULL;
}
}
out:
for (i = 0; i < num_query; i++) {
if (query[i].pValue)
free(query[i].pValue);
query[i].pValue = NULL;
}
ret = P11FUNC(module, FindObjectsFinal, (P11SESSION(module)));
if (ret != CKR_OK) {
return -2;
}
return 0;
}
static int
print_id(void *ptr, CK_ATTRIBUTE *query, int num_query)
{
printf("id: %.*s\n", (int)query[0].ulValueLen, (char *)query[0].pValue);
return 0;
}
static int
print_cert(void *ptr, CK_ATTRIBUTE *query, int num_query)
{
hx509_validate_ctx ctx;
hx509_cert cert;
Certificate c;
int ret;
printf("id: %d\n", (int)query[0].ulValueLen);
memset(&c, 0, sizeof(c));
ret = decode_Certificate(query[1].pValue, query[1].ulValueLen,
&c, NULL);
if (ret) {
printf("decode_Certificate failed with %d\n", ret);
return 0;
}
ret = hx509_cert_init(&c, &cert);
if (ret)
abort();
free_Certificate(&c);
hx509_validate_ctx_init(&ctx);
hx509_validate_ctx_set_print(ctx, hx509_print_stdout, stdout);
hx509_validate_ctx_add_flags(ctx, HX509_VALIDATE_F_VERBOSE);
hx509_validate_cert(ctx, cert);
hx509_validate_ctx_free(ctx);
hx509_cert_free(cert);
return 0;
}
static int
p11_list_keys(hx509_security_device module, hx509_certs ks)
{
CK_OBJECT_CLASS key_class;
CK_ATTRIBUTE search_data[] = {
{CKA_CLASS, &key_class, sizeof(key_class)},
};
CK_ATTRIBUTE query_data[2] = {
{CKA_ID, NULL, 0},
{CKA_VALUE, NULL, 0}
};
int ret;
printf("---- private\n");
key_class = CKO_PRIVATE_KEY;
ret = iterate_entries(module, ks, search_data, 1,
query_data, 1,
print_id, NULL);
if (ret) {
return ret;
}
printf("---- public\n");
key_class = CKO_PUBLIC_KEY;
ret = iterate_entries(module, ks, search_data, 1,
query_data, 1,
print_id, NULL);
if (ret) {
return ret;
}
printf("---- cert\n");
key_class = CKO_CERTIFICATE;
ret = iterate_entries(module, ks, search_data, 1,
query_data, 2,
print_cert, NULL);
if (ret) {
return ret;
}
printf("----\n");
return 0;
}
static int
security_device_add(hx509_security_device *device, const char *conf)
{
hx509_security_device module;
char *c, *fn;
int ret;
*device = NULL;
c = strdup(conf);
if (c == NULL)
return ENOMEM;
fn = strchr(c, ':');
if (fn)
*fn++ = '\0';
else
fn = "/usr/lib/default-pkcs11.so";
if (strcasecmp(c, "PKCS11") != 0) {
free(c);
return EINVAL;
}
ret = hx509_p11_load_module(fn, &module);
free(c);
if (ret)
return ret;
*device = module;
return 0;
}
int
hx509_keyset_init(const char *file, const char *conf)
{
hx509_security_device module;
hx509_keyset ks;
int ret, slot;
ret = security_device_add(&module, file);
if (ret) {
printf("security_device_add: %d\n", ret);
return 0;
}
module->refcount++;
ks = calloc(1, sizeof(*ks));
if (ks == NULL)
return ENOMEM;
ks->device = module;
ret = hx509_certs_init("MEMORY:pkcs-11-store", 0, NULL, &ks->certs);
if (ret)
goto out;
/*
* XXX just check if the device change changed, and if that case
* refresh contents of cache
*/
slot = 0;
ret = p11_get_session(module, conf, slot);
if (ret)
goto out;
/* fetch certificates and keys */
ret = p11_list_keys(module, ks->certs);
if (ret)
goto out_session;
out_session:
ret = p11_put_session(module, slot);
out:
if (ret) {
hx509_certs_free(&ks->certs);
memset(ks, 0, sizeof(ks));
free(ks);
module->refcount--;
} else {
hx509_certs_iter(ks->certs, hx509_ci_print_names, stdout);
}
return 0;
}

387
lib/hx509/print.c Normal file
View File

@@ -0,0 +1,387 @@
/*
* Copyright (c) 2004 - 2005 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$");
struct hx509_validate_ctx_data {
int flags;
hx509_vprint_func vprint_func;
void *ctx;
};
/*
*
*/
static int
Time2string(const Time *T, char **str)
{
time_t t;
char *s;
struct tm *tm;
*str = NULL;
t = _hx509_Time2time_t(T);
tm = gmtime (&t);
s = malloc(30);
if (s == NULL)
return ENOMEM;
strftime(s, 30, "%Y-%m-%d %M:%M:%S", tm);
*str = s;
return 0;
}
void
hx509_print_stdout(void *ctx, const char *fmt, va_list va)
{
FILE *f = ctx;
vfprintf(f, fmt, va);
}
void
hx509_print_func(hx509_vprint_func func, void *ctx, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
(*func)(ctx, fmt, va);
va_end(va);
}
int
hx509_oid_sprint(const heim_oid *oid, char **str)
{
char *s, *r;
int i;
s = strdup("");
for (i = 0; i < oid->length; i++) {
asprintf(&r, "%s%d%s", s, oid->components[i],
i < oid->length - 1 ? "." : "");
free(s);
s = r;
}
*str = s;
return 0;
}
void
hx509_oid_print(const heim_oid *oid, hx509_vprint_func func, void *ctx)
{
char *str;
hx509_oid_sprint(oid, &str);
hx509_print_func(func, ctx, "%s", str);
free(str);
}
void
hx509_bitstring_print(const heim_bit_string *b,
hx509_vprint_func func, void *ctx)
{
int i;
hx509_print_func(func, ctx, "\tlength: %d\n\t", b->length);
for (i = 0; i < (b->length + 7) / 8; i++)
hx509_print_func(func, ctx, "%02x%s%s",
((unsigned char *)b->data)[i],
i < (b->length - 7) / 8
&& (i == 0 || (i % 16) != 15) ? ":" : "",
i != 0 && (i % 16) == 15 ?
(i <= ((b->length + 7) / 8 - 2) ? "\n\t" : "\n"):"");
}
/*
*
*/
static void
validate_vprint(void *c, const char *fmt, va_list va)
{
hx509_validate_ctx ctx = c;
if (ctx->vprint_func == NULL)
return;
(ctx->vprint_func)(ctx->ctx, fmt, va);
}
static void
validate_print(hx509_validate_ctx ctx, int flags, const char *fmt, ...)
{
va_list va;
if ((ctx->flags & flags) == 0)
return;
va_start(va, fmt);
validate_vprint(ctx, fmt, va);
va_end(va);
}
enum critical_flag { D_C = 0, S_C, S_N_C, M_C, M_N_C };
static int
check_Null(hx509_validate_ctx ctx, enum critical_flag cf, const Extension *e)
{
switch(cf) {
case D_C:
break;
case S_C:
if (!e->critical)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"\tCritical not set on SHOULD\n");
break;
case S_N_C:
if (e->critical)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"\tCritical set on SHOULD NOT\n");
break;
case M_C:
if (!e->critical)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"\tCritical not set on MUST\n");
break;
case M_N_C:
if (e->critical)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"\tCritical set on MUST NOT\n");
break;
default:
abort();
}
return 0;
}
static int
check_subjectKeyIdentifier(hx509_validate_ctx ctx,
enum critical_flag cf,
const Extension *e)
{
check_Null(ctx, cf, e);
return 0;
}
static int
check_subjectAltName(hx509_validate_ctx ctx,
enum critical_flag cf,
const Extension *e)
{
GeneralNames gn;
size_t size;
int ret;
check_Null(ctx, cf, e);
ret = decode_GeneralNames(e->extnValue.data, e->extnValue.length,
&gn, &size);
if (ret) {
printf("\tret = %d while decoding GeneralNames\n", ret);
return 0;
}
free_GeneralNames(&gn);
return 0;
}
static int
check_basicConstraints(hx509_validate_ctx ctx,
enum critical_flag cf,
const Extension *e)
{
BasicConstraints b;
size_t size;
int ret;
check_Null(ctx, cf, e);
ret = decode_BasicConstraints(e->extnValue.data, e->extnValue.length,
&b, &size);
if (ret) {
printf("\tret = %d while decoding BasicConstraints\n", ret);
return 0;
}
if (size != e->extnValue.length)
printf("\tlength of der data isn't same as extension\n");
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"\tis %sa CA\n", b.cA && *b.cA ? "" : "NOT ");
if (b.pathLenConstraint)
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"\tpathLenConstraint: %d\n", *b.pathLenConstraint);
return 0;
}
struct {
const char *name;
const heim_oid *(*oid)(void);
int (*func)(hx509_validate_ctx ctx,
enum critical_flag cf,
const Extension *);
enum critical_flag cf;
} check_extension[] = {
#define ext(name, checkname) #name, &oid_id_x509_ce_##name, check_##checkname
{ ext(subjectDirectoryAttributes, Null), M_N_C },
{ ext(subjectKeyIdentifier, subjectKeyIdentifier), M_N_C },
{ ext(keyUsage, Null), S_C },
{ ext(subjectAltName, subjectAltName), M_N_C },
{ ext(issuerAltName, Null), S_N_C },
{ ext(basicConstraints, basicConstraints), M_C },
{ ext(cRLNumber, Null), M_N_C },
{ ext(cRLReasons, Null), M_N_C },
{ ext(holdInstructionCode, Null), M_N_C },
{ ext(invalidityDate, Null), M_N_C },
{ ext(deltaCRLIndicator, Null), M_C },
{ ext(issuingDistributionPoint, Null), M_C },
{ ext(certificateIssuer, Null), M_C },
{ ext(nameConstraints, Null), M_C },
{ ext(cRLDistributionPoints, Null), S_N_C },
{ ext(certificatePolicies, Null) },
{ ext(policyMappings, Null), M_N_C },
{ ext(authorityKeyIdentifier, Null), M_N_C },
{ ext(policyConstraints, Null), D_C },
{ ext(extKeyUsage, Null), D_C },
{ ext(freshestCRL, Null), M_N_C },
{ ext(inhibitAnyPolicy, Null), M_C },
{ NULL }
};
int
hx509_validate_ctx_init(hx509_validate_ctx *ctx)
{
*ctx = malloc(sizeof(**ctx));
if (*ctx == NULL)
return ENOMEM;
memset(*ctx, 0, sizeof(**ctx));
return 0;
}
void
hx509_validate_ctx_set_print(hx509_validate_ctx ctx,
hx509_vprint_func func,
void *c)
{
ctx->vprint_func = func;
ctx->ctx = c;
}
void
hx509_validate_ctx_add_flags(hx509_validate_ctx ctx, int flags)
{
ctx->flags |= flags;
}
void
hx509_validate_ctx_free(hx509_validate_ctx ctx)
{
free(ctx);
}
int
hx509_validate_cert(hx509_validate_ctx ctx, hx509_cert cert)
{
Certificate *c = _hx509_get_cert(cert);
TBSCertificate *t = &c->tbsCertificate;
hx509_name name;
char *str;
if (_hx509_cert_get_version(c) != 3)
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"Not version 3 certificate\n");
if (t->version && *t->version < 2 && t->extensions)
validate_print(ctx, HX509_VALIDATE_F_VALIDATE,
"Not version 3 certificate with extensions\n");
_hx509_name_from_Name(&t->subject, &name);
hx509_name_to_string(name, &str);
hx509_name_free(&name);
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"subject name: %s\n", str);
free(str);
_hx509_name_from_Name(&t->issuer, &name);
hx509_name_to_string(name, &str);
hx509_name_free(&name);
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"issuer name: %s\n", str);
free(str);
validate_print(ctx, HX509_VALIDATE_F_VERBOSE,
"Validity:\n");
Time2string(&t->validity.notBefore, &str);
validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "\tnotBefore %s\n", str);
free(str);
Time2string(&t->validity.notAfter, &str);
validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "\tnotAfter %s\n", str);
free(str);
if (t->extensions) {
int i, j;
if (t->extensions->len == 0) {
validate_print(ctx,
HX509_VALIDATE_F_VALIDATE|HX509_VALIDATE_F_VERBOSE,
"The empty extensions list is not "
"allowed by PKIX\n");
}
for (i = 0; i < t->extensions->len; i++) {
for (j = 0; check_extension[j].name; j++)
if (heim_oid_cmp((*check_extension[j].oid)(),
&t->extensions->val[i].extnID) == 0)
break;
if (check_extension[j].name == NULL) {
int flags = HX509_VALIDATE_F_VERBOSE;
if (t->extensions->val[i].critical)
flags |= HX509_VALIDATE_F_VALIDATE;
validate_print(ctx, flags, "don't know what ");
if (t->extensions->val[i].critical)
validate_print(ctx, flags, "and is CRITICAL ");
if (ctx->flags & flags)
hx509_oid_print(&t->extensions->val[i].extnID,
validate_vprint, ctx);
validate_print(ctx, flags, " is\n");
continue;
}
validate_print(ctx,
HX509_VALIDATE_F_VALIDATE|HX509_VALIDATE_F_VERBOSE,
"checking extention: %s\n",
check_extension[j].name);
(*check_extension[j].func)(ctx,
check_extension[j].cf,
&t->extensions->val[i]);
}
} else
validate_print(ctx, HX509_VALIDATE_F_VERBOSE, "no extentions\n");
return 0;
}

299
lib/hx509/ref/pkcs11.h Normal file
View File

@@ -0,0 +1,299 @@
/* pkcs11.h include file for PKCS #11. */
/* $Revision$ */
/* License to copy and use this software is granted provided that it is
* identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
* (Cryptoki)" in all material mentioning or referencing this software.
* License is also granted to make and use derivative works provided that
* such works are identified as "derived from the RSA Security Inc. PKCS #11
* Cryptographic Token Interface (Cryptoki)" in all material mentioning or
* referencing the derived work.
* RSA Security Inc. makes no representations concerning either the
* merchantability of this software or the suitability of this software for
* any particular purpose. It is provided "as is" without express or implied
* warranty of any kind.
*/
#ifndef _PKCS11_H_
#define _PKCS11_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Before including this file (pkcs11.h) (or pkcs11t.h by
* itself), 6 platform-specific macros must be defined. These
* macros are described below, and typical definitions for them
* are also given. Be advised that these definitions can depend
* on both the platform and the compiler used (and possibly also
* on whether a Cryptoki library is linked statically or
* dynamically).
*
* In addition to defining these 6 macros, the packing convention
* for Cryptoki structures should be set. The Cryptoki
* convention on packing is that structures should be 1-byte
* aligned.
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, this might be done by using the following
* preprocessor directive before including pkcs11.h or pkcs11t.h:
*
* #pragma pack(push, cryptoki, 1)
*
* and using the following preprocessor directive after including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(pop, cryptoki)
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, this might be done by using
* the following preprocessor directive before including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(1)
*
* In a UNIX environment, you're on your own for this. You might
* not need to do (or be able to do!) anything.
*
*
* Now for the macros:
*
*
* 1. CK_PTR: The indirection string for making a pointer to an
* object. It can be used like this:
*
* typedef CK_BYTE CK_PTR CK_BYTE_PTR;
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, it might be defined by:
*
* #define CK_PTR *
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, it might be defined by:
*
* #define CK_PTR far *
*
* In a typical UNIX environment, it might be defined by:
*
* #define CK_PTR *
*
*
* 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
* an exportable Cryptoki library function definition out of a
* return type and a function name. It should be used in the
* following fashion to define the exposed Cryptoki functions in
* a Cryptoki library:
*
* CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
* CK_VOID_PTR pReserved
* )
* {
* ...
* }
*
* If you're using Microsoft Developer Studio 5.0 to define a
* function in a Win32 Cryptoki .dll, it might be defined by:
*
* #define CK_DEFINE_FUNCTION(returnType, name) \
* returnType __declspec(dllexport) name
*
* If you're using an earlier version of Microsoft Developer
* Studio to define a function in a Win16 Cryptoki .dll, it
* might be defined by:
*
* #define CK_DEFINE_FUNCTION(returnType, name) \
* returnType __export _far _pascal name
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DEFINE_FUNCTION(returnType, name) \
* returnType name
*
*
* 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
* an importable Cryptoki library function declaration out of a
* return type and a function name. It should be used in the
* following fashion:
*
* extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
* CK_VOID_PTR pReserved
* );
*
* If you're using Microsoft Developer Studio 5.0 to declare a
* function in a Win32 Cryptoki .dll, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __declspec(dllimport) name
*
* If you're using an earlier version of Microsoft Developer
* Studio to declare a function in a Win16 Cryptoki .dll, it
* might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __export _far _pascal name
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType name
*
*
* 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
* which makes a Cryptoki API function pointer declaration or
* function pointer type declaration out of a return type and a
* function name. It should be used in the following fashion:
*
* // Define funcPtr to be a pointer to a Cryptoki API function
* // taking arguments args and returning CK_RV.
* CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
*
* or
*
* // Define funcPtrType to be the type of a pointer to a
* // Cryptoki API function taking arguments args and returning
* // CK_RV, and then define funcPtr to be a variable of type
* // funcPtrType.
* typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
* funcPtrType funcPtr;
*
* If you're using Microsoft Developer Studio 5.0 to access
* functions in a Win32 Cryptoki .dll, in might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __declspec(dllimport) (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to access functions in a Win16 Cryptoki .dll, it might
* be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __export _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType (* name)
*
*
* 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
* a function pointer type for an application callback out of
* a return type for the callback and a name for the callback.
* It should be used in the following fashion:
*
* CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
*
* to declare a function pointer, myCallback, to a callback
* which takes arguments args and returns a CK_RV. It can also
* be used like this:
*
* typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
* myCallbackType myCallback;
*
* If you're using Microsoft Developer Studio 5.0 to do Win32
* Cryptoki development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to do Win16 development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
*
* 6. NULL_PTR: This macro is the value of a NULL pointer.
*
* In any ANSI/ISO C environment (and in many others as well),
* this should best be defined by
*
* #ifndef NULL_PTR
* #define NULL_PTR 0
* #endif
*/
/* All the various Cryptoki types and #define'd values are in the
* file pkcs11t.h. */
#include "pkcs11t.h"
#define __PASTE(x,y) x##y
/* ==============================================================
* Define the "extern" form of all the entry points.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
extern CK_DECLARE_FUNCTION(CK_RV, name)
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes. */
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define the typedef form of all the entry points. That is, for
* each Cryptoki function C_XXX, define a type CK_C_XXX which is
* a pointer to that kind of function.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes. */
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define structed vector of entry points. A CK_FUNCTION_LIST
* contains a CK_VERSION indicating a library's Cryptoki version
* and then a whole slew of function pointers to the routines in
* the library. This type was declared, but not defined, in
* pkcs11t.h.
* ==============================================================
*/
#define CK_PKCS11_FUNCTION_INFO(name) \
__PASTE(CK_,name) name;
struct CK_FUNCTION_LIST {
CK_VERSION version; /* Cryptoki version */
/* Pile all the function pointers into the CK_FUNCTION_LIST. */
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes. */
#include "pkcs11f.h"
};
#undef CK_PKCS11_FUNCTION_INFO
#undef __PASTE
#ifdef __cplusplus
}
#endif
#endif

912
lib/hx509/ref/pkcs11f.h Normal file
View File

@@ -0,0 +1,912 @@
/* pkcs11f.h include file for PKCS #11. */
/* $Revision$ */
/* License to copy and use this software is granted provided that it is
* identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
* (Cryptoki)" in all material mentioning or referencing this software.
* License is also granted to make and use derivative works provided that
* such works are identified as "derived from the RSA Security Inc. PKCS #11
* Cryptographic Token Interface (Cryptoki)" in all material mentioning or
* referencing the derived work.
* RSA Security Inc. makes no representations concerning either the
* merchantability of this software or the suitability of this software for
* any particular purpose. It is provided "as is" without express or implied
* warranty of any kind.
*/
/* This header file contains pretty much everything about all the */
/* Cryptoki function prototypes. Because this information is */
/* used for more than just declaring function prototypes, the */
/* order of the functions appearing herein is important, and */
/* should not be altered. */
/* General-purpose */
/* C_Initialize initializes the Cryptoki library. */
CK_PKCS11_FUNCTION_INFO(C_Initialize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
* cast to CK_C_INITIALIZE_ARGS_PTR
* and dereferenced */
);
#endif
/* C_Finalize indicates that an application is done with the
* Cryptoki library. */
CK_PKCS11_FUNCTION_INFO(C_Finalize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
);
#endif
/* C_GetInfo returns general information about Cryptoki. */
CK_PKCS11_FUNCTION_INFO(C_GetInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_INFO_PTR pInfo /* location that receives information */
);
#endif
/* C_GetFunctionList returns the function list. */
CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
#ifdef CK_NEED_ARG_LIST
(
CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
* function list */
);
#endif
/* Slot and token management */
/* C_GetSlotList obtains a list of slots in the system. */
CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
#ifdef CK_NEED_ARG_LIST
(
CK_BBOOL tokenPresent, /* only slots with tokens? */
CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
CK_ULONG_PTR pulCount /* receives number of slots */
);
#endif
/* C_GetSlotInfo obtains information about a particular slot in
* the system. */
CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the ID of the slot */
CK_SLOT_INFO_PTR pInfo /* receives the slot information */
);
#endif
/* C_GetTokenInfo obtains information about a particular token
* in the system. */
CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_TOKEN_INFO_PTR pInfo /* receives the token information */
);
#endif
/* C_GetMechanismList obtains a list of mechanism types
* supported by a token. */
CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of token's slot */
CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
CK_ULONG_PTR pulCount /* gets # of mechs. */
);
#endif
/* C_GetMechanismInfo obtains information about a particular
* mechanism possibly supported by a token. */
CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_MECHANISM_TYPE type, /* type of mechanism */
CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
);
#endif
/* C_InitToken initializes a token. */
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
CK_ULONG ulPinLen, /* length in bytes of the PIN */
CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
#endif
/* C_InitPIN initializes the normal user's PIN. */
CK_PKCS11_FUNCTION_INFO(C_InitPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
CK_ULONG ulPinLen /* length in bytes of the PIN */
);
#endif
/* C_SetPIN modifies the PIN of the user who is logged in. */
CK_PKCS11_FUNCTION_INFO(C_SetPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
CK_ULONG ulOldLen, /* length of the old PIN */
CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
CK_ULONG ulNewLen /* length of the new PIN */
);
#endif
/* Session management */
/* C_OpenSession opens a session between an application and a
* token. */
CK_PKCS11_FUNCTION_INFO(C_OpenSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the slot's ID */
CK_FLAGS flags, /* from CK_SESSION_INFO */
CK_VOID_PTR pApplication, /* passed to callback */
CK_NOTIFY Notify, /* callback function */
CK_SESSION_HANDLE_PTR phSession /* gets session handle */
);
#endif
/* C_CloseSession closes a session between an application and a
* token. */
CK_PKCS11_FUNCTION_INFO(C_CloseSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CloseAllSessions closes all sessions with a token. */
CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID /* the token's slot */
);
#endif
/* C_GetSessionInfo obtains information about the session. */
CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_SESSION_INFO_PTR pInfo /* receives session info */
);
#endif
/* C_GetOperationState obtains the state of the cryptographic operation
* in a session. */
CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* gets state */
CK_ULONG_PTR pulOperationStateLen /* gets state length */
);
#endif
/* C_SetOperationState restores the state of the cryptographic
* operation in a session. */
CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* holds state */
CK_ULONG ulOperationStateLen, /* holds state length */
CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
);
#endif
/* C_Login logs a user into a token. */
CK_PKCS11_FUNCTION_INFO(C_Login)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_USER_TYPE userType, /* the user type */
CK_UTF8CHAR_PTR pPin, /* the user's PIN */
CK_ULONG ulPinLen /* the length of the PIN */
);
#endif
/* C_Logout logs a user out from a token. */
CK_PKCS11_FUNCTION_INFO(C_Logout)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Object management */
/* C_CreateObject creates a new object. */
CK_PKCS11_FUNCTION_INFO(C_CreateObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
);
#endif
/* C_CopyObject copies an object, creating a new object for the
* copy. */
CK_PKCS11_FUNCTION_INFO(C_CopyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
);
#endif
/* C_DestroyObject destroys an object. */
CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject /* the object's handle */
);
#endif
/* C_GetObjectSize gets the size of an object in bytes. */
CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ULONG_PTR pulSize /* receives size of object */
);
#endif
/* C_GetAttributeValue obtains the value of one or more object
* attributes. */
CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_SetAttributeValue modifies the value of one or more object
* attributes */
CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_FindObjectsInit initializes a search for token and session
* objects that match a template. */
CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
CK_ULONG ulCount /* attrs in search template */
);
#endif
/* C_FindObjects continues a search for token and session
* objects that match a template, obtaining additional object
* handles. */
CK_PKCS11_FUNCTION_INFO(C_FindObjects)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
CK_ULONG ulMaxObjectCount, /* max handles to get */
CK_ULONG_PTR pulObjectCount /* actual # returned */
);
#endif
/* C_FindObjectsFinal finishes a search for token and session
* objects. */
CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Encryption and decryption */
/* C_EncryptInit initializes an encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of encryption key */
);
#endif
/* C_Encrypt encrypts single-part data. */
CK_PKCS11_FUNCTION_INFO(C_Encrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pData, /* the plaintext data */
CK_ULONG ulDataLen, /* bytes of plaintext */
CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
);
#endif
/* C_EncryptUpdate continues a multiple-part encryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext data len */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
);
#endif
/* C_EncryptFinal finishes a multiple-part encryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session handle */
CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
);
#endif
/* C_DecryptInit initializes a decryption operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of decryption key */
);
#endif
/* C_Decrypt decrypts encrypted data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Decrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedData, /* ciphertext */
CK_ULONG ulEncryptedDataLen, /* ciphertext length */
CK_BYTE_PTR pData, /* gets plaintext */
CK_ULONG_PTR pulDataLen /* gets p-text size */
);
#endif
/* C_DecryptUpdate continues a multiple-part decryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* encrypted data */
CK_ULONG ulEncryptedPartLen, /* input length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* p-text size */
);
#endif
/* C_DecryptFinal finishes a multiple-part decryption
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pLastPart, /* gets plaintext */
CK_ULONG_PTR pulLastPartLen /* p-text size */
);
#endif
/* Message digesting */
/* C_DigestInit initializes a message-digesting operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
);
#endif
/* C_Digest digests data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Digest)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* data to be digested */
CK_ULONG ulDataLen, /* bytes of data to digest */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets digest length */
);
#endif
/* C_DigestUpdate continues a multiple-part message-digesting
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* data to be digested */
CK_ULONG ulPartLen /* bytes of data to be digested */
);
#endif
/* C_DigestKey continues a multi-part message-digesting
* operation, by digesting the value of a secret key as part of
* the data already digested. */
CK_PKCS11_FUNCTION_INFO(C_DigestKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hKey /* secret key to digest */
);
#endif
/* C_DigestFinal finishes a multiple-part message-digesting
* operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
);
#endif
/* Signing and MACing */
/* C_SignInit initializes a signature (private key encryption)
* operation, where the signature is (will be) an appendix to
* the data, and plaintext cannot be recovered from the
*signature. */
CK_PKCS11_FUNCTION_INFO(C_SignInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of signature key */
);
#endif
/* C_Sign signs (encrypts with private key) data in a single
* part, where the signature is (will be) an appendix to the
* data, and plaintext cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_Sign)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignUpdate continues a multiple-part signature operation,
* where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* the data to sign */
CK_ULONG ulPartLen /* count of bytes to sign */
);
#endif
/* C_SignFinal finishes a multiple-part signature operation,
* returning the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignRecoverInit initializes a signature operation, where
* the data can be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of the signature key */
);
#endif
/* C_SignRecover signs data in a single operation, where the
* data can be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_SignRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* Verifying signatures and MACs */
/* C_VerifyInit initializes a verification operation, where the
* signature is an appendix to the data, and plaintext cannot
* cannot be recovered from the signature (e.g. DSA). */
CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_Verify verifies a signature in a single-part operation,
* where the signature is an appendix to the data, and plaintext
* cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_Verify)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* signed data */
CK_ULONG ulDataLen, /* length of signed data */
CK_BYTE_PTR pSignature, /* signature */
CK_ULONG ulSignatureLen /* signature length*/
);
#endif
/* C_VerifyUpdate continues a multiple-part verification
* operation, where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* signed data */
CK_ULONG ulPartLen /* length of signed data */
);
#endif
/* C_VerifyFinal finishes a multiple-part verification
* operation, checking the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen /* signature length */
);
#endif
/* C_VerifyRecoverInit initializes a signature verification
* operation, where the data is recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_VerifyRecover verifies a signature in a single-part
* operation, where the data is recovered from the signature. */
CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen, /* signature length */
CK_BYTE_PTR pData, /* gets signed data */
CK_ULONG_PTR pulDataLen /* gets signed data len */
);
#endif
/* Dual-function cryptographic operations */
/* C_DigestEncryptUpdate continues a multiple-part digesting
* and encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptDigestUpdate continues a multiple-part decryption and
* digesting operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets plaintext len */
);
#endif
/* C_SignEncryptUpdate continues a multiple-part signing and
* encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptVerifyUpdate continues a multiple-part decryption and
* verify operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets p-text length */
);
#endif
/* Key management */
/* C_GenerateKey generates a secret key, creating a new key
* object. */
CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* key generation mech. */
CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
CK_ULONG ulCount, /* # of attrs in template */
CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
);
#endif
/* C_GenerateKeyPair generates a public-key/private-key pair,
* creating new key objects. */
CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session
* handle */
CK_MECHANISM_PTR pMechanism, /* key-gen
* mech. */
CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
* for pub.
* key */
CK_ULONG ulPublicKeyAttributeCount, /* # pub.
* attrs. */
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
* for priv.
* key */
CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
* attrs. */
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
* key
* handle */
CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
* priv. key
* handle */
);
#endif
/* C_WrapKey wraps (i.e., encrypts) a key. */
CK_PKCS11_FUNCTION_INFO(C_WrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
CK_OBJECT_HANDLE hKey, /* key to be wrapped */
CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
);
#endif
/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
* key object. */
CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
CK_ULONG ulWrappedKeyLen, /* wrapped key len */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* C_DeriveKey derives a key from a base key, creating a new key
* object. */
CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
CK_OBJECT_HANDLE hBaseKey, /* base key */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* Random number generation */
/* C_SeedRandom mixes additional seed material into the token's
* random number generator. */
CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSeed, /* the seed material */
CK_ULONG ulSeedLen /* length of seed material */
);
#endif
/* C_GenerateRandom generates random data. */
CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR RandomData, /* receives the random data */
CK_ULONG ulRandomLen /* # of bytes to generate */
);
#endif
/* Parallel function management */
/* C_GetFunctionStatus is a legacy function; it obtains an
* updated status of a function running in parallel with an
* application. */
CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CancelFunction is a legacy function; it cancels a function
* running in parallel. */
CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Functions added in for Cryptoki Version 2.01 or later */
/* C_WaitForSlotEvent waits for a slot event (token insertion,
* removal, etc.) to occur. */
CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
#ifdef CK_NEED_ARG_LIST
(
CK_FLAGS flags, /* blocking/nonblocking flag */
CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
);
#endif

1440
lib/hx509/ref/pkcs11t.h Normal file

File diff suppressed because it is too large Load Diff

21
lib/hx509/ref/pkcs11u.h Normal file
View File

@@ -0,0 +1,21 @@
/* unix version adaption file */
#define CK_PTR *
#define CK_DEFINE_FUNCTION(returnType, name) \
returnType name
#define CK_DECLARE_FUNCTION(returnType, name) \
returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) \
returnType (* name)
#ifndef NULL_PTR
#define NULL_PTR NULL
#endif