check in v3.8.1 source

This commit is contained in:
2023-09-03 18:24:16 -07:00
parent fbb21ed921
commit b31c897352
1205 changed files with 561101 additions and 0 deletions

2186
apps/openssl/apps.c Normal file

File diff suppressed because it is too large Load Diff

324
apps/openssl/apps.h Normal file
View File

@@ -0,0 +1,324 @@
/* $OpenBSD: apps.h,v 1.34 2023/06/11 13:02:10 jsg Exp $ */
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-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
* 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).
*
*/
#ifndef HEADER_APPS_H
#define HEADER_APPS_H
#include <openssl/opensslconf.h>
#include <openssl/bio.h>
#include <openssl/conf.h>
#include <openssl/lhash.h>
#include <openssl/ossl_typ.h>
#include <openssl/txt_db.h>
#include <openssl/x509.h>
#include <openssl/ui.h>
#ifndef OPENSSL_NO_OCSP
#include <openssl/ocsp.h>
#endif
#include <unistd.h>
extern int single_execution;
extern CONF *config;
extern char *default_config_file;
extern BIO *bio_err;
#define PW_MIN_LENGTH 4
typedef struct pw_cb_data {
const void *password;
const char *prompt_info;
} PW_CB_DATA;
int password_callback(char *buf, int bufsiz, int verify, void *cb_data);
int setup_ui(void);
void destroy_ui(void);
extern UI_METHOD *ui_method;
int ui_open(UI *ui);
int ui_read(UI *ui, UI_STRING *uis);
int ui_write(UI *ui, UI_STRING *uis);
int ui_close(UI *ui);
int should_retry(int i);
int args_from_file(char *file, int *argc, char **argv[]);
int str2fmt(char *s);
void program_name(char *in, char *out, int size);
#ifdef HEADER_X509_H
int dump_cert_text(BIO *out, X509 *x);
void print_name(BIO *out, const char *title, X509_NAME *nm,
unsigned long lflags);
#endif
int set_cert_ex(unsigned long *flags, const char *arg);
int set_name_ex(unsigned long *flags, const char *arg);
int set_ext_copy(int *copy_type, const char *arg);
int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
int add_oid_section(BIO *err, CONF *conf);
X509 *load_cert(BIO *err, const char *file, int format,
const char *pass, const char *cert_descrip);
EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
const char *pass, const char *key_descrip);
EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
const char *pass, const char *key_descrip);
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
const char *pass, const char *cert_descrip);
STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
const char *pass, const char *cert_descrip);
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
#ifndef OPENSSL_NO_OCSP
OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
char *host, char *path, char *port, int use_ssl,
STACK_OF(CONF_VALUE) *headers, int req_timeout);
#endif
int load_config(BIO *err, CONF *cnf);
char *make_config_name(void);
/* Functions defined in ca.c and also used in ocsp.c */
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
ASN1_GENERALIZEDTIME **pinvtm, const char *str);
#define DB_type 0
#define DB_exp_date 1
#define DB_rev_date 2
#define DB_serial 3 /* index - unique */
#define DB_file 4
#define DB_name 5 /* index - unique when active and not disabled */
#define DB_NUMBER 6
#define DB_TYPE_REV 'R'
#define DB_TYPE_EXP 'E'
#define DB_TYPE_VAL 'V'
#define DB_TYPE_SUSP 'S'
typedef struct db_attr_st {
int unique_subject;
} DB_ATTR;
typedef struct ca_db_st {
DB_ATTR attributes;
TXT_DB *db;
} CA_DB;
BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai);
int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
ASN1_INTEGER **retai);
int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix);
int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
CA_DB *load_index(char *dbfile, DB_ATTR *dbattr);
int index_index(CA_DB *db);
int save_index(const char *dbfile, const char *suffix, CA_DB *db);
int rotate_index(const char *dbfile, const char *new_suffix,
const char *old_suffix);
void free_index(CA_DB *db);
#define index_name_cmp_noconst(a, b) \
index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
int parse_yesno(const char *str, int def);
X509_NAME *parse_name(char *str, long chtype, int multirdn);
int args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
X509_VERIFY_PARAM **pm);
int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, const char *algname,
int do_param);
int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
#define FORMAT_UNDEF 0
#define FORMAT_ASN1 1
#define FORMAT_TEXT 2
#define FORMAT_PEM 3
#define FORMAT_PKCS12 5
#define FORMAT_SMIME 6
#define FORMAT_PEMRSA 9 /* PEM RSAPublicKey format */
#define FORMAT_ASN1RSA 10 /* DER RSAPublicKey format */
#define FORMAT_MSBLOB 11 /* MS Key blob format */
#define FORMAT_PVK 12 /* MS PVK file format */
#define EXT_COPY_NONE 0
#define EXT_COPY_ADD 1
#define EXT_COPY_ALL 2
#define APP_PASS_LEN 1024
#define SERIAL_RAND_BITS 64
int app_isdir(const char *);
#define TM_RESET 0
#define TM_GET 1
double app_timer_real(int);
double app_timer_user(int);
#define OPENSSL_NO_SSL_INTERN
struct option {
const char *name;
const char *argname;
const char *desc;
enum {
OPTION_ARG,
OPTION_ARGV_FUNC,
OPTION_ARG_FORMAT,
OPTION_ARG_FUNC,
OPTION_ARG_INT,
OPTION_ARG_LONG,
OPTION_ARG_TIME,
OPTION_DISCARD,
OPTION_FUNC,
OPTION_FLAG,
OPTION_FLAG_ORD,
OPTION_VALUE,
OPTION_VALUE_AND,
OPTION_VALUE_OR,
OPTION_UL_VALUE_OR,
OPTION_ORDER,
} type;
union {
char **arg;
int (*argfunc)(char *arg);
int (*argvfunc)(int argc, char **argv, int *argsused);
int *flag;
int (*func)(void);
long *lvalue;
int *value;
unsigned long *ulvalue;
time_t *tvalue;
int *order;
} opt;
const int value;
const unsigned long ulvalue;
int *order;
};
void options_usage(const struct option *opts);
int options_parse(int argc, char **argv, const struct option *opts,
char **unnamed, int *argsused);
void show_cipher(const OBJ_NAME *name, void *arg);
int pkey_check(BIO *out, EVP_PKEY *pkey, int (check_fn)(EVP_PKEY_CTX *),
const char *desc);
#endif

175
apps/openssl/apps_posix.c Normal file
View File

@@ -0,0 +1,175 @@
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-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
* 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.
*
* 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).
*
*/
/*
* Functions that need to be overridden by non-POSIX operating systems.
*/
#include <sys/resource.h>
#include <sys/time.h>
#include <time.h>
#include "apps.h"
double
app_timer_real(int get)
{
static struct timespec start;
struct timespec elapsed, now;
clock_gettime(CLOCK_MONOTONIC, &now);
if (get) {
timespecsub(&now, &start, &elapsed);
return elapsed.tv_sec + elapsed.tv_nsec / 1000000000.0;
}
start = now;
return 0.0;
}
double
app_timer_user(int get)
{
static struct timeval start;
struct timeval elapsed;
struct rusage now;
getrusage(RUSAGE_SELF, &now);
if (get) {
timersub(&now.ru_utime, &start, &elapsed);
return elapsed.tv_sec + elapsed.tv_usec / 1000000.0;
}
start = now.ru_utime;
return 0.0;
}
int
setup_ui(void)
{
ui_method = UI_create_method("OpenSSL application user interface");
UI_method_set_opener(ui_method, ui_open);
UI_method_set_reader(ui_method, ui_read);
UI_method_set_writer(ui_method, ui_write);
UI_method_set_closer(ui_method, ui_close);
return 0;
}
void
destroy_ui(void)
{
if (ui_method) {
UI_destroy_method(ui_method);
ui_method = NULL;
}
}

470
apps/openssl/asn1pars.c Normal file
View File

@@ -0,0 +1,470 @@
/* $OpenBSD: asn1pars.c,v 1.16 2023/07/23 11:39:29 tb Exp $ */
/* 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.]
*/
/* A nice addition from Dr Stephen Henson <steve@openssl.org> to
* add the -strparse option which parses nested binary structures
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static struct {
char *derfile;
int dump;
char *genconf;
char *genstr;
int indent;
char *infile;
int informat;
unsigned int length;
int noout;
int offset;
char *oidfile;
STACK_OF(OPENSSL_STRING) *osk;
} cfg;
static int
asn1pars_opt_dlimit(char *arg)
{
const char *errstr;
cfg.dump = strtonum(arg, 1, INT_MAX, &errstr);
if (errstr) {
fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n",
errstr);
return (-1);
}
return (0);
}
static int
asn1pars_opt_length(char *arg)
{
const char *errstr;
cfg.length = strtonum(arg, 1, UINT_MAX, &errstr);
if (errstr) {
fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n",
errstr);
return (-1);
}
return (0);
}
static int
asn1pars_opt_strparse(char *arg)
{
if (sk_OPENSSL_STRING_push(cfg.osk, arg) == 0) {
fprintf(stderr, "-strparse cannot add argument\n");
return (-1);
}
return (0);
}
static const struct option asn1pars_options[] = {
{
.name = "dump",
.desc = "Dump unknown data in hex form",
.type = OPTION_VALUE,
.value = -1,
.opt.value = &cfg.dump,
},
{
.name = "dlimit",
.argname = "num",
.desc = "Dump the first num bytes of unknown data in hex form",
.type = OPTION_ARG_FUNC,
.opt.argfunc = asn1pars_opt_dlimit,
},
{
.name = "genconf",
.argname = "file",
.desc = "File to generate ASN.1 structure from",
.type = OPTION_ARG,
.opt.arg = &cfg.genconf,
},
{
.name = "genstr",
.argname = "string",
.desc = "String to generate ASN.1 structure from",
.type = OPTION_ARG,
.opt.arg = &cfg.genstr,
},
{
.name = "i",
.desc = "Indent output according to depth of structures",
.type = OPTION_FLAG,
.opt.flag = &cfg.indent,
},
{
.name = "in",
.argname = "file",
.desc = "The input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "fmt",
.desc = "Input format (DER, TXT or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "length",
.argname = "num",
.desc = "Number of bytes to parse (default until EOF)",
.type = OPTION_ARG_FUNC,
.opt.argfunc = asn1pars_opt_length,
},
{
.name = "noout",
.desc = "Do not produce any output",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "offset",
.argname = "num",
.desc = "Offset to begin parsing",
.type = OPTION_ARG_INT,
.opt.value = &cfg.offset,
},
{
.name = "oid",
.argname = "file",
.desc = "File containing additional object identifiers (OIDs)",
.type = OPTION_ARG,
.opt.arg = &cfg.oidfile,
},
{
.name = "out",
.argname = "file",
.desc = "Output file in DER format",
.type = OPTION_ARG,
.opt.arg = &cfg.derfile,
},
{
.name = "strparse",
.argname = "offset",
.desc = "Parse the content octets of ASN.1 object starting at"
" offset",
.type = OPTION_ARG_FUNC,
.opt.argfunc = asn1pars_opt_strparse,
},
{ NULL },
};
static void
asn1pars_usage(void)
{
fprintf(stderr,
"usage: asn1parse [-i] [-dlimit num] [-dump] [-genconf file] "
"[-genstr string]\n"
" [-in file] [-inform fmt] [-length num] [-noout] [-offset num] "
"[-oid file]\n"
" [-out file] [-strparse offset]\n\n");
options_usage(asn1pars_options);
}
static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
int
asn1parse_main(int argc, char **argv)
{
int i, j, ret = 1;
long num, tmplen;
BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL;
char *str = NULL;
const char *errstr = NULL;
unsigned char *tmpbuf;
const unsigned char *ctmpbuf;
BUF_MEM *buf = NULL;
ASN1_TYPE *at = NULL;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
if ((cfg.osk = sk_OPENSSL_STRING_new_null()) == NULL) {
BIO_printf(bio_err, "Memory allocation failure\n");
goto end;
}
if (options_parse(argc, argv, asn1pars_options, NULL, NULL) != 0) {
asn1pars_usage();
return (1);
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
if (cfg.oidfile != NULL) {
if (BIO_read_filename(in, cfg.oidfile) <= 0) {
BIO_printf(bio_err, "problems opening %s\n",
cfg.oidfile);
ERR_print_errors(bio_err);
goto end;
}
OBJ_create_objects(in);
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.derfile != NULL) {
if ((derout = BIO_new_file(cfg.derfile, "wb")) == NULL) {
BIO_printf(bio_err, "problems opening %s\n",
cfg.derfile);
ERR_print_errors(bio_err);
goto end;
}
}
if ((buf = BUF_MEM_new()) == NULL)
goto end;
if (!BUF_MEM_grow(buf, BUFSIZ * 8))
goto end;
if (cfg.genstr != NULL || cfg.genconf) {
num = do_generate(bio_err, cfg.genstr, cfg.genconf, buf);
if (num < 0) {
ERR_print_errors(bio_err);
goto end;
}
} else {
if (cfg.informat == FORMAT_PEM) {
BIO *tmp;
if ((b64 = BIO_new(BIO_f_base64())) == NULL)
goto end;
BIO_push(b64, in);
tmp = in;
in = b64;
b64 = tmp;
}
num = 0;
for (;;) {
if (!BUF_MEM_grow(buf, (int) num + BUFSIZ))
goto end;
i = BIO_read(in, &(buf->data[num]), BUFSIZ);
if (i <= 0)
break;
num += i;
}
}
str = buf->data;
/* If any structs to parse go through in sequence */
if (sk_OPENSSL_STRING_num(cfg.osk) > 0) {
tmpbuf = (unsigned char *) str;
tmplen = num;
for (i = 0; i < sk_OPENSSL_STRING_num(cfg.osk); i++) {
ASN1_TYPE *atmp;
int typ;
j = strtonum(sk_OPENSSL_STRING_value(cfg.osk, i),
1, INT_MAX, &errstr);
if (errstr) {
BIO_printf(bio_err,
"'%s' is an invalid number: %s\n",
sk_OPENSSL_STRING_value(cfg.osk, i), errstr);
continue;
}
tmpbuf += j;
tmplen -= j;
atmp = at;
ctmpbuf = tmpbuf;
at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
ASN1_TYPE_free(atmp);
if (!at) {
BIO_printf(bio_err, "Error parsing structure\n");
ERR_print_errors(bio_err);
goto end;
}
typ = ASN1_TYPE_get(at);
if (typ == V_ASN1_BOOLEAN || typ == V_ASN1_NULL ||
typ == V_ASN1_OBJECT) {
BIO_printf(bio_err, "Can't parse %s type\n",
ASN1_tag2str(typ));
ERR_print_errors(bio_err);
goto end;
}
/* hmm... this is a little evil but it works */
tmpbuf = at->value.asn1_string->data;
tmplen = at->value.asn1_string->length;
}
str = (char *) tmpbuf;
num = tmplen;
}
if (cfg.offset >= num) {
BIO_printf(bio_err, "Error: offset too large\n");
goto end;
}
num -= cfg.offset;
if (cfg.length == 0 || (long)cfg.length > num)
cfg.length = (unsigned int) num;
if (derout != NULL) {
if (BIO_write(derout, str + cfg.offset,
cfg.length) != (int)cfg.length) {
BIO_printf(bio_err, "Error writing output\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (!cfg.noout && !ASN1_parse_dump(out,
(unsigned char *)&str[cfg.offset], cfg.length, cfg.indent, cfg.dump)) {
ERR_print_errors(bio_err);
goto end;
}
ret = 0;
end:
BIO_free(derout);
BIO_free(in);
BIO_free_all(out);
BIO_free(b64);
if (ret != 0)
ERR_print_errors(bio_err);
BUF_MEM_free(buf);
ASN1_TYPE_free(at);
sk_OPENSSL_STRING_free(cfg.osk);
OBJ_cleanup();
return (ret);
}
static int
do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
{
CONF *cnf = NULL;
int len;
long errline;
unsigned char *p;
ASN1_TYPE *atyp = NULL;
if (genconf) {
cnf = NCONF_new(NULL);
if (!NCONF_load(cnf, genconf, &errline))
goto conferr;
if (!genstr)
genstr = NCONF_get_string(cnf, "default", "asn1");
if (!genstr) {
BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
goto err;
}
}
atyp = ASN1_generate_nconf(genstr, cnf);
NCONF_free(cnf);
cnf = NULL;
if (!atyp)
return -1;
len = i2d_ASN1_TYPE(atyp, NULL);
if (len <= 0)
goto err;
if (!BUF_MEM_grow(buf, len))
goto err;
p = (unsigned char *) buf->data;
i2d_ASN1_TYPE(atyp, &p);
ASN1_TYPE_free(atyp);
return len;
conferr:
if (errline > 0)
BIO_printf(bio, "Error on line %ld of config file '%s'\n",
errline, genconf);
else
BIO_printf(bio, "Error loading config file '%s'\n", genconf);
err:
NCONF_free(cnf);
ASN1_TYPE_free(atyp);
return -1;
}

3042
apps/openssl/ca.c Normal file

File diff suppressed because it is too large Load Diff

691
apps/openssl/certhash.c Normal file
View File

@@ -0,0 +1,691 @@
/* $OpenBSD: certhash.c,v 1.21 2023/03/06 14:32:05 tb Exp $ */
/*
* Copyright (c) 2014, 2015 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include "apps.h"
static struct {
int dryrun;
int verbose;
} cfg;
static const struct option certhash_options[] = {
{
.name = "n",
.desc = "Perform a dry-run - do not make any changes",
.type = OPTION_FLAG,
.opt.flag = &cfg.dryrun,
},
{
.name = "v",
.desc = "Verbose",
.type = OPTION_FLAG,
.opt.flag = &cfg.verbose,
},
{ NULL },
};
struct hashinfo {
char *filename;
char *target;
unsigned long hash;
unsigned int index;
unsigned char fingerprint[EVP_MAX_MD_SIZE];
int is_crl;
int is_dup;
int exists;
int changed;
struct hashinfo *reference;
struct hashinfo *next;
};
static struct hashinfo *
hashinfo(const char *filename, unsigned long hash, unsigned char *fingerprint)
{
struct hashinfo *hi;
if ((hi = calloc(1, sizeof(*hi))) == NULL)
return (NULL);
if (filename != NULL) {
if ((hi->filename = strdup(filename)) == NULL) {
free(hi);
return (NULL);
}
}
hi->hash = hash;
if (fingerprint != NULL)
memcpy(hi->fingerprint, fingerprint, sizeof(hi->fingerprint));
return (hi);
}
static void
hashinfo_free(struct hashinfo *hi)
{
if (hi == NULL)
return;
free(hi->filename);
free(hi->target);
free(hi);
}
#ifdef DEBUG
static void
hashinfo_print(struct hashinfo *hi)
{
int i;
printf("hashinfo %s %08lx %u %i\n", hi->filename, hi->hash,
hi->index, hi->is_crl);
for (i = 0; i < (int)EVP_MAX_MD_SIZE; i++) {
printf("%02X%c", hi->fingerprint[i],
(i + 1 == (int)EVP_MAX_MD_SIZE) ? '\n' : ':');
}
}
#endif
static int
hashinfo_compare(const void *a, const void *b)
{
struct hashinfo *hia = *(struct hashinfo **)a;
struct hashinfo *hib = *(struct hashinfo **)b;
int rv;
rv = hia->hash < hib->hash ? -1 : hia->hash > hib->hash;
if (rv != 0)
return (rv);
rv = memcmp(hia->fingerprint, hib->fingerprint,
sizeof(hia->fingerprint));
if (rv != 0)
return (rv);
return strcmp(hia->filename, hib->filename);
}
static struct hashinfo *
hashinfo_chain(struct hashinfo *head, struct hashinfo *entry)
{
struct hashinfo *hi = head;
if (hi == NULL)
return (entry);
while (hi->next != NULL)
hi = hi->next;
hi->next = entry;
return (head);
}
static void
hashinfo_chain_free(struct hashinfo *hi)
{
struct hashinfo *next;
while (hi != NULL) {
next = hi->next;
hashinfo_free(hi);
hi = next;
}
}
static size_t
hashinfo_chain_length(struct hashinfo *hi)
{
int len = 0;
while (hi != NULL) {
len++;
hi = hi->next;
}
return (len);
}
static int
hashinfo_chain_sort(struct hashinfo **head)
{
struct hashinfo **list, *entry;
size_t len;
int i;
if (*head == NULL)
return (0);
len = hashinfo_chain_length(*head);
if ((list = reallocarray(NULL, len, sizeof(struct hashinfo *))) == NULL)
return (-1);
for (entry = *head, i = 0; entry != NULL; entry = entry->next, i++)
list[i] = entry;
qsort(list, len, sizeof(struct hashinfo *), hashinfo_compare);
*head = entry = list[0];
for (i = 1; i < len; i++) {
entry->next = list[i];
entry = list[i];
}
entry->next = NULL;
free(list);
return (0);
}
static char *
hashinfo_linkname(struct hashinfo *hi)
{
char *filename;
if (asprintf(&filename, "%08lx.%s%u", hi->hash,
(hi->is_crl ? "r" : ""), hi->index) == -1)
return (NULL);
return (filename);
}
static int
filename_is_hash(const char *filename)
{
const char *p = filename;
while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f'))
p++;
if (*p++ != '.')
return (0);
if (*p == 'r') /* CRL format. */
p++;
while (*p >= '0' && *p <= '9')
p++;
if (*p != '\0')
return (0);
return (1);
}
static int
filename_is_pem(const char *filename)
{
const char *q, *p = filename;
if ((q = strchr(p, '\0')) == NULL)
return (0);
if ((q - p) < 4)
return (0);
if (strncmp((q - 4), ".pem", 4) != 0)
return (0);
return (1);
}
static struct hashinfo *
hashinfo_from_linkname(const char *linkname, const char *target)
{
struct hashinfo *hi = NULL;
const char *errstr;
char *l, *p, *ep;
long long val;
if ((l = strdup(linkname)) == NULL)
goto err;
if ((p = strchr(l, '.')) == NULL)
goto err;
*p++ = '\0';
if ((hi = hashinfo(linkname, 0, NULL)) == NULL)
goto err;
if ((hi->target = strdup(target)) == NULL)
goto err;
errno = 0;
val = strtoll(l, &ep, 16);
if (l[0] == '\0' || *ep != '\0')
goto err;
if (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN))
goto err;
if (val < 0 || val > ULONG_MAX)
goto err;
hi->hash = (unsigned long)val;
if (*p == 'r') {
hi->is_crl = 1;
p++;
}
val = strtonum(p, 0, 0xffffffff, &errstr);
if (errstr != NULL)
goto err;
hi->index = (unsigned int)val;
goto done;
err:
hashinfo_free(hi);
hi = NULL;
done:
free(l);
return (hi);
}
static struct hashinfo *
certhash_cert(BIO *bio, const char *filename)
{
unsigned char fingerprint[EVP_MAX_MD_SIZE];
struct hashinfo *hi = NULL;
const EVP_MD *digest;
X509 *cert = NULL;
unsigned long hash;
unsigned int len;
if ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL)
goto err;
hash = X509_subject_name_hash(cert);
digest = EVP_sha256();
if (X509_digest(cert, digest, fingerprint, &len) != 1) {
fprintf(stderr, "out of memory\n");
goto err;
}
hi = hashinfo(filename, hash, fingerprint);
err:
X509_free(cert);
return (hi);
}
static struct hashinfo *
certhash_crl(BIO *bio, const char *filename)
{
unsigned char fingerprint[EVP_MAX_MD_SIZE];
struct hashinfo *hi = NULL;
const EVP_MD *digest;
X509_CRL *crl = NULL;
unsigned long hash;
unsigned int len;
if ((crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) == NULL)
return (NULL);
hash = X509_NAME_hash(X509_CRL_get_issuer(crl));
digest = EVP_sha256();
if (X509_CRL_digest(crl, digest, fingerprint, &len) != 1) {
fprintf(stderr, "out of memory\n");
goto err;
}
hi = hashinfo(filename, hash, fingerprint);
err:
X509_CRL_free(crl);
return (hi);
}
static int
certhash_addlink(struct hashinfo **links, struct hashinfo *hi)
{
struct hashinfo *link = NULL;
if ((link = hashinfo(NULL, hi->hash, hi->fingerprint)) == NULL)
goto err;
if ((link->filename = hashinfo_linkname(hi)) == NULL)
goto err;
link->reference = hi;
link->changed = 1;
*links = hashinfo_chain(*links, link);
hi->reference = link;
return (0);
err:
hashinfo_free(link);
return (-1);
}
static void
certhash_findlink(struct hashinfo *links, struct hashinfo *hi)
{
struct hashinfo *link;
for (link = links; link != NULL; link = link->next) {
if (link->is_crl == hi->is_crl &&
link->hash == hi->hash &&
link->index == hi->index &&
link->reference == NULL) {
link->reference = hi;
if (link->target == NULL ||
strcmp(link->target, hi->filename) != 0)
link->changed = 1;
hi->reference = link;
break;
}
}
}
static void
certhash_index(struct hashinfo *head, const char *name)
{
struct hashinfo *last, *entry;
int index = 0;
last = NULL;
for (entry = head; entry != NULL; entry = entry->next) {
if (last != NULL) {
if (entry->hash == last->hash) {
if (memcmp(entry->fingerprint,
last->fingerprint,
sizeof(entry->fingerprint)) == 0) {
fprintf(stderr, "WARNING: duplicate %s "
"in %s (using %s), ignoring...\n",
name, entry->filename,
last->filename);
entry->is_dup = 1;
continue;
}
index++;
} else {
index = 0;
}
}
entry->index = index;
last = entry;
}
}
static int
certhash_merge(struct hashinfo **links, struct hashinfo **certs,
struct hashinfo **crls)
{
struct hashinfo *cert, *crl;
/* Pass 1 - sort and index entries. */
if (hashinfo_chain_sort(certs) == -1)
return (-1);
if (hashinfo_chain_sort(crls) == -1)
return (-1);
certhash_index(*certs, "certificate");
certhash_index(*crls, "CRL");
/* Pass 2 - map to existing links. */
for (cert = *certs; cert != NULL; cert = cert->next) {
if (cert->is_dup == 1)
continue;
certhash_findlink(*links, cert);
}
for (crl = *crls; crl != NULL; crl = crl->next) {
if (crl->is_dup == 1)
continue;
certhash_findlink(*links, crl);
}
/* Pass 3 - determine missing links. */
for (cert = *certs; cert != NULL; cert = cert->next) {
if (cert->is_dup == 1 || cert->reference != NULL)
continue;
if (certhash_addlink(links, cert) == -1)
return (-1);
}
for (crl = *crls; crl != NULL; crl = crl->next) {
if (crl->is_dup == 1 || crl->reference != NULL)
continue;
if (certhash_addlink(links, crl) == -1)
return (-1);
}
return (0);
}
static int
certhash_link(struct dirent *dep, struct hashinfo **links)
{
struct hashinfo *hi = NULL;
char target[PATH_MAX];
struct stat sb;
int n;
if (lstat(dep->d_name, &sb) == -1) {
fprintf(stderr, "failed to stat %s\n", dep->d_name);
return (-1);
}
if (!S_ISLNK(sb.st_mode))
return (0);
n = readlink(dep->d_name, target, sizeof(target) - 1);
if (n == -1) {
fprintf(stderr, "failed to readlink %s\n", dep->d_name);
return (-1);
}
if (n >= sizeof(target) - 1) {
fprintf(stderr, "symbolic link is too long %s\n", dep->d_name);
return (-1);
}
target[n] = '\0';
hi = hashinfo_from_linkname(dep->d_name, target);
if (hi == NULL) {
fprintf(stderr, "failed to get hash info %s\n", dep->d_name);
return (-1);
}
hi->exists = 1;
*links = hashinfo_chain(*links, hi);
return (0);
}
static int
certhash_file(struct dirent *dep, struct hashinfo **certs,
struct hashinfo **crls)
{
struct hashinfo *hi = NULL;
int has_cert, has_crl;
int ret = -1;
BIO *bio = NULL;
FILE *f;
has_cert = has_crl = 0;
if ((f = fopen(dep->d_name, "r")) == NULL) {
fprintf(stderr, "failed to fopen %s\n", dep->d_name);
goto err;
}
if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
fprintf(stderr, "failed to create bio\n");
fclose(f);
goto err;
}
if ((hi = certhash_cert(bio, dep->d_name)) != NULL) {
has_cert = 1;
*certs = hashinfo_chain(*certs, hi);
}
if (BIO_reset(bio) != 0) {
fprintf(stderr, "BIO_reset failed\n");
goto err;
}
if ((hi = certhash_crl(bio, dep->d_name)) != NULL) {
has_crl = hi->is_crl = 1;
*crls = hashinfo_chain(*crls, hi);
}
if (!has_cert && !has_crl)
fprintf(stderr, "PEM file %s does not contain a certificate "
"or CRL, ignoring...\n", dep->d_name);
ret = 0;
err:
BIO_free(bio);
return (ret);
}
static int
certhash_directory(const char *path)
{
struct hashinfo *links = NULL, *certs = NULL, *crls = NULL, *link;
int ret = 0;
struct dirent *dep;
DIR *dip = NULL;
if ((dip = opendir(".")) == NULL) {
fprintf(stderr, "failed to open directory %s\n", path);
goto err;
}
if (cfg.verbose)
fprintf(stdout, "scanning directory %s\n", path);
/* Create lists of existing hash links, certs and CRLs. */
while ((dep = readdir(dip)) != NULL) {
if (filename_is_hash(dep->d_name)) {
if (certhash_link(dep, &links) == -1)
goto err;
}
if (filename_is_pem(dep->d_name)) {
if (certhash_file(dep, &certs, &crls) == -1)
goto err;
}
}
if (certhash_merge(&links, &certs, &crls) == -1) {
fprintf(stderr, "certhash merge failed\n");
goto err;
}
/* Remove spurious links. */
for (link = links; link != NULL; link = link->next) {
if (link->exists == 0 ||
(link->reference != NULL && link->changed == 0))
continue;
if (cfg.verbose)
fprintf(stdout, "%s link %s -> %s\n",
(cfg.dryrun ? "would remove" :
"removing"), link->filename, link->target);
if (cfg.dryrun)
continue;
if (unlink(link->filename) == -1) {
fprintf(stderr, "failed to remove link %s\n",
link->filename);
goto err;
}
}
/* Create missing links. */
for (link = links; link != NULL; link = link->next) {
if (link->exists == 1 && link->changed == 0)
continue;
if (cfg.verbose)
fprintf(stdout, "%s link %s -> %s\n",
(cfg.dryrun ? "would create" :
"creating"), link->filename,
link->reference->filename);
if (cfg.dryrun)
continue;
if (symlink(link->reference->filename, link->filename) == -1) {
fprintf(stderr, "failed to create link %s -> %s\n",
link->filename, link->reference->filename);
goto err;
}
}
goto done;
err:
ret = 1;
done:
hashinfo_chain_free(certs);
hashinfo_chain_free(crls);
hashinfo_chain_free(links);
if (dip != NULL)
closedir(dip);
return (ret);
}
static void
certhash_usage(void)
{
fprintf(stderr, "usage: certhash [-nv] dir ...\n");
options_usage(certhash_options);
}
int
certhash_main(int argc, char **argv)
{
int argsused;
int i, cwdfd, ret = 0;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, certhash_options, NULL, &argsused) != 0) {
certhash_usage();
return (1);
}
if ((cwdfd = open(".", O_RDONLY)) == -1) {
perror("failed to open current directory");
return (1);
}
for (i = argsused; i < argc; i++) {
if (chdir(argv[i]) == -1) {
fprintf(stderr,
"failed to change to directory %s: %s\n",
argv[i], strerror(errno));
ret = 1;
continue;
}
ret |= certhash_directory(argv[i]);
if (fchdir(cwdfd) == -1) {
perror("failed to restore current directory");
ret = 1;
break; /* can't continue safely */
}
}
close(cwdfd);
return (ret);
}

200
apps/openssl/ciphers.c Normal file
View File

