check in v3.8.2 source
This commit is contained in:
2186
apps/openssl/apps.c
Normal file
2186
apps/openssl/apps.c
Normal file
File diff suppressed because it is too large
Load Diff
324
apps/openssl/apps.h
Normal file
324
apps/openssl/apps.h
Normal 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
175
apps/openssl/apps_posix.c
Normal 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
470
apps/openssl/asn1pars.c
Normal 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
3042
apps/openssl/ca.c
Normal file
File diff suppressed because it is too large
Load Diff
691
apps/openssl/certhash.c
Normal file
691
apps/openssl/certhash.c
Normal 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
200
apps/openssl/ciphers.c
Normal 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
1961
apps/openssl/cms.c
Normal file
File diff suppressed because it is too large
Load Diff
482
apps/openssl/crl.c
Normal file
482
apps/openssl/crl.c
Normal 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
331
apps/openssl/crl2p7.c
Normal 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
671
apps/openssl/dgst.c
Normal 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
298
apps/openssl/dh.c
Normal 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
502
apps/openssl/dhparam.c
Normal 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
365
apps/openssl/dsa.c
Normal 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
377
apps/openssl/dsaparam.c
Normal 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
392
apps/openssl/ec.c
Normal 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
606
apps/openssl/ecparam.c
Normal 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
783
apps/openssl/enc.c
Normal 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
117
apps/openssl/errstr.c
Normal 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
219
apps/openssl/gendh.c
Normal 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
296
apps/openssl/gendsa.c
Normal 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
418
apps/openssl/genpkey.c
Normal 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
389
apps/openssl/genrsa.c
Normal 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
1532
apps/openssl/ocsp.c
Normal file
File diff suppressed because it is too large
Load Diff
736
apps/openssl/openssl.c
Normal file
736
apps/openssl/openssl.c
Normal 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
524
apps/openssl/passwd.c
Normal 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
1128
apps/openssl/pkcs12.c
Normal file
File diff suppressed because it is too large
Load Diff
291
apps/openssl/pkcs7.c
Normal file
291
apps/openssl/pkcs7.c
Normal 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
366
apps/openssl/pkcs8.c
Normal 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
309
apps/openssl/pkey.c
Normal 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
185
apps/openssl/pkeyparam.c
Normal 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
571
apps/openssl/pkeyutl.c
Normal 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
201
apps/openssl/prime.c
Normal 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
48
apps/openssl/progs.h
Normal 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
182
apps/openssl/rand.c
Normal 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
1878
apps/openssl/req.c
Normal file
File diff suppressed because it is too large
Load Diff
411
apps/openssl/rsa.c
Normal file
411
apps/openssl/rsa.c
Normal 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
402
apps/openssl/rsautl.c
Normal 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
151
apps/openssl/s_apps.h
Normal 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
932
apps/openssl/s_cb.c
Normal 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
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
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
327
apps/openssl/s_socket.c
Normal 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
465
apps/openssl/s_time.c
Normal 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
293
apps/openssl/sess_id.c
Normal 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
1103
apps/openssl/smime.c
Normal file
File diff suppressed because it is too large
Load Diff
2136
apps/openssl/speed.c
Normal file
2136
apps/openssl/speed.c
Normal file
File diff suppressed because it is too large
Load Diff
311
apps/openssl/spkac.c
Normal file
311
apps/openssl/spkac.c
Normal 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
258
apps/openssl/testdsa.h
Normal 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
517
apps/openssl/testrsa.h
Normal 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
67
apps/openssl/timeouts.h
Normal 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
1252
apps/openssl/ts.c
Normal file
File diff suppressed because it is too large
Load Diff
457
apps/openssl/verify.c
Normal file
457
apps/openssl/verify.c
Normal 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
249
apps/openssl/version.c
Normal 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
1557
apps/openssl/x509.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user