original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -0,0 +1,368 @@
/* crypto/x509/by_dir.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include "cryptlib.h"
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef MAC_OS_pre_X
# include <stat.h>
#else
# include <sys/stat.h>
#endif
#include <openssl/lhash.h>
#include <openssl/x509.h>
#ifdef _WIN32
# define stat _stat
#endif
typedef struct lookup_dir_st {
BUF_MEM *buffer;
int num_dirs;
char **dirs;
int *dirs_type;
int num_dirs_alloced;
} BY_DIR;
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
char **ret);
static int new_dir(X509_LOOKUP *lu);
static void free_dir(X509_LOOKUP *lu);
static int add_cert_dir(BY_DIR *ctx, const char *dir, int type);
static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
X509_OBJECT *ret);
X509_LOOKUP_METHOD x509_dir_lookup = {
"Load certs from files in a directory",
new_dir, /* new */
free_dir, /* free */
NULL, /* init */
NULL, /* shutdown */
dir_ctrl, /* ctrl */
get_cert_by_subject, /* get_by_subject */
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
};
X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
{
return (&x509_dir_lookup);
}
static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
char **retp)
{
int ret = 0;
BY_DIR *ld;
char *dir = NULL;
ld = (BY_DIR *)ctx->method_data;
switch (cmd) {
case X509_L_ADD_DIR:
if (argl == X509_FILETYPE_DEFAULT) {
dir = (char *)Getenv(X509_get_default_cert_dir_env());
if (dir)
ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
else
ret = add_cert_dir(ld, X509_get_default_cert_dir(),
X509_FILETYPE_PEM);
if (!ret) {
X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR);
}
} else
ret = add_cert_dir(ld, argp, (int)argl);
break;
}
return (ret);
}
static int new_dir(X509_LOOKUP *lu)
{
BY_DIR *a;
if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL)
return (0);
if ((a->buffer = BUF_MEM_new()) == NULL) {
OPENSSL_free(a);
return (0);
}
a->num_dirs = 0;
a->dirs = NULL;
a->dirs_type = NULL;
a->num_dirs_alloced = 0;
lu->method_data = (char *)a;
return (1);
}
static void free_dir(X509_LOOKUP *lu)
{
BY_DIR *a;
int i;
a = (BY_DIR *)lu->method_data;
for (i = 0; i < a->num_dirs; i++)
if (a->dirs[i] != NULL)
OPENSSL_free(a->dirs[i]);
if (a->dirs != NULL)
OPENSSL_free(a->dirs);
if (a->dirs_type != NULL)
OPENSSL_free(a->dirs_type);
if (a->buffer != NULL)
BUF_MEM_free(a->buffer);
OPENSSL_free(a);
}
static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
{
int j, len;
int *ip;
const char *s, *ss, *p;
char **pp;
if (dir == NULL || !*dir) {
X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY);
return 0;
}
s = dir;
p = s;
for (;; p++) {
if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) {
ss = s;
s = p + 1;
len = (int)(p - ss);
if (len == 0)
continue;
for (j = 0; j < ctx->num_dirs; j++)
if (strlen(ctx->dirs[j]) == (size_t)len &&
strncmp(ctx->dirs[j], ss, (unsigned int)len) == 0)
break;
if (j < ctx->num_dirs)
continue;
if (ctx->num_dirs_alloced < (ctx->num_dirs + 1)) {
ctx->num_dirs_alloced += 10;
pp = (char **)OPENSSL_malloc(ctx->num_dirs_alloced *
sizeof(char *));
ip = (int *)OPENSSL_malloc(ctx->num_dirs_alloced *
sizeof(int));
if ((pp == NULL) || (ip == NULL)) {
X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE);
return (0);
}
memcpy(pp, ctx->dirs, (ctx->num_dirs_alloced - 10) *
sizeof(char *));
memcpy(ip, ctx->dirs_type, (ctx->num_dirs_alloced - 10) *
sizeof(int));
if (ctx->dirs != NULL)
OPENSSL_free(ctx->dirs);
if (ctx->dirs_type != NULL)
OPENSSL_free(ctx->dirs_type);
ctx->dirs = pp;
ctx->dirs_type = ip;
}
ctx->dirs_type[ctx->num_dirs] = type;
ctx->dirs[ctx->num_dirs] =
(char *)OPENSSL_malloc((unsigned int)len + 1);
if (ctx->dirs[ctx->num_dirs] == NULL)
return (0);
strncpy(ctx->dirs[ctx->num_dirs], ss, (unsigned int)len);
ctx->dirs[ctx->num_dirs][len] = '\0';
ctx->num_dirs++;
}
if (*p == '\0')
break;
}
return (1);
}
static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
X509_OBJECT *ret)
{
BY_DIR *ctx;
union {
struct {
X509 st_x509;
X509_CINF st_x509_cinf;
} x509;
struct {
X509_CRL st_crl;
X509_CRL_INFO st_crl_info;
} crl;
} data;
int ok = 0;
int i, j, k;
unsigned long h;
BUF_MEM *b = NULL;
struct stat st;
X509_OBJECT stmp, *tmp;
const char *postfix = "";
if (name == NULL)
return (0);
stmp.type = type;
if (type == X509_LU_X509) {
data.x509.st_x509.cert_info = &data.x509.st_x509_cinf;
data.x509.st_x509_cinf.subject = name;
stmp.data.x509 = &data.x509.st_x509;
postfix = "";
} else if (type == X509_LU_CRL) {
data.crl.st_crl.crl = &data.crl.st_crl_info;
data.crl.st_crl_info.issuer = name;
stmp.data.crl = &data.crl.st_crl;
postfix = "r";
} else {
X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE);
goto finish;
}
if ((b = BUF_MEM_new()) == NULL) {
X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB);
goto finish;
}
ctx = (BY_DIR *)xl->method_data;
h = X509_NAME_hash(name);
for (i = 0; i < ctx->num_dirs; i++) {
j = strlen(ctx->dirs[i]) + 1 + 8 + 6 + 1 + 1;
if (!BUF_MEM_grow(b, j)) {
X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
goto finish;
}
k = 0;
for (;;) {
char c = '/';
#ifdef OPENSSL_SYS_VMS
c = ctx->dirs[i][strlen(ctx->dirs[i]) - 1];
if (c != ':' && c != '>' && c != ']') {
/*
* If no separator is present, we assume the directory
* specifier is a logical name, and add a colon. We really
* should use better VMS routines for merging things like
* this, but this will do for now... -- Richard Levitte
*/
c = ':';
} else {
c = '\0';
}
#endif
if (c == '\0') {
/*
* This is special. When c == '\0', no directory separator
* should be added.
*/
BIO_snprintf(b->data, b->max,
"%s%08lx.%s%d", ctx->dirs[i], h, postfix, k);
} else {
BIO_snprintf(b->data, b->max,
"%s%c%08lx.%s%d", ctx->dirs[i], c, h,
postfix, k);
}
k++;
if (stat(b->data, &st) < 0)
break;
/* found one. */
if (type == X509_LU_X509) {
if ((X509_load_cert_file(xl, b->data,
ctx->dirs_type[i])) == 0)
break;
} else if (type == X509_LU_CRL) {
if ((X509_load_crl_file(xl, b->data, ctx->dirs_type[i])) == 0)
break;
}
/* else case will caught higher up */
}
/*
* we have added it to the cache so now pull it out again
*/
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
if (j != -1)
tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
else
tmp = NULL;
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (tmp != NULL) {
ok = 1;
ret->type = tmp->type;
memcpy(&ret->data, &tmp->data, sizeof(ret->data));
/*
* If we were going to up the reference count, we would need to
* do it on a perl 'type' basis
*/
/*- CRYPTO_add(&tmp->data.x509->references,1,
CRYPTO_LOCK_X509);*/
goto finish;
}
}
finish:
if (b != NULL)
BUF_MEM_free(b);
return (ok);
}
@@ -0,0 +1,277 @@
/* crypto/x509/by_file.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/lhash.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#ifndef OPENSSL_NO_STDIO
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
long argl, char **ret);
X509_LOOKUP_METHOD x509_file_lookup = {
"Load file into cache",
NULL, /* new */
NULL, /* free */
NULL, /* init */
NULL, /* shutdown */
by_file_ctrl, /* ctrl */
NULL, /* get_by_subject */
NULL, /* get_by_issuer_serial */
NULL, /* get_by_fingerprint */
NULL, /* get_by_alias */
};
X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
{
return (&x509_file_lookup);
}
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
long argl, char **ret)
{
int ok = 0;
char *file;
switch (cmd) {
case X509_L_FILE_LOAD:
if (argl == X509_FILETYPE_DEFAULT) {
file = (char *)Getenv(X509_get_default_cert_file_env());
if (file)
ok = (X509_load_cert_crl_file(ctx, file,
X509_FILETYPE_PEM) != 0);
else
ok = (X509_load_cert_crl_file
(ctx, X509_get_default_cert_file(),
X509_FILETYPE_PEM) != 0);
if (!ok) {
X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS);
}
} else {
if (argl == X509_FILETYPE_PEM)
ok = (X509_load_cert_crl_file(ctx, argp,
X509_FILETYPE_PEM) != 0);
else
ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0);
}
break;
}
return (ok);
}
int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
{
int ret = 0;
BIO *in = NULL;
int i, count = 0;
X509 *x = NULL;
if (file == NULL)
return (1);
in = BIO_new(BIO_s_file_internal());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB);
goto err;
}
if (type == X509_FILETYPE_PEM) {
for (;;) {
x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
if (x == NULL) {
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
PEM_R_NO_START_LINE) && (count > 0)) {
ERR_clear_error();
break;
} else {
X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB);
goto err;
}
}
i = X509_STORE_add_cert(ctx->store_ctx, x);
if (!i)
goto err;
count++;
X509_free(x);
x = NULL;
}
ret = count;
} else if (type == X509_FILETYPE_ASN1) {
x = d2i_X509_bio(in, NULL);
if (x == NULL) {
X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB);
goto err;
}
i = X509_STORE_add_cert(ctx->store_ctx, x);
if (!i)
goto err;
ret = i;
} else {
X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE);
goto err;
}
err:
if (x != NULL)
X509_free(x);
if (in != NULL)
BIO_free(in);
return (ret);
}
int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
int ret = 0;
BIO *in = NULL;
int i, count = 0;
X509_CRL *x = NULL;
if (file == NULL)
return (1);
in = BIO_new(BIO_s_file_internal());
if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB);
goto err;
}
if (type == X509_FILETYPE_PEM) {
for (;;) {
x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
if (x == NULL) {
if ((ERR_GET_REASON(ERR_peek_last_error()) ==
PEM_R_NO_START_LINE) && (count > 0)) {
ERR_clear_error();
break;
} else {
X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB);
goto err;
}
}
i = X509_STORE_add_crl(ctx->store_ctx, x);
if (!i)
goto err;
count++;
X509_CRL_free(x);
x = NULL;
}
ret = count;
} else if (type == X509_FILETYPE_ASN1) {
x = d2i_X509_CRL_bio(in, NULL);
if (x == NULL) {
X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB);
goto err;
}
i = X509_STORE_add_crl(ctx->store_ctx, x);
if (!i)
goto err;
ret = i;
} else {
X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE);
goto err;
}
err:
if (x != NULL)
X509_CRL_free(x);
if (in != NULL)
BIO_free(in);
return (ret);
}
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
STACK_OF(X509_INFO) *inf;
X509_INFO *itmp;
BIO *in;
int i, count = 0;
if (type != X509_FILETYPE_PEM)
return X509_load_cert_file(ctx, file, type);
in = BIO_new_file(file, "r");
if (!in) {
X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB);
return 0;
}
inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
BIO_free(in);
if (!inf) {
X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
return 0;
}
for (i = 0; i < sk_X509_INFO_num(inf); i++) {
itmp = sk_X509_INFO_value(inf, i);
if (itmp->x509) {
X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
count++;
}
if (itmp->crl) {
X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
count++;
}
}
sk_X509_INFO_pop_free(inf, X509_INFO_free);
return count;
}
#endif /* OPENSSL_NO_STDIO */
@@ -0,0 +1,384 @@
/* crypto/x509/x509_att.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/stack.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
{
return sk_X509_ATTRIBUTE_num(x);
}
int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
int lastpos)
{
ASN1_OBJECT *obj;
obj = OBJ_nid2obj(nid);
if (obj == NULL)
return (-2);
return (X509at_get_attr_by_OBJ(x, obj, lastpos));
}
int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_ATTRIBUTE *ex;
if (sk == NULL)
return (-1);
lastpos++;
if (lastpos < 0)
lastpos = 0;
n = sk_X509_ATTRIBUTE_num(sk);
for (; lastpos < n; lastpos++) {
ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
if (OBJ_cmp(ex->object, obj) == 0)
return (lastpos);
}
return (-1);
}
X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
return NULL;
else
return sk_X509_ATTRIBUTE_value(x, loc);
}
X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
{
X509_ATTRIBUTE *ret;
if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
return (NULL);
ret = sk_X509_ATTRIBUTE_delete(x, loc);
return (ret);
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
X509_ATTRIBUTE *attr)
{
X509_ATTRIBUTE *new_attr = NULL;
STACK_OF(X509_ATTRIBUTE) *sk = NULL;
if (x == NULL) {
X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
if (*x == NULL) {
if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
goto err;
} else
sk = *x;
if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
goto err2;
if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
goto err;
if (*x == NULL)
*x = sk;
return (sk);
err:
X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE);
err2:
if (new_attr != NULL)
X509_ATTRIBUTE_free(new_attr);
if (sk != NULL)
sk_X509_ATTRIBUTE_free(sk);
return (NULL);
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
**x, const ASN1_OBJECT *obj,
int type,
const unsigned char *bytes,
int len)
{
X509_ATTRIBUTE *attr;
STACK_OF(X509_ATTRIBUTE) *ret;
attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
if (!attr)
return 0;
ret = X509at_add1_attr(x, attr);
X509_ATTRIBUTE_free(attr);
return ret;
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
**x, int nid, int type,
const unsigned char *bytes,
int len)
{
X509_ATTRIBUTE *attr;
STACK_OF(X509_ATTRIBUTE) *ret;
attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
if (!attr)
return 0;
ret = X509at_add1_attr(x, attr);
X509_ATTRIBUTE_free(attr);
return ret;
}
STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
**x, const char *attrname,
int type,
const unsigned char *bytes,
int len)
{
X509_ATTRIBUTE *attr;
STACK_OF(X509_ATTRIBUTE) *ret;
attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
if (!attr)
return 0;
ret = X509at_add1_attr(x, attr);
X509_ATTRIBUTE_free(attr);
return ret;
}
void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
ASN1_OBJECT *obj, int lastpos, int type)
{
int i;
X509_ATTRIBUTE *at;
i = X509at_get_attr_by_OBJ(x, obj, lastpos);
if (i == -1)
return NULL;
if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
return NULL;
at = X509at_get_attr(x, i);
if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
return NULL;
return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
int atrtype, const void *data,
int len)
{
ASN1_OBJECT *obj;
X509_ATTRIBUTE *ret;
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID);
return (NULL);
}
ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
if (ret == NULL)
ASN1_OBJECT_free(obj);
return (ret);
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
const ASN1_OBJECT *obj,
int atrtype, const void *data,
int len)
{
X509_ATTRIBUTE *ret;
if ((attr == NULL) || (*attr == NULL)) {
if ((ret = X509_ATTRIBUTE_new()) == NULL) {
X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,
ERR_R_MALLOC_FAILURE);
return (NULL);
}
} else
ret = *attr;
if (!X509_ATTRIBUTE_set1_object(ret, obj))
goto err;
if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
goto err;
if ((attr != NULL) && (*attr == NULL))
*attr = ret;
return (ret);
err:
if ((attr == NULL) || (ret != *attr))
X509_ATTRIBUTE_free(ret);
return (NULL);
}
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
const char *atrname, int type,
const unsigned char *bytes,
int len)
{
ASN1_OBJECT *obj;
X509_ATTRIBUTE *nattr;
obj = OBJ_txt2obj(atrname, 0);
if (obj == NULL) {
X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", atrname);
return (NULL);
}
nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
ASN1_OBJECT_free(obj);
return nattr;
}
int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
{
if ((attr == NULL) || (obj == NULL))
return (0);
ASN1_OBJECT_free(attr->object);
attr->object = OBJ_dup(obj);
return (1);
}
int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
const void *data, int len)
{
ASN1_TYPE *ttmp;
ASN1_STRING *stmp = NULL;
int atype = 0;
if (!attr)
return 0;
if (attrtype & MBSTRING_FLAG) {
stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
OBJ_obj2nid(attr->object));
if (!stmp) {
X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
return 0;
}
atype = stmp->type;
} else if (len != -1) {
if (!(stmp = ASN1_STRING_type_new(attrtype)))
goto err;
if (!ASN1_STRING_set(stmp, data, len))
goto err;
atype = attrtype;
}
if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
goto err;
attr->single = 0;
/*
* This is a bit naughty because the attribute should really have at
* least one value but some types use and zero length SET and require
* this.
*/
if (attrtype == 0)
return 1;
if (!(ttmp = ASN1_TYPE_new()))
goto err;
if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
if (!ASN1_TYPE_set1(ttmp, attrtype, data))
goto err;
} else
ASN1_TYPE_set(ttmp, atype, stmp);
if (!sk_ASN1_TYPE_push(attr->value.set, ttmp))
goto err;
return 1;
err:
X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
return 0;
}
int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
{
if (!attr->single)
return sk_ASN1_TYPE_num(attr->value.set);
if (attr->value.single)
return 1;
return 0;
}
ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
{
if (attr == NULL)
return (NULL);
return (attr->object);
}
void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
int atrtype, void *data)
{
ASN1_TYPE *ttmp;
ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
if (!ttmp)
return NULL;
if (atrtype != ASN1_TYPE_get(ttmp)) {
X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
return NULL;
}
return ttmp->value.ptr;
}
ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
{
if (attr == NULL)
return (NULL);
if (idx >= X509_ATTRIBUTE_count(attr))
return NULL;
if (!attr->single)
return sk_ASN1_TYPE_value(attr->value.set, idx);
else
return attr->value.single;
}
@@ -0,0 +1,425 @@
/* crypto/x509/x509_cmp.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <ctype.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
{
int i;
X509_CINF *ai, *bi;
ai = a->cert_info;
bi = b->cert_info;
i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber);
if (i)
return (i);
return (X509_NAME_cmp(ai->issuer, bi->issuer));
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_issuer_and_serial_hash(X509 *a)
{
unsigned long ret = 0;
EVP_MD_CTX ctx;
unsigned char md[16];
char *f;
EVP_MD_CTX_init(&ctx);
f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0);
ret = strlen(f);
EVP_DigestInit_ex(&ctx, EVP_md5(), NULL);
EVP_DigestUpdate(&ctx, (unsigned char *)f, ret);
OPENSSL_free(f);
EVP_DigestUpdate(&ctx, (unsigned char *)a->cert_info->serialNumber->data,
(unsigned long)a->cert_info->serialNumber->length);
EVP_DigestFinal_ex(&ctx, &(md[0]), NULL);
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
) & 0xffffffffL;
EVP_MD_CTX_cleanup(&ctx);
return (ret);
}
#endif
int X509_issuer_name_cmp(const X509 *a, const X509 *b)
{
return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer));
}
int X509_subject_name_cmp(const X509 *a, const X509 *b)
{
return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject));
}
int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
{
return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer));
}
X509_NAME *X509_get_issuer_name(X509 *a)
{
return (a->cert_info->issuer);
}
unsigned long X509_issuer_name_hash(X509 *x)
{
return (X509_NAME_hash(x->cert_info->issuer));
}
X509_NAME *X509_get_subject_name(X509 *a)
{
return (a->cert_info->subject);
}
ASN1_INTEGER *X509_get_serialNumber(X509 *a)
{
return (a->cert_info->serialNumber);
}
unsigned long X509_subject_name_hash(X509 *x)
{
return (X509_NAME_hash(x->cert_info->subject));
}
#ifndef OPENSSL_NO_SHA
/*
* Compare two certificates: they must be identical for this to work. NB:
* Although "cmp" operations are generally prototyped to take "const"
* arguments (eg. for use in STACKs), the way X509 handling is - these
* operations may involve ensuring the hashes are up-to-date and ensuring
* certain cert information is cached. So this is the point where the
* "depth-first" constification tree has to halt with an evil cast.
*/
int X509_cmp(const X509 *a, const X509 *b)
{
/* ensure hash is valid */
X509_check_purpose((X509 *)a, -1, 0);
X509_check_purpose((X509 *)b, -1, 0);
return memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
}
#endif
/* Case insensitive string comparision */
static int nocase_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int i;
if (a->length != b->length)
return (a->length - b->length);
for (i = 0; i < a->length; i++) {
int ca, cb;
ca = tolower(a->data[i]);
cb = tolower(b->data[i]);
if (ca != cb)
return (ca - cb);
}
return 0;
}
/*
* Case insensitive string comparision with space normalization Space
* normalization - ignore leading, trailing spaces, multiple spaces between
* characters are replaced by single space
*/
static int nocase_spacenorm_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
unsigned char *pa = NULL, *pb = NULL;
int la, lb;
la = a->length;
lb = b->length;
pa = a->data;
pb = b->data;
/* skip leading spaces */
while (la > 0 && isspace(*pa)) {
la--;
pa++;
}
while (lb > 0 && isspace(*pb)) {
lb--;
pb++;
}
/* skip trailing spaces */
while (la > 0 && isspace(pa[la - 1]))
la--;
while (lb > 0 && isspace(pb[lb - 1]))
lb--;
/* compare strings with space normalization */
while (la > 0 && lb > 0) {
int ca, cb;
/* compare character */
ca = tolower(*pa);
cb = tolower(*pb);
if (ca != cb)
return (ca - cb);
pa++;
pb++;
la--;
lb--;
if (la <= 0 || lb <= 0)
break;
/* is white space next character ? */
if (isspace(*pa) && isspace(*pb)) {
/* skip remaining white spaces */
while (la > 0 && isspace(*pa)) {
la--;
pa++;
}
while (lb > 0 && isspace(*pb)) {
lb--;
pb++;
}
}
}
if (la > 0 || lb > 0)
return la - lb;
return 0;
}
static int asn1_string_memcmp(ASN1_STRING *a, ASN1_STRING *b)
{
int j;
j = a->length - b->length;
if (j)
return j;
return memcmp(a->data, b->data, a->length);
}
#define STR_TYPE_CMP (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_UTF8STRING)
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
{
int i, j;
X509_NAME_ENTRY *na, *nb;
unsigned long nabit, nbbit;
j = sk_X509_NAME_ENTRY_num(a->entries)
- sk_X509_NAME_ENTRY_num(b->entries);
if (j)
return j;
for (i = sk_X509_NAME_ENTRY_num(a->entries) - 1; i >= 0; i--) {
na = sk_X509_NAME_ENTRY_value(a->entries, i);
nb = sk_X509_NAME_ENTRY_value(b->entries, i);
j = na->value->type - nb->value->type;
if (j) {
nabit = ASN1_tag2bit(na->value->type);
nbbit = ASN1_tag2bit(nb->value->type);
if (!(nabit & STR_TYPE_CMP) || !(nbbit & STR_TYPE_CMP))
return j;
if (!asn1_string_memcmp(na->value, nb->value))
j = 0;
} else if (na->value->type == V_ASN1_PRINTABLESTRING)
j = nocase_spacenorm_cmp(na->value, nb->value);
else if (na->value->type == V_ASN1_IA5STRING
&& OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
j = nocase_cmp(na->value, nb->value);
else
j = asn1_string_memcmp(na->value, nb->value);
if (j)
return (j);
j = na->set - nb->set;
if (j)
return (j);
}
/*
* We will check the object types after checking the values since the
* values will more often be different than the object types.
*/
for (i = sk_X509_NAME_ENTRY_num(a->entries) - 1; i >= 0; i--) {
na = sk_X509_NAME_ENTRY_value(a->entries, i);
nb = sk_X509_NAME_ENTRY_value(b->entries, i);
j = OBJ_cmp(na->object, nb->object);
if (j)
return (j);
}
return (0);
}
#ifndef OPENSSL_NO_MD5
/*
* I now DER encode the name and hash it. Since I cache the DER encoding,
* this is reasonably efficient.
*/
unsigned long X509_NAME_hash(X509_NAME *x)
{
unsigned long ret = 0;
unsigned char md[16];
EVP_MD_CTX md_ctx;
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x, NULL);
EVP_MD_CTX_init(&md_ctx);
EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
EVP_DigestFinal_ex(&md_ctx, md, NULL);
EVP_MD_CTX_cleanup(&md_ctx);
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
) & 0xffffffffL;
return (ret);
}
#endif
/* Search a stack of X509 for a match */
X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
ASN1_INTEGER *serial)
{
int i;
X509_CINF cinf;
X509 x, *x509 = NULL;
if (!sk)
return NULL;
x.cert_info = &cinf;
cinf.serialNumber = serial;
cinf.issuer = name;
for (i = 0; i < sk_X509_num(sk); i++) {
x509 = sk_X509_value(sk, i);
if (X509_issuer_and_serial_cmp(x509, &x) == 0)
return (x509);
}
return (NULL);
}
X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
{
X509 *x509;
int i;
for (i = 0; i < sk_X509_num(sk); i++) {
x509 = sk_X509_value(sk, i);
if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
return (x509);
}
return (NULL);
}
EVP_PKEY *X509_get_pubkey(X509 *x)
{
if ((x == NULL) || (x->cert_info == NULL))
return (NULL);
return (X509_PUBKEY_get(x->cert_info->key));
}
ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
{
if (!x)
return NULL;
return x->cert_info->key->public_key;
}
int X509_check_private_key(X509 *x, EVP_PKEY *k)
{
EVP_PKEY *xk = NULL;
int ok = 0;
xk = X509_get_pubkey(x);
switch (EVP_PKEY_cmp(xk, k)) {
case 1:
ok = 1;
break;
case 0:
X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
#ifndef OPENSSL_NO_EC
if (k->type == EVP_PKEY_EC) {
X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
break;
}
#endif
#ifndef OPENSSL_NO_DH
if (k->type == EVP_PKEY_DH) {
/* No idea */
X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_CANT_CHECK_DH_KEY);
break;
}
#endif
X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
return (ok);
}
@@ -0,0 +1,109 @@
/* crypto/x509/x509_d2.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_STDIO
int X509_STORE_set_default_paths(X509_STORE *ctx)
{
X509_LOOKUP *lookup;
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
if (lookup == NULL)
return (0);
X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
if (lookup == NULL)
return (0);
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
/* clear any errors */
ERR_clear_error();
return (1);
}
int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
const char *path)
{
X509_LOOKUP *lookup;
if (file != NULL) {
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
if (lookup == NULL)
return (0);
if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
return (0);
}
if (path != NULL) {
lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
if (lookup == NULL)
return (0);
if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
return (0);
}
if ((path == NULL) && (file == NULL))
return (0);
return (1);
}
#endif
@@ -0,0 +1,92 @@
/* crypto/x509/x509_def.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
const char *X509_get_default_private_dir(void)
{
return (X509_PRIVATE_DIR);
}
const char *X509_get_default_cert_area(void)
{
return (X509_CERT_AREA);
}
const char *X509_get_default_cert_dir(void)
{
return (X509_CERT_DIR);
}
const char *X509_get_default_cert_file(void)
{
return (X509_CERT_FILE);
}
const char *X509_get_default_cert_dir_env(void)
{
return (X509_CERT_DIR_EVP);
}
const char *X509_get_default_cert_file_env(void)
{
return (X509_CERT_FILE_EVP);
}
@@ -0,0 +1,175 @@
/* crypto/x509/x509_err.c */
/* ====================================================================
* Copyright (c) 1999-2005 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/*
* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
static ERR_STRING_DATA X509_str_functs[] = {
{ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"},
{ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"},
{ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"},
{ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"},
{ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"},
{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"},
{ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"},
{ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"},
{ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"},
{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID),
"X509_ATTRIBUTE_create_by_NID"},
{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),
"X509_ATTRIBUTE_create_by_OBJ"},
{ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),
"X509_ATTRIBUTE_create_by_txt"},
{ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"},
{ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"},
{ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"},
{ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"},
{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),
"X509_EXTENSION_create_by_NID"},
{ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),
"X509_EXTENSION_create_by_OBJ"},
{ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),
"X509_get_pubkey_parameters"},
{ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"},
{ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"},
{ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"},
{ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"},
{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID),
"X509_NAME_ENTRY_create_by_NID"},
{ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),
"X509_NAME_ENTRY_create_by_txt"},
{ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),
"X509_NAME_ENTRY_set_object"},
{ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"},
{ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"},
{ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"},
{ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"},
{ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"},
{ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY),
"X509_REQ_check_private_key"},
{ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"},
{ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"},
{ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"},
{ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"},
{ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"},
{ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER),
"X509_STORE_CTX_get1_issuer"},
{ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"},
{ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"},
{ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT),
"X509_STORE_CTX_purpose_inherit"},
{ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"},
{ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"},
{ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"},
{ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"},
{0, NULL}
};
static ERR_STRING_DATA X509_str_reasons[] = {
{ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"},
{ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"},
{ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
{ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),
"cert already in hash table"},
{ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"},
{ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"},
{ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"},
{ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"},
{ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"},
{ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"},
{ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"},
{ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"},
{ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
"no cert set for us to verify"},
{ERR_REASON(X509_R_SHOULD_RETRY), "should retry"},
{ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),
"unable to find parameters in chain"},
{ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),
"unable to get certs public key"},
{ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"},
{ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"},
{ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"},
{ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
{ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
{ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"},
{ERR_REASON(X509_R_WRONG_TYPE), "wrong type"},
{0, NULL}
};
#endif
void ERR_load_X509_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(X509_str_functs[0].error) == NULL) {
ERR_load_strings(0, X509_str_functs);
ERR_load_strings(0, X509_str_reasons);
}
#endif
}
@@ -0,0 +1,211 @@
/* crypto/x509/x509_ext.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/stack.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int X509_CRL_get_ext_count(X509_CRL *x)
{
return (X509v3_get_ext_count(x->crl->extensions));
}
int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos)
{
return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos));
}
int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos)
{
return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos));
}
int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos)
{
return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos));
}
X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc)
{
return (X509v3_get_ext(x->crl->extensions, loc));
}
X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
{
return (X509v3_delete_ext(x->crl->extensions, loc));
}
void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx)
{
return X509V3_get_d2i(x->crl->extensions, nid, crit, idx);
}
int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
unsigned long flags)
{
return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags);
}
int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
{
return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL);
}
int X509_get_ext_count(X509 *x)
{
return (X509v3_get_ext_count(x->cert_info->extensions));
}
int X509_get_ext_by_NID(X509 *x, int nid, int lastpos)
{
return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos));
}
int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos)
{
return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos));
}
int X509_get_ext_by_critical(X509 *x, int crit, int lastpos)
{
return (X509v3_get_ext_by_critical
(x->cert_info->extensions, crit, lastpos));
}
X509_EXTENSION *X509_get_ext(X509 *x, int loc)
{
return (X509v3_get_ext(x->cert_info->extensions, loc));
}
X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
{
return (X509v3_delete_ext(x->cert_info->extensions, loc));
}
int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
{
return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL);
}
void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx)
{
return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx);
}
int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
unsigned long flags)
{
return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit,
flags);
}
int X509_REVOKED_get_ext_count(X509_REVOKED *x)
{
return (X509v3_get_ext_count(x->extensions));
}
int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos)
{
return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos));
}
int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
int lastpos)
{
return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos));
}
int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos)
{
return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
}
X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc)
{
return (X509v3_get_ext(x->extensions, loc));
}
X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
{
return (X509v3_delete_ext(x->extensions, loc));
}
int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
{
return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
}
void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx)
{
return X509V3_get_d2i(x->extensions, nid, crit, idx);
}
int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
unsigned long flags)
{
return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
}
IMPLEMENT_STACK_OF(X509_EXTENSION)
IMPLEMENT_ASN1_SET_OF(X509_EXTENSION)
@@ -0,0 +1,565 @@
/* crypto/x509/x509_lu.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/lhash.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
{
X509_LOOKUP *ret;
ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP));
if (ret == NULL)
return NULL;
ret->init = 0;
ret->skip = 0;
ret->method = method;
ret->method_data = NULL;
ret->store_ctx = NULL;
if ((method->new_item != NULL) && !method->new_item(ret)) {
OPENSSL_free(ret);
return NULL;
}
return ret;
}
void X509_LOOKUP_free(X509_LOOKUP *ctx)
{
if (ctx == NULL)
return;
if ((ctx->method != NULL) && (ctx->method->free != NULL))
ctx->method->free(ctx);
OPENSSL_free(ctx);
}
int X509_LOOKUP_init(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
return 0;
if (ctx->method->init != NULL)
return ctx->method->init(ctx);
else
return 1;
}
int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
{
if (ctx->method == NULL)
return 0;
if (ctx->method->shutdown != NULL)
return ctx->method->shutdown(ctx);
else
return 1;
}
int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
char **ret)
{
if (ctx->method == NULL)
return -1;
if (ctx->method->ctrl != NULL)
return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
else
return 1;
}
int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
return X509_LU_FAIL;
if (ctx->skip)
return 0;
return ctx->method->get_by_subject(ctx, type, name, ret);
}
int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
ASN1_INTEGER *serial, X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
return X509_LU_FAIL;
return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
}
int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
unsigned char *bytes, int len,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
return X509_LU_FAIL;
return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
}
int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
X509_OBJECT *ret)
{
if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
return X509_LU_FAIL;
return ctx->method->get_by_alias(ctx, type, str, len, ret);
}
static int x509_object_cmp(const X509_OBJECT *const *a,
const X509_OBJECT *const *b)
{
int ret;
ret = ((*a)->type - (*b)->type);
if (ret)
return ret;
switch ((*a)->type) {
case X509_LU_X509:
ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
break;
case X509_LU_CRL:
ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
break;
default:
/* abort(); */
return 0;
}
return ret;
}
X509_STORE *X509_STORE_new(void)
{
X509_STORE *ret;
if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
return NULL;
ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
ret->cache = 1;
ret->get_cert_methods = sk_X509_LOOKUP_new_null();
ret->verify = 0;
ret->verify_cb = 0;
if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
return NULL;
ret->get_issuer = 0;
ret->check_issued = 0;
ret->check_revocation = 0;
ret->get_crl = 0;
ret->check_crl = 0;
ret->cert_crl = 0;
ret->cleanup = 0;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
sk_X509_OBJECT_free(ret->objs);
OPENSSL_free(ret);
return NULL;
}
ret->references = 1;
return ret;
}
static void cleanup(X509_OBJECT *a)
{
if (!a)
return;
if (a->type == X509_LU_X509) {
X509_free(a->data.x509);
} else if (a->type == X509_LU_CRL) {
X509_CRL_free(a->data.crl);
} else {
/* abort(); */
}
OPENSSL_free(a);
}
void X509_STORE_free(X509_STORE *vfy)
{
int i;
STACK_OF(X509_LOOKUP) *sk;
X509_LOOKUP *lu;
if (vfy == NULL)
return;
sk = vfy->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
lu = sk_X509_LOOKUP_value(sk, i);
X509_LOOKUP_shutdown(lu);
X509_LOOKUP_free(lu);
}
sk_X509_LOOKUP_free(sk);
sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
if (vfy->param)
X509_VERIFY_PARAM_free(vfy->param);
OPENSSL_free(vfy);
}
X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
{
int i;
STACK_OF(X509_LOOKUP) *sk;
X509_LOOKUP *lu;
sk = v->get_cert_methods;
for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
lu = sk_X509_LOOKUP_value(sk, i);
if (m == lu->method) {
return lu;
}
}
/* a new one */
lu = X509_LOOKUP_new(m);
if (lu == NULL)
return NULL;
else {
lu->store_ctx = v;
if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
return lu;
else {
X509_LOOKUP_free(lu);
return NULL;
}
}
}
int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
X509_OBJECT *ret)
{
X509_STORE *ctx = vs->ctx;
X509_LOOKUP *lu;
X509_OBJECT stmp, *tmp;
int i, j;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
if (tmp == NULL) {
for (i = vs->current_method;
i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
if (j < 0) {
vs->current_method = j;
return j;
} else if (j) {
tmp = &stmp;
break;
}
}
vs->current_method = 0;
if (tmp == NULL)
return 0;
}
/*- if (ret->data.ptr != NULL)
X509_OBJECT_free_contents(ret); */
ret->type = tmp->type;
ret->data.ptr = tmp->data.ptr;
X509_OBJECT_up_ref_count(ret);
return 1;
}
int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
{
X509_OBJECT *obj;
int ret = 1;
if (x == NULL)
return 0;
obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type = X509_LU_X509;
obj->data.x509 = x;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_up_ref_count(obj);
if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
X509_OBJECT_free_contents(obj);
OPENSSL_free(obj);
X509err(X509_F_X509_STORE_ADD_CERT,
X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
} else
sk_X509_OBJECT_push(ctx->objs, obj);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return ret;
}
int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
{
X509_OBJECT *obj;
int ret = 1;
if (x == NULL)
return 0;
obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL) {
X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type = X509_LU_CRL;
obj->data.crl = x;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
X509_OBJECT_up_ref_count(obj);
if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
X509_OBJECT_free_contents(obj);
OPENSSL_free(obj);
X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
} else
sk_X509_OBJECT_push(ctx->objs, obj);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return ret;
}
void X509_OBJECT_up_ref_count(X509_OBJECT *a)
{
switch (a->type) {
case X509_LU_X509:
CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509);
break;
case X509_LU_CRL:
CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL);
break;
}
}
void X509_OBJECT_free_contents(X509_OBJECT *a)
{
switch (a->type) {
case X509_LU_X509:
X509_free(a->data.x509);
break;
case X509_LU_CRL:
X509_CRL_free(a->data.crl);
break;
}
}
int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
X509_NAME *name)
{
X509_OBJECT stmp;
X509 x509_s;
X509_CINF cinf_s;
X509_CRL crl_s;
X509_CRL_INFO crl_info_s;
stmp.type = type;
switch (type) {
case X509_LU_X509:
stmp.data.x509 = &x509_s;
x509_s.cert_info = &cinf_s;
cinf_s.subject = name;
break;
case X509_LU_CRL:
stmp.data.crl = &crl_s;
crl_s.crl = &crl_info_s;
crl_info_s.issuer = name;
break;
default:
/* abort(); */
return -1;
}
return sk_X509_OBJECT_find(h, &stmp);
}
X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
int type, X509_NAME *name)
{
int idx;
idx = X509_OBJECT_idx_by_subject(h, type, name);
if (idx == -1)
return NULL;
return sk_X509_OBJECT_value(h, idx);
}
X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
X509_OBJECT *x)
{
int idx, i;
X509_OBJECT *obj;
idx = sk_X509_OBJECT_find(h, x);
if (idx == -1)
return NULL;
if (x->type != X509_LU_X509)
return sk_X509_OBJECT_value(h, idx);
for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
obj = sk_X509_OBJECT_value(h, i);
if (x509_object_cmp
((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
return NULL;
if ((x->type != X509_LU_X509)
|| !X509_cmp(obj->data.x509, x->data.x509))
return obj;
}
return NULL;
}
/*-
* Try to get issuer certificate from store. Due to limitations
* of the API this can only retrieve a single certificate matching
* a given subject name. However it will fill the cache with all
* matching certificates, so we can examine the cache for all
* matches.
*
* Return values are:
* 1 lookup successful.
* 0 certificate not found.
* -1 some other error.
*/
int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
{
X509_NAME *xn;
X509_OBJECT obj, *pobj;
int i, ok, idx, ret;
xn = X509_get_issuer_name(x);
ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj);
if (ok != X509_LU_X509) {
if (ok == X509_LU_RETRY) {
X509_OBJECT_free_contents(&obj);
X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY);
return -1;
} else if (ok != X509_LU_FAIL) {
X509_OBJECT_free_contents(&obj);
/* not good :-(, break anyway */
return -1;
}
return 0;
}
/* If certificate matches all OK */
if (ctx->check_issued(ctx, x, obj.data.x509)) {
*issuer = obj.data.x509;
return 1;
}
X509_OBJECT_free_contents(&obj);
/* Else find index of first cert accepted by 'check_issued' */
ret = 0;
CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
if (idx != -1) { /* should be true as we've had at least one
* match */
/* Look through all matching certs for suitable issuer */
for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
/* See if we've run past the matches */
if (pobj->type != X509_LU_X509)
break;
if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
break;
if (ctx->check_issued(ctx, x, pobj->data.x509)) {
*issuer = pobj->data.x509;
X509_OBJECT_up_ref_count(pobj);
ret = 1;
break;
}
}
}
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
return ret;
}
int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
{
return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
}
int X509_STORE_set_depth(X509_STORE *ctx, int depth)
{
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
return 1;
}
int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
{
return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
}
int X509_STORE_set_trust(X509_STORE *ctx, int trust)
{
return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
}
int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
{
return X509_VERIFY_PARAM_set1(ctx->param, param);
}
IMPLEMENT_STACK_OF(X509_LOOKUP)
IMPLEMENT_STACK_OF(X509_OBJECT)
@@ -0,0 +1,212 @@
/* crypto/x509/x509_obj.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/lhash.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/buffer.h>
char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
{
X509_NAME_ENTRY *ne;
int i;
int n, lold, l, l1, l2, num, j, type;
const char *s;
char *p;
unsigned char *q;
BUF_MEM *b = NULL;
static char hex[17] = "0123456789ABCDEF";
int gs_doit[4];
char tmp_buf[80];
#ifdef CHARSET_EBCDIC
char ebcdic_buf[1024];
#endif
if (buf == NULL) {
if ((b = BUF_MEM_new()) == NULL)
goto err;
if (!BUF_MEM_grow(b, 200))
goto err;
b->data[0] = '\0';
len = 200;
}
if (a == NULL) {
if (b) {
buf = b->data;
OPENSSL_free(b);
}
strncpy(buf, "NO X509_NAME", len);
buf[len - 1] = '\0';
return buf;
}
len--; /* space for '\0' */
l = 0;
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
ne = sk_X509_NAME_ENTRY_value(a->entries, i);
n = OBJ_obj2nid(ne->object);
if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
s = tmp_buf;
}
l1 = strlen(s);
type = ne->value->type;
num = ne->value->length;
q = ne->value->data;
#ifdef CHARSET_EBCDIC
if (type == V_ASN1_GENERALSTRING ||
type == V_ASN1_VISIBLESTRING ||
type == V_ASN1_PRINTABLESTRING ||
type == V_ASN1_TELETEXSTRING ||
type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) {
ascii2ebcdic(ebcdic_buf, q, (num > sizeof ebcdic_buf)
? sizeof ebcdic_buf : num);
q = ebcdic_buf;
}
#endif
if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
for (j = 0; j < num; j++)
if (q[j] != 0)
gs_doit[j & 3] = 1;
if (gs_doit[0] | gs_doit[1] | gs_doit[2])
gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
else {
gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
gs_doit[3] = 1;
}
} else
gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
for (l2 = j = 0; j < num; j++) {
if (!gs_doit[j & 3])
continue;
l2++;
#ifndef CHARSET_EBCDIC
if ((q[j] < ' ') || (q[j] > '~'))
l2 += 3;
#else
if ((os_toascii[q[j]] < os_toascii[' ']) ||
(os_toascii[q[j]] > os_toascii['~']))
l2 += 3;
#endif
}
lold = l;
l += 1 + l1 + 1 + l2;
if (b != NULL) {
if (!BUF_MEM_grow(b, l + 1))
goto err;
p = &(b->data[lold]);
} else if (l > len) {
break;
} else
p = &(buf[lold]);
*(p++) = '/';
memcpy(p, s, (unsigned int)l1);
p += l1;
*(p++) = '=';
#ifndef CHARSET_EBCDIC /* q was assigned above already. */
q = ne->value->data;
#endif
for (j = 0; j < num; j++) {
if (!gs_doit[j & 3])
continue;
#ifndef CHARSET_EBCDIC
n = q[j];
if ((n < ' ') || (n > '~')) {
*(p++) = '\\';
*(p++) = 'x';
*(p++) = hex[(n >> 4) & 0x0f];
*(p++) = hex[n & 0x0f];
} else
*(p++) = n;
#else
n = os_toascii[q[j]];
if ((n < os_toascii[' ']) || (n > os_toascii['~'])) {
*(p++) = '\\';
*(p++) = 'x';
*(p++) = hex[(n >> 4) & 0x0f];
*(p++) = hex[n & 0x0f];
} else
*(p++) = q[j];
#endif
}
*p = '\0';
}
if (b != NULL) {
p = b->data;
OPENSSL_free(b);
} else
p = buf;
if (i == 0)
*p = '\0';
return (p);
err:
X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
if (b != NULL)
BUF_MEM_free(b);
return (NULL);
}
@@ -0,0 +1,113 @@
/* crypto/x509/x509_r2x.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
{
X509 *ret = NULL;
X509_CINF *xi = NULL;
X509_NAME *xn;
if ((ret = X509_new()) == NULL) {
X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE);
goto err;
}
/* duplicate the request */
xi = ret->cert_info;
if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
goto err;
if (!ASN1_INTEGER_set(xi->version, 2))
goto err;
/*- xi->extensions=ri->attributes; <- bad, should not ever be done
ri->attributes=NULL; */
}
xn = X509_REQ_get_subject_name(r);
if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
goto err;
if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
goto err;
if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
goto err;
if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
NULL)
goto err;
X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
if (!X509_sign(ret, pkey, EVP_md5()))
goto err;
if (0) {
err:
X509_free(ret);
ret = NULL;
}
return (ret);
}
@@ -0,0 +1,341 @@
/* crypto/x509/x509_req.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/pem.h>
X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
X509_REQ *ret;
X509_REQ_INFO *ri;
int i;
EVP_PKEY *pktmp;
ret = X509_REQ_new();
if (ret == NULL) {
X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE);
goto err;
}
ri = ret->req_info;
ri->version->length = 1;
ri->version->data = (unsigned char *)OPENSSL_malloc(1);
if (ri->version->data == NULL)
goto err;
ri->version->data[0] = 0; /* version == 0 */
if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
goto err;
pktmp = X509_get_pubkey(x);
if (pktmp == NULL)
goto err;
i = X509_REQ_set_pubkey(ret, pktmp);
EVP_PKEY_free(pktmp);
if (!i)
goto err;
if (pkey != NULL) {
if (!X509_REQ_sign(ret, pkey, md))
goto err;
}
return (ret);
err:
X509_REQ_free(ret);
return (NULL);
}
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
{
if ((req == NULL) || (req->req_info == NULL))
return (NULL);
return (X509_PUBKEY_get(req->req_info->pubkey));
}
int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
{
EVP_PKEY *xk = NULL;
int ok = 0;
xk = X509_REQ_get_pubkey(x);
switch (EVP_PKEY_cmp(xk, k)) {
case 1:
ok = 1;
break;
case 0:
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
#ifndef OPENSSL_NO_EC
if (k->type == EVP_PKEY_EC) {
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
break;
}
#endif
#ifndef OPENSSL_NO_DH
if (k->type == EVP_PKEY_DH) {
/* No idea */
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
X509_R_CANT_CHECK_DH_KEY);
break;
}
#endif
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
return (ok);
}
/*
* It seems several organisations had the same idea of including a list of
* extensions in a certificate request. There are at least two OIDs that are
* used and there may be more: so the list is configurable.
*/
static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef };
static int *ext_nids = ext_nid_list;
int X509_REQ_extension_nid(int req_nid)
{
int i, nid;
for (i = 0;; i++) {
nid = ext_nids[i];
if (nid == NID_undef)
return 0;
else if (req_nid == nid)
return 1;
}
}
int *X509_REQ_get_extension_nids(void)
{
return ext_nids;
}
void X509_REQ_set_extension_nids(int *nids)
{
ext_nids = nids;
}
STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
{
X509_ATTRIBUTE *attr;
ASN1_TYPE *ext = NULL;
int idx, *pnid;
const unsigned char *p;
if ((req == NULL) || (req->req_info == NULL) || !ext_nids)
return (NULL);
for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
if (idx == -1)
continue;
attr = X509_REQ_get_attr(req, idx);
if (attr->single)
ext = attr->value.single;
else if (sk_ASN1_TYPE_num(attr->value.set))
ext = sk_ASN1_TYPE_value(attr->value.set, 0);
break;
}
if (!ext || (ext->type != V_ASN1_SEQUENCE))
return NULL;
p = ext->value.sequence->data;
return d2i_ASN1_SET_OF_X509_EXTENSION(NULL, &p,
ext->value.sequence->length,
d2i_X509_EXTENSION,
X509_EXTENSION_free,
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
}
/*
* Add a STACK_OF extensions to a certificate request: allow alternative OIDs
* in case we want to create a non standard one.
*/
int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
int nid)
{
unsigned char *p = NULL, *q;
long len;
ASN1_TYPE *at = NULL;
X509_ATTRIBUTE *attr = NULL;
if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new()))
goto err;
at->type = V_ASN1_SEQUENCE;
/* Generate encoding of extensions */
len = i2d_ASN1_SET_OF_X509_EXTENSION(exts, NULL, i2d_X509_EXTENSION,
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
IS_SEQUENCE);
if (!(p = OPENSSL_malloc(len)))
goto err;
q = p;
i2d_ASN1_SET_OF_X509_EXTENSION(exts, &q, i2d_X509_EXTENSION,
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
IS_SEQUENCE);
at->value.sequence->data = p;
p = NULL;
at->value.sequence->length = len;
if (!(attr = X509_ATTRIBUTE_new()))
goto err;
if (!(attr->value.set = sk_ASN1_TYPE_new_null()))
goto err;
if (!sk_ASN1_TYPE_push(attr->value.set, at))
goto err;
at = NULL;
attr->single = 0;
attr->object = OBJ_nid2obj(nid);
if (!req->req_info->attributes) {
if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null()))
goto err;
}
if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr))
goto err;
return 1;
err:
if (p)
OPENSSL_free(p);
X509_ATTRIBUTE_free(attr);
ASN1_TYPE_free(at);
return 0;
}
/* This is the normal usage: use the "official" OID */
int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
{
return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
}
/* Request attribute functions */
int X509_REQ_get_attr_count(const X509_REQ *req)
{
return X509at_get_attr_count(req->req_info->attributes);
}
int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
{
return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos);
}
int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
int lastpos)
{
return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos);
}
X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
{
return X509at_get_attr(req->req_info->attributes, loc);
}
X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
{
return X509at_delete_attr(req->req_info->attributes, loc);
}
int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
{
if (X509at_add1_attr(&req->req_info->attributes, attr))
return 1;
return 0;
}
int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
const ASN1_OBJECT *obj, int type,
const unsigned char *bytes, int len)
{
if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj,
type, bytes, len))
return 1;
return 0;
}
int X509_REQ_add1_attr_by_NID(X509_REQ *req,
int nid, int type,
const unsigned char *bytes, int len)
{
if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid,
type, bytes, len))
return 1;
return 0;
}
int X509_REQ_add1_attr_by_txt(X509_REQ *req,
const char *attrname, int type,
const unsigned char *bytes, int len)
{
if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname,
type, bytes, len))
return 1;
return 0;
}
@@ -0,0 +1,147 @@
/* crypto/x509/x509_set.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
int X509_set_version(X509 *x, long version)
{
if (x == NULL)
return (0);
if (x->cert_info->version == NULL) {
if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL)
return (0);
}
return (ASN1_INTEGER_set(x->cert_info->version, version));
}
int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
{
ASN1_INTEGER *in;
if (x == NULL)
return (0);
in = x->cert_info->serialNumber;
if (in != serial) {
in = M_ASN1_INTEGER_dup(serial);
if (in != NULL) {
M_ASN1_INTEGER_free(x->cert_info->serialNumber);
x->cert_info->serialNumber = in;
}
}
return (in != NULL);
}
int X509_set_issuer_name(X509 *x, X509_NAME *name)
{
if ((x == NULL) || (x->cert_info == NULL))
return (0);
return (X509_NAME_set(&x->cert_info->issuer, name));
}
int X509_set_subject_name(X509 *x, X509_NAME *name)
{
if ((x == NULL) || (x->cert_info == NULL))
return (0);
return (X509_NAME_set(&x->cert_info->subject, name));
}
int X509_set_notBefore(X509 *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
if ((x == NULL) || (x->cert_info->validity == NULL))
return (0);
in = x->cert_info->validity->notBefore;
if (in != tm) {
in = M_ASN1_TIME_dup(tm);
if (in != NULL) {
M_ASN1_TIME_free(x->cert_info->validity->notBefore);
x->cert_info->validity->notBefore = in;
}
}
return (in != NULL);
}
int X509_set_notAfter(X509 *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
if ((x == NULL) || (x->cert_info->validity == NULL))
return (0);
in = x->cert_info->validity->notAfter;
if (in != tm) {
in = M_ASN1_TIME_dup(tm);
if (in != NULL) {
M_ASN1_TIME_free(x->cert_info->validity->notAfter);
x->cert_info->validity->notAfter = in;
}
}
return (in != NULL);
}
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
{
if ((x == NULL) || (x->cert_info == NULL))
return (0);
return (X509_PUBKEY_set(&(x->cert_info->key), pkey));
}
@@ -0,0 +1,308 @@
/* x509_trs.c */
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/x509v3.h>
static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b);
static void trtable_free(X509_TRUST *p);
static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
static int obj_trust(int id, X509 *x, int flags);
static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
/*
* WARNING: the following table should be kept in order of trust and without
* any gaps so we can just subtract the minimum trust value to get an index
* into the table
*/
static X509_TRUST trstandard[] = {
{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
{X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth,
NULL},
{X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth,
NULL},
{X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect,
NULL},
{X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign,
NULL},
{X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign,
NULL},
{X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, NULL}
};
#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST))
IMPLEMENT_STACK_OF(X509_TRUST)
static STACK_OF(X509_TRUST) *trtable = NULL;
static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b)
{
return (*a)->trust - (*b)->trust;
}
int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
int) {
int (*oldtrust) (int, X509 *, int);
oldtrust = default_trust;
default_trust = trust;
return oldtrust;
}
int X509_check_trust(X509 *x, int id, int flags)
{
X509_TRUST *pt;
int idx;
if (id == -1)
return 1;
idx = X509_TRUST_get_by_id(id);
if (idx == -1)
return default_trust(id, x, flags);
pt = X509_TRUST_get0(idx);
return pt->check_trust(pt, x, flags);
}
int X509_TRUST_get_count(void)
{
if (!trtable)
return X509_TRUST_COUNT;
return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
}
X509_TRUST *X509_TRUST_get0(int idx)
{
if (idx < 0)
return NULL;
if (idx < (int)X509_TRUST_COUNT)
return trstandard + idx;
return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
}
int X509_TRUST_get_by_id(int id)
{
X509_TRUST tmp;
int idx;
if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
return id - X509_TRUST_MIN;
tmp.trust = id;
if (!trtable)
return -1;
idx = sk_X509_TRUST_find(trtable, &tmp);
if (idx == -1)
return -1;
return idx + X509_TRUST_COUNT;
}
int X509_TRUST_set(int *t, int trust)
{
if (X509_TRUST_get_by_id(trust) == -1) {
X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
return 0;
}
*t = trust;
return 1;
}
int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
char *name, int arg1, void *arg2)
{
int idx;
X509_TRUST *trtmp;
/*
* This is set according to what we change: application can't set it
*/
flags &= ~X509_TRUST_DYNAMIC;
/* This will always be set for application modified trust entries */
flags |= X509_TRUST_DYNAMIC_NAME;
/* Get existing entry if any */
idx = X509_TRUST_get_by_id(id);
/* Need a new entry */
if (idx == -1) {
if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
return 0;
}
trtmp->flags = X509_TRUST_DYNAMIC;
} else
trtmp = X509_TRUST_get0(idx);
/* OPENSSL_free existing name if dynamic */
if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
OPENSSL_free(trtmp->name);
/* dup supplied name */
if (!(trtmp->name = BUF_strdup(name))) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
return 0;
}
/* Keep the dynamic flag of existing entry */
trtmp->flags &= X509_TRUST_DYNAMIC;
/* Set all other flags */
trtmp->flags |= flags;
trtmp->trust = id;
trtmp->check_trust = ck;
trtmp->arg1 = arg1;
trtmp->arg2 = arg2;
/* If its a new entry manage the dynamic table */
if (idx == -1) {
if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!sk_X509_TRUST_push(trtable, trtmp)) {
X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
return 0;
}
}
return 1;
}
static void trtable_free(X509_TRUST *p)
{
if (!p)
return;
if (p->flags & X509_TRUST_DYNAMIC) {
if (p->flags & X509_TRUST_DYNAMIC_NAME)
OPENSSL_free(p->name);
OPENSSL_free(p);
}
}
void X509_TRUST_cleanup(void)
{
unsigned int i;
for (i = 0; i < X509_TRUST_COUNT; i++)
trtable_free(trstandard + i);
sk_X509_TRUST_pop_free(trtable, trtable_free);
trtable = NULL;
}
int X509_TRUST_get_flags(X509_TRUST *xp)
{
return xp->flags;
}
char *X509_TRUST_get0_name(X509_TRUST *xp)
{
return xp->name;
}
int X509_TRUST_get_trust(X509_TRUST *xp)
{
return xp->trust;
}
static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
{
if (x->aux && (x->aux->trust || x->aux->reject))
return obj_trust(trust->arg1, x, flags);
/*
* we don't have any trust settings: for compatibility we return trusted
* if it is self signed
*/
return trust_compat(trust, x, flags);
}
static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
{
if (x->aux)
return obj_trust(trust->arg1, x, flags);
return X509_TRUST_UNTRUSTED;
}
static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
{
X509_check_purpose(x, -1, 0);
if (x->ex_flags & EXFLAG_SS)
return X509_TRUST_TRUSTED;
else
return X509_TRUST_UNTRUSTED;
}
static int obj_trust(int id, X509 *x, int flags)
{
ASN1_OBJECT *obj;
int i;
X509_CERT_AUX *ax;
ax = x->aux;
if (!ax)
return X509_TRUST_UNTRUSTED;
if (ax->reject) {
for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
obj = sk_ASN1_OBJECT_value(ax->reject, i);
if (OBJ_obj2nid(obj) == id)
return X509_TRUST_REJECTED;
}
}
if (ax->trust) {
for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
obj = sk_ASN1_OBJECT_value(ax->trust, i);
if (OBJ_obj2nid(obj) == id)
return X509_TRUST_TRUSTED;
}
}
return X509_TRUST_UNTRUSTED;
}
@@ -0,0 +1,171 @@
/* crypto/x509/x509_txt.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include "cryptlib.h"
#include <openssl/lhash.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
const char *X509_verify_cert_error_string(long n)
{
static char buf[100];
switch ((int)n) {
case X509_V_OK:
return ("ok");
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
return ("unable to get issuer certificate");
case X509_V_ERR_UNABLE_TO_GET_CRL:
return ("unable to get certificate CRL");
case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
return ("unable to decrypt certificate's signature");
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
return ("unable to decrypt CRL's signature");
case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
return ("unable to decode issuer public key");
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
return ("certificate signature failure");
case X509_V_ERR_CRL_SIGNATURE_FAILURE:
return ("CRL signature failure");
case X509_V_ERR_CERT_NOT_YET_VALID:
return ("certificate is not yet valid");
case X509_V_ERR_CRL_NOT_YET_VALID:
return ("CRL is not yet valid");
case X509_V_ERR_CERT_HAS_EXPIRED:
return ("certificate has expired");
case X509_V_ERR_CRL_HAS_EXPIRED:
return ("CRL has expired");
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
return ("format error in certificate's notBefore field");
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
return ("format error in certificate's notAfter field");
case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
return ("format error in CRL's lastUpdate field");
case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
return ("format error in CRL's nextUpdate field");
case X509_V_ERR_OUT_OF_MEM:
return ("out of memory");
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
return ("self signed certificate");
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
return ("self signed certificate in certificate chain");
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
return ("unable to get local issuer certificate");
case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
return ("unable to verify the first certificate");
case X509_V_ERR_CERT_CHAIN_TOO_LONG:
return ("certificate chain too long");
case X509_V_ERR_CERT_REVOKED:
return ("certificate revoked");
case X509_V_ERR_INVALID_CA:
return ("invalid CA certificate");
case X509_V_ERR_INVALID_NON_CA:
return ("invalid non-CA certificate (has CA markings)");
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
return ("path length constraint exceeded");
case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
return ("proxy path length constraint exceeded");
case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
return
("proxy certificates not allowed, please set the appropriate flag");
case X509_V_ERR_INVALID_PURPOSE:
return ("unsupported certificate purpose");
case X509_V_ERR_CERT_UNTRUSTED:
return ("certificate not trusted");
case X509_V_ERR_CERT_REJECTED:
return ("certificate rejected");
case X509_V_ERR_APPLICATION_VERIFICATION:
return ("application verification failure");
case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
return ("subject issuer mismatch");
case X509_V_ERR_AKID_SKID_MISMATCH:
return ("authority and subject key identifier mismatch");
case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
return ("authority and issuer serial number mismatch");
case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
return ("key usage does not include certificate signing");
case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
return ("unable to get CRL issuer certificate");
case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
return ("unhandled critical extension");
case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
return ("key usage does not include CRL signing");
case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
return ("key usage does not include digital signature");
case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
return ("unhandled critical CRL extension");
case X509_V_ERR_INVALID_EXTENSION:
return ("invalid or inconsistent certificate extension");
case X509_V_ERR_INVALID_POLICY_EXTENSION:
return ("invalid or inconsistent certificate policy extension");
case X509_V_ERR_NO_EXPLICIT_POLICY:
return ("no explicit policy");
case X509_V_ERR_UNNESTED_RESOURCE:
return ("RFC 3779 resource not subset of parent's resources");
default:
BIO_snprintf(buf, sizeof buf, "error number %ld", n);
return (buf);
}
}
@@ -0,0 +1,284 @@
/* crypto/x509/x509_v3.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/stack.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
{
if (x == NULL)
return (0);
return (sk_X509_EXTENSION_num(x));
}
int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
int lastpos)
{
ASN1_OBJECT *obj;
obj = OBJ_nid2obj(nid);
if (obj == NULL)
return (-2);
return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
}
int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_EXTENSION *ex;
if (sk == NULL)
return (-1);
lastpos++;
if (lastpos < 0)
lastpos = 0;
n = sk_X509_EXTENSION_num(sk);
for (; lastpos < n; lastpos++) {
ex = sk_X509_EXTENSION_value(sk, lastpos);
if (OBJ_cmp(ex->object, obj) == 0)
return (lastpos);
}
return (-1);
}
int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
int lastpos)
{
int n;
X509_EXTENSION *ex;
if (sk == NULL)
return (-1);
lastpos++;
if (lastpos < 0)
lastpos = 0;
n = sk_X509_EXTENSION_num(sk);
for (; lastpos < n; lastpos++) {
ex = sk_X509_EXTENSION_value(sk, lastpos);
if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
return (lastpos);
}
return (-1);
}
X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
{
if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
return NULL;
else
return sk_X509_EXTENSION_value(x, loc);
}
X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
{
X509_EXTENSION *ret;
if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
return (NULL);
ret = sk_X509_EXTENSION_delete(x, loc);
return (ret);
}
STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
X509_EXTENSION *ex, int loc)
{
X509_EXTENSION *new_ex = NULL;
int n;
STACK_OF(X509_EXTENSION) *sk = NULL;
if (x == NULL) {
X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
if (*x == NULL) {
if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
goto err;
} else
sk = *x;
n = sk_X509_EXTENSION_num(sk);
if (loc > n)
loc = n;
else if (loc < 0)
loc = n;
if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
goto err2;
if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
goto err;
if (*x == NULL)
*x = sk;
return (sk);
err:
X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE);
err2:
if (new_ex != NULL)
X509_EXTENSION_free(new_ex);
if (sk != NULL)
sk_X509_EXTENSION_free(sk);
return (NULL);
}
X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
int crit,
ASN1_OCTET_STRING *data)
{
ASN1_OBJECT *obj;
X509_EXTENSION *ret;
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID);
return (NULL);
}
ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
if (ret == NULL)
ASN1_OBJECT_free(obj);
return (ret);
}
X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
ASN1_OBJECT *obj, int crit,
ASN1_OCTET_STRING *data)
{
X509_EXTENSION *ret;
if ((ex == NULL) || (*ex == NULL)) {
if ((ret = X509_EXTENSION_new()) == NULL) {
X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,
ERR_R_MALLOC_FAILURE);
return (NULL);
}
} else
ret = *ex;
if (!X509_EXTENSION_set_object(ret, obj))
goto err;
if (!X509_EXTENSION_set_critical(ret, crit))
goto err;
if (!X509_EXTENSION_set_data(ret, data))
goto err;
if ((ex != NULL) && (*ex == NULL))
*ex = ret;
return (ret);
err:
if ((ex == NULL) || (ret != *ex))
X509_EXTENSION_free(ret);
return (NULL);
}
int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj)
{
if ((ex == NULL) || (obj == NULL))
return (0);
ASN1_OBJECT_free(ex->object);
ex->object = OBJ_dup(obj);
return (1);
}
int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
{
if (ex == NULL)
return (0);
ex->critical = (crit) ? 0xFF : -1;
return (1);
}
int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
{
int i;
if (ex == NULL)
return (0);
i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length);
if (!i)
return (0);
return (1);
}
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
{
if (ex == NULL)
return (NULL);
return (ex->object);
}
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
{
if (ex == NULL)
return (NULL);
return (ex->value);
}
int X509_EXTENSION_get_critical(X509_EXTENSION *ex)
{
if (ex == NULL)
return (0);
if (ex->critical > 0)
return 1;
return 0;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,426 @@
/* x509_vpm.c */
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 2004.
*/
/* ====================================================================
* Copyright (c) 2004 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/crypto.h>
#include <openssl/lhash.h>
#include <openssl/buffer.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
/* X509_VERIFY_PARAM functions */
static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
{
if (!param)
return;
param->name = NULL;
param->purpose = 0;
param->trust = 0;
param->inh_flags = 0;
param->flags = 0;
param->depth = -1;
if (param->policies) {
sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
param->policies = NULL;
}
}
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
{
X509_VERIFY_PARAM *param;
param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM));
memset(param, 0, sizeof(X509_VERIFY_PARAM));
x509_verify_param_zero(param);
return param;
}
void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
{
x509_verify_param_zero(param);
OPENSSL_free(param);
}
/*-
* This function determines how parameters are "inherited" from one structure
* to another. There are several different ways this can happen.
*
* 1. If a child structure needs to have its values initialized from a parent
* they are simply copied across. For example SSL_CTX copied to SSL.
* 2. If the structure should take on values only if they are currently unset.
* For example the values in an SSL structure will take appropriate value
* for SSL servers or clients but only if the application has not set new
* ones.
*
* The "inh_flags" field determines how this function behaves.
*
* Normally any values which are set in the default are not copied from the
* destination and verify flags are ORed together.
*
* If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
* to the destination. Effectively the values in "to" become default values
* which will be used only if nothing new is set in "from".
*
* If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
* they are set or not. Flags is still Ored though.
*
* If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
* of ORed.
*
* If X509_VP_FLAG_LOCKED is set then no values are copied.
*
* If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
* after the next call.
*/
/* Macro to test if a field should be copied from src to dest */
#define test_x509_verify_param_copy(field, def) \
(to_overwrite || \
((src->field != def) && (to_default || (dest->field == def))))
/* Macro to test and copy a field if necessary */
#define x509_verify_param_copy(field, def) \
if (test_x509_verify_param_copy(field, def)) \
dest->field = src->field
int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
const X509_VERIFY_PARAM *src)
{
unsigned long inh_flags;
int to_default, to_overwrite;
if (!src)
return 1;
inh_flags = dest->inh_flags | src->inh_flags;
if (inh_flags & X509_VP_FLAG_ONCE)
dest->inh_flags = 0;
if (inh_flags & X509_VP_FLAG_LOCKED)
return 1;
if (inh_flags & X509_VP_FLAG_DEFAULT)
to_default = 1;
else
to_default = 0;
if (inh_flags & X509_VP_FLAG_OVERWRITE)
to_overwrite = 1;
else
to_overwrite = 0;
x509_verify_param_copy(purpose, 0);
x509_verify_param_copy(trust, 0);
x509_verify_param_copy(depth, -1);
/* If overwrite or check time not set, copy across */
if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
dest->check_time = src->check_time;
dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
/* Don't need to copy flag: that is done below */
}
if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
dest->flags = 0;
dest->flags |= src->flags;
if (test_x509_verify_param_copy(policies, NULL)) {
if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
return 0;
}
return 1;
}
int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
const X509_VERIFY_PARAM *from)
{
unsigned long save_flags = to->inh_flags;
int ret;
to->inh_flags |= X509_VP_FLAG_DEFAULT;
ret = X509_VERIFY_PARAM_inherit(to, from);
to->inh_flags = save_flags;
return ret;
}
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
{
if (param->name)
OPENSSL_free(param->name);
param->name = BUF_strdup(name);
if (param->name)
return 1;
return 0;
}
int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
{
param->flags |= flags;
if (flags & X509_V_FLAG_POLICY_MASK)
param->flags |= X509_V_FLAG_POLICY_CHECK;
return 1;
}
int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
unsigned long flags)
{
param->flags &= ~flags;
return 1;
}
unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
{
return param->flags;
}
int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
{
return X509_PURPOSE_set(&param->purpose, purpose);
}
int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
{
return X509_TRUST_set(&param->trust, trust);
}
void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
{
param->depth = depth;
}
void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
{
param->check_time = t;
param->flags |= X509_V_FLAG_USE_CHECK_TIME;
}
int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
ASN1_OBJECT *policy)
{
if (!param->policies) {
param->policies = sk_ASN1_OBJECT_new_null();
if (!param->policies)
return 0;
}
if (!sk_ASN1_OBJECT_push(param->policies, policy))
return 0;
return 1;
}
int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
STACK_OF(ASN1_OBJECT) *policies)
{
int i;
ASN1_OBJECT *oid, *doid;
if (!param)
return 0;
if (param->policies)
sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
if (!policies) {
param->policies = NULL;
return 1;
}
param->policies = sk_ASN1_OBJECT_new_null();
if (!param->policies)
return 0;
for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
oid = sk_ASN1_OBJECT_value(policies, i);
doid = OBJ_dup(oid);
if (!doid)
return 0;
if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
ASN1_OBJECT_free(doid);
return 0;
}
}
param->flags |= X509_V_FLAG_POLICY_CHECK;
return 1;
}
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
{
return param->depth;
}
/*
* Default verify parameters: these are used for various applications and can
* be overridden by the user specified table. NB: the 'name' field *must* be
* in alphabetical order because it will be searched using OBJ_search.
*/
static const X509_VERIFY_PARAM default_table[] = {
{
"default", /* X509 default parameters */
0, /* Check time */
0, /* internal flags */
0, /* flags */
0, /* purpose */
0, /* trust */
100, /* depth */
NULL /* policies */
},
{
"pkcs7", /* S/MIME signing parameters */
0, /* Check time */
0, /* internal flags */
0, /* flags */
X509_PURPOSE_SMIME_SIGN, /* purpose */
X509_TRUST_EMAIL, /* trust */
-1, /* depth */
NULL /* policies */
},
{
"smime_sign", /* S/MIME signing parameters */
0, /* Check time */
0, /* internal flags */
0, /* flags */
X509_PURPOSE_SMIME_SIGN, /* purpose */
X509_TRUST_EMAIL, /* trust */
-1, /* depth */
NULL /* policies */
},
{
"ssl_client", /* SSL/TLS client parameters */
0, /* Check time */
0, /* internal flags */
0, /* flags */
X509_PURPOSE_SSL_CLIENT, /* purpose */
X509_TRUST_SSL_CLIENT, /* trust */
-1, /* depth */
NULL /* policies */
},
{
"ssl_server", /* SSL/TLS server parameters */
0, /* Check time */
0, /* internal flags */
0, /* flags */
X509_PURPOSE_SSL_SERVER, /* purpose */
X509_TRUST_SSL_SERVER, /* trust */
-1, /* depth */
NULL /* policies */
}
};
static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
static int table_cmp(const void *pa, const void *pb)
{
const X509_VERIFY_PARAM *a = pa, *b = pb;
return strcmp(a->name, b->name);
}
static int param_cmp(const X509_VERIFY_PARAM *const *a,
const X509_VERIFY_PARAM *const *b)
{
return strcmp((*a)->name, (*b)->name);
}
int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
{
int idx;
X509_VERIFY_PARAM *ptmp;
if (!param_table) {
param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
if (!param_table)
return 0;
} else {
idx = sk_X509_VERIFY_PARAM_find(param_table, param);
if (idx != -1) {
ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
X509_VERIFY_PARAM_free(ptmp);
(void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
}
}
if (!sk_X509_VERIFY_PARAM_push(param_table, param))
return 0;
return 1;
}
const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
{
int idx;
X509_VERIFY_PARAM pm;
pm.name = (char *)name;
if (param_table) {
idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
if (idx != -1)
return sk_X509_VERIFY_PARAM_value(param_table, idx);
}
return (const X509_VERIFY_PARAM *)OBJ_bsearch((char *)&pm,
(char *)&default_table,
sizeof(default_table) /
sizeof(X509_VERIFY_PARAM),
sizeof(X509_VERIFY_PARAM),
table_cmp);
}
void X509_VERIFY_PARAM_table_cleanup(void)
{
if (param_table)
sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
param_table = NULL;
}
@@ -0,0 +1,167 @@
/* crypto/x509/x509cset.c */
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 2001.
*/
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
int X509_CRL_set_version(X509_CRL *x, long version)
{
if (x == NULL)
return (0);
if (x->crl->version == NULL) {
if ((x->crl->version = M_ASN1_INTEGER_new()) == NULL)
return (0);
}
return (ASN1_INTEGER_set(x->crl->version, version));
}
int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
{
if ((x == NULL) || (x->crl == NULL))
return (0);
return (X509_NAME_set(&x->crl->issuer, name));
}
int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
if (x == NULL)
return (0);
in = x->crl->lastUpdate;
if (in != tm) {
in = M_ASN1_TIME_dup(tm);
if (in != NULL) {
M_ASN1_TIME_free(x->crl->lastUpdate);
x->crl->lastUpdate = in;
}
}
return (in != NULL);
}
int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
if (x == NULL)
return (0);
in = x->crl->nextUpdate;
if (in != tm) {
in = M_ASN1_TIME_dup(tm);
if (in != NULL) {
M_ASN1_TIME_free(x->crl->nextUpdate);
x->crl->nextUpdate = in;
}
}
return (in != NULL);
}
int X509_CRL_sort(X509_CRL *c)
{
int i;
X509_REVOKED *r;
/*
* sort the data so it will be written in serial number order
*/
sk_X509_REVOKED_sort(c->crl->revoked);
for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) {
r = sk_X509_REVOKED_value(c->crl->revoked, i);
r->sequence = i;
}
c->crl->enc.modified = 1;
return 1;
}
int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
if (x == NULL)
return (0);
in = x->revocationDate;
if (in != tm) {
in = M_ASN1_TIME_dup(tm);
if (in != NULL) {
M_ASN1_TIME_free(x->revocationDate);
x->revocationDate = in;
}
}
return (in != NULL);
}
int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
{
ASN1_INTEGER *in;
if (x == NULL)
return (0);
in = x->serialNumber;
if (in != serial) {
in = M_ASN1_INTEGER_dup(serial);
if (in != NULL) {
M_ASN1_INTEGER_free(x->serialNumber);
x->serialNumber = in;
}
}
return (in != NULL);
}
@@ -0,0 +1,397 @@
/* crypto/x509/x509name.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <openssl/stack.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
{
ASN1_OBJECT *obj;
obj = OBJ_nid2obj(nid);
if (obj == NULL)
return (-1);
return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
}
int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf,
int len)
{
int i;
ASN1_STRING *data;
i = X509_NAME_get_index_by_OBJ(name, obj, -1);
if (i < 0)
return (-1);
data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
i = (data->length > (len - 1)) ? (len - 1) : data->length;
if (buf == NULL)
return (data->length);
memcpy(buf, data->data, i);
buf[i] = '\0';
return (i);
}
int X509_NAME_entry_count(X509_NAME *name)
{
if (name == NULL)
return (0);
return (sk_X509_NAME_ENTRY_num(name->entries));
}
int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
{
ASN1_OBJECT *obj;
obj = OBJ_nid2obj(nid);
if (obj == NULL)
return (-2);
return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
}
/* NOTE: you should be passsing -1, not 0 as lastpos */
int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos)
{
int n;
X509_NAME_ENTRY *ne;
STACK_OF(X509_NAME_ENTRY) *sk;
if (name == NULL)
return (-1);
if (lastpos < 0)
lastpos = -1;
sk = name->entries;
n = sk_X509_NAME_ENTRY_num(sk);
for (lastpos++; lastpos < n; lastpos++) {
ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
if (OBJ_cmp(ne->object, obj) == 0)
return (lastpos);
}
return (-1);
}
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc)
{
if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
|| loc < 0)
return (NULL);
else
return (sk_X509_NAME_ENTRY_value(name->entries, loc));
}
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
{
X509_NAME_ENTRY *ret;
int i, n, set_prev, set_next;
STACK_OF(X509_NAME_ENTRY) *sk;
if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
|| loc < 0)
return (NULL);
sk = name->entries;
ret = sk_X509_NAME_ENTRY_delete(sk, loc);
n = sk_X509_NAME_ENTRY_num(sk);
name->modified = 1;
if (loc == n)
return (ret);
/* else we need to fixup the set field */
if (loc != 0)
set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
else
set_prev = ret->set - 1;
set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
/*-
* set_prev is the previous set
* set is the current set
* set_next is the following
* prev 1 1 1 1 1 1 1 1
* set 1 1 2 2
* next 1 1 2 2 2 2 3 2
* so basically only if prev and next differ by 2, then
* re-number down by 1
*/
if (set_prev + 1 < set_next)
for (i = loc; i < n; i++)
sk_X509_NAME_ENTRY_value(sk, i)->set--;
return (ret);
}
int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
unsigned char *bytes, int len, int loc,
int set)
{
X509_NAME_ENTRY *ne;
int ret;
ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
if (!ne)
return 0;
ret = X509_NAME_add_entry(name, ne, loc, set);
X509_NAME_ENTRY_free(ne);
return ret;
}
int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
unsigned char *bytes, int len, int loc,
int set)
{
X509_NAME_ENTRY *ne;
int ret;
ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
if (!ne)
return 0;
ret = X509_NAME_add_entry(name, ne, loc, set);
X509_NAME_ENTRY_free(ne);
return ret;
}
int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
const unsigned char *bytes, int len, int loc,
int set)
{
X509_NAME_ENTRY *ne;
int ret;
ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
if (!ne)
return 0;
ret = X509_NAME_add_entry(name, ne, loc, set);
X509_NAME_ENTRY_free(ne);
return ret;
}
/*
* if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
* guy we are about to stomp on.
*/
int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
int set)
{
X509_NAME_ENTRY *new_name = NULL;
int n, i, inc;
STACK_OF(X509_NAME_ENTRY) *sk;
if (name == NULL)
return (0);
sk = name->entries;
n = sk_X509_NAME_ENTRY_num(sk);
if (loc > n)
loc = n;
else if (loc < 0)
loc = n;
name->modified = 1;
if (set == -1) {
if (loc == 0) {
set = 0;
inc = 1;
} else {
set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
inc = 0;
}
} else { /* if (set >= 0) */
if (loc >= n) {
if (loc != 0)
set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
else
set = 0;
} else
set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
inc = (set == 0) ? 1 : 0;
}
if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL)
goto err;
new_name->set = set;
if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (inc) {
n = sk_X509_NAME_ENTRY_num(sk);
for (i = loc + 1; i < n; i++)
sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1;
}
return (1);
err:
if (new_name != NULL)
X509_NAME_ENTRY_free(new_name);
return (0);
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
const char *field, int type,
const unsigned char *bytes,
int len)
{
ASN1_OBJECT *obj;
X509_NAME_ENTRY *nentry;
obj = OBJ_txt2obj(field, 0);
if (obj == NULL) {
X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", field);
return (NULL);
}
nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
ASN1_OBJECT_free(obj);
return nentry;
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
int type, unsigned char *bytes,
int len)
{
ASN1_OBJECT *obj;
X509_NAME_ENTRY *nentry;
obj = OBJ_nid2obj(nid);
if (obj == NULL) {
X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID);
return (NULL);
}
nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
ASN1_OBJECT_free(obj);
return nentry;
}
X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
ASN1_OBJECT *obj, int type,
const unsigned char *bytes,
int len)
{
X509_NAME_ENTRY *ret;
if ((ne == NULL) || (*ne == NULL)) {
if ((ret = X509_NAME_ENTRY_new()) == NULL)
return (NULL);
} else
ret = *ne;
if (!X509_NAME_ENTRY_set_object(ret, obj))
goto err;
if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
goto err;
if ((ne != NULL) && (*ne == NULL))
*ne = ret;
return (ret);
err:
if ((ne == NULL) || (ret != *ne))
X509_NAME_ENTRY_free(ret);
return (NULL);
}
int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj)
{
if ((ne == NULL) || (obj == NULL)) {
X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,
ERR_R_PASSED_NULL_PARAMETER);
return (0);
}
ASN1_OBJECT_free(ne->object);
ne->object = OBJ_dup(obj);
return ((ne->object == NULL) ? 0 : 1);
}
int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
const unsigned char *bytes, int len)
{
int i;
if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
return (0);
if ((type > 0) && (type & MBSTRING_FLAG))
return ASN1_STRING_set_by_NID(&ne->value, bytes,
len, type,
OBJ_obj2nid(ne->object)) ? 1 : 0;
if (len < 0)
len = strlen((char *)bytes);
i = ASN1_STRING_set(ne->value, bytes, len);
if (!i)
return (0);
if (type != V_ASN1_UNDEF) {
if (type == V_ASN1_APP_CHOOSE)
ne->value->type = ASN1_PRINTABLE_type(bytes, len);
else
ne->value->type = type;
}
return (1);
}
ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne)
{
if (ne == NULL)
return (NULL);
return (ne->object);
}
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne)
{
if (ne == NULL)
return (NULL);
return (ne->value);
}
@@ -0,0 +1,85 @@
/* crypto/x509/x509rset.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
int X509_REQ_set_version(X509_REQ *x, long version)
{
if (x == NULL)
return (0);
return (ASN1_INTEGER_set(x->req_info->version, version));
}
int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
{
if ((x == NULL) || (x->req_info == NULL))
return (0);
return (X509_NAME_set(&x->req_info->subject, name));
}
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
{
if ((x == NULL) || (x->req_info == NULL))
return (0);
return (X509_PUBKEY_set(&x->req_info->pubkey, pkey));
}
@@ -0,0 +1,123 @@
/* x509spki.c */
/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/x509.h>
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
{
if ((x == NULL) || (x->spkac == NULL))
return (0);
return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey));
}
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
{
if ((x == NULL) || (x->spkac == NULL))
return (NULL);
return (X509_PUBKEY_get(x->spkac->pubkey));
}
/* Load a Netscape SPKI from a base64 encoded string */
NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len)
{
unsigned char *spki_der;
const unsigned char *p;
int spki_len;
NETSCAPE_SPKI *spki;
if (len <= 0)
len = strlen(str);
if (!(spki_der = OPENSSL_malloc(len + 1))) {
X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
return NULL;
}
spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
if (spki_len < 0) {
X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR);
OPENSSL_free(spki_der);
return NULL;
}
p = spki_der;
spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
OPENSSL_free(spki_der);
return spki;
}
/* Generate a base64 encoded string from an SPKI */
char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
{
unsigned char *der_spki, *p;
char *b64_str;
int der_len;
der_len = i2d_NETSCAPE_SPKI(spki, NULL);
der_spki = OPENSSL_malloc(der_len);
b64_str = OPENSSL_malloc(der_len * 2);
if (!der_spki || !b64_str) {
X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
return NULL;
}
p = der_spki;
i2d_NETSCAPE_SPKI(spki, &p);
EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
OPENSSL_free(der_spki);
return b64_str;
}
@@ -0,0 +1,121 @@
/* crypto/x509/x509type.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include "cryptlib.h"
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
{
EVP_PKEY *pk;
int ret = 0, i;
if (x == NULL)
return (0);
if (pkey == NULL)
pk = X509_get_pubkey(x);
else
pk = pkey;
if (pk == NULL)
return (0);
switch (pk->type) {
case EVP_PKEY_RSA:
ret = EVP_PK_RSA | EVP_PKT_SIGN;
/* if (!sign only extension) */
ret |= EVP_PKT_ENC;
break;
case EVP_PKEY_DSA:
ret = EVP_PK_DSA | EVP_PKT_SIGN;
break;
case EVP_PKEY_EC:
ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
break;
case EVP_PKEY_DH:
ret = EVP_PK_DH | EVP_PKT_EXCH;
break;
default:
break;
}
i = X509_get_signature_type(x);
switch (i) {
case EVP_PKEY_RSA:
ret |= EVP_PKS_RSA;
break;
case EVP_PKEY_DSA:
ret |= EVP_PKS_DSA;
break;
case EVP_PKEY_EC:
ret |= EVP_PKS_EC;
break;
default:
break;
}
/* /8 because it's 1024 bits we look for, not bytes */
if (EVP_PKEY_size(pk) <= 1024 / 8)
ret |= EVP_PKT_EXP;
if (pkey == NULL)
EVP_PKEY_free(pk);
return (ret);
}
@@ -0,0 +1,528 @@
/* crypto/x509/x_all.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#undef SSLEAY_MACROS
#include <openssl/stack.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
# include <openssl/dsa.h>
#endif
int X509_verify(X509 *a, EVP_PKEY *r)
{
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
return 0;
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg,
a->signature, a->cert_info, r));
}
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
{
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
a->sig_alg, a->signature, a->req_info, r));
}
int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r)
{
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
a->sig_alg, a->signature, a->crl, r));
}
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
{
return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
a->sig_algor, a->signature, a->spkac, r));
}
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
x->cert_info->enc.modified = 1;
return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature,
x->sig_alg, x->signature, x->cert_info, pkey, md));
}
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
{
return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL,
x->signature, x->req_info, pkey, md));
}
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
{
x->crl->enc.modified = 1;
return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
x->sig_alg, x->signature, x->crl, pkey, md));
}
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
{
return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL,
x->signature, x->spkac, pkey, md));
}
#ifndef OPENSSL_NO_FP_API
X509 *d2i_X509_fp(FILE *fp, X509 **x509)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
}
int i2d_X509_fp(FILE *fp, X509 *x509)
{
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
}
#endif
X509 *d2i_X509_bio(BIO *bp, X509 **x509)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
}
int i2d_X509_bio(BIO *bp, X509 *x509)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
}
#ifndef OPENSSL_NO_FP_API
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
}
int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
{
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
}
#endif
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
}
int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
}
#ifndef OPENSSL_NO_FP_API
PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
}
int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
{
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
}
#endif
PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
}
int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
}
#ifndef OPENSSL_NO_FP_API
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
}
int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
{
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
}
#endif
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
}
int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
}
#ifndef OPENSSL_NO_RSA
# ifndef OPENSSL_NO_FP_API
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
}
int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
}
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
{
return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
}
RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
{
return ASN1_d2i_fp((void *(*)(void))
RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
(void **)rsa);
}
int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
}
int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
{
return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa);
}
# endif
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
}
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
}
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
{
return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
}
RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
{
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
}
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
}
int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
{
return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa);
}
#endif
#ifndef OPENSSL_NO_DSA
# ifndef OPENSSL_NO_FP_API
DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
{
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
}
int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
{
return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
}
DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
{
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
}
int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
{
return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa);
}
# endif
DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
{
return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
}
int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
{
return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
}
DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
{
return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
}
int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
{
return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa);
}
#endif
#ifndef OPENSSL_NO_EC
# ifndef OPENSSL_NO_FP_API
EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
{
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
}
int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
}
EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
{
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
}
int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
}
# endif
EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
{
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
}
int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
{
return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
}
EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
{
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
}
int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
{
return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
}
#endif
int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
unsigned char *md, unsigned int *len)
{
ASN1_BIT_STRING *key;
key = X509_get0_pubkey_bitstr(data);
if (!key)
return 0;
return EVP_Digest(key->data, key->length, md, len, type, NULL);
}
int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
unsigned int *len)
{
return (ASN1_item_digest
(ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
}
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
unsigned char *md, unsigned int *len)
{
return (ASN1_item_digest
(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
}
int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
unsigned char *md, unsigned int *len)
{
return (ASN1_item_digest
(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
}
int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
unsigned char *md, unsigned int *len)
{
return (ASN1_item_digest
(ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
}
int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
const EVP_MD *type, unsigned char *md,
unsigned int *len)
{
return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type,
(char *)data, md, len));
}
#ifndef OPENSSL_NO_FP_API
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
{
return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
}
int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
{
return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
}
#endif
X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
{
return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
}
int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
{
return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
}
#ifndef OPENSSL_NO_FP_API
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
PKCS8_PRIV_KEY_INFO **p8inf)
{
return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
}
int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
{
return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
p8inf);
}
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
{
PKCS8_PRIV_KEY_INFO *p8inf;
int ret;
p8inf = EVP_PKEY2PKCS8(key);
if (!p8inf)
return 0;
ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
}
EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
{
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
}
int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
}
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
{
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
}
#endif
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
PKCS8_PRIV_KEY_INFO **p8inf)
{
return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
}
int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
{
return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
p8inf);
}
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
{
PKCS8_PRIV_KEY_INFO *p8inf;
int ret;
p8inf = EVP_PKEY2PKCS8(key);
if (!p8inf)
return 0;
ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
}
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
{
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
}
int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
}
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
{
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
}