@@ -0,0 +1,200 @@
/* $OpenBSD: ciphers.c,v 1.18 2023/03/06 14:32:05 tb Exp $ */
/*
* Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include "apps.h"
#include "progs.h"
static struct {
int usage;
int use_supported;
int verbose;
int version;
} cfg;
static const struct option ciphers_options[] = {
{
.name = "h",
.type = OPTION_FLAG,
.opt.flag = &cfg.usage,
},
{
.name = "?",
.type = OPTION_FLAG,
.opt.flag = &cfg.usage,
},
{
.name = "s",
.desc = "Only list ciphers that are supported by the TLS method",
.type = OPTION_FLAG,
.opt.flag = &cfg.use_supported,
},
{
.name = "tls1",
.desc = "Use TLS protocol version 1",
.type = OPTION_VALUE,
.opt.value = &cfg.version,
.value = TLS1_VERSION,
},
{
.name = "tls1_1",
.desc = "Use TLS protocol version 1.1",
.type = OPTION_VALUE,
.opt.value = &cfg.version,
.value = TLS1_1_VERSION,
},
{
.name = "tls1_2",
.desc = "Use TLS protocol version 1.2",
.type = OPTION_VALUE,
.opt.value = &cfg.version,
.value = TLS1_2_VERSION,
},
{
.name = "tls1_3",
.desc = "Use TLS protocol version 1.3",
.type = OPTION_VALUE,
.opt.value = &cfg.version,
.value = TLS1_3_VERSION,
},
{
.name = "v",
.desc = "Provide cipher listing",
.type = OPTION_VALUE,
.opt.value = &cfg.verbose,
.value = 1,
},
{
.name = "V",
.desc = "Provide cipher listing with cipher suite values",
.type = OPTION_VALUE,
.opt.value = &cfg.verbose,
.value = 2,
},
{ NULL },
};
static void
ciphers_usage(void)
{
fprintf(stderr, "usage: ciphers [-hsVv] [-tls1] [-tls1_1] [-tls1_2] "
"[-tls1_3] [cipherlist]\n");
options_usage(ciphers_options);
}
int
ciphers_main(int argc, char **argv)
{
char *cipherlist = NULL;
STACK_OF(SSL_CIPHER) *ciphers;
STACK_OF(SSL_CIPHER) *supported_ciphers = NULL;
const SSL_CIPHER *cipher;
SSL_CTX *ssl_ctx = NULL;
SSL *ssl = NULL;
uint16_t value;
int i, rv = 0;
char *desc;
if (pledge("stdio rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, ciphers_options, &cipherlist,
NULL) != 0) {
ciphers_usage();
return (1);
}
if (cfg.usage) {
ciphers_usage();
return (1);
}
if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL)
goto err;
if (cfg.version != 0) {
if (!SSL_CTX_set_min_proto_version(ssl_ctx,
cfg.version))
goto err;
if (!SSL_CTX_set_max_proto_version(ssl_ctx,
cfg.version))
goto err;
}
if (cipherlist != NULL) {
if (SSL_CTX_set_cipher_list(ssl_ctx, cipherlist) == 0)
goto err;
}
if ((ssl = SSL_new(ssl_ctx)) == NULL)
goto err;
if (cfg.use_supported) {
if ((supported_ciphers =
SSL_get1_supported_ciphers(ssl)) == NULL)
goto err;
ciphers = supported_ciphers;
} else {
if ((ciphers = SSL_get_ciphers(ssl)) == NULL)
goto err;
}
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
cipher = sk_SSL_CIPHER_value(ciphers, i);
if (cfg.verbose == 0) {
fprintf(stdout, "%s%s", (i ? ":" : ""),
SSL_CIPHER_get_name(cipher));
continue;
}
if (cfg.verbose > 1) {
value = SSL_CIPHER_get_value(cipher);
fprintf(stdout, "%-*s0x%02X,0x%02X - ", 10, "",
((value >> 8) & 0xff), (value & 0xff));
}
desc = SSL_CIPHER_description(cipher, NULL, 0);
if (strcmp(desc, "OPENSSL_malloc Error") == 0) {
fprintf(stderr, "out of memory\n");
goto err;
}
fprintf(stdout, "%s", desc);
free(desc);
}
if (cfg.verbose == 0)
fprintf(stdout, "\n");
goto done;
err:
ERR_print_errors_fp(stderr);
rv = 1;
done:
sk_SSL_CIPHER_free(supported_ciphers);
SSL_CTX_free(ssl_ctx);
SSL_free(ssl);
return (rv);
}

1961
apps/openssl/cms.c Normal file

File diff suppressed because it is too large Load Diff

482
apps/openssl/crl.c Normal file
View File

@@ -0,0 +1,482 @@
/* $OpenBSD: crl.c,v 1.17 2023/03/06 14:32:05 tb Exp $ */
/* 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 <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
static struct {
char *cafile;
char *capath;
int crlnumber;
int fingerprint;
int hash;
int hash_old;
char *infile;
int informat;
int issuer;
int lastupdate;
char *nameopt;
int nextupdate;
int noout;
char *outfile;
int outformat;
int text;
int verify;
} cfg;
static const struct option crl_options[] = {
{
.name = "CAfile",
.argname = "file",
.desc = "Verify the CRL using certificates in the given file",
.type = OPTION_ARG,
.opt.arg = &cfg.cafile,
},
{
.name = "CApath",
.argname = "path",
.desc = "Verify the CRL using certificates in the given path",
.type = OPTION_ARG,
.opt.arg = &cfg.capath,
},
{
.name = "crlnumber",
.desc = "Print the CRL number",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.crlnumber,
},
{
.name = "fingerprint",
.desc = "Print the CRL fingerprint",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.fingerprint,
},
{
.name = "hash",
.desc = "Print the hash of the issuer name",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.hash,
},
{
.name = "hash_old",
.desc = "Print an old-style (MD5) hash of the issuer name",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.hash_old,
},
{
.name = "in",
.argname = "file",
.desc = "Input file to read from (stdin if unspecified)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "issuer",
.desc = "Print the issuer name",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.issuer,
},
{
.name = "lastupdate",
.desc = "Print the lastUpdate field",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.lastupdate,
},
{
.name = "nameopt",
.argname = "options",
.desc = "Specify certificate name options",
.type = OPTION_ARG,
.opt.arg = &cfg.nameopt,
},
{
.name = "nextupdate",
.desc = "Print the nextUpdate field",
.type = OPTION_FLAG_ORD,
.opt.flag = &cfg.nextupdate,
},
{
.name = "noout",
.desc = "Do not output the encoded version of the CRL",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file to write to (stdout if unspecified)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "text",
.desc = "Print out the CRL in text form",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{
.name = "verify",
.desc = "Verify the signature on the CRL",
.type = OPTION_FLAG,
.opt.flag = &cfg.verify,
},
{NULL},
};
static void
crl_usage(void)
{
fprintf(stderr,
"usage: crl [-CAfile file] [-CApath dir] [-fingerprint] [-hash]\n"
" [-in file] [-inform DER | PEM] [-issuer] [-lastupdate]\n"
" [-nextupdate] [-noout] [-out file] [-outform DER | PEM]\n"
" [-text]\n\n");
options_usage(crl_options);
}
static X509_CRL *load_crl(char *file, int format);
static BIO *bio_out = NULL;
int
crl_main(int argc, char **argv)
{
unsigned long nmflag = 0;
X509_CRL *x = NULL;
int ret = 1, i;
BIO *out = NULL;
X509_STORE *store = NULL;
X509_STORE_CTX *ctx = NULL;
X509_LOOKUP *lookup = NULL;
X509_OBJECT *xobj = NULL;
EVP_PKEY *pkey;
const EVP_MD *digest;
char *digest_name = NULL;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
if (bio_out == NULL) {
if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
}
}
digest = EVP_sha256();
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
crl_usage();
goto end;
}
if (cfg.cafile != NULL || cfg.capath != NULL)
cfg.verify = 1;
if (cfg.nameopt != NULL) {
if (set_name_ex(&nmflag, cfg.nameopt) != 1) {
fprintf(stderr,
"Invalid -nameopt argument '%s'\n",
cfg.nameopt);
goto end;
}
}
if (digest_name != NULL) {
if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
fprintf(stderr,
"Unknown message digest algorithm '%s'\n",
digest_name);
goto end;
}
}
x = load_crl(cfg.infile, cfg.informat);
if (x == NULL)
goto end;
if (cfg.verify) {
store = X509_STORE_new();
if (store == NULL)
goto end;
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
if (lookup == NULL)
goto end;
if (!X509_LOOKUP_load_file(lookup, cfg.cafile,
X509_FILETYPE_PEM))
X509_LOOKUP_load_file(lookup, NULL,
X509_FILETYPE_DEFAULT);
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
if (lookup == NULL)
goto end;
if (!X509_LOOKUP_add_dir(lookup, cfg.capath,
X509_FILETYPE_PEM))
X509_LOOKUP_add_dir(lookup, NULL,
X509_FILETYPE_DEFAULT);
ERR_clear_error();
if ((ctx = X509_STORE_CTX_new()) == NULL)
goto end;
if ((xobj = X509_OBJECT_new()) == NULL)
goto end;
if (!X509_STORE_CTX_init(ctx, store, NULL, NULL)) {
BIO_printf(bio_err,
"Error initialising X509 store\n");
goto end;
}
i = X509_STORE_get_by_subject(ctx, X509_LU_X509,
X509_CRL_get_issuer(x), xobj);
if (i <= 0) {
BIO_printf(bio_err,
"Error getting CRL issuer certificate\n");
goto end;
}
pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj));
X509_OBJECT_free(xobj);
xobj = NULL;
if (!pkey) {
BIO_printf(bio_err,
"Error getting CRL issuer public key\n");
goto end;
}
i = X509_CRL_verify(x, pkey);
EVP_PKEY_free(pkey);
if (i < 0)
goto end;
if (i == 0)
BIO_printf(bio_err, "verify failure\n");
else
BIO_printf(bio_err, "verify OK\n");
}
/* Print requested information the order that the flags were given. */
for (i = 1; i <= argc; i++) {
if (cfg.issuer == i) {
print_name(bio_out, "issuer=",
X509_CRL_get_issuer(x), nmflag);
}
if (cfg.crlnumber == i) {
ASN1_INTEGER *crlnum;
crlnum = X509_CRL_get_ext_d2i(x,
NID_crl_number, NULL, NULL);
BIO_printf(bio_out, "crlNumber=");
if (crlnum) {
i2a_ASN1_INTEGER(bio_out, crlnum);
ASN1_INTEGER_free(crlnum);
} else
BIO_puts(bio_out, "<NONE>");
BIO_printf(bio_out, "\n");
}
if (cfg.hash == i) {
BIO_printf(bio_out, "%08lx\n",
X509_NAME_hash(X509_CRL_get_issuer(x)));
}
#ifndef OPENSSL_NO_MD5
if (cfg.hash_old == i) {
BIO_printf(bio_out, "%08lx\n",
X509_NAME_hash_old(X509_CRL_get_issuer(x)));
}
#endif
if (cfg.lastupdate == i) {
BIO_printf(bio_out, "lastUpdate=");
ASN1_TIME_print(bio_out,
X509_CRL_get_lastUpdate(x));
BIO_printf(bio_out, "\n");
}
if (cfg.nextupdate == i) {
BIO_printf(bio_out, "nextUpdate=");
if (X509_CRL_get_nextUpdate(x))
ASN1_TIME_print(bio_out,
X509_CRL_get_nextUpdate(x));
else
BIO_printf(bio_out, "NONE");
BIO_printf(bio_out, "\n");
}
if (cfg.fingerprint == i) {
int j;
unsigned int n;
unsigned char md[EVP_MAX_MD_SIZE];
if (!X509_CRL_digest(x, digest, md, &n)) {
BIO_printf(bio_err, "out of memory\n");
goto end;
}
BIO_printf(bio_out, "%s Fingerprint=",
OBJ_nid2sn(EVP_MD_type(digest)));
for (j = 0; j < (int) n; j++) {
BIO_printf(bio_out, "%02X%c", md[j],
(j + 1 == (int)n) ? '\n' : ':');
}
}
}
out = BIO_new(BIO_s_file());
if (out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.text)
X509_CRL_print(out, x);
if (cfg.noout) {
ret = 0;
goto end;
}
if (cfg.outformat == FORMAT_ASN1)
i = (int) i2d_X509_CRL_bio(out, x);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_X509_CRL(out, x);
else {
BIO_printf(bio_err,
"bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write CRL\n");
goto end;
}
ret = 0;
end:
BIO_free_all(out);
BIO_free_all(bio_out);
bio_out = NULL;
X509_CRL_free(x);
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
X509_OBJECT_free(xobj);
return (ret);
}
static X509_CRL *
load_crl(char *infile, int format)
{
X509_CRL *x = NULL;
BIO *in = NULL;
in = BIO_new(BIO_s_file());
if (in == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, infile) <= 0) {
perror(infile);
goto end;
}
}
if (format == FORMAT_ASN1)
x = d2i_X509_CRL_bio(in, NULL);
else if (format == FORMAT_PEM)
x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
else {
BIO_printf(bio_err,
"bad input format specified for input crl\n");
goto end;
}
if (x == NULL) {
BIO_printf(bio_err, "unable to load CRL\n");
ERR_print_errors(bio_err);
goto end;
}
end:
BIO_free(in);
return (x);
}

331
apps/openssl/crl2p7.c Normal file
View File

@@ -0,0 +1,331 @@
/* $OpenBSD: crl2p7.c,v 1.11 2023/03/06 14:32:05 tb Exp $ */
/* 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.]
*/
/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
* and donated 'to the cause' along with lots and lots of other fixes to
* the library. */
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
static int add_certs_from_file(STACK_OF(X509) * stack, char *certfile);
static struct {
STACK_OF(OPENSSL_STRING) *certflst;
char *infile;
int informat;
int nocrl;
char *outfile;
int outformat;
} cfg;
static int
crl2p7_opt_certfile(char *arg)
{
if (cfg.certflst == NULL)
cfg.certflst = sk_OPENSSL_STRING_new_null();
if (cfg.certflst == NULL) {
fprintf(stderr, "out of memory\n");
return (1);
}
if (!sk_OPENSSL_STRING_push(cfg.certflst, arg)) {
fprintf(stderr, "out of memory\n");
return (1);
}
return (0);
}
static const struct option crl2p7_options[] = {
{
.name = "certfile",
.argname = "file",
.desc = "Chain of PEM certificates to a trusted CA",
.type = OPTION_ARG_FUNC,
.opt.argfunc = crl2p7_opt_certfile,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "nocrl",
.desc = "Do not read CRL from input or include CRL in output",
.type = OPTION_FLAG,
.opt.flag = &cfg.nocrl,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{ NULL },
};
static void
crl2p7_usage(void)
{
fprintf(stderr,
"usage: crl2p7 [-certfile file] [-in file] [-inform DER | PEM]\n"
" [-nocrl] [-out file] [-outform DER | PEM]\n\n");
options_usage(crl2p7_options);
}
int
crl2pkcs7_main(int argc, char **argv)
{
int i;
BIO *in = NULL, *out = NULL;
char *certfile;
PKCS7 *p7 = NULL;
PKCS7_SIGNED *p7s = NULL;
X509_CRL *crl = NULL;
STACK_OF(X509_CRL) *crl_stack = NULL;
STACK_OF(X509) *cert_stack = NULL;
int ret = 1;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, crl2p7_options, NULL, NULL) != 0) {
crl2p7_usage();
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (!cfg.nocrl) {
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.informat == FORMAT_ASN1)
crl = d2i_X509_CRL_bio(in, NULL);
else if (cfg.informat == FORMAT_PEM)
crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
else {
BIO_printf(bio_err,
"bad input format specified for input crl\n");
goto end;
}
if (crl == NULL) {
BIO_printf(bio_err, "unable to load CRL\n");
ERR_print_errors(bio_err);
goto end;
}
}
if ((p7 = PKCS7_new()) == NULL)
goto end;
if ((p7s = PKCS7_SIGNED_new()) == NULL)
goto end;
p7->type = OBJ_nid2obj(NID_pkcs7_signed);
p7->d.sign = p7s;
p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
if (!ASN1_INTEGER_set(p7s->version, 1))
goto end;
if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
goto end;
p7s->crl = crl_stack;
if (crl != NULL) {
sk_X509_CRL_push(crl_stack, crl);
crl = NULL; /* now part of p7 for freeing */
}
if ((cert_stack = sk_X509_new_null()) == NULL)
goto end;
p7s->cert = cert_stack;
if (cfg.certflst) {
for (i = 0; i < sk_OPENSSL_STRING_num(cfg.certflst); i++) {
certfile = sk_OPENSSL_STRING_value(cfg.certflst, i);
if (add_certs_from_file(cert_stack, certfile) < 0) {
BIO_printf(bio_err,
"error loading certificates\n");
ERR_print_errors(bio_err);
goto end;
}
}
}
sk_OPENSSL_STRING_free(cfg.certflst);
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.outformat == FORMAT_ASN1)
i = i2d_PKCS7_bio(out, p7);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_PKCS7(out, p7);
else {
BIO_printf(bio_err,
"bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write pkcs7 object\n");
ERR_print_errors(bio_err);
goto end;
}
ret = 0;
end:
if (in != NULL)
BIO_free(in);
if (out != NULL)
BIO_free_all(out);
if (p7 != NULL)
PKCS7_free(p7);
if (crl != NULL)
X509_CRL_free(crl);
return (ret);
}
static int
add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
{
BIO *in = NULL;
int count = 0;
int ret = -1;
STACK_OF(X509_INFO) *sk = NULL;
X509_INFO *xi;
in = BIO_new(BIO_s_file());
if (in == NULL || BIO_read_filename(in, certfile) <= 0) {
BIO_printf(bio_err, "error opening the file, %s\n", certfile);
goto end;
}
/* This loads from a file, a stack of x509/crl/pkey sets */
sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
if (sk == NULL) {
BIO_printf(bio_err, "error reading the file, %s\n", certfile);
goto end;
}
/* scan over it and pull out the CRL's */
while (sk_X509_INFO_num(sk)) {
xi = sk_X509_INFO_shift(sk);
if (xi->x509 != NULL) {
sk_X509_push(stack, xi->x509);
xi->x509 = NULL;
count++;
}
X509_INFO_free(xi);
}
ret = count;
end:
/* never need to free x */
if (in != NULL)
BIO_free(in);
if (sk != NULL)
sk_X509_INFO_free(sk);
return (ret);
}

671
apps/openssl/dgst.c Normal file
View File

@@ -0,0 +1,671 @@
/* $OpenBSD: dgst.c,v 1.21 2023/03/06 14:32:05 tb Exp $ */
/* 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 <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#define BUFSIZE 1024*8
int
do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout,
EVP_PKEY * key, unsigned char *sigin, int siglen,
const char *sig_name, const char *md_name,
const char *file, BIO * bmd);
static struct {
int argsused;
int debug;
int do_verify;
char *hmac_key;
char *keyfile;
int keyform;
const EVP_MD *m;
char *mac_name;
STACK_OF(OPENSSL_STRING) *macopts;
const EVP_MD *md;
int out_bin;
char *outfile;
char *passargin;
int separator;
char *sigfile;
STACK_OF(OPENSSL_STRING) *sigopts;
int want_pub;
} cfg;
static int
dgst_opt_macopt(char *arg)
{
if (arg == NULL)
return (1);
if (cfg.macopts == NULL &&
(cfg.macopts = sk_OPENSSL_STRING_new_null()) == NULL)
return (1);
if (!sk_OPENSSL_STRING_push(cfg.macopts, arg))
return (1);
return (0);
}
static int
dgst_opt_md(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.m = EVP_get_digestbyname(name)) == NULL)
return (1);
cfg.md = cfg.m;
*argsused = 1;
return (0);
}
static int
dgst_opt_prverify(char *arg)
{
if (arg == NULL)
return (1);
cfg.keyfile = arg;
cfg.do_verify = 1;
return (0);
}
static int
dgst_opt_sigopt(char *arg)
{
if (arg == NULL)
return (1);
if (cfg.sigopts == NULL &&
(cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL)
return (1);
if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
return (1);
return (0);
}
static int
dgst_opt_verify(char *arg)
{
if (arg == NULL)
return (1);
cfg.keyfile = arg;
cfg.want_pub = 1;
cfg.do_verify = 1;
return (0);
}
static const struct option dgst_options[] = {
{
.name = "binary",
.desc = "Output the digest or signature in binary form",
.type = OPTION_VALUE,
.opt.value = &cfg.out_bin,
.value = 1,
},
{
.name = "c",
.desc = "Print the digest in two-digit groups separated by colons",
.type = OPTION_VALUE,
.opt.value = &cfg.separator,
.value = 1,
},
{
.name = "d",
.desc = "Print BIO debugging information",
.type = OPTION_FLAG,
.opt.flag = &cfg.debug,
},
{
.name = "hex",
.desc = "Output as hex dump",
.type = OPTION_VALUE,
.opt.value = &cfg.out_bin,
.value = 0,
},
{
.name = "hmac",
.argname = "key",
.desc = "Create hashed MAC with key",
.type = OPTION_ARG,
.opt.arg = &cfg.hmac_key,
},
{
.name = "keyform",
.argname = "format",
.desc = "Key file format (PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.keyform,
},
{
.name = "mac",
.argname = "algorithm",
.desc = "Create MAC (not necessarily HMAC)",
.type = OPTION_ARG,
.opt.arg = &cfg.mac_name,
},
{
.name = "macopt",
.argname = "nm:v",
.desc = "MAC algorithm parameters or key",
.type = OPTION_ARG_FUNC,
.opt.argfunc = dgst_opt_macopt,
},
{
.name = "out",
.argname = "file",
.desc = "Output to file rather than stdout",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "passin",
.argname = "arg",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "prverify",
.argname = "file",
.desc = "Verify a signature using private key in file",
.type = OPTION_ARG_FUNC,
.opt.argfunc = dgst_opt_prverify,
},
{
.name = "r",
.desc = "Output the digest in coreutils format",
.type = OPTION_VALUE,
.opt.value = &cfg.separator,
.value = 2,
},
{
.name = "sign",
.argname = "file",
.desc = "Sign digest using private key in file",
.type = OPTION_ARG,
.opt.arg = &cfg.keyfile,
},
{
.name = "signature",
.argname = "file",
.desc = "Signature to verify",
.type = OPTION_ARG,
.opt.arg = &cfg.sigfile,
},
{
.name = "sigopt",
.argname = "nm:v",
.desc = "Signature parameter",
.type = OPTION_ARG_FUNC,
.opt.argfunc = dgst_opt_sigopt,
},
{
.name = "verify",
.argname = "file",
.desc = "Verify a signature using public key in file",
.type = OPTION_ARG_FUNC,
.opt.argfunc = dgst_opt_verify,
},
{
.name = NULL,
.desc = "",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = dgst_opt_md,
},
{ NULL },
};
static void
list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg)
{
const char *mname;
/* Skip aliases */
if (!m)
return;
mname = OBJ_nid2ln(EVP_MD_type(m));
/* Skip shortnames */
if (strcmp(from, mname))
return;
if (strchr(mname, ' '))
mname = EVP_MD_name(m);
BIO_printf(arg, " -%-17s To use the %s message digest algorithm\n",
mname, mname);
}
static void
dgst_usage(void)
{
fprintf(stderr, "usage: dgst [-cdr] [-binary] [-digest] [-hex]");
fprintf(stderr, " [-hmac key] [-keyform fmt]\n");
fprintf(stderr, " [-mac algorithm] [-macopt nm:v] [-out file]");
fprintf(stderr, " [-passin arg]\n");
fprintf(stderr, " [-prverify file] [-sign file]");
fprintf(stderr, " [-signature file]\n");
fprintf(stderr, " [-sigopt nm:v] [-verify file] [file ...]\n\n");
options_usage(dgst_options);
EVP_MD_do_all_sorted(list_md_fn, bio_err);
fprintf(stderr, "\n");
}
int
dgst_main(int argc, char **argv)
{
unsigned char *buf = NULL;
int i, err = 1;
BIO *in = NULL, *inp;
BIO *bmd = NULL;
BIO *out = NULL;
#define PROG_NAME_SIZE 39
char pname[PROG_NAME_SIZE + 1];
EVP_PKEY *sigkey = NULL;
unsigned char *sigbuf = NULL;
int siglen = 0;
char *passin = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
if ((buf = malloc(BUFSIZE)) == NULL) {
BIO_printf(bio_err, "out of memory\n");
goto end;
}
memset(&cfg, 0, sizeof(cfg));
cfg.keyform = FORMAT_PEM;
cfg.out_bin = -1;
/* first check the program name */
program_name(argv[0], pname, sizeof pname);
cfg.md = EVP_get_digestbyname(pname);
if (options_parse(argc, argv, dgst_options, NULL,
&cfg.argsused) != 0) {
dgst_usage();
goto end;
}
argc -= cfg.argsused;
argv += cfg.argsused;
if (cfg.do_verify && !cfg.sigfile) {
BIO_printf(bio_err,
"No signature to verify: use the -signature option\n");
goto end;
}
in = BIO_new(BIO_s_file());
bmd = BIO_new(BIO_f_md());
if (in == NULL || bmd == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.debug) {
BIO_set_callback(in, BIO_debug_callback);
/* needed for windows 3.1 */
BIO_set_callback_arg(in, (char *) bio_err);
}
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
if (cfg.out_bin == -1) {
if (cfg.keyfile)
cfg.out_bin = 1;
else
cfg.out_bin = 0;
}
if (cfg.outfile) {
if (cfg.out_bin)
out = BIO_new_file(cfg.outfile, "wb");
else
out = BIO_new_file(cfg.outfile, "w");
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
if (!out) {
BIO_printf(bio_err, "Error opening output file %s\n",
cfg.outfile ? cfg.outfile : "(stdout)");
ERR_print_errors(bio_err);
goto end;
}
if ((!!cfg.mac_name + !!cfg.keyfile +
!!cfg.hmac_key) > 1) {
BIO_printf(bio_err,
"MAC and Signing key cannot both be specified\n");
goto end;
}
if (cfg.keyfile) {
if (cfg.want_pub)
sigkey = load_pubkey(bio_err, cfg.keyfile,
cfg.keyform, 0, NULL, "key file");
else
sigkey = load_key(bio_err, cfg.keyfile,
cfg.keyform, 0, passin, "key file");
if (!sigkey) {
/*
* load_[pub]key() has already printed an appropriate
* message
*/
goto end;
}
}
if (cfg.mac_name) {
EVP_PKEY_CTX *mac_ctx = NULL;
int r = 0;
if (!init_gen_str(bio_err, &mac_ctx, cfg.mac_name, 0))
goto mac_end;
if (cfg.macopts) {
char *macopt;
for (i = 0; i < sk_OPENSSL_STRING_num(
cfg.macopts); i++) {
macopt = sk_OPENSSL_STRING_value(
cfg.macopts, i);
if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
BIO_printf(bio_err,
"MAC parameter error \"%s\"\n",
macopt);
ERR_print_errors(bio_err);
goto mac_end;
}
}
}
if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
BIO_puts(bio_err, "Error generating key\n");
ERR_print_errors(bio_err);
goto mac_end;
}
r = 1;
mac_end:
EVP_PKEY_CTX_free(mac_ctx);
if (r == 0)
goto end;
}
if (cfg.hmac_key) {
sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
(unsigned char *) cfg.hmac_key, -1);
if (!sigkey)
goto end;
}
if (sigkey) {
EVP_MD_CTX *mctx = NULL;
EVP_PKEY_CTX *pctx = NULL;
int r;
if (!BIO_get_md_ctx(bmd, &mctx)) {
BIO_printf(bio_err, "Error getting context\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.do_verify)
r = EVP_DigestVerifyInit(mctx, &pctx, cfg.md,
NULL, sigkey);
else
r = EVP_DigestSignInit(mctx, &pctx, cfg.md,
NULL, sigkey);
if (!r) {
BIO_printf(bio_err, "Error setting context\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.sigopts) {
char *sigopt;
for (i = 0; i < sk_OPENSSL_STRING_num(
cfg.sigopts); i++) {
sigopt = sk_OPENSSL_STRING_value(
cfg.sigopts, i);
if (pkey_ctrl_string(pctx, sigopt) <= 0) {
BIO_printf(bio_err,
"parameter error \"%s\"\n",
sigopt);
ERR_print_errors(bio_err);
goto end;
}
}
}
}
/* we use md as a filter, reading from 'in' */
else {
if (cfg.md == NULL)
cfg.md = EVP_sha256();
if (!BIO_set_md(bmd, cfg.md)) {
BIO_printf(bio_err, "Error setting digest %s\n", pname);
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.sigfile && sigkey) {
BIO *sigbio;
siglen = EVP_PKEY_size(sigkey);
sigbuf = malloc(siglen);
if (sigbuf == NULL) {
BIO_printf(bio_err, "out of memory\n");
ERR_print_errors(bio_err);
goto end;
}
sigbio = BIO_new_file(cfg.sigfile, "rb");
if (!sigbio) {
BIO_printf(bio_err, "Error opening signature file %s\n",
cfg.sigfile);
ERR_print_errors(bio_err);
goto end;
}
siglen = BIO_read(sigbio, sigbuf, siglen);
BIO_free(sigbio);
if (siglen <= 0) {
BIO_printf(bio_err, "Error reading signature file %s\n",
cfg.sigfile);
ERR_print_errors(bio_err);
goto end;
}
}
inp = BIO_push(bmd, in);
if (cfg.md == NULL) {
EVP_MD_CTX *tctx;
BIO_get_md_ctx(bmd, &tctx);
cfg.md = EVP_MD_CTX_md(tctx);
}
if (argc == 0) {
BIO_set_fp(in, stdin, BIO_NOCLOSE);
err = do_fp(out, buf, inp, cfg.separator,
cfg.out_bin, sigkey, sigbuf, siglen, NULL, NULL,
"stdin", bmd);
} else {
const char *md_name = NULL, *sig_name = NULL;
if (!cfg.out_bin) {
if (sigkey) {
const EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_get0_asn1(sigkey);
if (ameth)
EVP_PKEY_asn1_get0_info(NULL, NULL,
NULL, NULL, &sig_name, ameth);
}
md_name = EVP_MD_name(cfg.md);
}
err = 0;
for (i = 0; i < argc; i++) {
int r;
if (BIO_read_filename(in, argv[i]) <= 0) {
perror(argv[i]);
err++;
continue;
} else {
r = do_fp(out, buf, inp, cfg.separator,
cfg.out_bin, sigkey, sigbuf, siglen,
sig_name, md_name, argv[i], bmd);
}
if (r)
err = r;
(void) BIO_reset(bmd);
}
}
end:
freezero(buf, BUFSIZE);
BIO_free(in);
free(passin);
BIO_free_all(out);
EVP_PKEY_free(sigkey);
sk_OPENSSL_STRING_free(cfg.sigopts);
sk_OPENSSL_STRING_free(cfg.macopts);
free(sigbuf);
BIO_free(bmd);
return (err);
}
int
do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout,
EVP_PKEY * key, unsigned char *sigin, int siglen,
const char *sig_name, const char *md_name,
const char *file, BIO * bmd)
{
size_t len;
int i;
for (;;) {
i = BIO_read(bp, (char *) buf, BUFSIZE);
if (i < 0) {
BIO_printf(bio_err, "Read Error in %s\n", file);
ERR_print_errors(bio_err);
return 1;
}
if (i == 0)
break;
}
if (sigin) {
EVP_MD_CTX *ctx;
BIO_get_md_ctx(bp, &ctx);
i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int) siglen);
if (i > 0)
BIO_printf(out, "Verified OK\n");
else if (i == 0) {
BIO_printf(out, "Verification Failure\n");
return 1;
} else {
BIO_printf(bio_err, "Error Verifying Data\n");
ERR_print_errors(bio_err);
return 1;
}
return 0;
}
if (key) {
EVP_MD_CTX *ctx;
BIO_get_md_ctx(bp, &ctx);
len = BUFSIZE;
if (!EVP_DigestSignFinal(ctx, buf, &len)) {
BIO_printf(bio_err, "Error Signing Data\n");
ERR_print_errors(bio_err);
return 1;
}
} else {
len = BIO_gets(bp, (char *) buf, BUFSIZE);
if ((int) len < 0) {
ERR_print_errors(bio_err);
return 1;
}
}
if (binout)
BIO_write(out, buf, len);
else if (sep == 2) {
for (i = 0; i < (int) len; i++)
BIO_printf(out, "%02x", buf[i]);
BIO_printf(out, " *%s\n", file);
} else {
if (sig_name)
BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
else if (md_name)
BIO_printf(out, "%s(%s)= ", md_name, file);
else
BIO_printf(out, "(%s)= ", file);
for (i = 0; i < (int) len; i++) {
if (sep && (i != 0))
BIO_printf(out, ":");
BIO_printf(out, "%02x", buf[i]);
}
BIO_printf(out, "\n");
}
return 0;
}

298
apps/openssl/dh.c Normal file
View File

