Initial revision
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15716 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
52
lib/hx509/Makefile.am
Normal file
52
lib/hx509/Makefile.am
Normal 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
1232
lib/hx509/cert.c
Normal file
File diff suppressed because it is too large
Load Diff
1010
lib/hx509/cms.c
Normal file
1010
lib/hx509/cms.c
Normal file
File diff suppressed because it is too large
Load Diff
1312
lib/hx509/crypto.c
Normal file
1312
lib/hx509/crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
84
lib/hx509/file.c
Normal file
84
lib/hx509/file.c
Normal 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
77
lib/hx509/hx509.h
Normal 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
49
lib/hx509/hx509_err.et
Normal 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
126
lib/hx509/hx_locl.h
Normal 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
549
lib/hx509/hxtool.c
Normal 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
281
lib/hx509/keyset.c
Normal 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
233
lib/hx509/ks_file.c
Normal 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
150
lib/hx509/ks_mem.c
Normal 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
89
lib/hx509/ks_null.c
Normal 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
526
lib/hx509/ks_p12.c
Normal 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
187
lib/hx509/lock.c
Normal 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
322
lib/hx509/name.c
Normal 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
576
lib/hx509/p11.c
Normal 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
387
lib/hx509/print.c
Normal 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
299
lib/hx509/ref/pkcs11.h
Normal 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
912
lib/hx509/ref/pkcs11f.h
Normal 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
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
21
lib/hx509/ref/pkcs11u.h
Normal 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
|
||||
|
Reference in New Issue
Block a user