@@ -0,0 +1,298 @@
/* $OpenBSD: dh.c,v 1.15 2023/03/06 14:32:05 tb Exp $ */
/* 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 <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
#ifndef OPENSSL_NO_DH
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/dh.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static struct {
int C;
int check;
char *infile;
int informat;
int noout;
char *outfile;
int outformat;
int text;
} cfg;
static const struct option dh_options[] = {
{
.name = "C",
.desc = "Convert DH parameters into C code",
.type = OPTION_FLAG,
.opt.flag = &cfg.C,
},
{
.name = "check",
.desc = "Check the DH parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.check,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "No output",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "text",
.desc = "Print a text form of the DH parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{ NULL },
};
static void
dh_usage(void)
{
fprintf(stderr,
"usage: dh [-C] [-check] [-in file] [-inform format]\n"
" [-noout] [-out file] [-outform format] [-text]\n\n");
options_usage(dh_options);
}
int
dh_main(int argc, char **argv)
{
DH *dh = NULL;
int i;
BIO *in = NULL, *out = NULL;
int ret = 1;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, dh_options, NULL, NULL) != 0) {
dh_usage();
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.informat == FORMAT_ASN1)
dh = d2i_DHparams_bio(in, NULL);
else if (cfg.informat == FORMAT_PEM)
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
else {
BIO_printf(bio_err, "bad input format specified\n");
goto end;
}
if (dh == NULL) {
BIO_printf(bio_err, "unable to load DH parameters\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.text) {
DHparams_print(out, dh);
}
if (cfg.check) {
if (!DH_check(dh, &i)) {
ERR_print_errors(bio_err);
goto end;
}
if (i & DH_CHECK_P_NOT_PRIME)
printf("p value is not prime\n");
if (i & DH_CHECK_P_NOT_SAFE_PRIME)
printf("p value is not a safe prime\n");
if (i & DH_UNABLE_TO_CHECK_GENERATOR)
printf("unable to check the generator value\n");
if (i & DH_NOT_SUITABLE_GENERATOR)
printf("the g value is not a generator\n");
if (i == 0)
printf("DH parameters appear to be ok.\n");
}
if (cfg.C) {
unsigned char *data;
int len, l, bits;
len = BN_num_bytes(DH_get0_p(dh));
bits = BN_num_bits(DH_get0_p(dh));
data = malloc(len);
if (data == NULL) {
perror("malloc");
goto end;
}
l = BN_bn2bin(DH_get0_p(dh), data);
printf("static unsigned char dh%d_p[] = {", bits);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t");
printf("0x%02X, ", data[i]);
}
printf("\n\t};\n");
l = BN_bn2bin(DH_get0_g(dh), data);
printf("static unsigned char dh%d_g[] = {", bits);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t");
printf("0x%02X, ", data[i]);
}
printf("\n\t};\n\n");
printf("DH *get_dh%d()\n\t{\n", bits);
printf("\tDH *dh;\n");
printf("\tBIGNUM *p = NULL, *g = NULL;\n\n");
printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n");
printf("\tp = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n",
bits, bits);
printf("\tg = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n",
bits, bits);
printf("\tif (p == NULL || g == NULL)\n");
printf("\t\t{ BN_free(p); BN_free(q); DH_free(dh); return(NULL); }\n");
printf("\tDH_set0_pqg(dh, p, NULL, g);\n");
printf("\treturn(dh);\n\t}\n");
free(data);
}
if (!cfg.noout) {
if (cfg.outformat == FORMAT_ASN1)
i = i2d_DHparams_bio(out, dh);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_DHparams(out, dh);
else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write DH parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
ret = 0;
end:
BIO_free(in);
BIO_free_all(out);
DH_free(dh);
return (ret);
}
#endif

502
apps/openssl/dhparam.c Normal file
View File

@@ -0,0 +1,502 @@
/* $OpenBSD: dhparam.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-2000 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).
*
*/
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
#ifndef OPENSSL_NO_DH
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/dh.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/dsa.h>
#define DEFBITS 2048
static struct {
int C;
int check;
int dsaparam;
int g;
char *infile;
int informat;
int noout;
char *outfile;
int outformat;
int text;
} cfg;
static const struct option dhparam_options[] = {
{
.name = "2",
.desc = "Generate DH parameters with a generator value of 2 "
"(default)",
.type = OPTION_VALUE,
.opt.value = &cfg.g,
.value = 2,
},
{
.name = "5",
.desc = "Generate DH parameters with a generator value of 5",
.type = OPTION_VALUE,
.opt.value = &cfg.g,
.value = 5,
},
{
.name = "C",
.desc = "Convert DH parameters into C code",
.type = OPTION_FLAG,
.opt.flag = &cfg.C,
},
{
.name = "check",
.desc = "Check the DH parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.check,
},
{
.name = "dsaparam",
.desc = "Read or generate DSA parameters and convert to DH",
.type = OPTION_FLAG,
.opt.flag = &cfg.dsaparam,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "Do not output encoded version of DH parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "text",
.desc = "Print DH parameters in plain text",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{ NULL },
};
static void
dhparam_usage(void)
{
fprintf(stderr,
"usage: dhparam [-2 | -5] [-C] [-check] [-dsaparam]\n"
" [-in file] [-inform DER | PEM] [-noout] [-out file]\n"
" [-outform DER | PEM] [-text] [numbits]\n\n");
options_usage(dhparam_options);
}
static int dh_cb(int p, int n, BN_GENCB *cb);
int
dhparam_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
BN_GENCB *cb = NULL;
char *num_bits = NULL;
DH *dh = NULL;
int num = 0;
int ret = 1;
int i;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) {
dhparam_usage();
return (1);
}
if (num_bits != NULL) {
if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) {
BIO_printf(bio_err, "invalid number of bits: %s\n",
num_bits);
return (1);
}
}
if (cfg.g && !num)
num = DEFBITS;
if (cfg.dsaparam) {
if (cfg.g) {
BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
goto end;
}
} else {
/* DH parameters */
if (num && !cfg.g)
cfg.g = 2;
}
if (num) {
if ((cb = BN_GENCB_new()) == NULL) {
BIO_printf(bio_err,
"Error allocating BN_GENCB object\n");
goto end;
}
BN_GENCB_set(cb, dh_cb, bio_err);
if (cfg.dsaparam) {
DSA *dsa = DSA_new();
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
if (!dsa || !DSA_generate_parameters_ex(dsa, num,
NULL, 0, NULL, NULL, cb)) {
DSA_free(dsa);
ERR_print_errors(bio_err);
goto end;
}
dh = DSA_dup_DH(dsa);
DSA_free(dsa);
if (dh == NULL) {
ERR_print_errors(bio_err);
goto end;
}
} else {
dh = DH_new();
BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, cfg.g);
BIO_printf(bio_err, "This is going to take a long time\n");
if (!dh || !DH_generate_parameters_ex(dh, num, cfg.g, cb)) {
ERR_print_errors(bio_err);
goto end;
}
}
} else {
in = BIO_new(BIO_s_file());
if (in == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.informat != FORMAT_ASN1 &&
cfg.informat != FORMAT_PEM) {
BIO_printf(bio_err, "bad input format specified\n");
goto end;
}
if (cfg.dsaparam) {
DSA *dsa;
if (cfg.informat == FORMAT_ASN1)
dsa = d2i_DSAparams_bio(in, NULL);
else /* informat == FORMAT_PEM */
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
if (dsa == NULL) {
BIO_printf(bio_err, "unable to load DSA parameters\n");
ERR_print_errors(bio_err);
goto end;
}
dh = DSA_dup_DH(dsa);
DSA_free(dsa);
if (dh == NULL) {
ERR_print_errors(bio_err);
goto end;
}
} else
{
if (cfg.informat == FORMAT_ASN1)
dh = d2i_DHparams_bio(in, NULL);
else /* informat == FORMAT_PEM */
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
if (dh == NULL) {
BIO_printf(bio_err, "unable to load DH parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
/* dh != NULL */
}
out = BIO_new(BIO_s_file());
if (out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.text) {
DHparams_print(out, dh);
}
if (cfg.check) {
if (!DH_check(dh, &i)) {
ERR_print_errors(bio_err);
goto end;
}
if (i & DH_CHECK_P_NOT_PRIME)
printf("p value is not prime\n");
if (i & DH_CHECK_P_NOT_SAFE_PRIME)
printf("p value is not a safe prime\n");
if (i & DH_UNABLE_TO_CHECK_GENERATOR)
printf("unable to check the generator value\n");
if (i & DH_NOT_SUITABLE_GENERATOR)
printf("the g value is not a generator\n");
if (i == 0)
printf("DH parameters appear to be ok.\n");
}
if (cfg.C) {
unsigned char *data;
int len, l, bits;
len = BN_num_bytes(DH_get0_p(dh));
bits = BN_num_bits(DH_get0_p(dh));
data = malloc(len);
if (data == NULL) {
perror("malloc");
goto end;
}
printf("#ifndef HEADER_DH_H\n"
"#include <openssl/dh.h>\n"
"#endif\n");
printf("DH *get_dh%d()\n\t{\n", bits);
l = BN_bn2bin(DH_get0_p(dh), data);
printf("\tstatic unsigned char dh%d_p[] = {", bits);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t\t");
printf("0x%02X, ", data[i]);
}
printf("\n\t\t};\n");
l = BN_bn2bin(DH_get0_g(dh), data);
printf("\tstatic unsigned char dh%d_g[] = {", bits);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t\t");
printf("0x%02X, ", data[i]);
}
printf("\n\t\t};\n");
printf("\tDH *dh;\n");
printf("\tBIGNUM *p = NULL, *g = NULL;\n\n");
printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n");
printf("\tp = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n",
bits, bits);
printf("\tg = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n",
bits, bits);
printf("\tif (p == NULL || g == NULL)\n");
printf("\t\t{ BN_free(p); BN_free(g); DH_free(dh); return(NULL); }\n");
printf("\tDH_set0_pqg(dh, p, NULL, g);\n");
if (DH_get_length(dh) > 0)
printf("\tDH_set_length(dh, %ld);\n", DH_get_length(dh));
printf("\treturn(dh);\n\t}\n");
free(data);
}
if (!cfg.noout) {
if (cfg.outformat == FORMAT_ASN1)
i = i2d_DHparams_bio(out, dh);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_DHparams(out, dh);
else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write DH parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
ret = 0;
end:
BIO_free(in);
BIO_free_all(out);
BN_GENCB_free(cb);
DH_free(dh);
return (ret);
}
/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
static int
dh_cb(int p, int n, BN_GENCB *cb)
{
char c = '*';
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
(void) BIO_flush(BN_GENCB_get_arg(cb));
return 1;
}
#endif

365
apps/openssl/dsa.c Normal file
View File

@@ -0,0 +1,365 @@
/* $OpenBSD: dsa.c,v 1.18 2023/03/06 14:32:06 tb Exp $ */
/* 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 <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static struct {
const EVP_CIPHER *enc;
char *infile;
int informat;
int modulus;
int noout;
char *outfile;
int outformat;
char *passargin;
char *passargout;
int pubin;
int pubout;
int pvk_encr;
int text;
} cfg;
static int
dsa_opt_enc(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.enc = EVP_get_cipherbyname(name)) != NULL) {
*argsused = 1;
return (0);
}
return (1);
}
static const struct option dsa_options[] = {
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (PEM (default) or any other supported"
" format)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "modulus",
.desc = "Print the DSA public value",
.type = OPTION_FLAG,
.opt.flag = &cfg.modulus,
},
{
.name = "noout",
.desc = "No output",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER, MSBLOB, PEM (default) or PVK)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "passin",
.argname = "source",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "passout",
.argname = "source",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{
.name = "pubin",
.desc = "Read a public key from the input file instead of"
" private key",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubin,
},
{
.name = "pubout",
.desc = "Output a public key instead of private key",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubout,
},
{
.name = "pvk-none",
.desc = "PVK encryption level",
.type = OPTION_VALUE,
.value = 0,
.opt.value = &cfg.pvk_encr,
},
{
.name = "pvk-strong",
.desc = "PVK encryption level (default)",
.type = OPTION_VALUE,
.value = 2,
.opt.value = &cfg.pvk_encr,
},
{
.name = "pvk-weak",
.desc = "PVK encryption level",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.pvk_encr,
},
{
.name = "text",
.desc = "Print the key in text form",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{
.name = NULL,
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = dsa_opt_enc,
},
{ NULL },
};
static void
dsa_usage(void)
{
int n = 0;
fprintf(stderr,
"usage: dsa [-in file] [-inform format] [-modulus] [-noout]\n"
" [-out file] [-outform format] [-passin src] [-passout src]\n"
" [-pubin] [-pubout] [-pvk-none | -pvk-strong | -pvk-weak]\n"
" [-text] [-ciphername]\n\n");
options_usage(dsa_options);
fprintf(stderr, "\n");
fprintf(stderr, "Valid ciphername values:\n\n");
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
fprintf(stderr, "\n");
}
int
dsa_main(int argc, char **argv)
{
int ret = 1;
DSA *dsa = NULL;
int i;
BIO *in = NULL, *out = NULL;
char *passin = NULL, *passout = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.pvk_encr = 2;
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, dsa_options, NULL, NULL) != 0) {
dsa_usage();
goto end;
}
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
&passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
BIO_printf(bio_err, "read DSA key\n");
{
EVP_PKEY *pkey;
if (cfg.pubin)
pkey = load_pubkey(bio_err, cfg.infile,
cfg.informat, 1, passin, "Public Key");
else
pkey = load_key(bio_err, cfg.infile,
cfg.informat, 1, passin, "Private Key");
if (pkey) {
dsa = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
}
}
if (dsa == NULL) {
BIO_printf(bio_err, "unable to load Key\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.text) {
if (!DSA_print(out, dsa, 0)) {
perror(cfg.outfile);
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.modulus) {
fprintf(stdout, "Public Key=");
BN_print(out, DSA_get0_pub_key(dsa));
fprintf(stdout, "\n");
}
if (cfg.noout)
goto end;
BIO_printf(bio_err, "writing DSA key\n");
if (cfg.outformat == FORMAT_ASN1) {
if (cfg.pubin || cfg.pubout)
i = i2d_DSA_PUBKEY_bio(out, dsa);
else
i = i2d_DSAPrivateKey_bio(out, dsa);
} else if (cfg.outformat == FORMAT_PEM) {
if (cfg.pubin || cfg.pubout)
i = PEM_write_bio_DSA_PUBKEY(out, dsa);
else
i = PEM_write_bio_DSAPrivateKey(out, dsa, cfg.enc,
NULL, 0, NULL, passout);
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
} else if (cfg.outformat == FORMAT_MSBLOB ||
cfg.outformat == FORMAT_PVK) {
EVP_PKEY *pk;
pk = EVP_PKEY_new();
EVP_PKEY_set1_DSA(pk, dsa);
if (cfg.outformat == FORMAT_PVK)
i = i2b_PVK_bio(out, pk, cfg.pvk_encr, 0,
passout);
else if (cfg.pubin || cfg.pubout)
i = i2b_PublicKey_bio(out, pk);
else
i = i2b_PrivateKey_bio(out, pk);
EVP_PKEY_free(pk);
#endif
} else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
if (i <= 0) {
BIO_printf(bio_err, "unable to write private key\n");
ERR_print_errors(bio_err);
} else
ret = 0;
end:
BIO_free(in);
BIO_free_all(out);
DSA_free(dsa);
free(passin);
free(passout);
return (ret);
}

377
apps/openssl/dsaparam.c Normal file
View File

@@ -0,0 +1,377 @@
/* $OpenBSD: dsaparam.c,v 1.15 2023/03/06 14:32:06 tb Exp $ */
/* 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 <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
/* Until the key-gen callbacks are modified to use newer prototypes, we allow
* deprecated functions for openssl-internal code */
#ifdef OPENSSL_NO_DEPRECATED
#undef OPENSSL_NO_DEPRECATED
#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/dsa.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static struct {
int C;
int genkey;
char *infile;
int informat;
int noout;
char *outfile;
int outformat;
int text;
} cfg;
static const struct option dsaparam_options[] = {
{
.name = "C",
.desc = "Convert DSA parameters into C code",
.type = OPTION_FLAG,
.opt.flag = &cfg.C,
},
{
.name = "genkey",
.desc = "Generate a DSA key",
.type = OPTION_FLAG,
.opt.flag = &cfg.genkey,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "No output",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "text",
.desc = "Print as text",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{ NULL },
};
static void
dsaparam_usage(void)
{
fprintf(stderr,
"usage: dsaparam [-C] [-genkey] [-in file]\n"
" [-inform format] [-noout] [-out file] [-outform format]\n"
" [-text] [numbits]\n\n");
options_usage(dsaparam_options);
}
static int dsa_cb(int p, int n, BN_GENCB *cb);
int
dsaparam_main(int argc, char **argv)
{
DSA *dsa = NULL;
int i;
BIO *in = NULL, *out = NULL;
BN_GENCB *cb = NULL;
int ret = 1;
int numbits = -1;
char *strbits = NULL;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, dsaparam_options, &strbits, NULL) != 0) {
dsaparam_usage();
goto end;
}
if (strbits != NULL) {
const char *errstr;
numbits = strtonum(strbits, 0, INT_MAX, &errstr);
if (errstr) {
fprintf(stderr, "Invalid number of bits: %s", errstr);
goto end;
}
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (numbits > 0) {
if ((cb = BN_GENCB_new()) == NULL) {
BIO_printf(bio_err,
"Error allocating BN_GENCB object\n");
goto end;
}
BN_GENCB_set(cb, dsa_cb, bio_err);
dsa = DSA_new();
if (!dsa) {
BIO_printf(bio_err, "Error allocating DSA object\n");
goto end;
}
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", numbits);
BIO_printf(bio_err, "This could take some time\n");
if (!DSA_generate_parameters_ex(dsa, numbits, NULL, 0, NULL, NULL, cb)) {
ERR_print_errors(bio_err);
BIO_printf(bio_err, "Error, DSA key generation failed\n");
goto end;
}
} else if (cfg.informat == FORMAT_ASN1)
dsa = d2i_DSAparams_bio(in, NULL);
else if (cfg.informat == FORMAT_PEM)
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
else {
BIO_printf(bio_err, "bad input format specified\n");
goto end;
}
if (dsa == NULL) {
BIO_printf(bio_err, "unable to load DSA parameters\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.text) {
DSAparams_print(out, dsa);
}
if (cfg.C) {
unsigned char *data;
int l, len, bits_p;
len = BN_num_bytes(DSA_get0_p(dsa));
bits_p = BN_num_bits(DSA_get0_p(dsa));
data = malloc(len + 20);
if (data == NULL) {
perror("malloc");
goto end;
}
l = BN_bn2bin(DSA_get0_p(dsa), data);
printf("static unsigned char dsa%d_p[] = {", bits_p);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t");
printf("0x%02X, ", data[i]);
}
printf("\n\t};\n");
l = BN_bn2bin(DSA_get0_q(dsa), data);
printf("static unsigned char dsa%d_q[] = {", bits_p);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t");
printf("0x%02X, ", data[i]);
}
printf("\n\t};\n");
l = BN_bn2bin(DSA_get0_g(dsa), data);
printf("static unsigned char dsa%d_g[] = {", bits_p);
for (i = 0; i < l; i++) {
if ((i % 12) == 0)
printf("\n\t");
printf("0x%02X, ", data[i]);
}
free(data);
printf("\n\t};\n\n");
printf("DSA *get_dsa%d()\n\t{\n", bits_p);
printf("\tBIGNUM *p = NULL, *q = NULL, *g = NULL;\n");
printf("\tDSA *dsa;\n\n");
printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n");
printf("\tp = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n",
bits_p, bits_p);
printf("\tq = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n",
bits_p, bits_p);
printf("\tg = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n",
bits_p, bits_p);
printf("\tif (p == NULL || q == NULL || g == NULL)\n");
printf("\t\t{ BN_free(p); BN_free(q); BN_free(g); DSA_free(dsa); return(NULL); }\n");
printf("\tDSA_set0_pqg(dsa, p, q, g);\n");
printf("\treturn(dsa);\n\t}\n");
}
if (!cfg.noout) {
if (cfg.outformat == FORMAT_ASN1)
i = i2d_DSAparams_bio(out, dsa);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_DSAparams(out, dsa);
else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write DSA parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.genkey) {
DSA *dsakey;
if ((dsakey = DSAparams_dup(dsa)) == NULL)
goto end;
if (!DSA_generate_key(dsakey)) {
ERR_print_errors(bio_err);
DSA_free(dsakey);
goto end;
}
if (cfg.outformat == FORMAT_ASN1)
i = i2d_DSAPrivateKey_bio(out, dsakey);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
DSA_free(dsakey);
goto end;
}
DSA_free(dsakey);
}
ret = 0;
end:
BIO_free(in);
BIO_free_all(out);
BN_GENCB_free(cb);
DSA_free(dsa);
return (ret);
}
static int
dsa_cb(int p, int n, BN_GENCB *cb)
{
char c = '*';
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
(void) BIO_flush(BN_GENCB_get_arg(cb));
#ifdef GENCB_TEST
if (stop_keygen_flag)
return 0;
#endif
return 1;
}

392
apps/openssl/ec.c Normal file
View File

@@ -0,0 +1,392 @@
/* $OpenBSD: ec.c,v 1.16 2023/03/06 14:32:06 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-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).
*
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
static struct {
int asn1_flag;
const EVP_CIPHER *enc;
point_conversion_form_t form;
char *infile;
int informat;
char *outfile;
int outformat;
int new_asn1_flag;
int new_form;
int noout;
int param_out;
char *passargin;
char *passargout;
int pubin;
int pubout;
int text;
} cfg;
static int
ec_opt_enc(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.enc = EVP_get_cipherbyname(name)) != NULL) {
*argsused = 1;
return (0);
}
return (1);
}
static int
ec_opt_form(char *arg)
{
if (strcmp(arg, "compressed") == 0)
cfg.form = POINT_CONVERSION_COMPRESSED;
else if (strcmp(arg, "uncompressed") == 0)
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
else if (strcmp(arg, "hybrid") == 0)
cfg.form = POINT_CONVERSION_HYBRID;
else {
fprintf(stderr, "Invalid point conversion: %s\n", arg);
return (1);
}
cfg.new_form = 1;
return (0);
}
static int
ec_opt_named(char *arg)
{
if (strcmp(arg, "named_curve") == 0)
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
else if (strcmp(arg, "explicit") == 0)
cfg.asn1_flag = 0;
else {
fprintf(stderr, "Invalid curve type: %s\n", arg);
return (1);
}
cfg.new_asn1_flag = 1;
return (0);
}
static const struct option ec_options[] = {
{
.name = "conv_form",
.argname = "form",
.desc = "Specify the point conversion form (default"
" \"named_curve\")",
.type = OPTION_ARG_FUNC,
.opt.argfunc = ec_opt_form,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "No output",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "param_enc",
.argname = "type",
.desc = "Specify the way the ec parameters are encoded"
" (default \"uncompressed\")",
.type = OPTION_ARG_FUNC,
.opt.argfunc = ec_opt_named,
},
{
.name = "param_out",
.desc = "Print the elliptic curve parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.param_out,
},
{
.name = "passin",
.argname = "source",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "passout",
.argname = "source",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{
.name = "pubin",
.desc = "Read public key instead of private key from input",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubin,
},
{
.name = "pubout",
.desc = "Output public key instead of private key in output",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubout,
},
{
.name = "text",
.desc = "Print the public/private key components and parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{
.name = NULL,
.desc = "Cipher to encrypt the output if using PEM format",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = ec_opt_enc,
},
{ NULL },
};
static void
ec_usage(void)
{
int n = 0;
fprintf(stderr,
"usage: ec [-conv_form form] [-in file]\n"
" [-inform format] [-noout] [-out file] [-outform format]\n"
" [-param_enc type] [-param_out] [-passin file]\n"
" [-passout file] [-pubin] [-pubout] [-text] [-ciphername]\n\n");
options_usage(ec_options);
fprintf(stderr, "\n");
fprintf(stderr, "Valid ciphername values:\n\n");
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
fprintf(stderr, "\n");
}
int
ec_main(int argc, char **argv)
{
int ret = 1;
EC_KEY *eckey = NULL;
const EC_GROUP *group;
int i;
BIO *in = NULL, *out = NULL;
char *passin = NULL, *passout = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, ec_options, NULL, NULL) != 0) {
ec_usage();
goto end;
}
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
&passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
BIO_printf(bio_err, "read EC key\n");
if (cfg.informat == FORMAT_ASN1) {
if (cfg.pubin)
eckey = d2i_EC_PUBKEY_bio(in, NULL);
else
eckey = d2i_ECPrivateKey_bio(in, NULL);
} else if (cfg.informat == FORMAT_PEM) {
if (cfg.pubin)
eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL,
NULL);
else
eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
passin);
} else {
BIO_printf(bio_err, "bad input format specified for key\n");
goto end;
}
if (eckey == NULL) {
BIO_printf(bio_err, "unable to load Key\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
group = EC_KEY_get0_group(eckey);
if (cfg.new_form)
EC_KEY_set_conv_form(eckey, cfg.form);
if (cfg.new_asn1_flag)
EC_KEY_set_asn1_flag(eckey, cfg.asn1_flag);
if (cfg.text)
if (!EC_KEY_print(out, eckey, 0)) {
perror(cfg.outfile);
ERR_print_errors(bio_err);
goto end;
}
if (cfg.noout) {
ret = 0;
goto end;
}
BIO_printf(bio_err, "writing EC key\n");
if (cfg.outformat == FORMAT_ASN1) {
if (cfg.param_out)
i = i2d_ECPKParameters_bio(out, group);
else if (cfg.pubin || cfg.pubout)
i = i2d_EC_PUBKEY_bio(out, eckey);
else
i = i2d_ECPrivateKey_bio(out, eckey);
} else if (cfg.outformat == FORMAT_PEM) {
if (cfg.param_out)
i = PEM_write_bio_ECPKParameters(out, group);
else if (cfg.pubin || cfg.pubout)
i = PEM_write_bio_EC_PUBKEY(out, eckey);
else
i = PEM_write_bio_ECPrivateKey(out, eckey,
cfg.enc, NULL, 0, NULL, passout);
} else {
BIO_printf(bio_err, "bad output format specified for "
"outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write private key\n");
ERR_print_errors(bio_err);
} else
ret = 0;
end:
BIO_free(in);
BIO_free_all(out);
EC_KEY_free(eckey);
free(passin);
free(passout);
return (ret);
}
#endif

606
apps/openssl/ecparam.c Normal file
View File

@@ -0,0 +1,606 @@
/* $OpenBSD: ecparam.c,v 1.23 2023/03/06 14:32:06 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
* Copyright (c) 1998-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).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The elliptic curve binary polynomial software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_EC
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static int ecparam_print_var(BIO *, BIGNUM *, const char *, int,
unsigned char *);
static struct {
int C;
int asn1_flag;
int check;
char *curve_name;
point_conversion_form_t form;
int genkey;
char *infile;
int informat;
int list_curves;
int new_asn1_flag;
int new_form;
int no_seed;
int noout;
char *outfile;
int outformat;
int text;
} cfg;
static int
ecparam_opt_form(char *arg)
{
if (strcmp(arg, "compressed") == 0)
cfg.form = POINT_CONVERSION_COMPRESSED;
else if (strcmp(arg, "uncompressed") == 0)
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
else if (strcmp(arg, "hybrid") == 0)
cfg.form = POINT_CONVERSION_HYBRID;
else
return (1);
cfg.new_form = 1;
return (0);
}
static int
ecparam_opt_enctype(char *arg)
{
if (strcmp(arg, "explicit") == 0)
cfg.asn1_flag = 0;
else if (strcmp(arg, "named_curve") == 0)
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
else
return (1);
cfg.new_asn1_flag = 1;
return (0);
}
static const struct option ecparam_options[] = {
{
.name = "C",
.desc = "Convert the EC parameters into C code",
.type = OPTION_FLAG,
.opt.flag = &cfg.C,
},
{
.name = "check",
.desc = "Validate the elliptic curve parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.check,
},
{
.name = "conv_form",
.argname = "form",
.desc = "Specify point conversion form:\n"
" compressed, uncompressed (default), hybrid",
.type = OPTION_ARG_FUNC,
.opt.argfunc = ecparam_opt_form,
},
{
.name = "genkey",
.desc = "Generate an EC private key using the specified "
"parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.genkey,
},
{
.name = "in",
.argname = "file",
.desc = "Input file to read parameters from (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "list_curves",
.desc = "Print list of all currently implemented EC "
"parameter names",
.type = OPTION_FLAG,
.opt.flag = &cfg.list_curves,
},
{
.name = "name",
.argname = "curve",
.desc = "Use the EC parameters with the specified name",
.type = OPTION_ARG,
.opt.arg = &cfg.curve_name,
},
{
.name = "no_seed",
.desc = "Do not output seed with explicit parameter encoding",
.type = OPTION_FLAG,
.opt.flag = &cfg.no_seed,
},
{
.name = "noout",
.desc = "Do not output encoded version of EC parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file to write parameters to (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "param_enc",
.argname = "type",
.desc = "Specify EC parameter ASN.1 encoding type:\n"
" explicit, named_curve (default)",
.type = OPTION_ARG_FUNC,
.opt.argfunc = ecparam_opt_enctype,
},
{
.name = "text",
.desc = "Print out the EC parameters in human readable form",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{NULL},
};
static void
ecparam_usage(void)
{
fprintf(stderr, "usage: ecparam [-C] [-check] [-conv_form arg] "
" [-genkey]\n"
" [-in file] [-inform DER | PEM] [-list_curves] [-name arg]\n"
" [-no_seed] [-noout] [-out file] [-outform DER | PEM]\n"
" [-param_enc arg] [-text]\n\n");
options_usage(ecparam_options);
}
int
ecparam_main(int argc, char **argv)
{
BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL;
BIGNUM *ec_order = NULL, *ec_cofactor = NULL;
EC_GROUP *group = NULL;
unsigned char *buffer = NULL;
BIO *in = NULL, *out = NULL;
int i, ret = 1;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, ecparam_options, NULL, NULL) != 0) {
ecparam_usage();
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if ((in == NULL) || (out == NULL)) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.list_curves) {
EC_builtin_curve *curves = NULL;
size_t crv_len = 0;
size_t n = 0;
crv_len = EC_get_builtin_curves(NULL, 0);
curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));
if (curves == NULL)
goto end;
if (!EC_get_builtin_curves(curves, crv_len)) {
free(curves);
goto end;
}
for (n = 0; n < crv_len; n++) {
const char *comment;
const char *sname;
comment = curves[n].comment;
sname = OBJ_nid2sn(curves[n].nid);
if (comment == NULL)
comment = "CURVE DESCRIPTION NOT AVAILABLE";
if (sname == NULL)
sname = "";
BIO_printf(out, " %-10s: ", sname);
BIO_printf(out, "%s\n", comment);
}
free(curves);
ret = 0;
goto end;
}
if (cfg.curve_name != NULL) {
int nid;
/*
* workaround for the SECG curve names secp192r1 and
* secp256r1 (which are the same as the curves prime192v1 and
* prime256v1 defined in X9.62)
*/
if (!strcmp(cfg.curve_name, "secp192r1")) {
BIO_printf(bio_err, "using curve name prime192v1 "
"instead of secp192r1\n");
nid = NID_X9_62_prime192v1;
} else if (!strcmp(cfg.curve_name, "secp256r1")) {
BIO_printf(bio_err, "using curve name prime256v1 "
"instead of secp256r1\n");
nid = NID_X9_62_prime256v1;
} else
nid = OBJ_sn2nid(cfg.curve_name);
if (nid == 0)
nid = EC_curve_nist2nid(cfg.curve_name);
if (nid == 0) {
BIO_printf(bio_err, "unknown curve name (%s)\n",
cfg.curve_name);
goto end;
}
group = EC_GROUP_new_by_curve_name(nid);
if (group == NULL) {
BIO_printf(bio_err, "unable to create curve (%s)\n",
cfg.curve_name);
goto end;
}
EC_GROUP_set_asn1_flag(group, cfg.asn1_flag);
EC_GROUP_set_point_conversion_form(group, cfg.form);
} else if (cfg.informat == FORMAT_ASN1) {
group = d2i_ECPKParameters_bio(in, NULL);
} else if (cfg.informat == FORMAT_PEM) {
group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
} else {
BIO_printf(bio_err, "bad input format specified\n");
goto end;
}
if (group == NULL) {
BIO_printf(bio_err,
"unable to load elliptic curve parameters\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.new_form)
EC_GROUP_set_point_conversion_form(group, cfg.form);
if (cfg.new_asn1_flag)
EC_GROUP_set_asn1_flag(group, cfg.asn1_flag);
if (cfg.no_seed)
EC_GROUP_set_seed(group, NULL, 0);
if (cfg.text) {
if (!ECPKParameters_print(out, group, 0))
goto end;
}
if (cfg.check) {
BIO_printf(bio_err, "checking elliptic curve parameters: ");
if (!EC_GROUP_check(group, NULL)) {
BIO_printf(bio_err, "failed\n");
ERR_print_errors(bio_err);
} else
BIO_printf(bio_err, "ok\n");
}
if (cfg.C) {
size_t buf_len = 0, tmp_len = 0;
const EC_POINT *point;
int is_prime, len = 0;
const EC_METHOD *meth = EC_GROUP_method_of(group);
if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
(ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
(ec_order = BN_new()) == NULL ||
(ec_cofactor = BN_new()) == NULL) {
perror("malloc");
goto end;
}
is_prime = (EC_METHOD_get_field_type(meth) ==
NID_X9_62_prime_field);
if (!EC_GROUP_get_curve(group, ec_p, ec_a, ec_b, NULL))
goto end;
if ((point = EC_GROUP_get0_generator(group)) == NULL)
goto end;
if (!EC_POINT_point2bn(group, point,
EC_GROUP_get_point_conversion_form(group), ec_gen,
NULL))
goto end;
if (!EC_GROUP_get_order(group, ec_order, NULL))
goto end;
if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
goto end;
len = BN_num_bits(ec_order);
if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len)
buf_len = tmp_len;
if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len)
buf_len = tmp_len;
buffer = malloc(buf_len);
if (buffer == NULL) {
perror("malloc");
goto end;
}
ecparam_print_var(out, ec_p, "ec_p", len, buffer);
ecparam_print_var(out, ec_a, "ec_a", len, buffer);
ecparam_print_var(out, ec_b, "ec_b", len, buffer);
ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
ecparam_print_var(out, ec_order, "ec_order", len, buffer);
ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
buffer);
BIO_printf(out, "\n\n");
BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
BIO_printf(out, "\tint ok=0;\n");
BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
BIO_printf(out, "\tEC_POINT *point = NULL;\n");
BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, "
"*tmp_3 = NULL;\n\n");
BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
"sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
"goto err;\n", len, len);
BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
"sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
"goto err;\n", len, len);
BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
"sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
"goto err;\n", len, len);
if (is_prime) {
BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
"GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
"\n\t\tgoto err;\n\n");
} else {
BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
"GF2m(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
"\n\t\tgoto err;\n\n");
}
BIO_printf(out, "\t/* build generator */\n");
BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
"sizeof(ec_gen_%d), tmp_1)) == NULL)"
"\n\t\tgoto err;\n", len, len);
BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
"NULL, NULL);\n");
BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
"sizeof(ec_order_%d), tmp_2)) == NULL)"
"\n\t\tgoto err;\n", len, len);
BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
"sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
"\n\t\tgoto err;\n", len, len);
BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
" tmp_2, tmp_3))\n\t\tgoto err;\n");
BIO_printf(out, "\n\tok=1;\n");
BIO_printf(out, "err:\n");
BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
BIO_printf(out, "\tif (!ok)\n");
BIO_printf(out, "\t\t{\n");
BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
BIO_printf(out, "\t\tgroup = NULL;\n");
BIO_printf(out, "\t\t}\n");
BIO_printf(out, "\treturn(group);\n\t}\n");
}
if (!cfg.noout) {
if (cfg.outformat == FORMAT_ASN1)
i = i2d_ECPKParameters_bio(out, group);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_ECPKParameters(out, group);
else {
BIO_printf(bio_err, "bad output format specified for"
" outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write elliptic "
"curve parameters\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.genkey) {
EC_KEY *eckey = EC_KEY_new();
if (eckey == NULL)
goto end;
if (EC_KEY_set_group(eckey, group) == 0) {
EC_KEY_free(eckey);
goto end;
}
if (!EC_KEY_generate_key(eckey)) {
EC_KEY_free(eckey);
goto end;
}
if (cfg.outformat == FORMAT_ASN1)
i = i2d_ECPrivateKey_bio(out, eckey);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
NULL, 0, NULL, NULL);
else {
BIO_printf(bio_err, "bad output format specified "
"for outfile\n");
EC_KEY_free(eckey);
goto end;
}
EC_KEY_free(eckey);
}
ret = 0;
end:
BN_free(ec_p);
BN_free(ec_a);
BN_free(ec_b);
BN_free(ec_gen);
BN_free(ec_order);
BN_free(ec_cofactor);
free(buffer);
BIO_free(in);
BIO_free_all(out);
EC_GROUP_free(group);
return (ret);
}
static int
ecparam_print_var(BIO * out, BIGNUM * in, const char *var,
int len, unsigned char *buffer)
{
BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
if (BN_is_zero(in))
BIO_printf(out, "\n\t0x00");
else {
int i, l;
l = BN_bn2bin(in, buffer);
for (i = 0; i < l - 1; i++) {
if ((i % 12) == 0)
BIO_printf(out, "\n\t");
BIO_printf(out, "0x%02X,", buffer[i]);
}
if ((i % 12) == 0)
BIO_printf(out, "\n\t");
BIO_printf(out, "0x%02X", buffer[i]);
}
BIO_printf(out, "\n\t};\n\n");
return 1;
}
#endif

783
apps/openssl/enc.c Normal file
View File

@@ -0,0 +1,783 @@
/* $OpenBSD: enc.c,v 1.31 2023/07/29 17:15:45 tb Exp $ */
/* 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
int set_hex(char *in, unsigned char *out, int size);
#define SIZE (512)
#define BSIZE (8*1024)
static struct {
int base64;
char *bufsize;
const EVP_CIPHER *cipher;
int debug;
int enc;
char *hiv;
char *hkey;
char *hsalt;
char *inf;
int iter;
char *keyfile;
char *keystr;
char *md;
int nopad;
int nosalt;
int olb64;
char *outf;
char *passarg;
int pbkdf2;
int printkey;
int verbose;
} cfg;
static int
enc_opt_cipher(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if (strcmp(name, "none") == 0) {
cfg.cipher = NULL;
*argsused = 1;
return (0);
}
if ((cfg.cipher = EVP_get_cipherbyname(name)) != NULL) {
*argsused = 1;
return (0);
}
return (1);
}
static const struct option enc_options[] = {
{
.name = "A",
.desc = "Process base64 data on one line (requires -a)",
.type = OPTION_FLAG,
.opt.flag = &cfg.olb64,
},
{
.name = "a",
.desc = "Perform base64 encoding/decoding (alias -base64)",
.type = OPTION_FLAG,
.opt.flag = &cfg.base64,
},
{
.name = "base64",
.type = OPTION_FLAG,
.opt.flag = &cfg.base64,
},
{
.name = "bufsize",
.argname = "size",
.desc = "Specify the buffer size to use for I/O",
.type = OPTION_ARG,
.opt.arg = &cfg.bufsize,
},
{
.name = "d",
.desc = "Decrypt the input data",
.type = OPTION_VALUE,
.opt.value = &cfg.enc,
.value = 0,
},
{
.name = "debug",
.desc = "Print debugging information",
.type = OPTION_FLAG,
.opt.flag = &cfg.debug,
},
{
.name = "e",
.desc = "Encrypt the input data (default)",
.type = OPTION_VALUE,
.opt.value = &cfg.enc,
.value = 1,
},
{
.name = "in",
.argname = "file",
.desc = "Input file to read from (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.inf,
},
{
.name = "iter",
.argname = "iterations",
.desc = "Specify iteration count and force use of PBKDF2",
.type = OPTION_ARG_INT,
.opt.value = &cfg.iter,
},
{
.name = "iv",
.argname = "IV",
.desc = "IV to use, specified as a hexadecimal string",
.type = OPTION_ARG,
.opt.arg = &cfg.hiv,
},
{
.name = "K",
.argname = "key",
.desc = "Key to use, specified as a hexadecimal string",
.type = OPTION_ARG,
.opt.arg = &cfg.hkey,
},
{
.name = "k", /* Superseded by -pass. */
.type = OPTION_ARG,
.opt.arg = &cfg.keystr,
},
{
.name = "kfile", /* Superseded by -pass. */
.type = OPTION_ARG,
.opt.arg = &cfg.keyfile,
},
{
.name = "md",
.argname = "digest",
.desc = "Digest to use to create a key from the passphrase",
.type = OPTION_ARG,
.opt.arg = &cfg.md,
},
{
.name = "none",
.desc = "Use NULL cipher (no encryption or decryption)",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = enc_opt_cipher,
},
{
.name = "nopad",
.desc = "Disable standard block padding",
.type = OPTION_FLAG,
.opt.flag = &cfg.nopad,
},
{
.name = "nosalt",
.type = OPTION_VALUE,
.opt.value = &cfg.nosalt,
.value = 1,
},
{
.name = "out",
.argname = "file",
.desc = "Output file to write to (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outf,
},
{
.name = "P",
.desc = "Print out the salt, key and IV used, then exit\n"
" (no encryption or decryption is performed)",
.type = OPTION_VALUE,
.opt.value = &cfg.printkey,
.value = 2,
},
{
.name = "p",
.desc = "Print out the salt, key and IV used",
.type = OPTION_VALUE,
.opt.value = &cfg.printkey,
.value = 1,
},
{
.name = "pass",
.argname = "source",
.desc = "Password source",
.type = OPTION_ARG,
.opt.arg = &cfg.passarg,
},
{
.name = "pbkdf2",
.desc = "Use the pbkdf2 key derivation function",
.type = OPTION_FLAG,
.opt.flag = &cfg.pbkdf2,
},
{
.name = "S",
.argname = "salt",
.desc = "Salt to use, specified as a hexadecimal string",
.type = OPTION_ARG,
.opt.arg = &cfg.hsalt,
},
{
.name = "salt",
.desc = "Use a salt in the key derivation routines (default)",
.type = OPTION_VALUE,
.opt.value = &cfg.nosalt,
.value = 0,
},
{
.name = "v",
.desc = "Verbose",
.type = OPTION_FLAG,
.opt.flag = &cfg.verbose,
},
{
.name = NULL,
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = enc_opt_cipher,
},
{ NULL },
};
static void
skip_aead_and_xts(const OBJ_NAME *name, void *arg)
{
const EVP_CIPHER *cipher;
if ((cipher = EVP_get_cipherbyname(name->name)) == NULL)
return;
if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0)
return;
if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)
return;
show_cipher(name, arg);
}
static void
enc_usage(void)
{
int n = 0;
fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] "
"[-bufsize number] [-debug]\n"
" [-in file] [-iter iterations] [-iv IV] [-K key] "
"[-k password]\n"
" [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n"
" [-out file] [-pass source] [-pbkdf2] [-S salt] [-salt]\n\n");
options_usage(enc_options);
fprintf(stderr, "\n");
fprintf(stderr, "Valid ciphername values:\n\n");
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, skip_aead_and_xts, &n);
fprintf(stderr, "\n");
}
int
enc_main(int argc, char **argv)
{
static const char magic[] = "Salted__";
char mbuf[sizeof magic - 1];
char *strbuf = NULL, *pass = NULL;
unsigned char *buff = NULL;
int bsize = BSIZE;
int ret = 1, inl;
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
unsigned char salt[PKCS5_SALT_LEN];
EVP_CIPHER_CTX *ctx = NULL;
const EVP_MD *dgst = NULL;
BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL;
BIO *rbio = NULL, *wbio = NULL;
#define PROG_NAME_SIZE 39
char pname[PROG_NAME_SIZE + 1];
int i;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.enc = 1;
/* first check the program name */
program_name(argv[0], pname, sizeof(pname));
if (strcmp(pname, "base64") == 0)
cfg.base64 = 1;
cfg.cipher = EVP_get_cipherbyname(pname);
if (!cfg.base64 && cfg.cipher == NULL && strcmp(pname, "enc") != 0) {
BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
goto end;
}
if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) {
enc_usage();
goto end;
}
if (cfg.keyfile != NULL) {
static char buf[128];
FILE *infile;
infile = fopen(cfg.keyfile, "r");
if (infile == NULL) {
BIO_printf(bio_err, "unable to read key from '%s'\n",
cfg.keyfile);
goto end;
}
buf[0] = '\0';
if (!fgets(buf, sizeof buf, infile)) {
BIO_printf(bio_err, "unable to read key from '%s'\n",
cfg.keyfile);
fclose(infile);
goto end;
}
fclose(infile);
i = strlen(buf);
if (i > 0 && (buf[i - 1] == '\n' || buf[i - 1] == '\r'))
buf[--i] = '\0';
if (i > 0 && (buf[i - 1] == '\n' || buf[i - 1] == '\r'))
buf[--i] = '\0';
if (i < 1) {
BIO_printf(bio_err, "zero length password\n");
goto end;
}
cfg.keystr = buf;
}
if (cfg.cipher != NULL &&
(EVP_CIPHER_flags(cfg.cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) {
BIO_printf(bio_err, "enc does not support AEAD ciphers\n");
goto end;
}
if (cfg.cipher != NULL &&
EVP_CIPHER_mode(cfg.cipher) == EVP_CIPH_XTS_MODE) {
BIO_printf(bio_err, "enc does not support XTS mode\n");
goto end;
}
if (cfg.md != NULL &&
(dgst = EVP_get_digestbyname(cfg.md)) == NULL) {
BIO_printf(bio_err,
"%s is an unsupported message digest type\n",
cfg.md);
goto end;
}
if (dgst == NULL)
dgst = EVP_sha256();
if (cfg.bufsize != NULL) {
char *p = cfg.bufsize;
unsigned long n;
/* XXX - provide an OPTION_ARG_DISKUNIT. */
for (n = 0; *p != '\0'; p++) {
i = *p;
if ((i <= '9') && (i >= '0'))
n = n * 10 + i - '0';
else if (i == 'k') {
n *= 1024;
p++;
break;
}
}
if (*p != '\0') {
BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
goto end;
}
/* It must be large enough for a base64 encoded line. */
if (cfg.base64 && n < 80)
n = 80;
bsize = (int)n;
if (cfg.verbose)
BIO_printf(bio_err, "bufsize=%d\n", bsize);
}
strbuf = malloc(SIZE);
buff = malloc(EVP_ENCODE_LENGTH(bsize));
if (buff == NULL || strbuf == NULL) {
BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if (in == NULL || out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.debug) {
BIO_set_callback(in, BIO_debug_callback);
BIO_set_callback(out, BIO_debug_callback);
BIO_set_callback_arg(in, (char *) bio_err);
BIO_set_callback_arg(out, (char *) bio_err);
}
if (cfg.inf == NULL) {
if (cfg.bufsize != NULL)
setvbuf(stdin, (char *) NULL, _IONBF, 0);
BIO_set_fp(in, stdin, BIO_NOCLOSE);
} else {
if (BIO_read_filename(in, cfg.inf) <= 0) {
perror(cfg.inf);
goto end;
}
}
if (!cfg.keystr && cfg.passarg) {
if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
cfg.keystr = pass;
}
if (cfg.keystr == NULL && cfg.cipher != NULL && cfg.hkey == NULL) {
for (;;) {
char buf[200];
int retval;
retval = snprintf(buf, sizeof buf,
"enter %s %s password:",
OBJ_nid2ln(EVP_CIPHER_nid(cfg.cipher)),
cfg.enc ? "encryption" : "decryption");
if ((size_t)retval >= sizeof buf) {
BIO_printf(bio_err,
"Password prompt too long\n");
goto end;
}
strbuf[0] = '\0';
i = EVP_read_pw_string((char *)strbuf, SIZE, buf,
cfg.enc);
if (i == 0) {
if (strbuf[0] == '\0') {
ret = 1;
goto end;
}
cfg.keystr = strbuf;
break;
}
if (i < 0) {
BIO_printf(bio_err, "bad password read\n");
goto end;
}
}
}
if (cfg.outf == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
if (cfg.bufsize != NULL)
setvbuf(stdout, (char *)NULL, _IONBF, 0);
} else {
if (BIO_write_filename(out, cfg.outf) <= 0) {
perror(cfg.outf);
goto end;
}
}
rbio = in;
wbio = out;
if (cfg.base64) {
if ((b64 = BIO_new(BIO_f_base64())) == NULL)
goto end;
if (cfg.debug) {
BIO_set_callback(b64, BIO_debug_callback);
BIO_set_callback_arg(b64, (char *) bio_err);
}
if (cfg.olb64)
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
if (cfg.enc)
wbio = BIO_push(b64, wbio);
else
rbio = BIO_push(b64, rbio);
}
if (cfg.cipher != NULL) {
/*
* Note that keystr is NULL if a key was passed on the command
* line, so we get no salt in that case. Is this a bug?
*/
if (cfg.keystr != NULL) {
/*
* Salt handling: if encrypting generate a salt and
* write to output BIO. If decrypting read salt from
* input BIO.
*/
unsigned char *sptr;
if (cfg.nosalt)
sptr = NULL;
else {
if (cfg.enc) {
if (cfg.hsalt) {
if (!set_hex(cfg.hsalt, salt, sizeof salt)) {
BIO_printf(bio_err,
"invalid hex salt value\n");
goto end;
}
} else
arc4random_buf(salt,
sizeof(salt));
/*
* If -P option then don't bother
* writing
*/
if ((cfg.printkey != 2)
&& (BIO_write(wbio, magic,
sizeof magic - 1) != sizeof magic - 1
|| BIO_write(wbio,
(char *) salt,
sizeof salt) != sizeof salt)) {
BIO_printf(bio_err, "error writing output file\n");
goto end;
}
} else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
|| BIO_read(rbio,
(unsigned char *) salt,
sizeof salt) != sizeof salt) {
BIO_printf(bio_err, "error reading input file\n");
goto end;
} else if (memcmp(mbuf, magic, sizeof magic - 1)) {
BIO_printf(bio_err, "bad magic number\n");
goto end;
}
sptr = salt;
}
if (cfg.pbkdf2 == 1 || cfg.iter > 0) {
/*
* derive key and default iv
* concatenated into a temporary buffer
*/
unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH];
int iklen = EVP_CIPHER_key_length(cfg.cipher);
int ivlen = EVP_CIPHER_iv_length(cfg.cipher);
/* not needed if HASH_UPDATE() is fixed : */
int islen = (sptr != NULL ? sizeof(salt) : 0);
if (cfg.iter == 0)
cfg.iter = 10000;
if (!PKCS5_PBKDF2_HMAC(cfg.keystr,
strlen(cfg.keystr), sptr, islen,
cfg.iter, dgst, iklen+ivlen, tmpkeyiv)) {
BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
goto end;
}
/* split and move data back to global buffer */
memcpy(key, tmpkeyiv, iklen);
memcpy(iv, tmpkeyiv + iklen, ivlen);
explicit_bzero(tmpkeyiv, sizeof tmpkeyiv);
} else {
EVP_BytesToKey(cfg.cipher, dgst, sptr,
(unsigned char *)cfg.keystr,
strlen(cfg.keystr), 1, key, iv);
}
/*
* zero the complete buffer or the string passed from
* the command line bug picked up by Larry J. Hughes
* Jr. <hughes@indiana.edu>
*/
if (cfg.keystr == strbuf)
explicit_bzero(cfg.keystr, SIZE);
else
explicit_bzero(cfg.keystr,
strlen(cfg.keystr));
}
if (cfg.hiv != NULL && !set_hex(cfg.hiv, iv, sizeof iv)) {
BIO_printf(bio_err, "invalid hex iv value\n");
goto end;
}
if (cfg.hiv == NULL && cfg.keystr == NULL &&
EVP_CIPHER_iv_length(cfg.cipher) != 0) {
/*
* No IV was explicitly set and no IV was generated
* during EVP_BytesToKey. Hence the IV is undefined,
* making correct decryption impossible.
*/
BIO_printf(bio_err, "iv undefined\n");
goto end;
}
if (cfg.hkey != NULL && !set_hex(cfg.hkey, key, sizeof key)) {
BIO_printf(bio_err, "invalid hex key value\n");
goto end;
}
if ((benc = BIO_new(BIO_f_cipher())) == NULL)
goto end;
/*
* Since we may be changing parameters work on the encryption
* context rather than calling BIO_set_cipher().
*/
BIO_get_cipher_ctx(benc, &ctx);
if (!EVP_CipherInit_ex(ctx, cfg.cipher, NULL, NULL,
NULL, cfg.enc)) {
BIO_printf(bio_err, "Error setting cipher %s\n",
EVP_CIPHER_name(cfg.cipher));
ERR_print_errors(bio_err);
goto end;
}
if (cfg.nopad)
EVP_CIPHER_CTX_set_padding(ctx, 0);
if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, cfg.enc)) {
BIO_printf(bio_err, "Error setting cipher %s\n",
EVP_CIPHER_name(cfg.cipher));
ERR_print_errors(bio_err);
goto end;
}
if (cfg.debug) {
BIO_set_callback(benc, BIO_debug_callback);
BIO_set_callback_arg(benc, (char *) bio_err);
}
if (cfg.printkey) {
int key_len, iv_len;
if (!cfg.nosalt) {
printf("salt=");
for (i = 0; i < (int) sizeof(salt); i++)
printf("%02X", salt[i]);
printf("\n");
}
key_len = EVP_CIPHER_key_length(cfg.cipher);
if (key_len > 0) {
printf("key=");
for (i = 0; i < key_len; i++)
printf("%02X", key[i]);
printf("\n");
}
iv_len = EVP_CIPHER_iv_length(cfg.cipher);
if (iv_len > 0) {
printf("iv =");
for (i = 0; i < iv_len; i++)
printf("%02X", iv[i]);
printf("\n");
}
if (cfg.printkey == 2) {
ret = 0;
goto end;
}
}
}
/* Only encrypt/decrypt as we write the file */
if (benc != NULL)
wbio = BIO_push(benc, wbio);
for (;;) {
inl = BIO_read(rbio, (char *) buff, bsize);
if (inl <= 0)
break;
if (BIO_write(wbio, (char *) buff, inl) != inl) {
BIO_printf(bio_err, "error writing output file\n");
goto end;
}
}
if (!BIO_flush(wbio)) {
BIO_printf(bio_err, "bad decrypt\n");
goto end;
}
ret = 0;
if (cfg.verbose) {
BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in));
BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
}
end:
ERR_print_errors(bio_err);
free(strbuf);
free(buff);
BIO_free(in);
BIO_free_all(out);
BIO_free(benc);
BIO_free(b64);
free(pass);
return (ret);
}
int
set_hex(char *in, unsigned char *out, int size)
{
int i, n;
unsigned char j;
n = strlen(in);
if (n > (size * 2)) {
BIO_printf(bio_err, "hex string is too long\n");
return (0);
}
memset(out, 0, size);
for (i = 0; i < n; i++) {
j = (unsigned char) *in;
*(in++) = '\0';
if (j == 0)
break;
if (j >= '0' && j <= '9')
j -= '0';
else if (j >= 'A' && j <= 'F')
j = j - 'A' + 10;
else if (j >= 'a' && j <= 'f')
j = j - 'a' + 10;
else {
BIO_printf(bio_err, "non-hex digit\n");
return (0);
}
if (i & 1)
out[i / 2] |= j;
else
out[i / 2] = (j << 4);
}
return (1);
}

117
apps/openssl/errstr.c Normal file
View File

@@ -0,0 +1,117 @@
/* $OpenBSD: errstr.c,v 1.11 2023/07/23 11:20:11 tb Exp $ */
/* 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 <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/ssl.h>
static const struct option errstr_options[] = {
{ NULL },
};
static void
errstr_usage(void)
{
fprintf(stderr, "usage: errstr errno ...\n");
}
int
errstr_main(int argc, char **argv)
{
unsigned long ulval;
char *ularg, *ep;
int argsused, i;
char buf[256];
int ret = 0;
if (pledge("stdio rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
if (options_parse(argc, argv, errstr_options, NULL, &argsused) != 0) {
errstr_usage();
return (1);
}
for (i = argsused; i < argc; i++) {
errno = 0;
ularg = argv[i];
ulval = strtoul(ularg, &ep, 16);
if (strchr(ularg, '-') != NULL ||
(ularg[0] == '\0' || *ep != '\0') ||
(errno == ERANGE && ulval == ULONG_MAX)) {
printf("%s: bad error code\n", ularg);
ret++;
continue;
}
ERR_error_string_n(ulval, buf, sizeof(buf));
printf("%s\n", buf);
}
return (ret);
}

219
apps/openssl/gendh.c Normal file
View File

@@ -0,0 +1,219 @@
/* $OpenBSD: gendh.c,v 1.14 2023/03/06 14:32:06 tb Exp $ */
/* 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 <openssl/opensslconf.h>
/* Until the key-gen callbacks are modified to use newer prototypes, we allow
* deprecated functions for openssl-internal code */
#ifdef OPENSSL_NO_DEPRECATED
#undef OPENSSL_NO_DEPRECATED
#endif
#ifndef OPENSSL_NO_DH
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#define DEFBITS 512
static int dh_cb(int p, int n, BN_GENCB *cb);
static struct {
int g;
char *outfile;
} cfg;
static const struct option gendh_options[] = {
{
.name = "2",
.desc = "Generate DH parameters with a generator value of 2 "
"(default)",
.type = OPTION_VALUE,
.value = 2,
.opt.value = &cfg.g,
},
{
.name = "5",
.desc = "Generate DH parameters with a generator value of 5",
.type = OPTION_VALUE,
.value = 5,
.opt.value = &cfg.g,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{ NULL },
};
static void
gendh_usage(void)
{
fprintf(stderr,
"usage: gendh [-2 | -5] [-out file] [numbits]\n\n");
options_usage(gendh_options);
}
int
gendh_main(int argc, char **argv)
{
BN_GENCB *cb = NULL;
DH *dh = NULL;
int ret = 1, numbits = DEFBITS;
BIO *out = NULL;
char *strbits = NULL;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
if ((cb = BN_GENCB_new()) == NULL) {
BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
goto end;
}
BN_GENCB_set(cb, dh_cb, bio_err);
memset(&cfg, 0, sizeof(cfg));
cfg.g = 2;
if (options_parse(argc, argv, gendh_options, &strbits, NULL) != 0) {
gendh_usage();
goto end;
}
if (strbits != NULL) {
const char *errstr;
numbits = strtonum(strbits, 0, INT_MAX, &errstr);
if (errstr) {
fprintf(stderr, "Invalid number of bits: %s\n", errstr);
goto end;
}
}
out = BIO_new(BIO_s_file());
if (out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime,"
" generator %d\n", numbits, cfg.g);
BIO_printf(bio_err, "This is going to take a long time\n");
if (((dh = DH_new()) == NULL) ||
!DH_generate_parameters_ex(dh, numbits, cfg.g, cb))
goto end;
if (!PEM_write_bio_DHparams(out, dh))
goto end;
ret = 0;
end:
if (ret != 0)
ERR_print_errors(bio_err);
BIO_free_all(out);
BN_GENCB_free(cb);
DH_free(dh);
return (ret);
}
static int
dh_cb(int p, int n, BN_GENCB *cb)
{
char c = '*';
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
(void) BIO_flush(BN_GENCB_get_arg(cb));
return 1;
}
#endif

296
apps/openssl/gendsa.c Normal file
View File

@@ -0,0 +1,296 @@
/* $OpenBSD: gendsa.c,v 1.17 2023/03/06 14:32:06 tb Exp $ */
/* 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 <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static struct {
const EVP_CIPHER *enc;
char *outfile;
char *passargout;
} cfg;
static const EVP_CIPHER *get_cipher_by_name(char *name)
{
if (name == NULL || strcmp(name, "") == 0)
return (NULL);
#ifndef OPENSSL_NO_AES
else if (strcmp(name, "aes128") == 0)
return EVP_aes_128_cbc();
else if (strcmp(name, "aes192") == 0)
return EVP_aes_192_cbc();
else if (strcmp(name, "aes256") == 0)
return EVP_aes_256_cbc();
#endif
#ifndef OPENSSL_NO_CAMELLIA
else if (strcmp(name, "camellia128") == 0)
return EVP_camellia_128_cbc();
else if (strcmp(name, "camellia192") == 0)
return EVP_camellia_192_cbc();
else if (strcmp(name, "camellia256") == 0)
return EVP_camellia_256_cbc();
#endif
#ifndef OPENSSL_NO_DES
else if (strcmp(name, "des") == 0)
return EVP_des_cbc();
else if (strcmp(name, "des3") == 0)
return EVP_des_ede3_cbc();
#endif
#ifndef OPENSSL_NO_IDEA
else if (strcmp(name, "idea") == 0)
return EVP_idea_cbc();
#endif
else
return (NULL);
}
static int
set_enc(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.enc = get_cipher_by_name(name)) == NULL)
return (1);
*argsused = 1;
return (0);
}
static const struct option gendsa_options[] = {
#ifndef OPENSSL_NO_AES
{
.name = "aes128",
.desc = "Encrypt PEM output with CBC AES",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "aes192",
.desc = "Encrypt PEM output with CBC AES",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "aes256",
.desc = "Encrypt PEM output with CBC AES",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
#ifndef OPENSSL_NO_CAMELLIA
{
.name = "camellia128",
.desc = "Encrypt PEM output with CBC Camellia",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "camellia192",
.desc = "Encrypt PEM output with CBC Camellia",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "camellia256",
.desc = "Encrypt PEM output with CBC Camellia",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
#ifndef OPENSSL_NO_DES
{
.name = "des",
.desc = "Encrypt the generated key with DES in CBC mode",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "des3",
.desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
#ifndef OPENSSL_NO_IDEA
{
.name = "idea",
.desc = "Encrypt the generated key with IDEA in CBC mode",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
{
.name = "out",
.argname = "file",
.desc = "Output the key to 'file'",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "passout",
.argname = "src",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{ NULL },
};
static void
gendsa_usage(void)
{
fprintf(stderr, "usage: gendsa [-aes128 | -aes192 | -aes256 |\n");
fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |\n");
fprintf(stderr, " -des | -des3 | -idea] [-out file] [-passout src]");
fprintf(stderr, " paramfile\n\n");
options_usage(gendsa_options);
fprintf(stderr, "\n");
}
int
gendsa_main(int argc, char **argv)
{
DSA *dsa = NULL;
int ret = 1;
char *dsaparams = NULL;
char *passout = NULL;
BIO *out = NULL, *in = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, gendsa_options, &dsaparams, NULL) != 0) {
gendsa_usage();
goto end;
}
if (dsaparams == NULL) {
gendsa_usage();
goto end;
}
if (!app_passwd(bio_err, NULL, cfg.passargout, NULL,
&passout)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
in = BIO_new(BIO_s_file());
if (!(BIO_read_filename(in, dsaparams))) {
perror(dsaparams);
goto end;
}
if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) {
BIO_printf(bio_err, "unable to load DSA parameter file\n");
goto end;
}
BIO_free(in);
in = NULL;
out = BIO_new(BIO_s_file());
if (out == NULL)
goto end;
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
BIO_printf(bio_err, "Generating DSA key, %d bits\n",
BN_num_bits(DSA_get0_p(dsa)));
if (!DSA_generate_key(dsa))
goto end;
if (!PEM_write_bio_DSAPrivateKey(out, dsa, cfg.enc, NULL, 0,
NULL, passout))
goto end;
ret = 0;
end:
if (ret != 0)
ERR_print_errors(bio_err);
BIO_free(in);
BIO_free_all(out);
DSA_free(dsa);
free(passout);
return (ret);
}

418
apps/openssl/genpkey.c Normal file
View File

@@ -0,0 +1,418 @@
/* $OpenBSD: genpkey.c,v 1.17 2023/07/23 11:39:29 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006
*/
/* ====================================================================
* Copyright (c) 2006 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 <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
static int init_keygen_file(BIO * err, EVP_PKEY_CTX **pctx, const char *file);
static int genpkey_cb(EVP_PKEY_CTX * ctx);
static struct {
const EVP_CIPHER *cipher;
EVP_PKEY_CTX **ctx;
int do_param;
char *outfile;
int outformat;
char *passarg;
int text;
} cfg;
static int
genpkey_opt_algorithm(char *arg)
{
if (!init_gen_str(bio_err, cfg.ctx, arg,
cfg.do_param))
return (1);
return (0);
}
static int
genpkey_opt_cipher(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if (cfg.do_param == 1)
return (1);
if (strcmp(name, "none") == 0) {
cfg.cipher = NULL;
*argsused = 1;
return (0);
}
if ((cfg.cipher = EVP_get_cipherbyname(name)) != NULL) {
*argsused = 1;
return (0);
}
return (1);
}
static int
genpkey_opt_paramfile(char *arg)
{
if (cfg.do_param == 1)
return (1);
if (!init_keygen_file(bio_err, cfg.ctx, arg))
return (1);
return (0);
}
static int
genpkey_opt_pkeyopt(char *arg)
{
if (*cfg.ctx == NULL) {
BIO_puts(bio_err, "No keytype specified\n");
return (1);
}
if (pkey_ctrl_string(*cfg.ctx, arg) <= 0) {
BIO_puts(bio_err, "parameter setting error\n");
ERR_print_errors(bio_err);
return (1);
}
return (0);
}
static const struct option genpkey_options[] = {
{
.name = "algorithm",
.argname = "name",
.desc = "Public key algorithm to use (must precede -pkeyopt)",
.type = OPTION_ARG_FUNC,
.opt.argfunc = genpkey_opt_algorithm,
},
{
.name = "genparam",
.desc = "Generate a set of parameters instead of a private key",
.type = OPTION_FLAG,
.opt.flag = &cfg.do_param,
},
{
.name = "out",
.argname = "file",
.desc = "Output file to write to (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "paramfile",
.argname = "file",
.desc = "File to load public key algorithm parameters from\n"
"(must precede -pkeyopt)",
.type = OPTION_ARG_FUNC,
.opt.argfunc = genpkey_opt_paramfile,
},
{
.name = "pass",
.argname = "arg",
.desc = "Output file password source",
.type = OPTION_ARG,
.opt.arg = &cfg.passarg,
},
{
.name = "pkeyopt",
.argname = "opt:value",
.desc = "Set public key algorithm option to the given value",
.type = OPTION_ARG_FUNC,
.opt.argfunc = genpkey_opt_pkeyopt,
},
{
.name = "text",
.desc = "Print the private/public key in human readable form",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{
.name = NULL,
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = genpkey_opt_cipher,
},
{NULL},
};
static void
genpkey_usage(void)
{
fprintf(stderr,
"usage: genpkey [-algorithm alg] [cipher] [-genparam] [-out file]\n"
" [-outform der | pem] [-paramfile file] [-pass arg]\n"
" [-pkeyopt opt:value] [-text]\n\n");
options_usage(genpkey_options);
}
int
genpkey_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *pkey = NULL;
char *pass = NULL;
int ret = 1, rv;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.ctx = &ctx;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, genpkey_options, NULL, NULL) != 0) {
genpkey_usage();
goto end;
}
if (ctx == NULL) {
genpkey_usage();
goto end;
}
if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
BIO_puts(bio_err, "Error getting password\n");
goto end;
}
if (cfg.outfile != NULL) {
if ((out = BIO_new_file(cfg.outfile, "wb")) ==
NULL) {
BIO_printf(bio_err, "Can't open output file %s\n",
cfg.outfile);
goto end;
}
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
if (cfg.do_param) {
if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
BIO_puts(bio_err, "Error generating parameters\n");
ERR_print_errors(bio_err);
goto end;
}
} else {
if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
BIO_puts(bio_err, "Error generating key\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.do_param)
rv = PEM_write_bio_Parameters(out, pkey);
else if (cfg.outformat == FORMAT_PEM)
rv = PEM_write_bio_PrivateKey(out, pkey, cfg.cipher,
NULL, 0, NULL, pass);
else if (cfg.outformat == FORMAT_ASN1)
rv = i2d_PrivateKey_bio(out, pkey);
else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
if (rv <= 0) {
BIO_puts(bio_err, "Error writing key\n");
ERR_print_errors(bio_err);
}
if (cfg.text) {
if (cfg.do_param)
rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
else
rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
if (rv <= 0) {
BIO_puts(bio_err, "Error printing key\n");
ERR_print_errors(bio_err);
}
}
ret = 0;
end:
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(ctx);
BIO_free_all(out);
BIO_free(in);
free(pass);
return ret;
}
static int
init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file)
{
BIO *pbio;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
if (*pctx) {
BIO_puts(err, "Parameters already set!\n");
return 0;
}
pbio = BIO_new_file(file, "r");
if (!pbio) {
BIO_printf(err, "Can't open parameter file %s\n", file);
return 0;
}
pkey = PEM_read_bio_Parameters(pbio, NULL);
BIO_free(pbio);
if (!pkey) {
BIO_printf(bio_err, "Error reading parameter file %s\n", file);
return 0;
}
ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!ctx)
goto err;
if (EVP_PKEY_keygen_init(ctx) <= 0)
goto err;
EVP_PKEY_free(pkey);
*pctx = ctx;
return 1;
err:
BIO_puts(err, "Error initializing context\n");
ERR_print_errors(err);
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
return 0;
}
int
init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, const char *algname, int do_param)
{
const EVP_PKEY_ASN1_METHOD *ameth;
EVP_PKEY_CTX *ctx = NULL;
int pkey_id;
if (*pctx) {
BIO_puts(err, "Algorithm already set!\n");
return 0;
}
ameth = EVP_PKEY_asn1_find_str(NULL, algname, -1);
if (!ameth) {
BIO_printf(bio_err, "Algorithm %s not found\n", algname);
return 0;
}
ERR_clear_error();
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL);
if (!ctx)
goto err;
if (do_param) {
if (EVP_PKEY_paramgen_init(ctx) <= 0)
goto err;
} else {
if (EVP_PKEY_keygen_init(ctx) <= 0)
goto err;
}
*pctx = ctx;
return 1;
err:
BIO_printf(err, "Error initializing %s context\n", algname);
ERR_print_errors(err);
EVP_PKEY_CTX_free(ctx);
return 0;
}
static int
genpkey_cb(EVP_PKEY_CTX * ctx)
{
char c = '*';
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
int p;
p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(b, &c, 1);
(void) BIO_flush(b);
return 1;
}

389
apps/openssl/genrsa.c Normal file
View File

@@ -0,0 +1,389 @@
/* $OpenBSD: genrsa.c,v 1.22 2023/03/06 14:32:06 tb Exp $ */
/* 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 <openssl/opensslconf.h>
/* Until the key-gen callbacks are modified to use newer prototypes, we allow
* deprecated functions for openssl-internal code */
#ifdef OPENSSL_NO_DEPRECATED
#undef OPENSSL_NO_DEPRECATED
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#define DEFBITS 2048
static int genrsa_cb(int p, int n, BN_GENCB *cb);
static struct {
const EVP_CIPHER *enc;
unsigned long f4;
char *outfile;
char *passargout;
} cfg;
static int
set_public_exponent(int argc, char **argv, int *argsused)
{
char *option = argv[0];
if (strcmp(option, "-3") == 0)
cfg.f4 = 3;
else if (strcmp(option, "-f4") == 0 || strcmp(option, "-F4") == 0)
cfg.f4 = RSA_F4;
else
return (1);
*argsused = 1;
return (0);
}
static const EVP_CIPHER *get_cipher_by_name(char *name)
{
if (name == NULL || strcmp(name, "") == 0)
return (NULL);
#ifndef OPENSSL_NO_AES
else if (strcmp(name, "aes128") == 0)
return EVP_aes_128_cbc();
else if (strcmp(name, "aes192") == 0)
return EVP_aes_192_cbc();
else if (strcmp(name, "aes256") == 0)
return EVP_aes_256_cbc();
#endif
#ifndef OPENSSL_NO_CAMELLIA
else if (strcmp(name, "camellia128") == 0)
return EVP_camellia_128_cbc();
else if (strcmp(name, "camellia192") == 0)
return EVP_camellia_192_cbc();
else if (strcmp(name, "camellia256") == 0)
return EVP_camellia_256_cbc();
#endif
#ifndef OPENSSL_NO_DES
else if (strcmp(name, "des") == 0)
return EVP_des_cbc();
else if (strcmp(name, "des3") == 0)
return EVP_des_ede3_cbc();
#endif
#ifndef OPENSSL_NO_IDEA
else if (strcmp(name, "idea") == 0)
return EVP_idea_cbc();
#endif
else
return (NULL);
}
static int
set_enc(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.enc = get_cipher_by_name(name)) == NULL)
return (1);
*argsused = 1;
return (0);
}
static const struct option genrsa_options[] = {
{
.name = "3",
.desc = "Use 3 for the E value",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_public_exponent,
},
{
.name = "f4",
.desc = "Use F4 (0x10001) for the E value",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_public_exponent,
},
{
.name = "F4",
.desc = "Use F4 (0x10001) for the E value",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_public_exponent,
},
#ifndef OPENSSL_NO_AES
{
.name = "aes128",
.desc = "Encrypt PEM output with CBC AES",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "aes192",
.desc = "Encrypt PEM output with CBC AES",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "aes256",
.desc = "Encrypt PEM output with CBC AES",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
#ifndef OPENSSL_NO_CAMELLIA
{
.name = "camellia128",
.desc = "Encrypt PEM output with CBC Camellia",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "camellia192",
.desc = "Encrypt PEM output with CBC Camellia",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "camellia256",
.desc = "Encrypt PEM output with CBC Camellia",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
#ifndef OPENSSL_NO_DES
{
.name = "des",
.desc = "Encrypt the generated key with DES in CBC mode",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
{
.name = "des3",
.desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
#ifndef OPENSSL_NO_IDEA
{
.name = "idea",
.desc = "Encrypt the generated key with IDEA in CBC mode",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = set_enc,
},
#endif
{
.name = "out",
.argname = "file",
.desc = "Output the key to 'file'",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "passout",
.argname = "arg",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{ NULL },
};
static void
genrsa_usage(void)
{
fprintf(stderr, "usage: genrsa [-3 | -f4] [-aes128 | -aes192 |");
fprintf(stderr, " -aes256 |\n");
fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |");
fprintf(stderr, " -des | -des3 | -idea]\n");
fprintf(stderr, " [-out file] [-passout arg] [numbits]\n\n");
options_usage(genrsa_options);
fprintf(stderr, "\n");
}
int
genrsa_main(int argc, char **argv)
{
BN_GENCB *cb = NULL;
int ret = 1;
int num = DEFBITS;
char *numbits = NULL;
char *passout = NULL;
BIO *out = NULL;
BIGNUM *bn = NULL;
RSA *rsa = NULL;
char *rsa_e_hex = NULL, *rsa_e_dec = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
if ((bn = BN_new()) == NULL)
goto err;
if ((cb = BN_GENCB_new()) == NULL) {
BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
goto err;
}
BN_GENCB_set(cb, genrsa_cb, bio_err);
if ((out = BIO_new(BIO_s_file())) == NULL) {
BIO_printf(bio_err, "unable to create BIO for output\n");
goto err;
}
memset(&cfg, 0, sizeof(cfg));
cfg.f4 = RSA_F4;
if (options_parse(argc, argv, genrsa_options, &numbits, NULL) != 0) {
genrsa_usage();
goto err;
}
if ((numbits != NULL) &&
((sscanf(numbits, "%d", &num) == 0) || (num < 0))) {
genrsa_usage();
goto err;
}
if (!app_passwd(bio_err, NULL, cfg.passargout, NULL,
&passout)) {
BIO_printf(bio_err, "Error getting password\n");
goto err;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto err;
}
}
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
num);
rsa = RSA_new();
if (!rsa)
goto err;
if (!BN_set_word(bn, cfg.f4) ||
!RSA_generate_key_ex(rsa, num, bn, cb))
goto err;
if ((rsa_e_hex = BN_bn2hex(RSA_get0_e(rsa))) == NULL)
goto err;
if ((rsa_e_dec = BN_bn2dec(RSA_get0_e(rsa))) == NULL)
goto err;
BIO_printf(bio_err, "e is %s (0x%s)\n", rsa_e_dec, rsa_e_hex);
{
PW_CB_DATA cb_data;
cb_data.password = passout;
cb_data.prompt_info = cfg.outfile;
if (!PEM_write_bio_RSAPrivateKey(out, rsa, cfg.enc,
NULL, 0, password_callback, &cb_data))
goto err;
}
ret = 0;
err:
BN_free(bn);
BN_GENCB_free(cb);
RSA_free(rsa);
BIO_free_all(out);
free(rsa_e_dec);
free(rsa_e_hex);
free(passout);
if (ret != 0)
ERR_print_errors(bio_err);
return (ret);
}
static int
genrsa_cb(int p, int n, BN_GENCB *cb)
{
char c = '*';
if (p == 0)
c = '.';
if (p == 1)
c = '+';
if (p == 2)
c = '*';
if (p == 3)
c = '\n';
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
(void) BIO_flush(BN_GENCB_get_arg(cb));
return 1;
}

1532
apps/openssl/ocsp.c Normal file

File diff suppressed because it is too large Load Diff

736
apps/openssl/openssl.c Normal file
View File

@@ -0,0 +1,736 @@
/* $OpenBSD: openssl.c,v 1.35 2023/06/11 13:02:10 jsg Exp $ */
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 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).
*
*/
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "progs.h"
#include "s_apps.h"
#define FUNC_TYPE_GENERAL 1
#define FUNC_TYPE_MD 2
#define FUNC_TYPE_CIPHER 3
#define FUNC_TYPE_PKEY 4
#define FUNC_TYPE_MD_ALG 5
#define FUNC_TYPE_CIPHER_ALG 6
typedef struct {
int type;
const char *name;
int (*func)(int argc, char **argv);
} FUNCTION;
DECLARE_LHASH_OF(FUNCTION);
FUNCTION functions[] = {
/* General functions. */
{ FUNC_TYPE_GENERAL, "asn1parse", asn1parse_main },
{ FUNC_TYPE_GENERAL, "ca", ca_main },
{ FUNC_TYPE_GENERAL, "certhash", certhash_main },
{ FUNC_TYPE_GENERAL, "ciphers", ciphers_main },
#ifndef OPENSSL_NO_CMS
{ FUNC_TYPE_GENERAL, "cms", cms_main },
#endif
{ FUNC_TYPE_GENERAL, "crl2pkcs7", crl2pkcs7_main },
{ FUNC_TYPE_GENERAL, "crl", crl_main },
{ FUNC_TYPE_GENERAL, "dgst", dgst_main },
{ FUNC_TYPE_GENERAL, "enc", enc_main },
{ FUNC_TYPE_GENERAL, "errstr", errstr_main },
{ FUNC_TYPE_GENERAL, "genpkey", genpkey_main },
#ifndef OPENSSL_NO_OCSP
{ FUNC_TYPE_GENERAL, "ocsp", ocsp_main },
#endif
{ FUNC_TYPE_GENERAL, "passwd", passwd_main },
{ FUNC_TYPE_GENERAL, "pkcs7", pkcs7_main },
{ FUNC_TYPE_GENERAL, "pkcs8", pkcs8_main },
#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
{ FUNC_TYPE_GENERAL, "pkcs12", pkcs12_main },
#endif
{ FUNC_TYPE_GENERAL, "pkey", pkey_main },
{ FUNC_TYPE_GENERAL, "pkeyparam", pkeyparam_main },
{ FUNC_TYPE_GENERAL, "pkeyutl", pkeyutl_main },
{ FUNC_TYPE_GENERAL, "prime", prime_main },
{ FUNC_TYPE_GENERAL, "rand", rand_main },
{ FUNC_TYPE_GENERAL, "req", req_main },
{ FUNC_TYPE_GENERAL, "s_client", s_client_main },
{ FUNC_TYPE_GENERAL, "s_server", s_server_main },
{ FUNC_TYPE_GENERAL, "s_time", s_time_main },
{ FUNC_TYPE_GENERAL, "sess_id", sess_id_main },
{ FUNC_TYPE_GENERAL, "smime", smime_main },
#ifndef OPENSSL_NO_SPEED
{ FUNC_TYPE_GENERAL, "speed", speed_main },
#endif
{ FUNC_TYPE_GENERAL, "spkac", spkac_main },
{ FUNC_TYPE_GENERAL, "ts", ts_main },
{ FUNC_TYPE_GENERAL, "verify", verify_main },
{ FUNC_TYPE_GENERAL, "version", version_main },
{ FUNC_TYPE_GENERAL, "x509", x509_main },
#ifndef OPENSSL_NO_DH
{ FUNC_TYPE_GENERAL, "dh", dh_main },
{ FUNC_TYPE_GENERAL, "dhparam", dhparam_main },
{ FUNC_TYPE_GENERAL, "gendh", gendh_main },
#endif
#ifndef OPENSSL_NO_DSA
{ FUNC_TYPE_GENERAL, "dsa", dsa_main },
{ FUNC_TYPE_GENERAL, "dsaparam", dsaparam_main },
{ FUNC_TYPE_GENERAL, "gendsa", gendsa_main },
#endif
#ifndef OPENSSL_NO_EC
{ FUNC_TYPE_GENERAL, "ec", ec_main },
{ FUNC_TYPE_GENERAL, "ecparam", ecparam_main },
#endif
#ifndef OPENSSL_NO_RSA
{ FUNC_TYPE_GENERAL, "genrsa", genrsa_main },
{ FUNC_TYPE_GENERAL, "rsa", rsa_main },
{ FUNC_TYPE_GENERAL, "rsautl", rsautl_main },
#endif
/* Message Digests. */
#ifndef OPENSSL_NO_GOST
{ FUNC_TYPE_MD, "gost-mac", dgst_main },
{ FUNC_TYPE_MD, "md_gost94", dgst_main },
{ FUNC_TYPE_MD, "streebog256", dgst_main },
{ FUNC_TYPE_MD, "streebog512", dgst_main },
#endif
#ifndef OPENSSL_NO_MD4
{ FUNC_TYPE_MD, "md4", dgst_main },
#endif
#ifndef OPENSSL_NO_MD5
{ FUNC_TYPE_MD, "md5", dgst_main },
#endif
#ifndef OPENSSL_NO_RIPEMD160
{ FUNC_TYPE_MD, "ripemd160", dgst_main },
#endif
#ifndef OPENSSL_NO_SHA1
{ FUNC_TYPE_MD, "sha1", dgst_main },
#endif
#ifndef OPENSSL_NO_SHA224
{ FUNC_TYPE_MD, "sha224", dgst_main },
#endif
#ifndef OPENSSL_NO_SHA256
{ FUNC_TYPE_MD, "sha256", dgst_main },
#endif
#ifndef OPENSSL_NO_SHA384
{ FUNC_TYPE_MD, "sha384", dgst_main },
#endif
#ifndef OPENSSL_NO_SHA512
{ FUNC_TYPE_MD, "sha512", dgst_main },
#endif
#ifndef OPENSSL_NO_SM3
{ FUNC_TYPE_MD, "sm3", dgst_main },
{ FUNC_TYPE_MD, "sm3WithRSAEncryption", dgst_main },
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
{ FUNC_TYPE_MD, "whirlpool", dgst_main },
#endif
/* Ciphers. */
{ FUNC_TYPE_CIPHER, "base64", enc_main },
#ifndef OPENSSL_NO_AES
{ FUNC_TYPE_CIPHER, "aes-128-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "aes-128-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "aes-192-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "aes-192-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "aes-256-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "aes-256-ecb", enc_main },
#endif
#ifndef OPENSSL_NO_BF
{ FUNC_TYPE_CIPHER, "bf", enc_main },
{ FUNC_TYPE_CIPHER, "bf-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "bf-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "bf-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "bf-ofb", enc_main },
#endif
#ifndef OPENSSL_NO_CAMELLIA
{ FUNC_TYPE_CIPHER, "camellia-128-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "camellia-128-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "camellia-192-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "camellia-192-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "camellia-256-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "camellia-256-ecb", enc_main },
#endif
#ifndef OPENSSL_NO_CAST
{ FUNC_TYPE_CIPHER, "cast", enc_main },
{ FUNC_TYPE_CIPHER, "cast5-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "cast5-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "cast5-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "cast5-ofb", enc_main },
{ FUNC_TYPE_CIPHER, "cast-cbc", enc_main },
#endif
#ifndef OPENSSL_NO_CHACHA
{ FUNC_TYPE_CIPHER, "chacha", enc_main },
#endif
#ifndef OPENSSL_NO_DES
{ FUNC_TYPE_CIPHER, "des", enc_main },
{ FUNC_TYPE_CIPHER, "des3", enc_main },
{ FUNC_TYPE_CIPHER, "desx", enc_main },
{ FUNC_TYPE_CIPHER, "des-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede3", enc_main },
{ FUNC_TYPE_CIPHER, "des-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede3-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "des-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede3-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "des-ofb", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede-ofb", enc_main },
{ FUNC_TYPE_CIPHER, "des-ede3-ofb", enc_main },
#endif
#ifndef OPENSSL_NO_IDEA
{ FUNC_TYPE_CIPHER, "idea", enc_main },
{ FUNC_TYPE_CIPHER, "idea-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "idea-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "idea-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "idea-ofb", enc_main },
#endif
#ifndef OPENSSL_NO_RC2
{ FUNC_TYPE_CIPHER, "rc2", enc_main },
{ FUNC_TYPE_CIPHER, "rc2-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "rc2-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "rc2-cfb", enc_main },
{ FUNC_TYPE_CIPHER, "rc2-ofb", enc_main },
{ FUNC_TYPE_CIPHER, "rc2-64-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "rc2-40-cbc", enc_main },
#endif
#ifndef OPENSSL_NO_RC4
{ FUNC_TYPE_CIPHER, "rc4", enc_main },
{ FUNC_TYPE_CIPHER, "rc4-40", enc_main },
#endif
#ifndef OPENSSL_NO_SM4
{ FUNC_TYPE_CIPHER, "sm4", enc_main },
{ FUNC_TYPE_CIPHER, "sm4-ecb", enc_main },
{ FUNC_TYPE_CIPHER, "sm4-cbc", enc_main },
{ FUNC_TYPE_CIPHER, "sm4-ofb", enc_main },
{ FUNC_TYPE_CIPHER, "sm4-cfb", enc_main },
#endif
{ 0, NULL, NULL }
};
static void openssl_startup(void);
static void openssl_shutdown(void);
/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
* base prototypes (we cast each variable inside the function to the required
* type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
* functions. */
static LHASH_OF(FUNCTION) *prog_init(void);
static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]);
static void print_help(void);
static void list_pkey(BIO * out);
static void list_cipher(BIO * out);
static void list_md(BIO * out);
char *default_config_file = NULL;
CONF *config = NULL;
BIO *bio_err = NULL;
static void
openssl_startup(void)
{
#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
#endif
OpenSSL_add_all_algorithms();
SSL_library_init();
SSL_load_error_strings();
setup_ui();
}
static void
openssl_shutdown(void)
{
CONF_modules_unload(1);
destroy_ui();
OBJ_cleanup();
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_remove_thread_state(NULL);
ERR_free_strings();
}
int
main(int argc, char **argv)
{
char *to_free = NULL;
int i, ret = 0;
char *p;
LHASH_OF(FUNCTION) * prog = NULL;
long errline;
if (pledge("stdio cpath wpath rpath inet dns proc flock tty", NULL) == -1) {
fprintf(stderr, "openssl: pledge: %s\n", strerror(errno));
exit(1);
}
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
if (bio_err == NULL) {
fprintf(stderr, "openssl: failed to initialise bio_err\n");
exit(1);
}
if (BIO_sock_init() != 1) {
BIO_printf(bio_err, "BIO_sock_init failed\n");
exit(1);
}
openssl_startup();
/* Lets load up our environment a little */
p = getenv("OPENSSL_CONF");
if (p == NULL) {
p = to_free = make_config_name();
if (p == NULL) {
BIO_printf(bio_err, "error making config file name\n");
goto end;
}
}
default_config_file = p;
config = NCONF_new(NULL);
i = NCONF_load(config, p, &errline);
if (i == 0) {
if (ERR_GET_REASON(ERR_peek_last_error()) ==
CONF_R_NO_SUCH_FILE) {
BIO_printf(bio_err,
"WARNING: can't open config file: %s\n", p);
ERR_clear_error();
NCONF_free(config);
config = NULL;
} else {
ERR_print_errors(bio_err);
NCONF_free(config);
exit(1);
}
}
if (!load_config(bio_err, NULL)) {
BIO_printf(bio_err, "failed to load configuration\n");
goto end;
}
prog = prog_init();
/*
* ok, now check that there are not arguments, if there are, run with
* them, shifting the executable name off the front
*/
argc--;
argv++;
if (argc < 1) {
print_help();
goto end;
}
ret = do_cmd(prog, argc, argv);
if (ret < 0)
ret = 0;
end:
free(to_free);
if (config != NULL) {
NCONF_free(config);
config = NULL;
}
if (prog != NULL)
lh_FUNCTION_free(prog);
openssl_shutdown();
if (bio_err != NULL) {
BIO_free(bio_err);
bio_err = NULL;
}
return (ret);
}
#define LIST_STANDARD_COMMANDS "list-standard-commands"
#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
#define LIST_CIPHER_COMMANDS "list-cipher-commands"
#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
static int
do_cmd(LHASH_OF(FUNCTION) * prog, int argc, char *argv[])
{
FUNCTION f, *fp;
int ret = 1;
if (argc <= 0 || argv[0] == NULL)
return 0;
f.name = argv[0];
fp = lh_FUNCTION_retrieve(prog, &f);
if (fp == NULL) {
if (EVP_get_digestbyname(argv[0])) {
f.type = FUNC_TYPE_MD;
f.func = dgst_main;
fp = &f;
} else if (EVP_get_cipherbyname(argv[0])) {
f.type = FUNC_TYPE_CIPHER;
f.func = enc_main;
fp = &f;
}
}
if (fp != NULL)
return fp->func(argc, argv);
if (strcmp(argv[0], "help") == 0) {
print_help();
return 0;
}
if ((strncmp(argv[0], "no-", 3)) == 0) {
BIO *bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
f.name = argv[0] + 3;
ret = (lh_FUNCTION_retrieve(prog, &f) != NULL);
if (!ret)
BIO_printf(bio_stdout, "%s\n", argv[0]);
else
BIO_printf(bio_stdout, "%s\n", argv[0] + 3);
BIO_free_all(bio_stdout);
return ret;
}
if ((strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) ||
(strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
(strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
(strcmp(argv[0], LIST_CIPHER_COMMANDS) == 0) ||
(strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) ||
(strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)) {
int list_type;
BIO *bio_stdout;
if (strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0)
list_type = FUNC_TYPE_GENERAL;
else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0)
list_type = FUNC_TYPE_MD;
else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
list_type = FUNC_TYPE_MD_ALG;
else if (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)
list_type = FUNC_TYPE_PKEY;
else if (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0)
list_type = FUNC_TYPE_CIPHER_ALG;
else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
list_type = FUNC_TYPE_CIPHER;
bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
if (list_type == FUNC_TYPE_PKEY)
list_pkey(bio_stdout);
if (list_type == FUNC_TYPE_MD_ALG)
list_md(bio_stdout);
if (list_type == FUNC_TYPE_CIPHER_ALG)
list_cipher(bio_stdout);
else {
for (fp = functions; fp->name != NULL; fp++)
if (fp->type == list_type)
BIO_printf(bio_stdout, "%s\n",
fp->name);
}
BIO_free_all(bio_stdout);
return 0;
}
BIO_printf(bio_err,
"openssl:Error: '%s' is an invalid command.\n",
argv[0]);
print_help();
return 1;
}
static void
print_help(void)
{
FUNCTION *fp;
int i = 0;
int tp = 0;
int nl;
BIO_printf(bio_err, "\nStandard commands");
for (fp = functions; fp->name != NULL; fp++) {
nl = 0;
#ifdef OPENSSL_NO_CAMELLIA
if (((i++) % 5) == 0)
#else
if (((i++) % 4) == 0)
#endif
{
BIO_printf(bio_err, "\n");
nl = 1;
}
if (fp->type != tp) {
tp = fp->type;
if (!nl)
BIO_printf(bio_err, "\n");
if (tp == FUNC_TYPE_MD) {
i = 1;
BIO_printf(bio_err,
"\nMessage Digest commands (see the `dgst' command for more details)\n");
} else if (tp == FUNC_TYPE_CIPHER) {
i = 1;
BIO_printf(bio_err, "\nCipher commands (see the `enc' command for more details)\n");
}
}
#ifdef OPENSSL_NO_CAMELLIA
BIO_printf(bio_err, "%-15s", fp->name);
#else
BIO_printf(bio_err, "%-18s", fp->name);
#endif
}
BIO_printf(bio_err, "\n\n");
}
static int
SortFnByName(const void *_f1, const void *_f2)
{
const FUNCTION *f1 = _f1;
const FUNCTION *f2 = _f2;
if (f1->type != f2->type)
return f1->type - f2->type;
return strcmp(f1->name, f2->name);
}
static void
list_pkey(BIO * out)
{
int i;
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
const EVP_PKEY_ASN1_METHOD *ameth;
int pkey_id, pkey_base_id, pkey_flags;
const char *pinfo, *pem_str;
ameth = EVP_PKEY_asn1_get0(i);
EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
&pinfo, &pem_str, ameth);
if (pkey_flags & ASN1_PKEY_ALIAS) {
BIO_printf(out, "Name: %s\n",
OBJ_nid2ln(pkey_id));
BIO_printf(out, "\tType: Alias to %s\n",
OBJ_nid2ln(pkey_base_id));
} else {
BIO_printf(out, "Name: %s\n", pinfo);
BIO_printf(out, "\tType: %s Algorithm\n",
pkey_flags & ASN1_PKEY_DYNAMIC ?
"External" : "Builtin");
BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
if (pem_str == NULL)
pem_str = "(none)";
BIO_printf(out, "\tPEM string: %s\n", pem_str);
}
}
}
static void
list_cipher_fn(const EVP_CIPHER * c, const char *from, const char *to,
void *arg)
{
if (c)
BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
else {
if (!from)
from = "<undefined>";
if (!to)
to = "<undefined>";
BIO_printf(arg, "%s => %s\n", from, to);
}
}
static void
list_cipher(BIO * out)
{
EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
}
static void
list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg)
{
if (m)
BIO_printf(arg, "%s\n", EVP_MD_name(m));
else {
if (!from)
from = "<undefined>";
if (!to)
to = "<undefined>";
BIO_printf(arg, "%s => %s\n", from, to);
}
}
static void
list_md(BIO * out)
{
EVP_MD_do_all_sorted(list_md_fn, out);
}
static int
function_cmp(const FUNCTION * a, const FUNCTION * b)
{
return strncmp(a->name, b->name, 8);
}
static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
static unsigned long
function_hash(const FUNCTION * a)
{
return lh_strhash(a->name);
}
static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
static LHASH_OF(FUNCTION) *
prog_init(void)
{
LHASH_OF(FUNCTION) * ret;
FUNCTION *f;
size_t i;
/* Purely so it looks nice when the user hits ? */
for (i = 0, f = functions; f->name != NULL; ++f, ++i)
;
qsort(functions, i, sizeof *functions, SortFnByName);
if ((ret = lh_FUNCTION_new()) == NULL)
return (NULL);
for (f = functions; f->name != NULL; f++)
(void) lh_FUNCTION_insert(ret, f);
return (ret);
}

524
apps/openssl/passwd.c Normal file
View File

@@ -0,0 +1,524 @@
/* $OpenBSD: passwd.c,v 1.14 2023/03/06 14:32:06 tb Exp $ */
#if defined OPENSSL_NO_MD5
#define NO_MD5CRYPT_1
#endif
#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
#include <assert.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
#endif
#ifndef NO_MD5CRYPT_1
#include <openssl/md5.h>
#endif
static unsigned const char cov_2char[64] = {
/* from crypto/des/fcrypt.c */
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
static int
do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO * out, int quiet, int table, int reverse,
size_t pw_maxlen, int usecrypt, int use1, int useapr1);
static struct {
char *infile;
int in_stdin;
int noverify;
int quiet;
int reverse;
char *salt;
int table;
int use1;
int useapr1;
int usecrypt;
} cfg;
static const struct option passwd_options[] = {
#ifndef NO_MD5CRYPT_1
{
.name = "1",
.desc = "Use MD5 based BSD password algorithm 1",
.type = OPTION_FLAG,
.opt.flag = &cfg.use1,
},
{
.name = "apr1",
.desc = "Use apr1 algorithm (Apache variant of BSD algorithm)",
.type = OPTION_FLAG,
.opt.flag = &cfg.useapr1,
},
#endif
#ifndef OPENSSL_NO_DES
{
.name = "crypt",
.desc = "Use crypt algorithm (default)",
.type = OPTION_FLAG,
.opt.flag = &cfg.usecrypt,
},
#endif
{
.name = "in",
.argname = "file",
.desc = "Read passwords from specified file",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "noverify",
.desc = "Do not verify password",
.type = OPTION_FLAG,
.opt.flag = &cfg.noverify,
},
{
.name = "quiet",
.desc = "Do not output warnings",
.type = OPTION_FLAG,
.opt.flag = &cfg.quiet,
},
{
.name = "reverse",
.desc = "Reverse table columns (requires -table)",
.type = OPTION_FLAG,
.opt.flag = &cfg.reverse,
},
{
.name = "salt",
.argname = "string",
.desc = "Use specified salt",
.type = OPTION_ARG,
.opt.arg = &cfg.salt,
},
{
.name = "stdin",
.desc = "Read passwords from stdin",
.type = OPTION_FLAG,
.opt.flag = &cfg.in_stdin,
},
{
.name = "table",
.desc = "Output cleartext and hashed passwords (tab separated)",
.type = OPTION_FLAG,
.opt.flag = &cfg.table,
},
{ NULL },
};
static void
passwd_usage(void)
{
fprintf(stderr, "usage: passwd [-1 | -apr1 | -crypt] [-in file] "
"[-noverify] [-quiet]\n"
" [-reverse] [-salt string] [-stdin] [-table] [password]\n\n");
options_usage(passwd_options);
}
int
passwd_main(int argc, char **argv)
{
char *passwd = NULL, **passwds = NULL;
char *salt_malloc = NULL, *passwd_malloc = NULL;
size_t passwd_malloc_size = 0;
BIO *in = NULL, *out = NULL;
int badopt = 0;
int passed_salt = 0;
size_t pw_maxlen = 0;
int argsused;
int ret = 1;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, passwd_options, NULL, &argsused) != 0) {
passwd_usage();
goto err;
}
if (argsused < argc)
passwds = &argv[argsused];
if (cfg.salt != NULL)
passed_salt = 1;
if (!cfg.usecrypt && !cfg.use1 &&
!cfg.useapr1)
cfg.usecrypt = 1; /* use default */
if (cfg.usecrypt + cfg.use1 +
cfg.useapr1 > 1)
badopt = 1; /* conflicting options */
/* Reject unsupported algorithms */
#ifdef OPENSSL_NO_DES
if (cfg.usecrypt)
badopt = 1;
#endif
#ifdef NO_MD5CRYPT_1
if (cfg.use1 || cfg.useapr1)
badopt = 1;
#endif
if (badopt) {
passwd_usage();
goto err;
}
if ((out = BIO_new(BIO_s_file())) == NULL)
goto err;
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
if (cfg.infile != NULL || cfg.in_stdin) {
if ((in = BIO_new(BIO_s_file())) == NULL)
goto err;
if (cfg.infile != NULL) {
assert(cfg.in_stdin == 0);
if (BIO_read_filename(in, cfg.infile) <= 0)
goto err;
} else {
assert(cfg.in_stdin);
BIO_set_fp(in, stdin, BIO_NOCLOSE);
}
}
if (cfg.usecrypt)
pw_maxlen = 8;
else if (cfg.use1 || cfg.useapr1)
pw_maxlen = 256;/* arbitrary limit, should be enough for most
* passwords */
if (passwds == NULL) {
/* no passwords on the command line */
passwd_malloc_size = pw_maxlen + 2;
/* longer than necessary so that we can warn about truncation */
passwd = passwd_malloc = malloc(passwd_malloc_size);
if (passwd_malloc == NULL)
goto err;
}
if (in == NULL && passwds == NULL) {
/* build a null-terminated list */
static char *passwds_static[2] = {NULL, NULL};
passwds = passwds_static;
if (in == NULL)
if (EVP_read_pw_string(passwd_malloc,
passwd_malloc_size, "Password: ",
!(passed_salt || cfg.noverify)) != 0)
goto err;
passwds[0] = passwd_malloc;
}
if (in == NULL) {
assert(passwds != NULL);
assert(*passwds != NULL);
do { /* loop over list of passwords */
passwd = *passwds++;
if (!do_passwd(passed_salt, &cfg.salt,
&salt_malloc, passwd, out, cfg.quiet,
cfg.table, cfg.reverse,
pw_maxlen, cfg.usecrypt,
cfg.use1, cfg.useapr1))
goto err;
} while (*passwds != NULL);
} else {
int done;
assert(passwd != NULL);
do {
int r = BIO_gets(in, passwd, pw_maxlen + 1);
if (r > 0) {
char *c = (strchr(passwd, '\n'));
if (c != NULL)
*c = 0; /* truncate at newline */
else {
/* ignore rest of line */
char trash[BUFSIZ];
do
r = BIO_gets(in, trash, sizeof trash);
while ((r > 0) && (!strchr(trash, '\n')));
}
if (!do_passwd(passed_salt, &cfg.salt,
&salt_malloc, passwd, out,
cfg.quiet, cfg.table,
cfg.reverse, pw_maxlen,
cfg.usecrypt, cfg.use1,
cfg.useapr1))
goto err;
}
done = (r <= 0);
} while (!done);
}
ret = 0;
err:
ERR_print_errors(bio_err);
free(salt_malloc);
free(passwd_malloc);
BIO_free(in);
BIO_free_all(out);
return (ret);
}
#ifndef NO_MD5CRYPT_1
/* MD5-based password algorithm (should probably be available as a library
* function; then the static buffer would not be acceptable).
* For magic string "1", this should be compatible to the MD5-based BSD
* password algorithm.
* For 'magic' string "apr1", this is compatible to the MD5-based Apache
* password algorithm.
* (Apparently, the Apache password algorithm is identical except that the
* 'magic' string was changed -- the laziest application of the NIH principle
* I've ever encountered.)
*/
static char *
md5crypt(const char *passwd, const char *magic, const char *salt)
{
static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5h
* ash..........\0" */
unsigned char buf[MD5_DIGEST_LENGTH];
char *salt_out;
int n;
unsigned int i;
EVP_MD_CTX *md = NULL, *md2 = NULL;
size_t passwd_len, salt_len;
passwd_len = strlen(passwd);
out_buf[0] = '$';
out_buf[1] = 0;
assert(strlen(magic) <= 4); /* "1" or "apr1" */
strlcat(out_buf, magic, sizeof(out_buf));
strlcat(out_buf, "$", sizeof(out_buf));
strlcat(out_buf, salt, sizeof(out_buf));
assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
salt_out = out_buf + 2 + strlen(magic);
salt_len = strlen(salt_out);
assert(salt_len <= 8);
if ((md = EVP_MD_CTX_new()) == NULL)
goto err;
if (!EVP_DigestInit_ex(md, EVP_md5(), NULL))
goto err;
if (!EVP_DigestUpdate(md, passwd, passwd_len))
goto err;
if (!EVP_DigestUpdate(md, "$", 1))
goto err;
if (!EVP_DigestUpdate(md, magic, strlen(magic)))
goto err;
if (!EVP_DigestUpdate(md, "$", 1))
goto err;
if (!EVP_DigestUpdate(md, salt_out, salt_len))
goto err;
if ((md2 = EVP_MD_CTX_new()) == NULL)
goto err;
if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
goto err;
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
goto err;
if (!EVP_DigestUpdate(md2, salt_out, salt_len))
goto err;
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
goto err;
if (!EVP_DigestFinal_ex(md2, buf, NULL))
goto err;
for (i = passwd_len; i > sizeof buf; i -= sizeof buf) {
if (!EVP_DigestUpdate(md, buf, sizeof buf))
goto err;
}
if (!EVP_DigestUpdate(md, buf, i))
goto err;
n = passwd_len;
while (n) {
if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1))
goto err;
n >>= 1;
}
if (!EVP_DigestFinal_ex(md, buf, NULL))
goto err;
for (i = 0; i < 1000; i++) {
if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
goto err;
if (!EVP_DigestUpdate(md2,
(i & 1) ? (unsigned const char *) passwd : buf,
(i & 1) ? passwd_len : sizeof buf))
goto err;
if (i % 3) {
if (!EVP_DigestUpdate(md2, salt_out, salt_len))
goto err;
}
if (i % 7) {
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
goto err;
}
if (!EVP_DigestUpdate(md2,
(i & 1) ? buf : (unsigned const char *) passwd,
(i & 1) ? sizeof buf : passwd_len))
goto err;
if (!EVP_DigestFinal_ex(md2, buf, NULL))
goto err;
}
EVP_MD_CTX_free(md2);
md2 = NULL;
{
/* transform buf into output string */
unsigned char buf_perm[sizeof buf];
int dest, source;
char *output;
/* silly output permutation */
for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17)
buf_perm[dest] = buf[source];
buf_perm[14] = buf[5];
buf_perm[15] = buf[11];
assert(16 == sizeof buf_perm);
output = salt_out + salt_len;
assert(output == out_buf + strlen(out_buf));
*output++ = '$';
for (i = 0; i < 15; i += 3) {
*output++ = cov_2char[buf_perm[i + 2] & 0x3f];
*output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) |
(buf_perm[i + 2] >> 6)];
*output++ = cov_2char[((buf_perm[i] & 3) << 4) |
(buf_perm[i + 1] >> 4)];
*output++ = cov_2char[buf_perm[i] >> 2];
}
assert(i == 15);
*output++ = cov_2char[buf_perm[i] & 0x3f];
*output++ = cov_2char[buf_perm[i] >> 6];
*output = 0;
assert(strlen(out_buf) < sizeof(out_buf));
}
EVP_MD_CTX_free(md);
return out_buf;
err:
EVP_MD_CTX_free(md);
EVP_MD_CTX_free(md2);
return NULL;
}
#endif
static int
do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO * out, int quiet, int table, int reverse,
size_t pw_maxlen, int usecrypt, int use1, int useapr1)
{
char *hash = NULL;
assert(salt_p != NULL);
assert(salt_malloc_p != NULL);
/* first make sure we have a salt */
if (!passed_salt) {
#ifndef OPENSSL_NO_DES
if (usecrypt) {
if (*salt_malloc_p == NULL) {
*salt_p = *salt_malloc_p = malloc(3);
if (*salt_malloc_p == NULL)
goto err;
}
arc4random_buf(*salt_p, 2);
(*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
(*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
(*salt_p)[2] = 0;
}
#endif /* !OPENSSL_NO_DES */
#ifndef NO_MD5CRYPT_1
if (use1 || useapr1) {
int i;
if (*salt_malloc_p == NULL) {
*salt_p = *salt_malloc_p = malloc(9);
if (*salt_malloc_p == NULL)
goto err;
}
arc4random_buf(*salt_p, 8);
for (i = 0; i < 8; i++)
(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
(*salt_p)[8] = 0;
}
#endif /* !NO_MD5CRYPT_1 */
}
assert(*salt_p != NULL);
/* truncate password if necessary */
if ((strlen(passwd) > pw_maxlen)) {
if (!quiet)
BIO_printf(bio_err,
"Warning: truncating password to %zu characters\n",
pw_maxlen);
passwd[pw_maxlen] = 0;
}
assert(strlen(passwd) <= pw_maxlen);
/* now compute password hash */
#ifndef OPENSSL_NO_DES
if (usecrypt)
hash = DES_crypt(passwd, *salt_p);
#endif
#ifndef NO_MD5CRYPT_1
if (use1 || useapr1)
if ((hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p)) == NULL)
goto err;
#endif
assert(hash != NULL);
if (table && !reverse)
BIO_printf(out, "%s\t%s\n", passwd, hash);
else if (table && reverse)
BIO_printf(out, "%s\t%s\n", hash, passwd);
else
BIO_printf(out, "%s\n", hash);
return 1;
err:
free(*salt_malloc_p);
*salt_malloc_p = NULL;
return 0;
}
#else
int
passwd_main(int argc, char **argv)
{
fputs("Program not available.\n", stderr)
return (1);
}
#endif

1128
apps/openssl/pkcs12.c Normal file

File diff suppressed because it is too large Load Diff

291
apps/openssl/pkcs7.c Normal file
View File

@@ -0,0 +1,291 @@
/* $OpenBSD: pkcs7.c,v 1.15 2023/07/23 11:39:29 tb Exp $ */
/* 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 <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/x509.h>
static struct {
char *infile;
int informat;
int noout;
char *outfile;
int outformat;
int p7_print;
int print_certs;
int text;
} cfg;
static const struct option pkcs7_options[] = {
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "Do not output encoded version of PKCS#7 structure",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "print",
.desc = "Output ASN.1 representation of PKCS#7 structure",
.type = OPTION_FLAG,
.opt.flag = &cfg.p7_print,
},
{
.name = "print_certs",
.desc = "Print out any certificates or CRLs contained in file",
.type = OPTION_FLAG,
.opt.flag = &cfg.print_certs,
},
{
.name = "text",
.desc = "Print out full certificate details",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{ NULL },
};
static void
pkcs7_usage(void)
{
fprintf(stderr, "usage: pkcs7 [-in file] "
"[-inform DER | PEM] [-noout]\n"
" [-out file] [-outform DER | PEM] [-print_certs] [-text]\n\n");
options_usage(pkcs7_options);
}
int
pkcs7_main(int argc, char **argv)
{
PKCS7 *p7 = NULL;
BIO *in = NULL, *out = NULL;
int ret = 1;
int i;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, pkcs7_options, NULL, NULL) != 0) {
pkcs7_usage();
goto end;
}
in = BIO_new(BIO_s_file());
out = BIO_new(BIO_s_file());
if ((in == NULL) || (out == NULL)) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, cfg.infile) <= 0) {
perror(cfg.infile);
goto end;
}
}
if (cfg.informat == FORMAT_ASN1)
p7 = d2i_PKCS7_bio(in, NULL);
else if (cfg.informat == FORMAT_PEM)
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
else {
BIO_printf(bio_err, "bad input format specified for pkcs7 object\n");
goto end;
}
if (p7 == NULL) {
BIO_printf(bio_err, "unable to load PKCS7 object\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.p7_print)
PKCS7_print_ctx(out, p7, 0, NULL);
if (cfg.print_certs) {
STACK_OF(X509) * certs = NULL;
STACK_OF(X509_CRL) * crls = NULL;
i = OBJ_obj2nid(p7->type);
switch (i) {
case NID_pkcs7_signed:
if (p7->d.sign != NULL) {
certs = p7->d.sign->cert;
crls = p7->d.sign->crl;
}
break;
case NID_pkcs7_signedAndEnveloped:
if (p7->d.signed_and_enveloped != NULL) {
certs = p7->d.signed_and_enveloped->cert;
crls = p7->d.signed_and_enveloped->crl;
}
break;
default:
break;
}
if (certs != NULL) {
X509 *x;
for (i = 0; i < sk_X509_num(certs); i++) {
x = sk_X509_value(certs, i);
if (cfg.text)
X509_print(out, x);
else
dump_cert_text(out, x);
if (!cfg.noout)
PEM_write_bio_X509(out, x);
BIO_puts(out, "\n");
}
}
if (crls != NULL) {
X509_CRL *crl;
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
crl = sk_X509_CRL_value(crls, i);
X509_CRL_print(out, crl);
if (!cfg.noout)
PEM_write_bio_X509_CRL(out, crl);
BIO_puts(out, "\n");
}
}
ret = 0;
goto end;
}
if (!cfg.noout) {
if (cfg.outformat == FORMAT_ASN1)
i = i2d_PKCS7_bio(out, p7);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_PKCS7(out, p7);
else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write pkcs7 object\n");
ERR_print_errors(bio_err);
goto end;
}
}
ret = 0;
end:
if (p7 != NULL)
PKCS7_free(p7);
if (in != NULL)
BIO_free(in);
if (out != NULL)
BIO_free_all(out);
return (ret);
}

366
apps/openssl/pkcs8.c Normal file
View File

@@ -0,0 +1,366 @@
/* $OpenBSD: pkcs8.c,v 1.17 2023/07/23 11:39:29 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999-2004.
*/
/* ====================================================================
* 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 <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
static struct {
const EVP_CIPHER *cipher;
char *infile;
int informat;
int iter;
int nocrypt;
char *outfile;
int outformat;
char *passargin;
char *passargout;
int pbe_nid;
int topk8;
} cfg;
static int
pkcs8_opt_v1(char *arg)
{
if ((cfg.pbe_nid = OBJ_txt2nid(arg)) == NID_undef) {
fprintf(stderr, "Unknown PBE algorithm '%s'\n", arg);
return (1);
}
return (0);
}
static int
pkcs8_opt_v2(char *arg)
{
if ((cfg.cipher = EVP_get_cipherbyname(arg)) == NULL) {
fprintf(stderr, "Unknown cipher '%s'\n", arg);
return (1);
}
return (0);
}
static const struct option pkcs8_options[] = {
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "der | pem",
.desc = "Input format (default PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "nocrypt",
.desc = "Use or expect unencrypted private key",
.type = OPTION_FLAG,
.opt.flag = &cfg.nocrypt,
},
{
.name = "noiter",
.desc = "Use 1 as iteration count",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.iter,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "der | pem",
.desc = "Output format (default PEM)",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "passin",
.argname = "source",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "passout",
.argname = "source",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{
.name = "topk8",
.desc = "Read traditional format key and write PKCS#8 format"
" key",
.type = OPTION_FLAG,
.opt.flag = &cfg.topk8,
},
{
.name = "v1",
.argname = "algorithm",
.desc = "Use PKCS#5 v1.5 or PKCS#12 with given algorithm",
.type = OPTION_ARG_FUNC,
.opt.argfunc = pkcs8_opt_v1,
},
{
.name = "v2",
.argname = "cipher",
.desc = "Use PKCS#5 v2.0 with given cipher",
.type = OPTION_ARG_FUNC,
.opt.argfunc = pkcs8_opt_v2,
},
{ NULL },
};
static void
pkcs8_usage(void)
{
fprintf(stderr, "usage: pkcs8 [-in file] [inform der | pem] "
"[-nocrypt] [-noiter]\n"
" [-out file] [-outform der | pem] [-passin arg]\n"
" [-passout arg] [-topk8] [-v1 alg] [-v2 alg]\n\n");
options_usage(pkcs8_options);
}
int
pkcs8_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
X509_SIG *p8 = NULL;
PKCS8_PRIV_KEY_INFO *p8inf = NULL;
EVP_PKEY *pkey = NULL;
char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
int ret = 1;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.iter = PKCS12_DEFAULT_ITER;
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
cfg.pbe_nid = -1;
if (options_parse(argc, argv, pkcs8_options, NULL, NULL) != 0) {
pkcs8_usage();
return (1);
}
if (!app_passwd(bio_err, cfg.passargin,
cfg.passargout, &passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
if ((cfg.pbe_nid == -1) && !cfg.cipher)
cfg.pbe_nid = NID_pbeWithMD5AndDES_CBC;
if (cfg.infile) {
if (!(in = BIO_new_file(cfg.infile, "rb"))) {
BIO_printf(bio_err,
"Can't open input file '%s'\n",
cfg.infile);
goto end;
}
} else
in = BIO_new_fp(stdin, BIO_NOCLOSE);
if (cfg.outfile) {
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
BIO_printf(bio_err, "Can't open output file '%s'\n",
cfg.outfile);
goto end;
}
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
if (cfg.topk8) {
pkey = load_key(bio_err, cfg.infile,
cfg.informat, 1, passin, "key");
if (!pkey)
goto end;
if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
BIO_printf(bio_err, "Error converting key\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.nocrypt) {
if (cfg.outformat == FORMAT_PEM)
PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
else if (cfg.outformat == FORMAT_ASN1)
i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
else {
BIO_printf(bio_err,
"Bad format specified for key\n");
goto end;
}
} else {
if (passout)
p8pass = passout;
else {
p8pass = pass;
if (EVP_read_pw_string(pass, sizeof pass,
"Enter Encryption Password:", 1))
goto end;
}
if (!(p8 = PKCS8_encrypt(cfg.pbe_nid,
cfg.cipher, p8pass, strlen(p8pass),
NULL, 0, cfg.iter, p8inf))) {
BIO_printf(bio_err, "Error encrypting key\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outformat == FORMAT_PEM)
PEM_write_bio_PKCS8(out, p8);
else if (cfg.outformat == FORMAT_ASN1)
i2d_PKCS8_bio(out, p8);
else {
BIO_printf(bio_err,
"Bad format specified for key\n");
goto end;
}
}
ret = 0;
goto end;
}
if (cfg.nocrypt) {
if (cfg.informat == FORMAT_PEM)
p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL,
NULL, NULL);
else if (cfg.informat == FORMAT_ASN1)
p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
} else {
if (cfg.informat == FORMAT_PEM)
p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
else if (cfg.informat == FORMAT_ASN1)
p8 = d2i_PKCS8_bio(in, NULL);
else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
if (!p8) {
BIO_printf(bio_err, "Error reading key\n");
ERR_print_errors(bio_err);
goto end;
}
if (passin)
p8pass = passin;
else {
p8pass = pass;
EVP_read_pw_string(pass, sizeof pass,
"Enter Password:", 0);
}
p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
}
if (!p8inf) {
BIO_printf(bio_err, "Error decrypting key\n");
ERR_print_errors(bio_err);
goto end;
}
if (!(pkey = EVP_PKCS82PKEY(p8inf))) {
BIO_printf(bio_err, "Error converting key\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outformat == FORMAT_PEM)
PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL,
passout);
else if (cfg.outformat == FORMAT_ASN1)
i2d_PrivateKey_bio(out, pkey);
else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
ret = 0;
end:
X509_SIG_free(p8);
PKCS8_PRIV_KEY_INFO_free(p8inf);
EVP_PKEY_free(pkey);
BIO_free_all(out);
BIO_free(in);
free(passin);
free(passout);
return ret;
}

309
apps/openssl/pkey.c Normal file
View File

@@ -0,0 +1,309 @@
/* $OpenBSD: pkey.c,v 1.20 2023/07/23 11:39:29 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006
*/
/* ====================================================================
* Copyright (c) 2006 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 <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
static struct {
int check;
const EVP_CIPHER *cipher;
char *infile;
int informat;
int noout;
char *outfile;
int outformat;
char *passargin;
char *passargout;
int pubcheck;
int pubin;
int pubout;
int pubtext;
int text;
} cfg;
static int
pkey_opt_cipher(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.cipher = EVP_get_cipherbyname(name)) == NULL) {
BIO_printf(bio_err, "Unknown cipher %s\n", name);
return (1);
}
*argsused = 1;
return (0);
}
static const struct option pkey_options[] = {
{
.name = "check",
.desc = "Check validity of key",
.type = OPTION_FLAG,
.opt.flag = &cfg.check,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "Do not print encoded version of the key",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "passin",
.argname = "src",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "passout",
.argname = "src",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{
.name = "pubcheck",
.desc = "Check validity of public key",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubcheck,
},
{
.name = "pubin",
.desc = "Expect a public key (default private key)",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.pubin,
},
{
.name = "pubout",
.desc = "Output a public key (default private key)",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.pubout,
},
{
.name = "text",
.desc = "Print the public/private key in plain text",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{
.name = "text_pub",
.desc = "Print out only public key in plain text",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubtext,
},
{
.name = NULL,
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = pkey_opt_cipher,
},
{ NULL }
};
static void
pkey_usage(void)
{
int n = 0;
fprintf(stderr,
"usage: pkey [-check] [-ciphername] [-in file] [-inform fmt] "
"[-noout] [-out file]\n"
" [-outform fmt] [-passin src] [-passout src] [-pubcheck] "
"[-pubin] [-pubout]\n"
" [-text] [-text_pub]\n\n");
options_usage(pkey_options);
fprintf(stderr, "\n");
fprintf(stderr, "Valid ciphername values:\n\n");
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
fprintf(stderr, "\n");
}
int
pkey_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
EVP_PKEY *pkey = NULL;
char *passin = NULL, *passout = NULL;
int ret = 1;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, pkey_options, NULL, NULL) != 0) {
pkey_usage();
goto end;
}
if (cfg.pubtext)
cfg.text = 1;
if (cfg.pubin)
cfg.pubout = cfg.pubtext = 1;
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
&passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
if (cfg.outfile) {
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
BIO_printf(bio_err,
"Can't open output file %s\n", cfg.outfile);
goto end;
}
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
if (cfg.pubin)
pkey = load_pubkey(bio_err, cfg.infile,
cfg.informat, 1, passin, "Public Key");
else
pkey = load_key(bio_err, cfg.infile,
cfg.informat, 1, passin, "key");
if (!pkey)
goto end;
if (cfg.check) {
if (!pkey_check(out, pkey, EVP_PKEY_check, "Key pair"))
goto end;
} else if (cfg.pubcheck) {
if (!pkey_check(out, pkey, EVP_PKEY_public_check, "Public key"))
goto end;
}
if (!cfg.noout) {
if (cfg.outformat == FORMAT_PEM) {
if (cfg.pubout)
PEM_write_bio_PUBKEY(out, pkey);
else
PEM_write_bio_PrivateKey(out, pkey,
cfg.cipher, NULL, 0, NULL, passout);
} else if (cfg.outformat == FORMAT_ASN1) {
if (cfg.pubout)
i2d_PUBKEY_bio(out, pkey);
else
i2d_PrivateKey_bio(out, pkey);
} else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
}
if (cfg.text) {
if (cfg.pubtext)
EVP_PKEY_print_public(out, pkey, 0, NULL);
else
EVP_PKEY_print_private(out, pkey, 0, NULL);
}
ret = 0;
end:
EVP_PKEY_free(pkey);
BIO_free_all(out);
BIO_free(in);
free(passin);
free(passout);
return ret;
}

185
apps/openssl/pkeyparam.c Normal file
View File

@@ -0,0 +1,185 @@
/* $OpenBSD: pkeyparam.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006
*/
/* ====================================================================
* Copyright (c) 2006 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 <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
static struct {
int check;
char *infile;
int noout;
char *outfile;
int text;
} cfg;
static const struct option pkeyparam_options[] = {
{
.name = "check",
.desc = "Check validity of key parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.check,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "noout",
.desc = "Do not print encoded version of the parameters",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "text",
.desc = "Print out the parameters in plain text",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{ NULL },
};
static void
pkeyparam_usage(void)
{
fprintf(stderr,
"usage: pkeyparam [-check] [-in file] [-noout] [-out file] "
"[-text]\n");
options_usage(pkeyparam_options);
}
int
pkeyparam_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
EVP_PKEY *pkey = NULL;
int ret = 1;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, pkeyparam_options, NULL, NULL) != 0) {
pkeyparam_usage();
return (1);
}
if (cfg.infile) {
if (!(in = BIO_new_file(cfg.infile, "r"))) {
BIO_printf(bio_err, "Can't open input file %s\n",
cfg.infile);
goto end;
}
} else
in = BIO_new_fp(stdin, BIO_NOCLOSE);
if (cfg.outfile) {
if (!(out = BIO_new_file(cfg.outfile, "w"))) {
BIO_printf(bio_err, "Can't open output file %s\n",
cfg.outfile);
goto end;
}
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
pkey = PEM_read_bio_Parameters(in, NULL);
if (!pkey) {
BIO_printf(bio_err, "Error reading parameters\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.check) {
if (!pkey_check(out, pkey, EVP_PKEY_param_check, "Parameters"))
goto end;
}
if (!cfg.noout)
PEM_write_bio_Parameters(out, pkey);
if (cfg.text)
EVP_PKEY_print_params(out, pkey, 0, NULL);
ret = 0;
end:
EVP_PKEY_free(pkey);
BIO_free_all(out);
BIO_free(in);
return ret;
}

571
apps/openssl/pkeyutl.c Normal file
View File

@@ -0,0 +1,571 @@
/* $OpenBSD: pkeyutl.c,v 1.20 2023/07/23 11:39:29 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
/* ====================================================================
* Copyright (c) 2006 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 <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#define KEY_PRIVKEY 1
#define KEY_PUBKEY 2
#define KEY_CERT 3
static struct {
int asn1parse;
EVP_PKEY_CTX *ctx;
int hexdump;
char *infile;
int key_type;
int keyform;
int keysize;
char *outfile;
char *passargin;
int peerform;
int pkey_op;
int rev;
char *sigfile;
} cfg;
static void pkeyutl_usage(void);
static int init_ctx(char *keyfile);
static int setup_peer(char *file);
static int pkeyutl_pkeyopt(char *pkeyopt);
static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
unsigned char *out, size_t * poutlen,
unsigned char *in, size_t inlen);
static const struct option pkeyutl_options[] = {
{
.name = "asn1parse",
.desc = "ASN.1 parse the output data",
.type = OPTION_FLAG,
.opt.flag = &cfg.asn1parse,
},
{
.name = "certin",
.desc = "Input is a certificate containing a public key",
.type = OPTION_VALUE,
.value = KEY_CERT,
.opt.value = &cfg.key_type,
},
{
.name = "decrypt",
.desc = "Decrypt the input data using a private key",
.type = OPTION_VALUE,
.value = EVP_PKEY_OP_DECRYPT,
.opt.value = &cfg.pkey_op,
},
{
.name = "derive",
.desc = "Derive a shared secret using the peer key",
.type = OPTION_VALUE,
.value = EVP_PKEY_OP_DERIVE,
.opt.value = &cfg.pkey_op,
},
{
.name = "encrypt",
.desc = "Encrypt the input data using a public key",
.type = OPTION_VALUE,
.value = EVP_PKEY_OP_ENCRYPT,
.opt.value = &cfg.pkey_op,
},
{
.name = "hexdump",
.desc = "Hex dump the output data",
.type = OPTION_FLAG,
.opt.flag = &cfg.hexdump,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inkey",
.argname = "file",
.desc = "Input key file",
.type = OPTION_ARG_FUNC,
.opt.argfunc = init_ctx,
},
{
.name = "keyform",
.argname = "fmt",
.desc = "Input key format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.keyform,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "passin",
.argname = "arg",
.desc = "Key password source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "peerform",
.argname = "fmt",
.desc = "Input key format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.peerform,
},
{
.name = "peerkey",
.argname = "file",
.desc = "Peer key file",
.type = OPTION_ARG_FUNC,
.opt.argfunc = setup_peer,
},
{
.name = "pkeyopt",
.argname = "opt:value",
.desc = "Public key options",
.type = OPTION_ARG_FUNC,
.opt.argfunc = pkeyutl_pkeyopt,
},
{
.name = "pubin",
.desc = "Input is a public key",
.type = OPTION_VALUE,
.value = KEY_PUBKEY,
.opt.value = &cfg.key_type,
},
{
.name = "rev",
.desc = "Reverse the input data",
.type = OPTION_FLAG,
.opt.flag = &cfg.rev,
},
{
.name = "sigfile",
.argname = "file",
.desc = "Signature file (verify operation only)",
.type = OPTION_ARG,
.opt.arg = &cfg.sigfile,
},
{
.name = "sign",
.desc = "Sign the input data using private key",
.type = OPTION_VALUE,
.value = EVP_PKEY_OP_SIGN,
.opt.value = &cfg.pkey_op,
},
{
.name = "verify",
.desc = "Verify the input data using public key",
.type = OPTION_VALUE,
.value = EVP_PKEY_OP_VERIFY,
.opt.value = &cfg.pkey_op,
},
{
.name = "verifyrecover",
.desc = "Verify with public key, recover original data",
.type = OPTION_VALUE,
.value = EVP_PKEY_OP_VERIFYRECOVER,
.opt.value = &cfg.pkey_op,
},
{NULL},
};
static void
pkeyutl_usage(void)
{
fprintf(stderr,
"usage: pkeyutl [-asn1parse] [-certin] [-decrypt] [-derive] "
"[-encrypt]\n"
" [-hexdump] [-in file] [-inkey file] [-keyform fmt]\n"
" [-out file] [-passin arg] [-peerform fmt]\n"
" [-peerkey file] [-pkeyopt opt:value] [-pubin] [-rev]\n"
" [-sigfile file] [-sign] [-verify] [-verifyrecover]\n\n");
options_usage(pkeyutl_options);
fprintf(stderr, "\n");
}
int
pkeyutl_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
size_t buf_outlen = 0;
int buf_inlen = 0, siglen = -1;
int ret = 1, rv = -1;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.pkey_op = EVP_PKEY_OP_SIGN;
cfg.key_type = KEY_PRIVKEY;
cfg.keyform = FORMAT_PEM;
cfg.peerform = FORMAT_PEM;
cfg.keysize = -1;
if (options_parse(argc, argv, pkeyutl_options, NULL, NULL) != 0) {
pkeyutl_usage();
goto end;
}
if (!cfg.ctx) {
pkeyutl_usage();
goto end;
}
if (cfg.sigfile &&
(cfg.pkey_op != EVP_PKEY_OP_VERIFY)) {
BIO_puts(bio_err, "Signature file specified for non verify\n");
goto end;
}
if (!cfg.sigfile &&
(cfg.pkey_op == EVP_PKEY_OP_VERIFY)) {
BIO_puts(bio_err, "No signature file specified for verify\n");
goto end;
}
if (cfg.pkey_op != EVP_PKEY_OP_DERIVE) {
if (cfg.infile) {
if (!(in = BIO_new_file(cfg.infile, "rb"))) {
BIO_puts(bio_err,
"Error Opening Input File\n");
ERR_print_errors(bio_err);
goto end;
}
} else
in = BIO_new_fp(stdin, BIO_NOCLOSE);
}
if (cfg.outfile) {
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
BIO_printf(bio_err, "Error Creating Output File\n");
ERR_print_errors(bio_err);
goto end;
}
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
if (cfg.sigfile) {
BIO *sigbio = BIO_new_file(cfg.sigfile, "rb");
if (!sigbio) {
BIO_printf(bio_err, "Can't open signature file %s\n",
cfg.sigfile);
goto end;
}
siglen = bio_to_mem(&sig, cfg.keysize * 10, sigbio);
BIO_free(sigbio);
if (siglen <= 0) {
BIO_printf(bio_err, "Error reading signature data\n");
goto end;
}
}
if (in) {
/* Read the input data */
buf_inlen = bio_to_mem(&buf_in, cfg.keysize * 10, in);
if (buf_inlen <= 0) {
BIO_printf(bio_err, "Error reading input Data\n");
exit(1);
}
if (cfg.rev) {
size_t i;
unsigned char ctmp;
size_t l = (size_t) buf_inlen;
for (i = 0; i < l / 2; i++) {
ctmp = buf_in[i];
buf_in[i] = buf_in[l - 1 - i];
buf_in[l - 1 - i] = ctmp;
}
}
}
if (cfg.pkey_op == EVP_PKEY_OP_VERIFY) {
rv = EVP_PKEY_verify(cfg.ctx, sig, (size_t) siglen,
buf_in, (size_t) buf_inlen);
if (rv == 1) {
BIO_puts(out, "Signature Verified Successfully\n");
ret = 0;
} else
BIO_puts(out, "Signature Verification Failure\n");
if (rv >= 0)
goto end;
} else {
rv = do_keyop(cfg.ctx, cfg.pkey_op, NULL,
(size_t *)&buf_outlen, buf_in, (size_t) buf_inlen);
if (rv > 0) {
buf_out = malloc(buf_outlen);
if (!buf_out)
rv = -1;
else
rv = do_keyop(cfg.ctx,
cfg.pkey_op,
buf_out, (size_t *) & buf_outlen,
buf_in, (size_t) buf_inlen);
}
}
if (rv <= 0) {
BIO_printf(bio_err, "Public Key operation error\n");
ERR_print_errors(bio_err);
goto end;
}
ret = 0;
if (cfg.asn1parse) {
if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
ERR_print_errors(bio_err);
} else if (cfg.hexdump)
BIO_dump(out, (char *) buf_out, buf_outlen);
else
BIO_write(out, buf_out, buf_outlen);
end:
EVP_PKEY_CTX_free(cfg.ctx);
BIO_free(in);
BIO_free_all(out);
free(buf_in);
free(buf_out);
free(sig);
return ret;
}
static int
init_ctx(char *keyfile)
{
EVP_PKEY *pkey = NULL;
char *passin = NULL;
int rv = -1;
X509 *x;
if (((cfg.pkey_op == EVP_PKEY_OP_SIGN)
|| (cfg.pkey_op == EVP_PKEY_OP_DECRYPT)
|| (cfg.pkey_op == EVP_PKEY_OP_DERIVE))
&& (cfg.key_type != KEY_PRIVKEY)) {
BIO_printf(bio_err,
"A private key is needed for this operation\n");
goto end;
}
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin,
NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
switch (cfg.key_type) {
case KEY_PRIVKEY:
pkey = load_key(bio_err, keyfile, cfg.keyform, 0,
passin, "Private Key");
break;
case KEY_PUBKEY:
pkey = load_pubkey(bio_err, keyfile, cfg.keyform, 0,
NULL, "Public Key");
break;
case KEY_CERT:
x = load_cert(bio_err, keyfile, cfg.keyform,
NULL, "Certificate");
if (x) {
pkey = X509_get_pubkey(x);
X509_free(x);
}
break;
}
cfg.keysize = EVP_PKEY_size(pkey);
if (!pkey)
goto end;
cfg.ctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_free(pkey);
if (!cfg.ctx)
goto end;
switch (cfg.pkey_op) {
case EVP_PKEY_OP_SIGN:
rv = EVP_PKEY_sign_init(cfg.ctx);
break;
case EVP_PKEY_OP_VERIFY:
rv = EVP_PKEY_verify_init(cfg.ctx);
break;
case EVP_PKEY_OP_VERIFYRECOVER:
rv = EVP_PKEY_verify_recover_init(cfg.ctx);
break;
case EVP_PKEY_OP_ENCRYPT:
rv = EVP_PKEY_encrypt_init(cfg.ctx);
break;
case EVP_PKEY_OP_DECRYPT:
rv = EVP_PKEY_decrypt_init(cfg.ctx);
break;
case EVP_PKEY_OP_DERIVE:
rv = EVP_PKEY_derive_init(cfg.ctx);
break;
}
if (rv <= 0) {
EVP_PKEY_CTX_free(cfg.ctx);
cfg.ctx = NULL;
}
end:
free(passin);
if (!cfg.ctx) {
BIO_puts(bio_err, "Error initializing context\n");
ERR_print_errors(bio_err);
return (1);
}
return (0);
}
static int
setup_peer(char *file)
{
EVP_PKEY *peer = NULL;
int ret;
if (!cfg.ctx) {
BIO_puts(bio_err, "-peerkey command before -inkey\n");
return (1);
}
peer = load_pubkey(bio_err, file, cfg.peerform, 0, NULL,
"Peer Key");
if (!peer) {
BIO_printf(bio_err, "Error reading peer key %s\n", file);
ERR_print_errors(bio_err);
return (1);
}
ret = EVP_PKEY_derive_set_peer(cfg.ctx, peer);
EVP_PKEY_free(peer);
if (ret <= 0) {
ERR_print_errors(bio_err);
return (1);
}
return (0);
}
static int
pkeyutl_pkeyopt(char *pkeyopt)
{
if (!cfg.ctx) {
BIO_puts(bio_err, "-pkeyopt command before -inkey\n");
return (1);
} else if (pkey_ctrl_string(cfg.ctx, pkeyopt) <= 0) {
BIO_puts(bio_err, "parameter setting error\n");
ERR_print_errors(bio_err);
return (1);
}
return (0);
}
static int
do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
unsigned char *out, size_t * poutlen,
unsigned char *in, size_t inlen)
{
int rv = 0;
switch (pkey_op) {
case EVP_PKEY_OP_VERIFYRECOVER:
rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
break;
case EVP_PKEY_OP_SIGN:
rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
break;
case EVP_PKEY_OP_ENCRYPT:
rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
break;
case EVP_PKEY_OP_DECRYPT:
rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
break;
case EVP_PKEY_OP_DERIVE:
rv = EVP_PKEY_derive(ctx, out, poutlen);
break;
}
return rv;
}

201
apps/openssl/prime.c Normal file
View File

@@ -0,0 +1,201 @@
/* $OpenBSD: prime.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
/* ====================================================================
* 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
* 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.
*
*/
#include <string.h>
#include <limits.h>
#include "apps.h"
#include <openssl/bn.h>
#include <openssl/err.h>
static struct {
int bits;
int checks;
int generate;
int hex;
int safe;
} cfg;
static const struct option prime_options[] = {
{
.name = "bits",
.argname = "n",
.desc = "Number of bits in the generated prime number",
.type = OPTION_ARG_INT,
.opt.value = &cfg.bits,
},
{
.name = "checks",
.argname = "n",
.desc = "Miller-Rabin probabilistic primality test iterations",
.type = OPTION_ARG_INT,
.opt.value = &cfg.checks,
},
{
.name = "generate",
.desc = "Generate a pseudo-random prime number",
.type = OPTION_FLAG,
.opt.flag = &cfg.generate,
},
{
.name = "hex",
.desc = "Hexadecimal prime numbers",
.type = OPTION_FLAG,
.opt.flag = &cfg.hex,
},
{
.name = "safe",
.desc = "Generate only \"safe\" prime numbers",
.type = OPTION_FLAG,
.opt.flag = &cfg.safe,
},
{NULL},
};
static void
prime_usage(void)
{
fprintf(stderr,
"usage: prime [-bits n] [-checks n] [-generate] [-hex] [-safe] "
"p\n");
options_usage(prime_options);
}
int
prime_main(int argc, char **argv)
{
BIGNUM *bn = NULL;
char *prime = NULL;
BIO *bio_out;
char *s;
int is_prime, ret = 1;
if (pledge("stdio rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
/* Default iterations for Miller-Rabin probabilistic primality test. */
cfg.checks = 20;
if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) {
prime_usage();
return (1);
}
if (prime == NULL && cfg.generate == 0) {
BIO_printf(bio_err, "No prime specified.\n");
prime_usage();
return (1);
}
if ((bio_out = BIO_new(BIO_s_file())) == NULL) {
ERR_print_errors(bio_err);
return (1);
}
BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
if (cfg.generate != 0) {
if (cfg.bits == 0) {
BIO_printf(bio_err, "Specify the number of bits.\n");
goto end;
}
bn = BN_new();
if (!bn) {
BIO_printf(bio_err, "Out of memory.\n");
goto end;
}
if (!BN_generate_prime_ex(bn, cfg.bits,
cfg.safe, NULL, NULL, NULL)) {
BIO_printf(bio_err, "Prime generation error.\n");
goto end;
}
s = cfg.hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
if (s == NULL) {
BIO_printf(bio_err, "Out of memory.\n");
goto end;
}
BIO_printf(bio_out, "%s\n", s);
free(s);
} else {
if (cfg.hex) {
if (!BN_hex2bn(&bn, prime)) {
BIO_printf(bio_err, "%s is an invalid hex "
"value.\n", prime);
goto end;
}
} else {
if (!BN_dec2bn(&bn, prime)) {
BIO_printf(bio_err, "%s is an invalid decimal "
"value.\n", prime);
goto end;
}
}
is_prime = BN_is_prime_ex(bn, cfg.checks, NULL, NULL);
if (is_prime < 0) {
BIO_printf(bio_err, "BN_is_prime_ex failed.\n");
goto end;
}
BIO_printf(bio_out, "%s is %sprime\n", prime,
is_prime == 1 ? "" : "not ");
}
ret = 0;
end:
BN_free(bn);
BIO_free_all(bio_out);
return (ret);
}

48
apps/openssl/progs.h Normal file
View File

@@ -0,0 +1,48 @@
/* $OpenBSD: progs.h,v 1.9 2019/11/04 15:25:54 jsing Exp $ */
/* Public domain */
int asn1parse_main(int argc, char **argv);
int ca_main(int argc, char **argv);
int certhash_main(int argc, char **argv);
int ciphers_main(int argc, char **argv);
int cms_main(int argc, char **argv);
int crl2pkcs7_main(int argc, char **argv);
int crl_main(int argc, char **argv);
int dgst_main(int argc, char **argv);
int dh_main(int argc, char **argv);
int dhparam_main(int argc, char **argv);
int dsa_main(int argc, char **argv);
int dsaparam_main(int argc, char **argv);
int ec_main(int argc, char **argv);
int ecparam_main(int argc, char **argv);
int enc_main(int argc, char **argv);
int errstr_main(int argc, char **argv);
int gendh_main(int argc, char **argv);
int gendsa_main(int argc, char **argv);
int genpkey_main(int argc, char **argv);
int genrsa_main(int argc, char **argv);
int nseq_main(int argc, char **argv);
int ocsp_main(int argc, char **argv);
int passwd_main(int argc, char **argv);
int pkcs7_main(int argc, char **argv);
int pkcs8_main(int argc, char **argv);
int pkcs12_main(int argc, char **argv);
int pkey_main(int argc, char **argv);
int pkeyparam_main(int argc, char **argv);
int pkeyutl_main(int argc, char **argv);
int prime_main(int argc, char **argv);
int rand_main(int argc, char **argv);
int req_main(int argc, char **argv);
int rsa_main(int argc, char **argv);
int rsautl_main(int argc, char **argv);
int s_client_main(int argc, char **argv);
int s_server_main(int argc, char **argv);
int s_time_main(int argc, char **argv);
int sess_id_main(int argc, char **argv);
int smime_main(int argc, char **argv);
int speed_main(int argc, char **argv);
int spkac_main(int argc, char **argv);
int ts_main(int argc, char **argv);
int verify_main(int argc, char **argv);
int version_main(int argc, char **argv);
int x509_main(int argc, char **argv);

182
apps/openssl/rand.c Normal file
View File

@@ -0,0 +1,182 @@
/* $OpenBSD: rand.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
/* ====================================================================
* Copyright (c) 1998-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
* 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).
*
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
static struct {
int base64;
int hex;
char *outfile;
} cfg;
static const struct option rand_options[] = {
{
.name = "base64",
.desc = "Perform base64 encoding on output",
.type = OPTION_FLAG,
.opt.flag = &cfg.base64,
},
{
.name = "hex",
.desc = "Hexadecimal output",
.type = OPTION_FLAG,
.opt.flag = &cfg.hex,
},
{
.name = "out",
.argname = "file",
.desc = "Write to the given file instead of standard output",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{NULL},
};
static void
rand_usage(void)
{
fprintf(stderr,
"usage: rand [-base64 | -hex] [-out file] num\n");
options_usage(rand_options);
}
int
rand_main(int argc, char **argv)
{
char *num_bytes = NULL;
int ret = 1;
int badopt = 0;
int num = -1;
int i, r;
BIO *out = NULL;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, rand_options, &num_bytes, NULL) != 0) {
rand_usage();
return (1);
}
if (num_bytes != NULL) {
r = sscanf(num_bytes, "%d", &num);
if (r == 0 || num < 0)
badopt = 1;
} else
badopt = 1;
if (cfg.hex && cfg.base64)
badopt = 1;
if (badopt) {
rand_usage();
goto err;
}
out = BIO_new(BIO_s_file());
if (out == NULL)
goto err;
if (cfg.outfile != NULL)
r = BIO_write_filename(out, cfg.outfile);
else
r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
if (r <= 0)
goto err;
if (cfg.base64) {
BIO *b64 = BIO_new(BIO_f_base64());
if (b64 == NULL)
goto err;
out = BIO_push(b64, out);
}
while (num > 0) {
unsigned char buf[4096];
int chunk;
chunk = num;
if (chunk > (int) sizeof(buf))
chunk = sizeof(buf);
arc4random_buf(buf, chunk);
if (cfg.hex) {
for (i = 0; i < chunk; i++)
BIO_printf(out, "%02x", buf[i]);
} else
BIO_write(out, buf, chunk);
num -= chunk;
}
if (cfg.hex)
BIO_puts(out, "\n");
(void) BIO_flush(out);
ret = 0;
err:
ERR_print_errors(bio_err);
BIO_free_all(out);
return (ret);
}

1878
apps/openssl/req.c Normal file

File diff suppressed because it is too large Load Diff

411
apps/openssl/rsa.c Normal file
View File

@@ -0,0 +1,411 @@
/* $OpenBSD: rsa.c,v 1.19 2023/07/23 11:39:29 tb Exp $ */
/* 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 <openssl/opensslconf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
static struct {
int check;
const EVP_CIPHER *enc;
char *infile;
int informat;
int modulus;
int noout;
char *outfile;
int outformat;
char *passargin;
char *passargout;
int pubin;
int pubout;
int pvk_encr;
int text;
} cfg;
static int
rsa_opt_cipher(int argc, char **argv, int *argsused)
{
char *name = argv[0];
if (*name++ != '-')
return (1);
if ((cfg.enc = EVP_get_cipherbyname(name)) == NULL) {
fprintf(stderr, "Invalid cipher '%s'\n", name);
return (1);
}
*argsused = 1;
return (0);
}
static const struct option rsa_options[] = {
{
.name = "check",
.desc = "Check consistency of RSA private key",
.type = OPTION_FLAG,
.opt.flag = &cfg.check,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER, NET or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "modulus",
.desc = "Print the RSA key modulus",
.type = OPTION_FLAG,
.opt.flag = &cfg.modulus,
},
{
.name = "noout",
.desc = "Do not print encoded version of the key",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER, NET or PEM (default PEM))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "passin",
.argname = "src",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "passout",
.argname = "src",
.desc = "Output file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargout,
},
{
.name = "pubin",
.desc = "Expect a public key (default private key)",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.pubin,
},
{
.name = "pubout",
.desc = "Output a public key (default private key)",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.pubout,
},
{
.name = "pvk-none",
.type = OPTION_VALUE,
.value = 0,
.opt.value = &cfg.pvk_encr,
},
{
.name = "pvk-strong",
.type = OPTION_VALUE,
.value = 2,
.opt.value = &cfg.pvk_encr,
},
{
.name = "pvk-weak",
.type = OPTION_VALUE,
.value = 1,
.opt.value = &cfg.pvk_encr,
},
{
.name = "RSAPublicKey_in",
.type = OPTION_VALUE,
.value = 2,
.opt.value = &cfg.pubin,
},
{
.name = "RSAPublicKey_out",
.type = OPTION_VALUE,
.value = 2,
.opt.value = &cfg.pubout,
},
{
.name = "text",
.desc = "Print in plain text in addition to encoded",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{
.name = NULL,
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = rsa_opt_cipher,
},
{ NULL }
};
static void
rsa_usage(void)
{
int n = 0;
fprintf(stderr,
"usage: rsa [-ciphername] [-check] [-in file] "
"[-inform fmt]\n"
" [-modulus] [-noout] [-out file] [-outform fmt] "
"[-passin src]\n"
" [-passout src] [-pubin] [-pubout] [-text]\n\n");
options_usage(rsa_options);
fprintf(stderr, "\n");
fprintf(stderr, "Valid ciphername values:\n\n");
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
fprintf(stderr, "\n");
}
int
rsa_main(int argc, char **argv)
{
int ret = 1;
RSA *rsa = NULL;
int i;
BIO *out = NULL;
char *passin = NULL, *passout = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.pvk_encr = 2;
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) {
rsa_usage();
goto end;
}
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
&passin, &passout)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
if (cfg.check && cfg.pubin) {
BIO_printf(bio_err, "Only private keys can be checked\n");
goto end;
}
out = BIO_new(BIO_s_file());
{
EVP_PKEY *pkey;
if (cfg.pubin) {
int tmpformat = -1;
if (cfg.pubin == 2) {
if (cfg.informat == FORMAT_PEM)
tmpformat = FORMAT_PEMRSA;
else if (cfg.informat == FORMAT_ASN1)
tmpformat = FORMAT_ASN1RSA;
} else
tmpformat = cfg.informat;
pkey = load_pubkey(bio_err, cfg.infile,
tmpformat, 1, passin, "Public Key");
} else
pkey = load_key(bio_err, cfg.infile,
cfg.informat, 1, passin, "Private Key");
if (pkey != NULL)
rsa = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
}
if (rsa == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile) <= 0) {
perror(cfg.outfile);
goto end;
}
}
if (cfg.text)
if (!RSA_print(out, rsa, 0)) {
perror(cfg.outfile);
ERR_print_errors(bio_err);
goto end;
}
if (cfg.modulus) {
BIO_printf(out, "Modulus=");
BN_print(out, RSA_get0_n(rsa));
BIO_printf(out, "\n");
}
if (cfg.check) {
int r = RSA_check_key(rsa);
if (r == 1)
BIO_printf(out, "RSA key ok\n");
else if (r == 0) {
unsigned long err;
while ((err = ERR_peek_error()) != 0 &&
ERR_GET_LIB(err) == ERR_LIB_RSA &&
ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
BIO_printf(out, "RSA key error: %s\n",
ERR_reason_error_string(err));
ERR_get_error(); /* remove e from error
* stack */
}
}
if (r == -1 || ERR_peek_error() != 0) { /* should happen only if
* r == -1 */
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.noout) {
ret = 0;
goto end;
}
BIO_printf(bio_err, "writing RSA key\n");
if (cfg.outformat == FORMAT_ASN1) {
if (cfg.pubout || cfg.pubin) {
if (cfg.pubout == 2)
i = i2d_RSAPublicKey_bio(out, rsa);
else
i = i2d_RSA_PUBKEY_bio(out, rsa);
} else
i = i2d_RSAPrivateKey_bio(out, rsa);
} else if (cfg.outformat == FORMAT_PEM) {
if (cfg.pubout || cfg.pubin) {
if (cfg.pubout == 2)
i = PEM_write_bio_RSAPublicKey(out, rsa);
else
i = PEM_write_bio_RSA_PUBKEY(out, rsa);
} else
i = PEM_write_bio_RSAPrivateKey(out, rsa,
cfg.enc, NULL, 0, NULL, passout);
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
} else if (cfg.outformat == FORMAT_MSBLOB ||
cfg.outformat == FORMAT_PVK) {
EVP_PKEY *pk;
pk = EVP_PKEY_new();
EVP_PKEY_set1_RSA(pk, rsa);
if (cfg.outformat == FORMAT_PVK)
i = i2b_PVK_bio(out, pk, cfg.pvk_encr, 0,
passout);
else if (cfg.pubin || cfg.pubout)
i = i2b_PublicKey_bio(out, pk);
else
i = i2b_PrivateKey_bio(out, pk);
EVP_PKEY_free(pk);
#endif
} else {
BIO_printf(bio_err,
"bad output format specified for outfile\n");
goto end;
}
if (i <= 0) {
BIO_printf(bio_err, "unable to write key\n");
ERR_print_errors(bio_err);
} else
ret = 0;
end:
BIO_free_all(out);
RSA_free(rsa);
free(passin);
free(passout);
return (ret);
}

402
apps/openssl/rsautl.c Normal file
View File

@@ -0,0 +1,402 @@
/* $OpenBSD: rsautl.c,v 1.24 2023/07/23 11:39:29 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000 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 <openssl/opensslconf.h>
#include <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#define RSA_SIGN 1
#define RSA_VERIFY 2
#define RSA_ENCRYPT 3
#define RSA_DECRYPT 4
#define KEY_PRIVKEY 1
#define KEY_PUBKEY 2
#define KEY_CERT 3
static struct {
int asn1parse;
int hexdump;
char *infile;
char *keyfile;
int keyform;
int key_type;
char *outfile;
int pad;
char *passargin;
int rev;
int rsa_mode;
} cfg;
static const struct option rsautl_options[] = {
{
.name = "asn1parse",
.desc = "ASN.1 parse the output data",
.type = OPTION_FLAG,
.opt.flag = &cfg.asn1parse,
},
{
.name = "certin",
.desc = "Input is a certificate containing an RSA public key",
.type = OPTION_VALUE,
.value = KEY_CERT,
.opt.value = &cfg.key_type,
},
{
.name = "decrypt",
.desc = "Decrypt the input data using RSA private key",
.type = OPTION_VALUE,
.value = RSA_DECRYPT,
.opt.value = &cfg.rsa_mode,
},
{
.name = "encrypt",
.desc = "Encrypt the input data using RSA public key",
.type = OPTION_VALUE,
.value = RSA_ENCRYPT,
.opt.value = &cfg.rsa_mode,
},
{
.name = "hexdump",
.desc = "Hex dump the output data",
.type = OPTION_FLAG,
.opt.flag = &cfg.hexdump,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inkey",
.argname = "file",
.desc = "Input key file",
.type = OPTION_ARG,
.opt.arg = &cfg.keyfile,
},
{
.name = "keyform",
.argname = "fmt",
.desc = "Input key format (DER, TXT or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.keyform,
},
{
.name = "oaep",
.desc = "Use PKCS#1 OAEP padding",
.type = OPTION_VALUE,
.value = RSA_PKCS1_OAEP_PADDING,
.opt.value = &cfg.pad,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "passin",
.argname = "arg",
.desc = "Key password source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "pkcs",
.desc = "Use PKCS#1 v1.5 padding (default)",
.type = OPTION_VALUE,
.value = RSA_PKCS1_PADDING,
.opt.value = &cfg.pad,
},
{
.name = "pubin",
.desc = "Input is an RSA public key",
.type = OPTION_VALUE,
.value = KEY_PUBKEY,
.opt.value = &cfg.key_type,
},
{
.name = "raw",
.desc = "Use no padding",
.type = OPTION_VALUE,
.value = RSA_NO_PADDING,
.opt.value = &cfg.pad,
},
{
.name = "rev",
.desc = "Reverse the input data",
.type = OPTION_FLAG,
.opt.flag = &cfg.rev,
},
{
.name = "sign",
.desc = "Sign the input data using RSA private key",
.type = OPTION_VALUE,
.value = RSA_SIGN,
.opt.value = &cfg.rsa_mode,
},
{
.name = "verify",
.desc = "Verify the input data using RSA public key",
.type = OPTION_VALUE,
.value = RSA_VERIFY,
.opt.value = &cfg.rsa_mode,
},
{
.name = "x931",
.desc = "Use ANSI X9.31 padding",
.type = OPTION_VALUE,
.value = RSA_X931_PADDING,
.opt.value = &cfg.pad,
},
{NULL},
};
static void
rsautl_usage(void)
{
fprintf(stderr,
"usage: rsautl [-asn1parse] [-certin] [-decrypt] [-encrypt] "
"[-hexdump]\n"
" [-in file] [-inkey file] [-keyform der | pem]\n"
" [-oaep | -pkcs | -raw | -x931] [-out file] [-passin arg]\n"
" [-pubin] [-rev] [-sign] [-verify]\n\n");
options_usage(rsautl_options);
}
int
rsautl_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
X509 *x;
EVP_PKEY *pkey = NULL;
RSA *rsa = NULL;
unsigned char *rsa_in = NULL, *rsa_out = NULL;
char *passin = NULL;
int rsa_inlen, rsa_outlen = 0;
int need_priv = 0;
int keysize;
int ret = 1;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.keyform = FORMAT_PEM;
cfg.key_type = KEY_PRIVKEY;
cfg.pad = RSA_PKCS1_PADDING;
cfg.rsa_mode = RSA_VERIFY;
if (options_parse(argc, argv, rsautl_options, NULL, NULL) != 0) {
rsautl_usage();
return (1);
}
if (cfg.rsa_mode == RSA_SIGN ||
cfg.rsa_mode == RSA_DECRYPT)
need_priv = 1;
if (need_priv && cfg.key_type != KEY_PRIVKEY) {
BIO_printf(bio_err, "A private key is needed for this operation\n");
goto end;
}
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
switch (cfg.key_type) {
case KEY_PRIVKEY:
pkey = load_key(bio_err, cfg.keyfile,
cfg.keyform, 0, passin, "Private Key");
break;
case KEY_PUBKEY:
pkey = load_pubkey(bio_err, cfg.keyfile,
cfg.keyform, 0, NULL, "Public Key");
break;
case KEY_CERT:
x = load_cert(bio_err, cfg.keyfile,
cfg.keyform, NULL, "Certificate");
if (x) {
pkey = X509_get_pubkey(x);
X509_free(x);
}
break;
}
if (!pkey)
goto end;
rsa = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if (!rsa) {
BIO_printf(bio_err, "Error getting RSA key\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.infile) {
if (!(in = BIO_new_file(cfg.infile, "rb"))) {
BIO_printf(bio_err, "Error Reading Input File\n");
ERR_print_errors(bio_err);
goto end;
}
} else
in = BIO_new_fp(stdin, BIO_NOCLOSE);
if (cfg.outfile) {
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
BIO_printf(bio_err, "Error Reading Output File\n");
ERR_print_errors(bio_err);
goto end;
}
} else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
keysize = RSA_size(rsa);
rsa_in = reallocarray(NULL, keysize, 2);
if (rsa_in == NULL) {
BIO_printf(bio_err, "Error allocating memory for input data\n");
exit(1);
}
rsa_out = malloc(keysize);
if (rsa_out == NULL) {
BIO_printf(bio_err, "Error allocating memory for output data\n");
exit(1);
}
/* Read the input data */
rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
if (rsa_inlen <= 0) {
BIO_printf(bio_err, "Error reading input Data\n");
exit(1);
}
if (cfg.rev) {
int i;
unsigned char ctmp;
for (i = 0; i < rsa_inlen / 2; i++) {
ctmp = rsa_in[i];
rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
rsa_in[rsa_inlen - 1 - i] = ctmp;
}
}
switch (cfg.rsa_mode) {
case RSA_VERIFY:
rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out,
rsa, cfg.pad);
break;
case RSA_SIGN:
rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out,
rsa, cfg.pad);
break;
case RSA_ENCRYPT:
rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out,
rsa, cfg.pad);
break;
case RSA_DECRYPT:
rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out,
rsa, cfg.pad);
break;
}
if (rsa_outlen <= 0) {
BIO_printf(bio_err, "RSA operation error\n");
ERR_print_errors(bio_err);
goto end;
}
ret = 0;
if (cfg.asn1parse) {
if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
ERR_print_errors(bio_err);
}
} else if (cfg.hexdump)
BIO_dump(out, (char *) rsa_out, rsa_outlen);
else
BIO_write(out, rsa_out, rsa_outlen);
end:
RSA_free(rsa);
BIO_free(in);
BIO_free_all(out);
free(rsa_in);
free(rsa_out);
free(passin);
return ret;
}

151
apps/openssl/s_apps.h Normal file
View File

@@ -0,0 +1,151 @@
/* $OpenBSD: s_apps.h,v 1.7 2021/12/06 11:06:58 tb Exp $ */
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-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
* 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).
*
*/
#include <sys/types.h>
#include <openssl/opensslconf.h>
#define PORT 4433
#define PORT_STR "4433"
#define PROTOCOL "tcp"
extern int verify_depth;
extern int verify_return_error;
int do_server(int port, int type, int *ret,
int (*cb)(int s, unsigned char *context),
unsigned char *context, int naccept);
#ifdef HEADER_X509_H
int verify_callback(int ok, X509_STORE_CTX *ctx);
#endif
#ifdef HEADER_SSL_H
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
#endif
int ssl_print_tmp_key(BIO *out, SSL *s);
int init_client(int *sock, char *server, char *port, int type, int af);
int should_retry(int i);
int extract_port(char *str, short *port_ptr);
int extract_host_port(char *str, char **host_ptr, unsigned char *ip, char **p);
long bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi,
long argl, long ret);
#ifdef HEADER_SSL_H
void apps_ssl_info_callback(const SSL *s, int where, int ret);
void msg_cb(int write_p, int version, int content_type, const void *buf,
size_t len, SSL *ssl, void *arg);
void tlsext_cb(SSL *s, int client_server, int type, unsigned char *data,
int len, void *arg);
#endif
int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
unsigned int *cookie_len);
int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
unsigned int cookie_len);

932
apps/openssl/s_cb.c Normal file
View File

@@ -0,0 +1,932 @@
/* $OpenBSD: s_cb.c,v 1.21 2023/04/14 15:27:13 tb Exp $ */
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 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).
*
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "s_apps.h"
#define COOKIE_SECRET_LENGTH 16
int verify_depth = 0;
int verify_return_error = 0;
unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
int cookie_initialized = 0;
int
verify_callback(int ok, X509_STORE_CTX * ctx)
{
X509 *err_cert;
int err, depth;
err_cert = X509_STORE_CTX_get_current_cert(ctx);
err = X509_STORE_CTX_get_error(ctx);
depth = X509_STORE_CTX_get_error_depth(ctx);
BIO_printf(bio_err, "depth=%d ", depth);
if (err_cert) {
X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
0, XN_FLAG_ONELINE);
BIO_puts(bio_err, "\n");
} else
BIO_puts(bio_err, "<no cert>\n");
if (!ok) {
BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
X509_verify_cert_error_string(err));
if (verify_depth >= depth) {
if (!verify_return_error)
ok = 1;
} else {
ok = 0;
}
}
switch (err) {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
BIO_puts(bio_err, "issuer= ");
if (err_cert == NULL)
BIO_puts(bio_err, "<error getting cert>");
else
X509_NAME_print_ex(bio_err,
X509_get_issuer_name(err_cert), 0, XN_FLAG_ONELINE);
BIO_puts(bio_err, "\n");
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
BIO_printf(bio_err, "notBefore=");
if (err_cert == NULL)
BIO_printf(bio_err, " <error getting cert>");
else
ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert));
BIO_printf(bio_err, "\n");
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
BIO_printf(bio_err, "notAfter=");
if (err_cert == NULL)
BIO_printf(bio_err, " <error getting cert>");
else
ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert));
BIO_printf(bio_err, "\n");
break;
case X509_V_ERR_NO_EXPLICIT_POLICY:
break;
}
BIO_printf(bio_err, "verify return:%d\n", ok);
return (ok);
}
int
set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
{
if (cert_file == NULL)
return 1;
if (key_file == NULL)
key_file = cert_file;
if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) {
BIO_printf(bio_err,
"unable to get certificate from '%s'\n", cert_file);
ERR_print_errors(bio_err);
return 0;
}
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
BIO_printf(bio_err, "unable to get private key from '%s'\n",
key_file);
ERR_print_errors(bio_err);
return 0;
}
/* Now we know that a key and cert have been set against the context. */
if (!SSL_CTX_check_private_key(ctx)) {
BIO_printf(bio_err,
"Private key does not match the certificate public key\n");
return 0;
}
return 1;
}
int
set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key)
{
if (cert == NULL)
return 1;
if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
BIO_printf(bio_err, "error setting certificate\n");
ERR_print_errors(bio_err);
return 0;
}
if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) {
BIO_printf(bio_err, "error setting private key\n");
ERR_print_errors(bio_err);
return 0;
}
/*
* Now we know that a key and cert have been set against the SSL
* context
*/
if (!SSL_CTX_check_private_key(ctx)) {
BIO_printf(bio_err,
"Private key does not match the certificate public key\n");
return 0;
}
return 1;
}
int
ssl_print_tmp_key(BIO *out, SSL *s)
{
const char *cname;
EVP_PKEY *pkey;
EC_KEY *ec;
const EC_GROUP *group;
int nid;
if (!SSL_get_server_tmp_key(s, &pkey))
return 0;
BIO_puts(out, "Server Temp Key: ");
switch (EVP_PKEY_id(pkey)) {
case EVP_PKEY_DH:
BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(pkey));
break;
case EVP_PKEY_EC:
if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
goto err;
if ((group = EC_KEY_get0_group(ec)) == NULL)
goto err;
nid = EC_GROUP_get_curve_name(group);
if ((cname = EC_curve_nid2nist(nid)) == NULL)
cname = OBJ_nid2sn(nid);
BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(pkey));
break;
default:
BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(pkey)),
EVP_PKEY_bits(pkey));
}
err:
EVP_PKEY_free(pkey);
return 1;
}
long
bio_dump_callback(BIO * bio, int cmd, const char *argp,
int argi, long argl, long ret)
{
BIO *out;
out = (BIO *) BIO_get_callback_arg(bio);
if (out == NULL)
return (ret);
if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
BIO_printf(out,
"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
(void *) bio, argp, (unsigned long) argi, ret, ret);
BIO_dump(out, argp, (int) ret);
return (ret);
} else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
BIO_printf(out,
"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
(void *) bio, argp, (unsigned long) argi, ret, ret);
BIO_dump(out, argp, (int) ret);
}
return (ret);
}
void
apps_ssl_info_callback(const SSL * s, int where, int ret)
{
const char *str;
int w;
w = where & ~SSL_ST_MASK;
if (w & SSL_ST_CONNECT)
str = "SSL_connect";
else if (w & SSL_ST_ACCEPT)
str = "SSL_accept";
else
str = "undefined";
if (where & SSL_CB_LOOP) {
BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s));
} else if (where & SSL_CB_ALERT) {
str = (where & SSL_CB_READ) ? "read" : "write";
BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str,
SSL_alert_type_string_long(ret),
SSL_alert_desc_string_long(ret));
} else if (where & SSL_CB_EXIT) {
if (ret == 0)
BIO_printf(bio_err, "%s:failed in %s\n",
str, SSL_state_string_long(s));
else if (ret < 0) {
BIO_printf(bio_err, "%s:error in %s\n",
str, SSL_state_string_long(s));
}
}
}
void
msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg)
{
BIO *bio = arg;
const char *str_write_p, *str_version, *str_content_type = "",
*str_details1 = "", *str_details2 = "";
str_write_p = write_p ? ">>>" : "<<<";
/* XXX convert to using ssl_get_version */
switch (version) {
case SSL2_VERSION:
str_version = "SSL 2.0";
break;
case SSL3_VERSION:
str_version = "SSL 3.0 ";
break;
case TLS1_VERSION:
str_version = "TLS 1.0 ";
break;
case TLS1_1_VERSION:
str_version = "TLS 1.1 ";
break;
case TLS1_2_VERSION:
str_version = "TLS 1.2 ";
break;
case TLS1_3_VERSION:
str_version = "TLS 1.3 ";
break;
case DTLS1_VERSION:
str_version = "DTLS 1.0 ";
break;
case DTLS1_2_VERSION:
str_version = "DTLS 1.2 ";
break;
default:
str_version = "???";
}
if (version == SSL2_VERSION) {
str_details1 = "???";
if (len > 0) {
/* XXX magic numbers */
switch (((const unsigned char *) buf)[0]) {
case 0:
str_details1 = ", ERROR:";
str_details2 = " ???";
if (len >= 3) {
unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2];
switch (err) {
case 0x0001:
str_details2 = " NO-CIPHER-ERROR";
break;
case 0x0002:
str_details2 = " NO-CERTIFICATE-ERROR";
break;
case 0x0004:
str_details2 = " BAD-CERTIFICATE-ERROR";
break;
case 0x0006:
str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
break;
}
}
break;
case 1:
str_details1 = ", CLIENT-HELLO";
break;
case 2:
str_details1 = ", CLIENT-MASTER-KEY";
break;
case 3:
str_details1 = ", CLIENT-FINISHED";
break;
case 4:
str_details1 = ", SERVER-HELLO";
break;
case 5:
str_details1 = ", SERVER-VERIFY";
break;
case 6:
str_details1 = ", SERVER-FINISHED";
break;
case 7:
str_details1 = ", REQUEST-CERTIFICATE";
break;
case 8:
str_details1 = ", CLIENT-CERTIFICATE";
break;
}
}
}
if (version == SSL3_VERSION || version == TLS1_VERSION ||
version == TLS1_1_VERSION || version == TLS1_2_VERSION ||
version == TLS1_3_VERSION || version == DTLS1_VERSION ||
version == DTLS1_2_VERSION) {
/* XXX magic numbers are in ssl3.h */
switch (content_type) {
case 20:
str_content_type = "ChangeCipherSpec";
break;
case 21:
str_content_type = "Alert";
break;
case 22:
str_content_type = "Handshake";
break;
}
if (content_type == 21) { /* Alert */
str_details1 = ", ???";
if (len == 2) {
switch (((const unsigned char *) buf)[0]) {
case 1:
str_details1 = ", warning";
break;
case 2:
str_details1 = ", fatal";
break;
}
str_details2 = " ???";
switch (((const unsigned char *) buf)[1]) {
case 0:
str_details2 = " close_notify";
break;
case 10:
str_details2 = " unexpected_message";
break;
case 20:
str_details2 = " bad_record_mac";
break;
case 21:
str_details2 = " decryption_failed";
break;
case 22:
str_details2 = " record_overflow";
break;
case 30:
str_details2 = " decompression_failure";
break;
case 40:
str_details2 = " handshake_failure";
break;
case 42:
str_details2 = " bad_certificate";
break;
case 43:
str_details2 = " unsupported_certificate";
break;
case 44:
str_details2 = " certificate_revoked";
break;
case 45:
str_details2 = " certificate_expired";
break;
case 46:
str_details2 = " certificate_unknown";
break;
case 47:
str_details2 = " illegal_parameter";
break;
case 48:
str_details2 = " unknown_ca";
break;
case 49:
str_details2 = " access_denied";
break;
case 50:
str_details2 = " decode_error";
break;
case 51:
str_details2 = " decrypt_error";
break;
case 60:
str_details2 = " export_restriction";
break;
case 70:
str_details2 = " protocol_version";
break;
case 71:
str_details2 = " insufficient_security";
break;
case 80:
str_details2 = " internal_error";
break;
case 90:
str_details2 = " user_canceled";
break;
case 100:
str_details2 = " no_renegotiation";
break;
case 110:
str_details2 = " unsupported_extension";
break;
case 111:
str_details2 = " certificate_unobtainable";
break;
case 112:
str_details2 = " unrecognized_name";
break;
case 113:
str_details2 = " bad_certificate_status_response";
break;
case 114:
str_details2 = " bad_certificate_hash_value";
break;
case 115:
str_details2 = " unknown_psk_identity";
break;
}
}
}
if (content_type == 22) { /* Handshake */
str_details1 = "???";
if (len > 0) {
switch (((const unsigned char *) buf)[0]) {
case 0:
str_details1 = ", HelloRequest";
break;
case 1:
str_details1 = ", ClientHello";
break;
case 2:
str_details1 = ", ServerHello";
break;
case 3:
str_details1 = ", HelloVerifyRequest";
break;
case 4:
str_details1 = ", NewSessionTicket";
break;
case 5:
str_details1 = ", EndOfEarlyData";
break;
case 8:
str_details1 = ", EncryptedExtensions";
break;
case 11:
str_details1 = ", Certificate";
break;
case 12:
str_details1 = ", ServerKeyExchange";
break;
case 13:
str_details1 = ", CertificateRequest";
break;
case 14:
str_details1 = ", ServerHelloDone";
break;
case 15:
str_details1 = ", CertificateVerify";
break;
case 16:
str_details1 = ", ClientKeyExchange";
break;
case 20:
str_details1 = ", Finished";
break;
case 24:
str_details1 = ", KeyUpdate";
break;
}
}
}
}
BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p,
str_version, str_content_type, (unsigned long) len,
str_details1, str_details2);
if (len > 0) {
size_t num, i;
BIO_printf(bio, " ");
num = len;
for (i = 0; i < num; i++) {
if (i % 16 == 0 && i > 0)
BIO_printf(bio, "\n ");
BIO_printf(bio, " %02x",
((const unsigned char *) buf)[i]);
}
if (i < len)
BIO_printf(bio, " ...");
BIO_printf(bio, "\n");
}
(void) BIO_flush(bio);
}
void
tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len,
void *arg)
{
BIO *bio = arg;
char *extname;
switch (type) {
case TLSEXT_TYPE_server_name:
extname = "server name";
break;
case TLSEXT_TYPE_max_fragment_length:
extname = "max fragment length";
break;
case TLSEXT_TYPE_client_certificate_url:
extname = "client certificate URL";
break;
case TLSEXT_TYPE_trusted_ca_keys:
extname = "trusted CA keys";
break;
case TLSEXT_TYPE_truncated_hmac:
extname = "truncated HMAC";
break;
case TLSEXT_TYPE_status_request:
extname = "status request";
break;
case TLSEXT_TYPE_user_mapping:
extname = "user mapping";
break;
case TLSEXT_TYPE_client_authz:
extname = "client authz";
break;
case TLSEXT_TYPE_server_authz:
extname = "server authz";
break;
case TLSEXT_TYPE_cert_type:
extname = "cert type";
break;
case TLSEXT_TYPE_supported_groups:
extname = "supported groups";
break;
case TLSEXT_TYPE_ec_point_formats:
extname = "EC point formats";
break;
case TLSEXT_TYPE_srp:
extname = "SRP";
break;
case TLSEXT_TYPE_signature_algorithms:
extname = "signature algorithms";
break;
case TLSEXT_TYPE_use_srtp:
extname = "use SRTP";
break;
case TLSEXT_TYPE_heartbeat:
extname = "heartbeat";
break;
case TLSEXT_TYPE_application_layer_protocol_negotiation:
extname = "application layer protocol negotiation";
break;
case TLSEXT_TYPE_padding:
extname = "TLS padding";
break;
case TLSEXT_TYPE_session_ticket:
extname = "session ticket";
break;
#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL)
case TLSEXT_TYPE_pre_shared_key:
extname = "pre shared key";
break;
case TLSEXT_TYPE_early_data:
extname = "early data";
break;
case TLSEXT_TYPE_supported_versions:
extname = "supported versions";
break;
case TLSEXT_TYPE_cookie:
extname = "cookie";
break;
case TLSEXT_TYPE_psk_key_exchange_modes:
extname = "PSK key exchange modes";
break;
case TLSEXT_TYPE_certificate_authorities:
extname = "certificate authorities";
break;
case TLSEXT_TYPE_oid_filters:
extname = "OID filters";
break;
case TLSEXT_TYPE_post_handshake_auth:
extname = "post handshake auth";
break;
case TLSEXT_TYPE_signature_algorithms_cert:
extname = "signature algorithms cert";
break;
case TLSEXT_TYPE_key_share:
extname = "key share";
break;
#endif
case TLSEXT_TYPE_renegotiate:
extname = "renegotiation info";
break;
default:
extname = "unknown";
break;
}
BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
client_server ? "server" : "client", extname, type, len);
BIO_dump(bio, (char *) data, len);
(void) BIO_flush(bio);
}
int
generate_cookie_callback(SSL * ssl, unsigned char *cookie,
unsigned int *cookie_len)
{
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length, resultlength;
union {
struct sockaddr sa;
struct sockaddr_in s4;
struct sockaddr_in6 s6;
} peer;
/* Initialize a random secret */
if (!cookie_initialized) {
arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH);
cookie_initialized = 1;
}
/* Read peer information */
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */
length = 0;
switch (peer.sa.sa_family) {
case AF_INET:
length += sizeof(struct in_addr);
length += sizeof(peer.s4.sin_port);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
length += sizeof(peer.s6.sin6_port);
break;
default:
OPENSSL_assert(0);
break;
}
buffer = malloc(length);
if (buffer == NULL) {
BIO_printf(bio_err, "out of memory\n");
return 0;
}
switch (peer.sa.sa_family) {
case AF_INET:
memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
memcpy(buffer + sizeof(peer.s4.sin_port),
&peer.s4.sin_addr, sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
memcpy(buffer + sizeof(peer.s6.sin6_port),
&peer.s6.sin6_addr, sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
/* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
buffer, length, result, &resultlength);
free(buffer);
memcpy(cookie, result, resultlength);
*cookie_len = resultlength;
return 1;
}
int
verify_cookie_callback(SSL * ssl, const unsigned char *cookie,
unsigned int cookie_len)
{
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length, resultlength;
union {
struct sockaddr sa;
struct sockaddr_in s4;
struct sockaddr_in6 s6;
} peer;
/* If secret isn't initialized yet, the cookie can't be valid */
if (!cookie_initialized)
return 0;
/* Read peer information */
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
/* Create buffer with peer's address and port */
length = 0;
switch (peer.sa.sa_family) {
case AF_INET:
length += sizeof(struct in_addr);
length += sizeof(peer.s4.sin_port);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
length += sizeof(peer.s6.sin6_port);
break;
default:
OPENSSL_assert(0);
break;
}
buffer = malloc(length);
if (buffer == NULL) {
BIO_printf(bio_err, "out of memory\n");
return 0;
}
switch (peer.sa.sa_family) {
case AF_INET:
memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
memcpy(buffer + sizeof(peer.s4.sin_port),
&peer.s4.sin_addr, sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
memcpy(buffer + sizeof(peer.s6.sin6_port),
&peer.s6.sin6_addr, sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
/* Calculate HMAC of buffer using the secret */
if (HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
buffer, length, result, &resultlength) == NULL) {
free(buffer);
return 0;
}
free(buffer);
if (cookie_len == resultlength &&
memcmp(result, cookie, resultlength) == 0)
return 1;
return 0;
}

1836
apps/openssl/s_client.c Normal file

File diff suppressed because it is too large Load Diff

2420
apps/openssl/s_server.c Normal file

File diff suppressed because it is too large Load Diff

327
apps/openssl/s_socket.c Normal file
View File

@@ -0,0 +1,327 @@
/* $OpenBSD: s_socket.c,v 1.13 2021/12/06 11:06:58 tb Exp $ */
/* 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 <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "apps.h"
#include <openssl/ssl.h>
#include "s_apps.h"
static int init_server(int *sock, int port, int type);
static int init_server_long(int *sock, int port, char *ip, int type);
static int do_accept(int acc_sock, int *sock);
int
init_client(int *sock, char *host, char *port, int type, int af)
{
struct addrinfo hints, *ai_top, *ai;
int i, s = -1;
memset(&hints, '\0', sizeof(hints));
hints.ai_family = af;
hints.ai_socktype = type;
if ((i = getaddrinfo(host, port, &hints, &ai_top)) != 0) {
BIO_printf(bio_err, "getaddrinfo: %s\n", gai_strerror(i));
return (0);
}
if (ai_top == NULL || ai_top->ai_addr == NULL) {
BIO_printf(bio_err, "getaddrinfo returned no addresses\n");
if (ai_top != NULL) {
freeaddrinfo(ai_top);
}
return (0);
}
for (ai = ai_top; ai != NULL; ai = ai->ai_next) {
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (s == -1) {
continue;
}
if (type == SOCK_STREAM) {
i = 0;
i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
(char *) &i, sizeof(i));
if (i == -1) {
perror("keepalive");
goto out;
}
}
if ((i = connect(s, ai->ai_addr, ai->ai_addrlen)) == 0) {
*sock = s;
freeaddrinfo(ai_top);
return (1);
}
close(s);
s = -1;
}
perror("connect");
out:
if (s != -1)
close(s);
freeaddrinfo(ai_top);
return (0);
}
int
do_server(int port, int type, int *ret,
int (*cb)(int s, unsigned char *context),
unsigned char *context, int naccept)
{
int sock;
int accept_socket = 0;
int i;
if (!init_server(&accept_socket, port, type))
return (0);
if (ret != NULL) {
*ret = accept_socket;
/* return(1); */
}
for (;;) {
if (type == SOCK_STREAM) {
if (do_accept(accept_socket, &sock) == 0) {
shutdown(accept_socket, SHUT_RD);
close(accept_socket);
return (0);
}
} else
sock = accept_socket;
i = cb(sock, context);
if (type == SOCK_STREAM) {
shutdown(sock, SHUT_RDWR);
close(sock);
}
if (naccept != -1)
naccept--;
if (i < 0 || naccept == 0) {
shutdown(accept_socket, SHUT_RDWR);
close(accept_socket);
return (i);
}
}
}
static int
init_server_long(int *sock, int port, char *ip, int type)
{
int ret = 0;
struct sockaddr_in server;
int s = -1;
memset((char *) &server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons((unsigned short) port);
if (ip == NULL)
server.sin_addr.s_addr = INADDR_ANY;
else
memcpy(&server.sin_addr.s_addr, ip, 4);
if (type == SOCK_STREAM)
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
else /* type == SOCK_DGRAM */
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1)
goto err;
#if defined SOL_SOCKET && defined SO_REUSEADDR
{
int j = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(void *) &j, sizeof j) == -1) {
perror("setsockopt");
goto err;
}
}
#endif
if (bind(s, (struct sockaddr *) & server, sizeof(server)) == -1) {
perror("bind");
goto err;
}
/* Make it 128 for linux */
if (type == SOCK_STREAM && listen(s, 128) == -1)
goto err;
*sock = s;
ret = 1;
err:
if ((ret == 0) && (s != -1)) {
shutdown(s, SHUT_RD);
close(s);
}
return (ret);
}
static int
init_server(int *sock, int port, int type)
{
return (init_server_long(sock, port, NULL, type));
}
static int
do_accept(int acc_sock, int *sock)
{
struct hostent *h1, *h2;
static struct sockaddr_in from;
socklen_t len;
char *host = NULL;
int ret;
redoit:
memset((char *) &from, 0, sizeof(from));
len = sizeof(from);
ret = accept(acc_sock, (struct sockaddr *) & from, &len);
if (ret == -1) {
if (errno == EINTR) {
/* check_timeout(); */
goto redoit;
}
fprintf(stderr, "errno=%d ", errno);
perror("accept");
return (0);
}
h1 = gethostbyaddr((char *) &from.sin_addr.s_addr,
sizeof(from.sin_addr.s_addr), AF_INET);
if (h1 == NULL) {
BIO_printf(bio_err, "bad gethostbyaddr\n");
} else {
if ((host = strdup(h1->h_name)) == NULL) {
perror("strdup");
close(ret);
return (0);
}
h2 = gethostbyname(host);
if (h2 == NULL) {
BIO_printf(bio_err, "gethostbyname failure\n");
close(ret);
free(host);
return (0);
}
if (h2->h_addrtype != AF_INET) {
BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
close(ret);
free(host);
return (0);
}
}
free(host);
*sock = ret;
return (1);
}
int
extract_host_port(char *str, char **host_ptr, unsigned char *ip,
char **port_ptr)
{
char *h, *p;
h = str;
p = strrchr(str, '/'); /* IPv6 host/port */
if (p == NULL) {
p = strrchr(str, ':');
}
if (p == NULL) {
BIO_printf(bio_err, "no port defined\n");
return (0);
}
*(p++) = '\0';
if (host_ptr != NULL)
*host_ptr = h;
if (port_ptr != NULL && p != NULL && *p != '\0')
*port_ptr = p;
return (1);
}
int
extract_port(char *str, short *port_ptr)
{
int i;
const char *errstr;
struct servent *s;
i = strtonum(str, 1, 65535, &errstr);
if (!errstr) {
*port_ptr = (unsigned short) i;
} else {
s = getservbyname(str, "tcp");
if (s == NULL) {
BIO_printf(bio_err, "getservbyname failure for %s\n", str);
return (0);
}
*port_ptr = ntohs((unsigned short) s->s_port);
}
return (1);
}

465
apps/openssl/s_time.c Normal file
View File

@@ -0,0 +1,465 @@
/* $OpenBSD: s_time.c,v 1.38 2023/03/06 14:32:06 tb Exp $ */
/* 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.]
*/
/*-----------------------------------------
s_time - SSL client connection timer program
Written and donated by Larry Streepy <streepy@healthcare.com>
-----------------------------------------*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include "apps.h"
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include "s_apps.h"
#define SSL_CONNECT_NAME "localhost:4433"
#define BUFSIZZ 1024*10
#define MYBUFSIZ 1024*8
#define SECONDS 30
extern int verify_depth;
static void s_time_usage(void);
static int run_test(SSL *);
static int benchmark(int);
static void print_tally_mark(SSL *);
static SSL_CTX *tm_ctx = NULL;
static const SSL_METHOD *s_time_meth = NULL;
static long bytes_read = 0;
static struct {
int bugs;
char *CAfile;
char *CApath;
char *certfile;
char *cipher;
char *host;
char *keyfile;
time_t maxtime;
int nbio;
int no_shutdown;
int perform;
int verify;
int verify_depth;
char *www_path;
} cfg;
static const struct option s_time_options[] = {
{
.name = "bugs",
.desc = "Enable workarounds for known SSL/TLS bugs",
.type = OPTION_FLAG,
.opt.flag = &cfg.bugs,
},
{
.name = "CAfile",
.argname = "file",
.desc = "File containing trusted certificates in PEM format",
.type = OPTION_ARG,
.opt.arg = &cfg.CAfile,
},
{
.name = "CApath",
.argname = "path",
.desc = "Directory containing trusted certificates",
.type = OPTION_ARG,
.opt.arg = &cfg.CApath,
},
{
.name = "cert",
.argname = "file",
.desc = "Client certificate to use, if one is requested",
.type = OPTION_ARG,
.opt.arg = &cfg.certfile,
},
{
.name = "cipher",
.argname = "list",
.desc = "List of cipher suites to send to the server",
.type = OPTION_ARG,
.opt.arg = &cfg.cipher,
},
{
.name = "connect",
.argname = "host:port",
.desc = "Host and port to connect to (default "
SSL_CONNECT_NAME ")",
.type = OPTION_ARG,
.opt.arg = &cfg.host,
},
{
.name = "key",
.argname = "file",
.desc = "Client private key to use, if one is required",
.type = OPTION_ARG,
.opt.arg = &cfg.keyfile,
},
{
.name = "nbio",
.desc = "Use non-blocking I/O",
.type = OPTION_FLAG,
.opt.flag = &cfg.nbio,
},
{
.name = "new",
.desc = "Use a new session ID for each connection",
.type = OPTION_VALUE,
.opt.value = &cfg.perform,
.value = 1,
},
{
.name = "no_shutdown",
.desc = "Shut down the connection without notifying the server",
.type = OPTION_FLAG,
.opt.flag = &cfg.no_shutdown,
},
{
.name = "reuse",
.desc = "Reuse the same session ID for each connection",
.type = OPTION_VALUE,
.opt.value = &cfg.perform,
.value = 2,
},
{
.name = "time",
.argname = "seconds",
.desc = "Duration to perform timing tests for (default 30)",
.type = OPTION_ARG_TIME,
.opt.tvalue = &cfg.maxtime,
},
{
.name = "verify",
.argname = "depth",
.desc = "Enable peer certificate verification with given depth",
.type = OPTION_ARG_INT,
.opt.value = &cfg.verify_depth,
},
{
.name = "www",
.argname = "page",
.desc = "Page to GET from the server (default none)",
.type = OPTION_ARG,
.opt.arg = &cfg.www_path,
},
{ NULL },
};
static void
s_time_usage(void)
{
fprintf(stderr,
"usage: s_time "
"[-bugs] [-CAfile file] [-CApath directory] [-cert file]\n"
" [-cipher cipherlist] [-connect host:port] [-key keyfile]\n"
" [-nbio] [-new] [-no_shutdown] [-reuse] [-time seconds]\n"
" [-verify depth] [-www page]\n\n");
options_usage(s_time_options);
}
/***********************************************************************
* MAIN - main processing area for client
* real name depends on MONOLITH
*/
int
s_time_main(int argc, char **argv)
{
int ret = 1;
if (pledge("stdio rpath inet dns", NULL) == -1) {
perror("pledge");
exit(1);
}
s_time_meth = TLS_client_method();
verify_depth = 0;
memset(&cfg, 0, sizeof(cfg));
cfg.host = SSL_CONNECT_NAME;
cfg.maxtime = SECONDS;
cfg.perform = 3;
cfg.verify = SSL_VERIFY_NONE;
cfg.verify_depth = -1;
if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) {
s_time_usage();
goto end;
}
if (cfg.verify_depth >= 0) {
cfg.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
verify_depth = cfg.verify_depth;
BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
}
if (cfg.www_path != NULL &&
strlen(cfg.www_path) > MYBUFSIZ - 100) {
BIO_printf(bio_err, "-www option too long\n");
goto end;
}
if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL)
return (1);
SSL_CTX_set_quiet_shutdown(tm_ctx, 1);
if (cfg.bugs)
SSL_CTX_set_options(tm_ctx, SSL_OP_ALL);
if (cfg.cipher != NULL) {
if (!SSL_CTX_set_cipher_list(tm_ctx, cfg.cipher)) {
BIO_printf(bio_err, "error setting cipher list\n");
ERR_print_errors(bio_err);
goto end;
}
}
SSL_CTX_set_verify(tm_ctx, cfg.verify, NULL);
if (!set_cert_stuff(tm_ctx, cfg.certfile,
cfg.keyfile))
goto end;
if ((!SSL_CTX_load_verify_locations(tm_ctx, cfg.CAfile,
cfg.CApath)) ||
(!SSL_CTX_set_default_verify_paths(tm_ctx))) {
/*
* BIO_printf(bio_err,"error setting default verify
* locations\n");
*/
ERR_print_errors(bio_err);
/* goto end; */
}
/* Loop and time how long it takes to make connections */
if (cfg.perform & 1) {
printf("Collecting connection statistics for %lld seconds\n",
(long long)cfg.maxtime);
if (benchmark(0))
goto end;
}
/*
* Now loop and time connections using the same session id over and
* over
*/
if (cfg.perform & 2) {
printf("\n\nNow timing with session id reuse.\n");
if (benchmark(1))
goto end;
}
ret = 0;
end:
if (tm_ctx != NULL) {
SSL_CTX_free(tm_ctx);
tm_ctx = NULL;
}
return (ret);
}
/***********************************************************************
* run_test - make a connection, get a file, and shut down the connection
*
* Args:
* scon = SSL connection
* Returns:
* 1 on success, 0 on error
*/
static int
run_test(SSL *scon)
{
char buf[1024 * 8];
struct pollfd pfd[1];
BIO *conn;
long verify_error;
int i, retval;
if ((conn = BIO_new(BIO_s_connect())) == NULL)
return 0;
BIO_set_conn_hostname(conn, cfg.host);
SSL_set_connect_state(scon);
SSL_set_bio(scon, conn, conn);
for (;;) {
i = SSL_connect(scon);
if (BIO_sock_should_retry(i)) {
BIO_printf(bio_err, "DELAY\n");
pfd[0].fd = SSL_get_fd(scon);
pfd[0].events = POLLIN;
poll(pfd, 1, -1);
continue;
}
break;
}
if (i <= 0) {
BIO_printf(bio_err, "ERROR\n");
verify_error = SSL_get_verify_result(scon);
if (verify_error != X509_V_OK)
BIO_printf(bio_err, "verify error:%s\n",
X509_verify_cert_error_string(verify_error));
else
ERR_print_errors(bio_err);
return 0;
}
if (cfg.www_path != NULL) {
retval = snprintf(buf, sizeof buf,
"GET %s HTTP/1.0\r\n\r\n", cfg.www_path);
if (retval < 0 || retval >= sizeof buf) {
fprintf(stderr, "URL too long\n");
return 0;
}
if (SSL_write(scon, buf, retval) != retval)
return 0;
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
bytes_read += i;
}
if (cfg.no_shutdown)
SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN |
SSL_RECEIVED_SHUTDOWN);
else
SSL_shutdown(scon);
return 1;
}
static void
print_tally_mark(SSL *scon)
{
int ver;
if (SSL_session_reused(scon))
ver = 'r';
else {
ver = SSL_version(scon);
if (ver == TLS1_VERSION)
ver = 't';
else
ver = '*';
}
fputc(ver, stdout);
fflush(stdout);
}
static int
benchmark(int reuse_session)
{
double elapsed, totalTime;
int nConn = 0;
SSL *scon = NULL;
int ret = 1;
if (reuse_session) {
/* Get an SSL object so we can reuse the session id */
if ((scon = SSL_new(tm_ctx)) == NULL)
goto end;
if (!run_test(scon)) {
fprintf(stderr, "Unable to get connection\n");
goto end;
}
printf("starting\n");
}
nConn = 0;
bytes_read = 0;
app_timer_real(TM_RESET);
app_timer_user(TM_RESET);
for (;;) {
elapsed = app_timer_real(TM_GET);
if (elapsed > cfg.maxtime)
break;
if (scon == NULL) {
if ((scon = SSL_new(tm_ctx)) == NULL)
goto end;
}
if (!run_test(scon))
goto end;
nConn += 1;
print_tally_mark(scon);
if (!reuse_session) {
SSL_free(scon);
scon = NULL;
}
}
totalTime = app_timer_user(TM_GET);
printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
nConn, totalTime, ((double) nConn / totalTime), bytes_read);
printf("%d connections in %.0f real seconds, %ld bytes read per connection\n",
nConn, elapsed, nConn > 0 ? bytes_read / nConn : 0);
ret = 0;
end:
SSL_free(scon);
return ret;
}

293
apps/openssl/sess_id.c Normal file
View File

@@ -0,0 +1,293 @@
/* $OpenBSD: sess_id.c,v 1.12 2023/03/06 14:32:06 tb Exp $ */
/* 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 <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
static struct {
int cert;
char *context;
char *infile;
int informat;
int noout;
char *outfile;
int outformat;
int text;
} cfg;
static const struct option sess_id_options[] = {
{
.name = "cert",
.desc = "Output certificate if present in session",
.type = OPTION_FLAG,
.opt.flag = &cfg.cert,
},
{
.name = "context",
.argname = "id",
.desc = "Set the session ID context for output",
.type = OPTION_ARG,
.opt.arg = &cfg.context,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "inform",
.argname = "format",
.desc = "Input format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.informat,
},
{
.name = "noout",
.desc = "Do not output the encoded session info",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "outform",
.argname = "format",
.desc = "Output format (DER or PEM (default))",
.type = OPTION_ARG_FORMAT,
.opt.value = &cfg.outformat,
},
{
.name = "text",
.desc = "Print various public or private key components in"
" plain text",
.type = OPTION_FLAG,
.opt.flag = &cfg.text,
},
{ NULL }
};
static void
sess_id_usage(void)
{
fprintf(stderr,
"usage: sess_id [-cert] [-context id] [-in file] [-inform fmt] "
"[-noout]\n"
" [-out file] [-outform fmt] [-text]\n\n");
options_usage(sess_id_options);
}
static SSL_SESSION *load_sess_id(char *file, int format);
int
sess_id_main(int argc, char **argv)
{
SSL_SESSION *x = NULL;
X509 *peer = NULL;
int ret = 1, i;
BIO *out = NULL;
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.informat = FORMAT_PEM;
cfg.outformat = FORMAT_PEM;
if (options_parse(argc, argv, sess_id_options, NULL, NULL) != 0) {
sess_id_usage();
return (1);
}
x = load_sess_id(cfg.infile, cfg.informat);
if (x == NULL) {
goto end;
}
peer = SSL_SESSION_get0_peer(x);
if (cfg.context) {
size_t ctx_len = strlen(cfg.context);
if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
BIO_printf(bio_err, "Context too long\n");
goto end;
}
SSL_SESSION_set1_id_context(x,
(unsigned char *)cfg.context, ctx_len);
}
if (!cfg.noout || cfg.text) {
out = BIO_new(BIO_s_file());
if (out == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile == NULL) {
BIO_set_fp(out, stdout, BIO_NOCLOSE);
} else {
if (BIO_write_filename(out, cfg.outfile)
<= 0) {
perror(cfg.outfile);
goto end;
}
}
}
if (cfg.text) {
SSL_SESSION_print(out, x);
if (cfg.cert) {
if (peer == NULL)
BIO_puts(out, "No certificate present\n");
else
X509_print(out, peer);
}
}
if (!cfg.noout && !cfg.cert) {
if (cfg.outformat == FORMAT_ASN1)
i = i2d_SSL_SESSION_bio(out, x);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_SSL_SESSION(out, x);
else {
BIO_printf(bio_err,
"bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write SSL_SESSION\n");
goto end;
}
} else if (!cfg.noout && (peer != NULL)) {
/* just print the certificate */
if (cfg.outformat == FORMAT_ASN1)
i = (int) i2d_X509_bio(out, peer);
else if (cfg.outformat == FORMAT_PEM)
i = PEM_write_bio_X509(out, peer);
else {
BIO_printf(bio_err,
"bad output format specified for outfile\n");
goto end;
}
if (!i) {
BIO_printf(bio_err, "unable to write X509\n");
goto end;
}
}
ret = 0;
end:
BIO_free_all(out);
SSL_SESSION_free(x);
return (ret);
}
static SSL_SESSION *
load_sess_id(char *infile, int format)
{
SSL_SESSION *x = NULL;
BIO *in = NULL;
in = BIO_new(BIO_s_file());
if (in == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (infile == NULL)
BIO_set_fp(in, stdin, BIO_NOCLOSE);
else {
if (BIO_read_filename(in, infile) <= 0) {
perror(infile);
goto end;
}
}
if (format == FORMAT_ASN1)
x = d2i_SSL_SESSION_bio(in, NULL);
else if (format == FORMAT_PEM)
x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
else {
BIO_printf(bio_err,
"bad input format specified for input crl\n");
goto end;
}
if (x == NULL) {
BIO_printf(bio_err, "unable to load SSL_SESSION\n");
ERR_print_errors(bio_err);
goto end;
}
end:
BIO_free(in);
return (x);
}

1103
apps/openssl/smime.c Normal file

File diff suppressed because it is too large Load Diff

2136
apps/openssl/speed.c Normal file

File diff suppressed because it is too large Load Diff

311
apps/openssl/spkac.c Normal file
View File

@@ -0,0 +1,311 @@
/* $OpenBSD: spkac.c,v 1.13 2023/03/06 14:32:06 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999. Based on an original idea by Massimiliano Pala
* (madwolf@openca.org).
*/
/* ====================================================================
* 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 <stdlib.h>
#include <string.h>
#include <time.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/lhash.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
static struct {
char *challenge;
char *infile;
char *keyfile;
int noout;
char *outfile;
char *passargin;
int pubkey;
char *spkac;
char *spksect;
int verify;
} cfg;
static const struct option spkac_options[] = {
{
.name = "challenge",
.argname = "string",
.desc = "Specify challenge string if SPKAC is generated",
.type = OPTION_ARG,
.opt.arg = &cfg.challenge,
},
{
.name = "in",
.argname = "file",
.desc = "Input file (default stdin)",
.type = OPTION_ARG,
.opt.arg = &cfg.infile,
},
{
.name = "key",
.argname = "file",
.desc = "Create SPKAC using private key file",
.type = OPTION_ARG,
.opt.arg = &cfg.keyfile,
},
{
.name = "noout",
.desc = "Do not print text version of SPKAC",
.type = OPTION_FLAG,
.opt.flag = &cfg.noout,
},
{
.name = "out",
.argname = "file",
.desc = "Output file (default stdout)",
.type = OPTION_ARG,
.opt.arg = &cfg.outfile,
},
{
.name = "passin",
.argname = "src",
.desc = "Input file passphrase source",
.type = OPTION_ARG,
.opt.arg = &cfg.passargin,
},
{
.name = "pubkey",
.desc = "Output public key of an SPKAC (not used if creating)",
.type = OPTION_FLAG,
.opt.flag = &cfg.pubkey,
},
{
.name = "spkac",
.argname = "name",
.desc = "SPKAC name (default \"SPKAC\")",
.type = OPTION_ARG,
.opt.arg = &cfg.spkac,
},
{
.name = "spksect",
.argname = "name",
.desc = "Name of the section containing SPKAC (default"
" \"default\")",
.type = OPTION_ARG,
.opt.arg = &cfg.spksect,
},
{
.name = "verify",
.desc = "Verify digital signature on supplied SPKAC",
.type = OPTION_FLAG,
.opt.flag = &cfg.verify,
},
{ NULL }
};
static void
spkac_usage(void)
{
fprintf(stderr,
"usage: spkac [-challenge string] [-in file] "
"[-key file] [-noout]\n"
" [-out file] [-passin src] [-pubkey] [-spkac name] "
"[-spksect section]\n"
" [-verify]\n\n");
options_usage(spkac_options);
}
int
spkac_main(int argc, char **argv)
{
int i, ret = 1;
BIO *in = NULL, *out = NULL;
char *passin = NULL;
char *spkstr = NULL;
CONF *conf = NULL;
NETSCAPE_SPKI *spki = NULL;
EVP_PKEY *pkey = NULL;
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
cfg.spkac = "SPKAC";
cfg.spksect = "default";
if (options_parse(argc, argv, spkac_options, NULL, NULL) != 0) {
spkac_usage();
return (1);
}
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
if (cfg.keyfile) {
pkey = load_key(bio_err,
strcmp(cfg.keyfile, "-") ? cfg.keyfile
: NULL, FORMAT_PEM, 1, passin, "private key");
if (!pkey) {
goto end;
}
spki = NETSCAPE_SPKI_new();
if (cfg.challenge)
ASN1_STRING_set(spki->spkac->challenge,
cfg.challenge,
(int) strlen(cfg.challenge));
NETSCAPE_SPKI_set_pubkey(spki, pkey);
NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
spkstr = NETSCAPE_SPKI_b64_encode(spki);
if (spkstr == NULL) {
BIO_printf(bio_err, "Error encoding SPKAC\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile)
out = BIO_new_file(cfg.outfile, "w");
else
out = BIO_new_fp(stdout, BIO_NOCLOSE);
if (!out) {
BIO_printf(bio_err, "Error opening output file\n");
ERR_print_errors(bio_err);
} else {
BIO_printf(out, "SPKAC=%s\n", spkstr);
ret = 0;
}
free(spkstr);
goto end;
}
if (cfg.infile)
in = BIO_new_file(cfg.infile, "r");
else
in = BIO_new_fp(stdin, BIO_NOCLOSE);
if (!in) {
BIO_printf(bio_err, "Error opening input file\n");
ERR_print_errors(bio_err);
goto end;
}
conf = NCONF_new(NULL);
i = NCONF_load_bio(conf, in, NULL);
if (!i) {
BIO_printf(bio_err, "Error parsing config file\n");
ERR_print_errors(bio_err);
goto end;
}
spkstr = NCONF_get_string(conf, cfg.spksect,
cfg.spkac);
if (!spkstr) {
BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n",
cfg.spkac);
ERR_print_errors(bio_err);
goto end;
}
spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
if (!spki) {
BIO_printf(bio_err, "Error loading SPKAC\n");
ERR_print_errors(bio_err);
goto end;
}
if (cfg.outfile)
out = BIO_new_file(cfg.outfile, "w");
else {
out = BIO_new_fp(stdout, BIO_NOCLOSE);
}
if (!out) {
BIO_printf(bio_err, "Error opening output file\n");
ERR_print_errors(bio_err);
goto end;
}
if (!cfg.noout)
NETSCAPE_SPKI_print(out, spki);
pkey = NETSCAPE_SPKI_get_pubkey(spki);
if (cfg.verify) {
i = NETSCAPE_SPKI_verify(spki, pkey);
if (i > 0)
BIO_printf(bio_err, "Signature OK\n");
else {
BIO_printf(bio_err, "Signature Failure\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (cfg.pubkey)
PEM_write_bio_PUBKEY(out, pkey);
ret = 0;
end:
NCONF_free(conf);
NETSCAPE_SPKI_free(spki);
BIO_free(in);
BIO_free_all(out);
EVP_PKEY_free(pkey);
free(passin);
return (ret);
}

258
apps/openssl/testdsa.h Normal file
View File

@@ -0,0 +1,258 @@
/* $OpenBSD: testdsa.h,v 1.5 2022/01/10 19:22:26 tb Exp $ */
DSA *get_dsa512(void);
DSA *get_dsa1024(void);
DSA *get_dsa2048(void);
DSA *get_dsa(const unsigned char *priv, size_t priv_size,
const unsigned char *pub, size_t pub_size,
const unsigned char *p, size_t p_size,
const unsigned char *q, size_t q_size,
const unsigned char *g, size_t g_size);
static const unsigned char dsa512_priv[] = {
0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
};
static const unsigned char dsa512_pub[] = {
0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
0xbe, 0xba, 0x0a, 0x6b, 0xc8,
};
static const unsigned char dsa512_p[] = {
0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
0xA2, 0x76, 0x7D, 0x31,
};
static const unsigned char dsa512_q[] = {
0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
};
static const unsigned char dsa512_g[] = {
0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
0xA2, 0x03, 0x9D, 0x20,
};
DSA *
get_dsa512(void)
{
return get_dsa(dsa512_priv, sizeof(dsa512_priv),
dsa512_pub, sizeof(dsa512_pub), dsa512_p, sizeof(dsa512_p),
dsa512_q, sizeof(dsa512_q), dsa512_g, sizeof(dsa512_g));
}
static const unsigned char dsa1024_priv[] = {
0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
};
static const unsigned char dsa1024_pub[] = {
0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
};
static const unsigned char dsa1024_p[] = {
0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
};
static const unsigned char dsa1024_q[] = {
0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
};
static const unsigned char dsa1024_g[] = {
0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
};
DSA *
get_dsa1024(void)
{
return get_dsa(dsa1024_priv, sizeof(dsa1024_priv),
dsa1024_pub, sizeof(dsa1024_pub), dsa1024_p, sizeof(dsa1024_p),
dsa1024_q, sizeof(dsa1024_q), dsa1024_g, sizeof(dsa1024_g));
}
static const unsigned char dsa2048_priv[] = {
0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
};
static const unsigned char dsa2048_pub[] = {
0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
0x8b, 0x33, 0xb7, 0xce,
};
static const unsigned char dsa2048_p[] = {
0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
0xF8, 0x68, 0xCF, 0x9B,
};
static const unsigned char dsa2048_q[] = {
0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
};
static const unsigned char dsa2048_g[] = {
0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
0xF8, 0xB2, 0xE5, 0x38,
};
DSA *
get_dsa2048(void)
{
return get_dsa(dsa2048_priv, sizeof(dsa2048_priv),
dsa2048_pub, sizeof(dsa2048_pub), dsa2048_p, sizeof(dsa2048_p),
dsa2048_q, sizeof(dsa2048_q), dsa2048_g, sizeof(dsa2048_g));
}
DSA *
get_dsa(const unsigned char *priv, size_t priv_size,
const unsigned char *pub, size_t pub_size,
const unsigned char *p_char, size_t p_size,
const unsigned char *q_char, size_t q_size,
const unsigned char *g_char, size_t g_size)
{
DSA *dsa;
BIGNUM *priv_key = NULL, *pub_key = NULL;
BIGNUM *p = NULL, *q = NULL, *g = NULL;
if ((dsa = DSA_new()) == NULL)
return (NULL);
priv_key = BN_bin2bn(priv, priv_size, NULL);
pub_key = BN_bin2bn(pub, pub_size, NULL);
if (priv_key == NULL || pub_key == NULL)
goto err;
if (!DSA_set0_key(dsa, pub_key, priv_key))
goto err;
pub_key = NULL;
priv_key = NULL;
p = BN_bin2bn(p_char, p_size, NULL);
q = BN_bin2bn(q_char, q_size, NULL);
g = BN_bin2bn(g_char, g_size, NULL);
if (p == NULL || q == NULL || g == NULL)
goto err;
if (!DSA_set0_pqg(dsa, p, q, g))
goto err;
p = NULL;
q = NULL;
g = NULL;
return dsa;
err:
DSA_free(dsa);
BN_free(priv_key);
BN_free(pub_key);
BN_free(p);
BN_free(q);
BN_free(g);
return NULL;
}

517
apps/openssl/testrsa.h Normal file
View File

@@ -0,0 +1,517 @@
/* $OpenBSD: testrsa.h,v 1.1 2014/08/26 17:47:25 jsing Exp $ */
/* 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.]
*/
static unsigned char test512[] = {
0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
};
static unsigned char test1024[] = {
0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
};
static unsigned char test2048[] = {
0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
0x95,
};
static unsigned char test4096[] = {
0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
};

67
apps/openssl/timeouts.h Normal file
View File

@@ -0,0 +1,67 @@
/* $OpenBSD: timeouts.h,v 1.1 2014/08/26 17:47:25 jsing Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
*/
/* ====================================================================
* 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).
*
*/
#ifndef INCLUDED_TIMEOUTS_H
#define INCLUDED_TIMEOUTS_H
/* numbers in us */
#define DGRAM_RCV_TIMEOUT 250000
#define DGRAM_SND_TIMEOUT 250000
#endif /* ! INCLUDED_TIMEOUTS_H */

1252
apps/openssl/ts.c Normal file

File diff suppressed because it is too large Load Diff

457
apps/openssl/verify.c Normal file
View File

@@ -0,0 +1,457 @@
/* $OpenBSD: verify.c,v 1.17 2023/04/14 15:27:13 tb Exp $ */
/* 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 <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
static int cb(int ok, X509_STORE_CTX *ctx);
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain,
STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls);
static int vflags = 0;
static struct {
char *CAfile;
char *CApath;
char *crlfile;
char *trustfile;
char *untfile;
int verbose;
X509_VERIFY_PARAM *vpm;
} cfg;
static int
verify_opt_args(int argc, char **argv, int *argsused)
{
int oargc = argc;
int badarg = 0;
if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm))
return (1);
if (badarg)
return (1);
*argsused = oargc - argc;
return (0);
}
static const struct option verify_options[] = {
{
.name = "CAfile",
.argname = "file",
.desc = "Certificate Authority file",
.type = OPTION_ARG,
.opt.arg = &cfg.CAfile,
},
{
.name = "CApath",
.argname = "path",
.desc = "Certificate Authority path",
.type = OPTION_ARG,
.opt.arg = &cfg.CApath,
},
{
.name = "CRLfile",
.argname = "file",
.desc = "Certificate Revocation List file",
.type = OPTION_ARG,
.opt.arg = &cfg.crlfile,
},
{
.name = "trusted",
.argname = "file",
.desc = "Trusted certificates file",
.type = OPTION_ARG,
.opt.arg = &cfg.trustfile,
},
{
.name = "untrusted",
.argname = "file",
.desc = "Untrusted certificates file",
.type = OPTION_ARG,
.opt.arg = &cfg.untfile,
},
{
.name = "verbose",
.desc = "Verbose",
.type = OPTION_FLAG,
.opt.flag = &cfg.verbose,
},
{
.name = NULL,
.desc = "",
.type = OPTION_ARGV_FUNC,
.opt.argvfunc = verify_opt_args,
},
{ NULL },
};
static const struct option verify_shared_options[] = {
{
.name = "attime",
.argname = "epoch",
.desc = "Use epoch as the verification time",
},
{
.name = "check_ss_sig",
.desc = "Check the root CA self-signed certificate signature",
},
{
.name = "crl_check",
.desc = "Enable CRL checking for the leaf certificate",
},
{
.name = "crl_check_all",
.desc = "Enable CRL checking for the entire certificate chain",
},
{
.name = "explicit_policy",
.desc = "Require explicit policy (per RFC 3280)",
},
{
.name = "extended_crl",
.desc = "Enable extended CRL support",
},
{
.name = "ignore_critical",
.desc = "Disable critical extension checking",
},
{
.name = "inhibit_any",
.desc = "Inhibit any policy (per RFC 3280)",
},
{
.name = "inhibit_map",
.desc = "Inhibit policy mapping (per RFC 3280)",
},
{
.name = "issuer_checks",
.desc = "Enable debugging of certificate issuer checks",
},
{
.name = "legacy_verify",
.desc = "Use legacy certificate chain verification",
},
{
.name = "policy",
.argname = "name",
.desc = "Add given policy to the acceptable set",
},
{
.name = "policy_check",
.desc = "Enable certificate policy checking",
},
{
.name = "policy_print",
.desc = "Print policy",
},
{
.name = "purpose",
.argname = "name",
.desc = "Verify for the given purpose",
},
{
.name = "use_deltas",
.desc = "Use delta CRLS (if present)",
},
{
.name = "verify_depth",
.argname = "num",
.desc = "Limit verification to the given depth",
},
{
.name = "x509_strict",
.desc = "Use strict X.509 rules (disables workarounds)",
},
{ NULL },
};
static void
verify_usage(void)
{
int i;
fprintf(stderr,
"usage: verify [-CAfile file] [-CApath directory] [-check_ss_sig]\n"
" [-CRLfile file] [-crl_check] [-crl_check_all]\n"
" [-explicit_policy] [-extended_crl]\n"
" [-ignore_critical] [-inhibit_any] [-inhibit_map]\n"
" [-issuer_checks] [-policy_check] [-purpose purpose]\n"
" [-trusted file] [-untrusted file] [-verbose]\n"
" [-x509_strict] [certificates]\n\n");
options_usage(verify_options);
fprintf(stderr, "\nVerification options:\n\n");
options_usage(verify_shared_options);
fprintf(stderr, "\nValid purposes:\n\n");
for (i = 0; i < X509_PURPOSE_get_count(); i++) {
X509_PURPOSE *ptmp = X509_PURPOSE_get0(i);
fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp),
X509_PURPOSE_get0_name(ptmp));
}
}
int
verify_main(int argc, char **argv)
{
STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
STACK_OF(X509_CRL) *crls = NULL;
X509_STORE *cert_ctx = NULL;
X509_LOOKUP *lookup = NULL;
char **cert_files = NULL;
int argsused;
int ret = 1;
if (pledge("stdio rpath", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, verify_options, NULL, &argsused) != 0) {
verify_usage();
goto end;
}
if (argsused < argc)
cert_files = &argv[argsused];
cert_ctx = X509_STORE_new();
if (cert_ctx == NULL)
goto end;
X509_STORE_set_verify_cb(cert_ctx, cb);
if (cfg.vpm)
X509_STORE_set1_param(cert_ctx, cfg.vpm);
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
if (lookup == NULL)
abort(); /* XXX */
if (cfg.CAfile) {
if (!X509_LOOKUP_load_file(lookup, cfg.CAfile,
X509_FILETYPE_PEM)) {
BIO_printf(bio_err, "Error loading file %s\n",
cfg.CAfile);
ERR_print_errors(bio_err);
goto end;
}
} else
X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
if (lookup == NULL)
abort(); /* XXX */
if (cfg.CApath) {
if (!X509_LOOKUP_add_dir(lookup, cfg.CApath,
X509_FILETYPE_PEM)) {
BIO_printf(bio_err, "Error loading directory %s\n",
cfg.CApath);
ERR_print_errors(bio_err);
goto end;
}
} else
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
ERR_clear_error();
if (cfg.untfile) {
untrusted = load_certs(bio_err, cfg.untfile,
FORMAT_PEM, NULL, "untrusted certificates");
if (!untrusted)
goto end;
}
if (cfg.trustfile) {
trusted = load_certs(bio_err, cfg.trustfile,
FORMAT_PEM, NULL, "trusted certificates");
if (!trusted)
goto end;
}
if (cfg.crlfile) {
crls = load_crls(bio_err, cfg.crlfile, FORMAT_PEM,
NULL, "other CRLs");
if (!crls)
goto end;
}
ret = 0;
if (cert_files == NULL) {
if (1 != check(cert_ctx, NULL, untrusted, trusted, crls))
ret = -1;
} else {
do {
if (1 != check(cert_ctx, *cert_files++, untrusted,
trusted, crls))
ret = -1;
} while (*cert_files != NULL);
}
end:
if (cfg.vpm)
X509_VERIFY_PARAM_free(cfg.vpm);
if (cert_ctx != NULL)
X509_STORE_free(cert_ctx);
sk_X509_pop_free(untrusted, X509_free);
sk_X509_pop_free(trusted, X509_free);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
return (ret < 0 ? 2 : ret);
}
static int
check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain,
STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls)
{
X509 *x = NULL;
X509_STORE_CTX *csc = NULL;
const char *certfile = (file == NULL) ? "stdin" : file;
int verify_err;
int i = 0, ret = 0;
x = load_cert(bio_err, file, FORMAT_PEM, NULL, "certificate file");
if (x == NULL)
goto end;
if ((csc = X509_STORE_CTX_new()) == NULL)
goto end;
X509_STORE_set_flags(ctx, vflags);
if (!X509_STORE_CTX_init(csc, ctx, x, uchain))
goto end;
if (tchain)
X509_STORE_CTX_trusted_stack(csc, tchain);
if (crls)
X509_STORE_CTX_set0_crls(csc, crls);
i = X509_verify_cert(csc);
verify_err = X509_STORE_CTX_get_error(csc);
if (i > 0 && verify_err == X509_V_OK) {
fprintf(stdout, "%s: OK\n", certfile);
ret = 1;
} else {
fprintf(stdout, "%s: verification failed: %d (%s)\n", certfile,
verify_err, X509_verify_cert_error_string(verify_err));
}
end:
if (i <= 0)
ERR_print_errors(bio_err);
X509_free(x);
X509_STORE_CTX_free(csc);
return (ret);
}
static int
cb(int ok, X509_STORE_CTX *ctx)
{
int cert_error = X509_STORE_CTX_get_error(ctx);
X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
if (!ok) {
if (current_cert) {
X509_NAME_print_ex_fp(stdout,
X509_get_subject_name(current_cert),
0, XN_FLAG_ONELINE);
printf("\n");
}
printf("%serror %d at %d depth lookup:%s\n",
X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
cert_error,
X509_STORE_CTX_get_error_depth(ctx),
X509_verify_cert_error_string(cert_error));
switch (cert_error) {
case X509_V_ERR_NO_EXPLICIT_POLICY:
case X509_V_ERR_CERT_HAS_EXPIRED:
/*
* since we are just checking the certificates, it is
* ok if they are self signed. But we should still
* warn the user.
*/
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
/* Continue after extension errors too */
case X509_V_ERR_INVALID_CA:
case X509_V_ERR_INVALID_NON_CA:
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
case X509_V_ERR_INVALID_PURPOSE:
case X509_V_ERR_CRL_HAS_EXPIRED:
case X509_V_ERR_CRL_NOT_YET_VALID:
case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
ok = 1;
}
return ok;
}
if (!cfg.verbose)
ERR_clear_error();
return (ok);
}

249
apps/openssl/version.c Normal file
View File

@@ -0,0 +1,249 @@
/* $OpenBSD: version.c,v 1.12 2023/07/27 07:01:50 tb Exp $ */
/* 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.]
*/
/* ====================================================================
* Copyright (c) 1998-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
* 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).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include <openssl/bn.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#ifndef OPENSSL_NO_BF
#include <openssl/blowfish.h>
#endif
#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
#endif
#ifndef OPENSSL_NO_IDEA
#include <openssl/idea.h>
#endif
#ifndef OPENSSL_NO_RC4
#include <openssl/rc4.h>
#endif
static struct {
int cflags;
int date;
int dir;
int options;
int platform;
int version;
} cfg;
static int
version_all_opts(void)
{
cfg.cflags = 1;
cfg.date = 1;
cfg.dir= 1;
cfg.options = 1;
cfg.platform = 1;
cfg.version = 1;
return (0);
}
static const struct option version_options[] = {
{
.name = "a",
.desc = "All information (same as setting all other flags)",
.type = OPTION_FUNC,
.opt.func = version_all_opts,
},
{
.name = "b",
.desc = "Date the current version of OpenSSL was built",
.type = OPTION_FLAG,
.opt.flag = &cfg.date,
},
{
.name = "d",
.desc = "OPENSSLDIR value",
.type = OPTION_FLAG,
.opt.flag = &cfg.dir,
},
{
.name = "f",
.desc = "Compilation flags",
.type = OPTION_FLAG,
.opt.flag = &cfg.cflags,
},
{
.name = "o",
.type = OPTION_FLAG,
.opt.flag = &cfg.options,
},
{
.name = "p",
.desc = "Platform settings",
.type = OPTION_FLAG,
.opt.flag = &cfg.platform,
},
{
.name = "v",
.desc = "Current OpenSSL version",
.type = OPTION_FLAG,
.opt.flag = &cfg.version,
},
{NULL},
};
static void
version_usage(void)
{
fprintf(stderr, "usage: version [-abdfpv]\n");
options_usage(version_options);
}
int
version_main(int argc, char **argv)
{
if (pledge("stdio", NULL) == -1) {
perror("pledge");
exit(1);
}
memset(&cfg, 0, sizeof(cfg));
if (options_parse(argc, argv, version_options, NULL, NULL) != 0) {
version_usage();
return (1);
}
if (argc == 1)
cfg.version = 1;
if (cfg.version) {
if (SSLeay() == SSLEAY_VERSION_NUMBER) {
printf("%s\n", SSLeay_version(SSLEAY_VERSION));
} else {
printf("%s (Library: %s)\n",
OPENSSL_VERSION_TEXT,
SSLeay_version(SSLEAY_VERSION));
}
}
if (cfg.date)
printf("%s\n", SSLeay_version(SSLEAY_BUILT_ON));
if (cfg.platform)
printf("%s\n", SSLeay_version(SSLEAY_PLATFORM));
if (cfg.cflags)
printf("%s\n", SSLeay_version(SSLEAY_CFLAGS));
if (cfg.dir)
printf("%s\n", SSLeay_version(SSLEAY_DIR));
return (0);
}

1557
apps/openssl/x509.c Normal file

File diff suppressed because it is too large Load Diff