diff --git a/apps/asn1pars.c b/apps/asn1pars.c index 9f21f0c730..ae47aa8efc 100644 --- a/apps/asn1pars.c +++ b/apps/asn1pars.c @@ -18,9 +18,6 @@ #include #include -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF_STRING() - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_IN, OPT_OUT, OPT_INDENT, OPT_NOOUT, diff --git a/apps/build.info b/apps/build.info index 8bfcec65d0..146e9009f5 100644 --- a/apps/build.info +++ b/apps/build.info @@ -18,7 +18,7 @@ $OPENSSLSRC=\ pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \ s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \ spkac.c verify.c version.c x509.c rehash.c storeutl.c \ - list.c info.c provider.c fipsinstall.c + list.c info.c fipsinstall.c IF[{- !$disabled{'des'} -}] $OPENSSLSRC=$OPENSSLSRC pkcs12.c ENDIF diff --git a/apps/ca.c b/apps/ca.c index fef0b82c39..4a67d61477 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -26,7 +26,7 @@ #ifndef W_OK # ifdef OPENSSL_SYS_VMS # include -# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) +# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_TANDEM) # include # endif #endif @@ -34,11 +34,6 @@ #include "apps.h" #include "progs.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF_STRING() - #ifndef W_OK # define F_OK 0 # define W_OK 2 @@ -106,7 +101,7 @@ static int certify(X509 **xret, const char *infile, int informat, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy, int selfsign); static int certify_cert(X509 **xret, const char *infile, int informat, - EVP_PKEY *pkey, X509 *x509, + const char *passin, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(OPENSSL_STRING) *vfyopts, @@ -155,7 +150,8 @@ typedef enum OPTION_choice { OPT_KEY, OPT_CERT, OPT_CERTFORM, OPT_SELFSIGN, OPT_IN, OPT_INFORM, OPT_OUT, OPT_OUTDIR, OPT_VFYOPT, OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN, - OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, + OPT_GENCRL, OPT_MSIE_HACK, OPT_CRL_LASTUPDATE, OPT_CRL_NEXTUPDATE, + OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, OPT_RAND_SERIAL, @@ -200,7 +196,7 @@ const OPTIONS ca_options[] = { {"rand_serial", OPT_RAND_SERIAL, '-', "Always create a random serial; do not store it"}, {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', - "Enable support for multivalued RDNs"}, + "Deprecated; multi-valued RDNs support is always on."}, {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"}, {"enddate", OPT_ENDDATE, 's', "YYMMDDHHMMSSZ cert notAfter (overrides -days)"}, @@ -214,17 +210,17 @@ const OPTIONS ca_options[] = { OPT_SECTION("Signing"), {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"}, - {"keyfile", OPT_KEYFILE, 's', "Private key"}, + {"keyfile", OPT_KEYFILE, 's', "The CA private key"}, {"keyform", OPT_KEYFORM, 'f', "Private key file format (ENGINE, other values ignored)"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, - {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"}, + {"passin", OPT_PASSIN, 's', "Key and cert input file pass phrase source"}, + {"key", OPT_KEY, 's', "Key to decrypt key or cert files. Better use -passin"}, {"cert", OPT_CERT, '<', "The CA cert"}, {"certform", OPT_CERTFORM, 'F', - "certificate input format (DER/PEM/P12); has no effect"}, + "Certificate input format (DER/PEM/P12); has no effect"}, {"selfsign", OPT_SELFSIGN, '-', "Sign a cert with the key associated with it"}, {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, - {"vfyopt", OPT_SIGOPT, 's', "Verification parameter in n:v form"}, + {"vfyopt", OPT_VFYOPT, 's', "Verification parameter in n:v form"}, OPT_SECTION("Revocation"), {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"}, @@ -241,6 +237,10 @@ const OPTIONS ca_options[] = { "sets compromise time to val and the revocation reason to keyCompromise"}, {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's', "sets compromise time to val and the revocation reason to CACompromise"}, + {"crl_lastupdate", OPT_CRL_LASTUPDATE, 's', + "Sets the CRL lastUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)"}, + {"crl_nextupdate", OPT_CRL_NEXTUPDATE, 's', + "Sets the CRL nextUpdate time to val (YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ)"}, {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"}, {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"}, {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"}, @@ -262,7 +262,6 @@ int ca_main(int argc, char **argv) EVP_PKEY *pkey = NULL; BIO *in = NULL, *out = NULL, *Sout = NULL; ASN1_INTEGER *tmpser; - ASN1_TIME *tmptm; CA_DB *db = NULL; DB_ATTR db_attr; STACK_OF(CONF_VALUE) *attribs = NULL; @@ -272,10 +271,11 @@ int ca_main(int argc, char **argv) const EVP_MD *dgst = NULL; char *configfile = default_config_file, *section = NULL; char *md = NULL, *policy = NULL, *keyfile = NULL; - char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *key = NULL; + char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL; int certformat = FORMAT_PEM, informat = FORMAT_PEM; const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL; const char *extensions = NULL, *extfile = NULL, *passinarg = NULL; + char *passin = NULL; char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL; const char *serialfile = NULL, *subj = NULL; char *prog, *startdate = NULL, *enddate = NULL; @@ -285,11 +285,12 @@ int ca_main(int argc, char **argv) char *const *pp; const char *p; size_t outdirlen = 0; - int create_ser = 0, free_key = 0, total = 0, total_done = 0; + int create_ser = 0, free_passin = 0, total = 0, total_done = 0; int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE; - int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0; + int keyformat = FORMAT_PEM, multirdn = 1, notext = 0, output_der = 0; int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0; int rand_ser = 0, i, j, selfsign = 0, def_nid, def_ret; + char *crl_lastupdate = NULL, *crl_nextupdate = NULL; long crldays = 0, crlhours = 0, crlsec = 0, days = 0; unsigned long chtype = MBSTRING_ASC, certopt = 0; X509 *x509 = NULL, *x509p = NULL, *x = NULL; @@ -343,7 +344,7 @@ int ca_main(int argc, char **argv) create_ser = 1; break; case OPT_MULTIVALUE_RDN: - multirdn = 1; + /* obsolete */ break; case OPT_STARTDATE: startdate = opt_arg(); @@ -379,7 +380,7 @@ int ca_main(int argc, char **argv) goto end; break; case OPT_KEY: - key = opt_arg(); + passin = opt_arg(); break; case OPT_CERT: certfile = opt_arg(); @@ -424,6 +425,12 @@ int ca_main(int argc, char **argv) case OPT_MSIE_HACK: msie_hack = 1; break; + case OPT_CRL_LASTUPDATE: + crl_lastupdate = opt_arg(); + break; + case OPT_CRL_NEXTUPDATE: + crl_nextupdate = opt_arg(); + break; case OPT_CRLDAYS: crldays = atol(opt_arg()); break; @@ -565,15 +572,14 @@ int ca_main(int argc, char **argv) && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL) goto end; - if (key == NULL) { - free_key = 1; - if (!app_passwd(passinarg, NULL, &key, NULL)) { + if (passin == NULL) { + free_passin = 1; + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } } - pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key"); - cleanse(key); + pkey = load_key(keyfile, keyformat, 0, passin, e, "CA private key"); if (pkey == NULL) /* load_key() has already printed an appropriate message */ goto end; @@ -585,7 +591,7 @@ int ca_main(int argc, char **argv) && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL) goto end; - x509 = load_cert(certfile, certformat, "CA certificate"); + x509 = load_cert_pass(certfile, certformat, passin, "CA certificate"); if (x509 == NULL) goto end; @@ -940,8 +946,8 @@ int ca_main(int argc, char **argv) } if (ss_cert_file != NULL) { total++; - j = certify_cert(&x, ss_cert_file, certformat, pkey, x509, dgst, - sigopts, vfyopts, attribs, + j = certify_cert(&x, ss_cert_file, certformat, passin, pkey, + x509, dgst, sigopts, vfyopts, attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, certopt, get_nameopt(), default_op, @@ -1146,7 +1152,8 @@ int ca_main(int argc, char **argv) crlhours = 0; ERR_clear_error(); } - if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) { + if ((crl_nextupdate == NULL) && + (crldays == 0) && (crlhours == 0) && (crlsec == 0)) { BIO_printf(bio_err, "cannot lookup how long until the next CRL is issued\n"); goto end; @@ -1159,19 +1166,18 @@ int ca_main(int argc, char **argv) if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509))) goto end; - tmptm = ASN1_TIME_new(); - if (tmptm == NULL - || X509_gmtime_adj(tmptm, 0) == NULL - || !X509_CRL_set1_lastUpdate(crl, tmptm) - || X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec, - NULL) == NULL) { - BIO_puts(bio_err, "error setting CRL nextUpdate\n"); - ASN1_TIME_free(tmptm); + if (!set_crl_lastupdate(crl, crl_lastupdate)) { + BIO_puts(bio_err, "error setting CRL lastUpdate\n"); + ret = 1; goto end; } - X509_CRL_set1_nextUpdate(crl, tmptm); - ASN1_TIME_free(tmptm); + if (!set_crl_nextupdate(crl, crl_nextupdate, + crldays, crlhours, crlsec)) { + BIO_puts(bio_err, "error setting CRL nextUpdate\n"); + ret = 1; + goto end; + } for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); @@ -1262,7 +1268,9 @@ int ca_main(int argc, char **argv) goto end; } else { X509 *revcert; - revcert = load_cert(infile, certformat, infile); + + revcert = load_cert_pass(infile, certformat, passin, + "certificate to be revoked"); if (revcert == NULL) goto end; if (dorevoke == 2) @@ -1291,8 +1299,9 @@ int ca_main(int argc, char **argv) BIO_free_all(in); sk_X509_pop_free(cert_sk, X509_free); - if (free_key) - OPENSSL_free(key); + cleanse(passin); + if (free_passin) + OPENSSL_free(passin); BN_free(serial); BN_free(crlnumber); free_index(db); @@ -1379,7 +1388,7 @@ static int certify(X509 **xret, const char *infile, int informat, } static int certify_cert(X509 **xret, const char *infile, int certformat, - EVP_PKEY *pkey, X509 *x509, + const char *passin, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(OPENSSL_STRING) *vfyopts, @@ -1390,23 +1399,23 @@ static int certify_cert(X509 **xret, const char *infile, int certformat, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) { - X509 *req = NULL; + X509 *template_cert = NULL; X509_REQ *rreq = NULL; EVP_PKEY *pktmp = NULL; int ok = -1, i; - if ((req = load_cert(infile, certformat, infile)) == NULL) + if ((template_cert = load_cert_pass(infile, certformat, passin, "template certificate")) == NULL) goto end; if (verbose) - X509_print(bio_err, req); + X509_print(bio_err, template_cert); BIO_printf(bio_err, "Check that the request matches the signature\n"); - if ((pktmp = X509_get0_pubkey(req)) == NULL) { + if ((pktmp = X509_get0_pubkey(template_cert)) == NULL) { BIO_printf(bio_err, "error unpacking public key\n"); goto end; } - i = do_X509_verify(req, pktmp, vfyopts); + i = do_X509_verify(template_cert, pktmp, vfyopts); if (i < 0) { ok = 0; BIO_printf(bio_err, "Signature verification problems....\n"); @@ -1420,7 +1429,7 @@ static int certify_cert(X509 **xret, const char *infile, int certformat, BIO_printf(bio_err, "Signature ok\n"); } - if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL) + if ((rreq = X509_to_X509_REQ(template_cert, NULL, NULL)) == NULL) goto end; ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, @@ -1430,7 +1439,7 @@ static int certify_cert(X509 **xret, const char *infile, int certformat, end: X509_REQ_free(rreq); - X509_free(req); + X509_free(template_cert); return ok; } @@ -1643,7 +1652,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "Everything appears to be ok, creating and signing the certificate\n"); - if ((ret = X509_new_with_libctx(app_get0_libctx(), app_get0_propq())) == NULL) + if ((ret = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; #ifdef X509_V3 diff --git a/apps/ciphers.c b/apps/ciphers.c index 380091f16f..500b416046 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -15,8 +15,6 @@ #include #include -DEFINE_STACK_OF_CONST(SSL_CIPHER) - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_STDNAME, diff --git a/apps/cmp.c b/apps/cmp.c index 01c5394344..e52eff3c28 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -42,15 +42,12 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(OSSL_CMP_ITAV) - static char *opt_config = NULL; #define CMP_SECTION "cmp" #define SECTION_NAME_MAX 40 /* max length of section name */ #define DEFAULT_SECTION "default" static char *opt_section = CMP_SECTION; +static int opt_verbosity = OSSL_CMP_LOG_INFO; #undef PROG #define PROG cmp_main @@ -73,11 +70,10 @@ typedef enum { /* message transfer */ static char *opt_server = NULL; -static char server_port_s[32] = { '\0' }; -static int server_port = 0; +static char server_port[32] = { '\0' }; static char *opt_proxy = NULL; static char *opt_no_proxy = NULL; -static char *opt_path = "/"; +static char *opt_path = NULL; static int opt_msg_timeout = -1; static int opt_total_timeout = -1; @@ -96,6 +92,7 @@ static char *opt_cacertsout = NULL; static char *opt_ref = NULL; static char *opt_secret = NULL; static char *opt_cert = NULL; +static char *opt_own_trusted = NULL; static char *opt_key = NULL; static char *opt_keypass = NULL; static char *opt_digest = NULL; @@ -128,6 +125,7 @@ static char *opt_out_trusted = NULL; static int opt_implicit_confirm = 0; static int opt_disable_confirm = 0; static char *opt_certout = NULL; +static char *opt_chainout = NULL; /* certificate enrollment and revocation */ static char *opt_oldcert = NULL; @@ -138,8 +136,6 @@ static char *opt_certform_s = "PEM"; static int opt_certform = FORMAT_PEM; static char *opt_keyform_s = "PEM"; static int opt_keyform = FORMAT_PEM; -static char *opt_certsform_s = "PEM"; -static int opt_certsform = FORMAT_PEM; static char *opt_otherpass = NULL; static char *opt_engine = NULL; @@ -196,7 +192,7 @@ static X509_VERIFY_PARAM *vpm = NULL; typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_CONFIG, OPT_SECTION, + OPT_CONFIG, OPT_SECTION, OPT_VERBOSITY, OPT_CMD, OPT_INFOTYPE, OPT_GENINFO, @@ -206,7 +202,7 @@ typedef enum OPTION_choice { OPT_POLICIES, OPT_POLICY_OIDS, OPT_POLICY_OIDS_CRITICAL, OPT_POPO, OPT_CSR, OPT_OUT_TRUSTED, OPT_IMPLICIT_CONFIRM, OPT_DISABLE_CONFIRM, - OPT_CERTOUT, + OPT_CERTOUT, OPT_CHAINOUT, OPT_OLDCERT, OPT_REVREASON, @@ -218,11 +214,11 @@ typedef enum OPTION_choice { OPT_IGNORE_KEYUSAGE, OPT_UNPROTECTED_ERRORS, OPT_EXTRACERTSOUT, OPT_CACERTSOUT, - OPT_REF, OPT_SECRET, OPT_CERT, OPT_KEY, OPT_KEYPASS, + OPT_REF, OPT_SECRET, OPT_CERT, OPT_OWN_TRUSTED, OPT_KEY, OPT_KEYPASS, OPT_DIGEST, OPT_MAC, OPT_EXTRACERTS, OPT_UNPROTECTED_REQUESTS, - OPT_CERTFORM, OPT_KEYFORM, OPT_CERTSFORM, + OPT_CERTFORM, OPT_KEYFORM, OPT_OTHERPASS, #ifndef OPENSSL_NO_ENGINE OPT_ENGINE, @@ -259,6 +255,8 @@ const OPTIONS cmp_options[] = { "Configuration file to use. \"\" = none. Default from env variable OPENSSL_CONF"}, {"section", OPT_SECTION, 's', "Section(s) in config file to get options from. \"\" = 'default'. Default 'cmp'"}, + {"verbosity", OPT_VERBOSITY, 'n', + "Log level; 3=ERR, 4=WARN, 6=INFO, 7=DEBUG, 8=TRACE. Default 6 = INFO"}, OPT_SECTION("Generic message"), {"cmd", OPT_CMD, 's', "CMP request to send: ir/cr/kur/p10cr/rr/genm"}, @@ -267,7 +265,7 @@ const OPTIONS cmp_options[] = { {"geninfo", OPT_GENINFO, 's', "generalInfo integer values to place in request PKIHeader with given OID"}, {OPT_MORE_STR, 0, 0, - "specified in the form :int:, e.g. \"1.2.3:int:987\""}, + "specified in the form :int:, e.g. \"1.2.3.4:int:56789\""}, OPT_SECTION("Certificate enrollment"), {"newkey", OPT_NEWKEY, 's', @@ -302,7 +300,7 @@ const OPTIONS cmp_options[] = { {OPT_MORE_STR, 0, 0, "-1 = NONE, 0 = RAVERIFIED, 1 = SIGNATURE (default), 2 = KEYENC"}, {"csr", OPT_CSR, 's', - "CSR file in PKCS#10 format to use in p10cr for legacy support"}, + "PKCS#10 CSR file in PEM or DER format to use in p10cr for legacy support"}, {"out_trusted", OPT_OUT_TRUSTED, 's', "Certificates to trust when verifying newly enrolled certificates"}, {"implicit_confirm", OPT_IMPLICIT_CONFIRM, '-', @@ -313,6 +311,8 @@ const OPTIONS cmp_options[] = { "confirmation. WARNING: This leads to behavior violating RFC 4210"}, {"certout", OPT_CERTOUT, 's', "File to save newly enrolled certificate"}, + {"chainout", OPT_CHAINOUT, 's', + "File to save the chain of newly enrolled certificate"}, OPT_SECTION("Certificate enrollment and revocation"), @@ -329,9 +329,9 @@ const OPTIONS cmp_options[] = { OPT_SECTION("Message transfer"), {"server", OPT_SERVER, 's', - "[http[s]://]address[:port] of CMP server. Default port 80 or 443."}, + "[http[s]://]address[:port][/path] of CMP server. Default port 80 or 443."}, {OPT_MORE_STR, 0, 0, - "The address may be a DNS name or an IP address"}, + "address may be a DNS name or an IP address; path can be overridden by -path"}, {"proxy", OPT_PROXY, 's', "[http[s]://]address[:port][/path] of HTTP(S) proxy to use; path is ignored"}, {"no_proxy", OPT_NO_PROXY, 's', @@ -339,7 +339,7 @@ const OPTIONS cmp_options[] = { {OPT_MORE_STR, 0, 0, "Default from environment variable 'no_proxy', else 'NO_PROXY', else none"}, {"path", OPT_PATH, 's', - "HTTP path (aka CMP alias) at the CMP server. Default \"/\""}, + "HTTP path (aka CMP alias) at the CMP server. Default from -server, else \"/\""}, {"msg_timeout", OPT_MSG_TIMEOUT, 'n', "Timeout per CMP message round trip (or 0 for none). Default 120 seconds"}, {"total_timeout", OPT_TOTAL_TIMEOUT, 'n', @@ -374,12 +374,16 @@ const OPTIONS cmp_options[] = { {"ref", OPT_REF, 's', "Reference value to use as senderKID in case no -cert is given"}, {"secret", OPT_SECRET, 's', - "Password source for client authentication with a pre-shared key (secret)"}, + "Prefer PBM (over signatures) for protecting msgs with given password source"}, {"cert", OPT_CERT, 's', - "Client's current certificate (needed unless using -secret for PBM);"}, + "Client's CMP signer certificate; its public key must match the -key argument"}, + {OPT_MORE_STR, 0, 0, + "This also used as default reference for subject DN and SANs."}, {OPT_MORE_STR, 0, 0, - "any further certs included are appended in extraCerts field"}, - {"key", OPT_KEY, 's', "Private key for the client's current certificate"}, + "Any further certs included are appended to the untrusted certs"}, + {"own_trusted", OPT_OWN_TRUSTED, 's', + "Optional certs to verify chain building for own CMP signer cert"}, + {"key", OPT_KEY, 's', "CMP signer private key, not used when -secret given"}, {"keypass", OPT_KEYPASS, 's', "Client private key (and cert and old cert file) pass phrase source"}, {"digest", OPT_DIGEST, 's', @@ -387,19 +391,17 @@ const OPTIONS cmp_options[] = { {"mac", OPT_MAC, 's', "MAC algorithm to use in PBM-based message protection. Default \"hmac-sha1\""}, {"extracerts", OPT_EXTRACERTS, 's', - "Certificates to append in extraCerts field of outgoing messages"}, + "Certificates to append in extraCerts field of outgoing messages."}, + {OPT_MORE_STR, 0, 0, + "This can be used as the default CMP signer cert chain to include"}, {"unprotected_requests", OPT_UNPROTECTED_REQUESTS, '-', "Send messages without CMP-level protection"}, OPT_SECTION("Credentials format"), {"certform", OPT_CERTFORM, 's', "Format (PEM or DER) to use when saving a certificate to a file. Default PEM"}, - {OPT_MORE_STR, 0, 0, - "This also determines format to use for writing (not supported for P12)"}, {"keyform", OPT_KEYFORM, 's', - "Format to assume when reading key files. Default PEM"}, - {"certsform", OPT_CERTSFORM, 's', - "Format (PEM/DER/P12) to try first reading multiple certs. Default PEM"}, + "Format of the key input (ENGINE, other values ignored)"}, {"otherpass", OPT_OTHERPASS, 's', "Pass phrase source potentially needed for loading certificates of others"}, #ifndef OPENSSL_NO_ENGINE @@ -513,7 +515,7 @@ typedef union { long *num_long; } varref; static varref cmp_vars[] = { /* must be in same order as enumerated above! */ - {&opt_config}, {&opt_section}, + {&opt_config}, {&opt_section}, {(char **)&opt_verbosity}, {&opt_cmd_s}, {&opt_infotype_s}, {&opt_geninfo}, @@ -524,7 +526,7 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {(char **)&opt_popo}, {&opt_csr}, {&opt_out_trusted}, {(char **)&opt_implicit_confirm}, {(char **)&opt_disable_confirm}, - {&opt_certout}, + {&opt_certout}, {&opt_chainout}, {&opt_oldcert}, {(char **)&opt_revreason}, @@ -536,11 +538,12 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {(char **)&opt_ignore_keyusage}, {(char **)&opt_unprotected_errors}, {&opt_extracertsout}, {&opt_cacertsout}, - {&opt_ref}, {&opt_secret}, {&opt_cert}, {&opt_key}, {&opt_keypass}, + {&opt_ref}, {&opt_secret}, + {&opt_cert}, {&opt_own_trusted}, {&opt_key}, {&opt_keypass}, {&opt_digest}, {&opt_mac}, {&opt_extracerts}, {(char **)&opt_unprotected_requests}, - {&opt_certform_s}, {&opt_keyform_s}, {&opt_certsform_s}, + {&opt_certform_s}, {&opt_keyform_s}, {&opt_otherpass}, #ifndef OPENSSL_NO_ENGINE {&opt_engine}, @@ -570,28 +573,32 @@ static varref cmp_vars[] = { /* must be in same order as enumerated above! */ {NULL} }; -#ifndef NDEBUG -# define FUNC (strcmp(OPENSSL_FUNC, "(unknown function)") == 0 \ - ? "CMP" : "OPENSSL_FUNC") -# define PRINT_LOCATION(bio) BIO_printf(bio, "%s:%s:%d:", \ - FUNC, OPENSSL_FILE, OPENSSL_LINE) -#else -# define PRINT_LOCATION(bio) ((void)0) -#endif -#define CMP_print(bio, prefix, msg, a1, a2, a3) \ - (PRINT_LOCATION(bio), \ - BIO_printf(bio, "CMP %s: " msg "\n", prefix, a1, a2, a3)) -#define CMP_INFO(msg, a1, a2, a3) CMP_print(bio_out, "info", msg, a1, a2, a3) +#define FUNC (strcmp(OPENSSL_FUNC, "(unknown function)") == 0 \ + ? "CMP" : OPENSSL_FUNC) +#define CMP_print(bio, level, prefix, msg, a1, a2, a3) \ + ((void)(level > opt_verbosity ? 0 : \ + (BIO_printf(bio, "%s:%s:%d:CMP %s: " msg "\n", \ + FUNC, OPENSSL_FILE, OPENSSL_LINE, prefix, a1, a2, a3)))) +#define CMP_DEBUG(m, a1, a2, a3) \ + CMP_print(bio_out, OSSL_CMP_LOG_DEBUG, "debug", m, a1, a2, a3) +#define CMP_debug(msg) CMP_DEBUG(msg"%s%s%s", "", "", "") +#define CMP_debug1(msg, a1) CMP_DEBUG(msg"%s%s", a1, "", "") +#define CMP_debug2(msg, a1, a2) CMP_DEBUG(msg"%s", a1, a2, "") +#define CMP_debug3(msg, a1, a2, a3) CMP_DEBUG(msg, a1, a2, a3) +#define CMP_INFO(msg, a1, a2, a3) \ + CMP_print(bio_out, OSSL_CMP_LOG_INFO, "info", msg, a1, a2, a3) #define CMP_info(msg) CMP_INFO(msg"%s%s%s", "", "", "") #define CMP_info1(msg, a1) CMP_INFO(msg"%s%s", a1, "", "") #define CMP_info2(msg, a1, a2) CMP_INFO(msg"%s", a1, a2, "") #define CMP_info3(msg, a1, a2, a3) CMP_INFO(msg, a1, a2, a3) -#define CMP_WARN(m, a1, a2, a3) CMP_print(bio_out, "warning", m, a1, a2, a3) +#define CMP_WARN(m, a1, a2, a3) \ + CMP_print(bio_out, OSSL_CMP_LOG_WARNING, "warning", m, a1, a2, a3) #define CMP_warn(msg) CMP_WARN(msg"%s%s%s", "", "", "") #define CMP_warn1(msg, a1) CMP_WARN(msg"%s%s", a1, "", "") #define CMP_warn2(msg, a1, a2) CMP_WARN(msg"%s", a1, a2, "") #define CMP_warn3(msg, a1, a2, a3) CMP_WARN(msg, a1, a2, a3) -#define CMP_ERR(msg, a1, a2, a3) CMP_print(bio_err, "error", msg, a1, a2, a3) +#define CMP_ERR(msg, a1, a2, a3) \ + CMP_print(bio_err, OSSL_CMP_LOG_ERR, "error", msg, a1, a2, a3) #define CMP_err(msg) CMP_ERR(msg"%s%s%s", "", "", "") #define CMP_err1(msg, a1) CMP_ERR(msg"%s%s", a1, "", "") #define CMP_err2(msg, a1, a2) CMP_ERR(msg"%s", a1, a2, "") @@ -603,54 +610,16 @@ static int print_to_bio_out(const char *func, const char *file, int line, return OSSL_CMP_print_to_bio(bio_out, func, file, line, level, msg); } -/* code duplicated from crypto/cmp/cmp_util.c */ -static int sk_X509_add1_cert(STACK_OF(X509) *sk, X509 *cert, - int no_dup, int prepend) +static int set_verbosity(int level) { - if (no_dup) { - /* - * not using sk_X509_set_cmp_func() and sk_X509_find() - * because this re-orders the certs on the stack - */ - int i; - - for (i = 0; i < sk_X509_num(sk); i++) { - if (X509_cmp(sk_X509_value(sk, i), cert) == 0) - return 1; - } - } - if (!X509_up_ref(cert)) - return 0; - if (!sk_X509_insert(sk, cert, prepend ? 0 : -1)) { - X509_free(cert); + if (level < OSSL_CMP_LOG_EMERG || level > OSSL_CMP_LOG_MAX) { + CMP_err1("Logging verbosity level %d out of range (0 .. 8)", level); return 0; } + opt_verbosity = level; return 1; } -/* code duplicated from crypto/cmp/cmp_util.c */ -static int sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, - int no_self_signed, int no_dups, int prepend) -/* compiler would allow 'const' for the list of certs, yet they are up-ref'ed */ -{ - int i; - - if (sk == NULL) - return 0; - if (certs == NULL) - return 1; - for (i = 0; i < sk_X509_num(certs); i++) { - X509 *cert = sk_X509_value(certs, i); - - if (!no_self_signed || X509_check_issued(cert, cert) != X509_V_OK) { - if (!sk_X509_add1_cert(sk, cert, no_dups, prepend)) - return 0; - } - } - return 1; -} - -/* TODO potentially move to apps/lib/apps.c */ static char *next_item(char *opt) /* in list separated by comma and/or space */ { /* advance to separator (comma or whitespace), if any */ @@ -690,87 +659,6 @@ static X509 *load_cert_pwd(const char *uri, const char *pass, const char *desc) return cert; } -/* TODO remove when PR #4930 is merged */ -static int load_pkcs12(BIO *in, const char *desc, - pem_password_cb *pem_cb, void *cb_data, - EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) -{ - const char *pass; - char tpass[PEM_BUFSIZE]; - int len; - int ret = 0; - PKCS12 *p12 = d2i_PKCS12_bio(in, NULL); - - if (desc == NULL) - desc = "PKCS12 input"; - if (p12 == NULL) { - BIO_printf(bio_err, "error loading PKCS12 file for %s\n", desc); - goto die; - } - - /* See if an empty password will do */ - if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) { - pass = ""; - } else { - if (pem_cb == NULL) - pem_cb = wrap_password_callback; - len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data); - if (len < 0) { - BIO_printf(bio_err, "passphrase callback error for %s\n", desc); - goto die; - } - if (len < PEM_BUFSIZE) - tpass[len] = 0; - if (!PKCS12_verify_mac(p12, tpass, len)) { - BIO_printf(bio_err, - "mac verify error (wrong password?) in PKCS12 file for %s\n", - desc); - goto die; - } - pass = tpass; - } - ret = PKCS12_parse(p12, pass, pkey, cert, ca); - die: - PKCS12_free(p12); - return ret; -} - -/* TODO potentially move this and related functions to apps/lib/apps.c */ -static int adjust_format(const char **infile, int format, int engine_ok) -{ - if (!strncasecmp(*infile, "http://", 7) - || !strncasecmp(*infile, "https://", 8)) { - format = FORMAT_HTTP; - } else if (engine_ok && strncasecmp(*infile, "engine:", 7) == 0) { - *infile += 7; - format = FORMAT_ENGINE; - } else { - if (strncasecmp(*infile, "file:", 5) == 0) - *infile += 5; - /* - * the following is a heuristic whether first to try PEM or DER - * or PKCS12 as the input format for files - */ - if (strlen(*infile) >= 4) { - const char *extension = *infile + strlen(*infile) - 4; - - if (strncasecmp(extension, ".crt", 4) == 0 - || strncasecmp(extension, ".pem", 4) == 0) - /* weak recognition of PEM format */ - format = FORMAT_PEM; - else if (strncasecmp(extension, ".cer", 4) == 0 - || strncasecmp(extension, ".der", 4) == 0) - /* weak recognition of DER format */ - format = FORMAT_ASN1; - else if (strncasecmp(extension, ".p12", 4) == 0) - /* weak recognition of PKCS#12 format */ - format = FORMAT_PKCS12; - /* else retain given format */ - } - } - return format; -} - /* * TODO potentially move this and related functions to apps/lib/ * or even better extend OSSL_STORE with type OSSL_STORE_INFO_CRL @@ -779,18 +667,13 @@ static X509_REQ *load_csr_autofmt(const char *infile, const char *desc) { X509_REQ *csr; BIO *bio_bak = bio_err; - int can_retry; - int format = adjust_format(&infile, FORMAT_PEM, 0); - can_retry = format == FORMAT_PEM || format == FORMAT_ASN1; - if (can_retry) - bio_err = NULL; /* do not show errors on more than one try */ - csr = load_csr(infile, format, desc); + bio_err = NULL; /* do not show errors on more than one try */ + csr = load_csr(infile, FORMAT_PEM, desc); bio_err = bio_bak; - if (csr == NULL && can_retry) { + if (csr == NULL) { ERR_clear_error(); - format = (format == FORMAT_PEM ? FORMAT_ASN1 : FORMAT_PEM); - csr = load_csr(infile, format, desc); + csr = load_csr(infile, FORMAT_ASN1, desc); } if (csr == NULL) { ERR_print_errors(bio_err); @@ -800,98 +683,59 @@ static X509_REQ *load_csr_autofmt(const char *infile, const char *desc) return csr; } -/* TODO replace by calling generalized load_certs() when PR #4930 is merged */ -static int load_certs_preliminary(const char *file, STACK_OF(X509) **certs, - int format, const char *pass, - const char *desc) +static void warn_cert_msg(const char *uri, X509 *cert, const char *msg) { - X509 *cert = NULL; - int ret = 0; + char *subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); - if (format == FORMAT_PKCS12) { - BIO *bio = bio_open_default(file, 'r', format); + CMP_warn3("certificate from '%s' with subject '%s' %s", uri, subj, msg); + OPENSSL_free(subj); +} - if (bio != NULL) { - EVP_PKEY *pkey = NULL; /* pkey is needed until PR #4930 is merged */ - PW_CB_DATA cb_data; +static void warn_cert(const char *uri, X509 *cert, int warn_EE) +{ + int res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), + X509_get0_notAfter(cert)); - cb_data.password = pass; - cb_data.prompt_info = file; - ret = load_pkcs12(bio, desc, wrap_password_callback, - &cb_data, &pkey, &cert, certs); - EVP_PKEY_free(pkey); - BIO_free(bio); - } - } else if (format == FORMAT_ASN1) { /* load only one cert in this case */ - CMP_warn1("can load only one certificate in DER format from %s", file); - cert = load_cert_pass(file, 0, pass, desc); - } - if (format == FORMAT_PKCS12 || format == FORMAT_ASN1) { - if (cert) { - if (*certs == NULL) - *certs = sk_X509_new_null(); - if (*certs != NULL) - ret = sk_X509_insert(*certs, cert, 0); - else - X509_free(cert); - } - } else { - ret = load_certs(file, certs, format, pass, desc); - } - return ret; + if (res != 0) + warn_cert_msg(uri, cert, res > 0 ? "has expired" : "not yet valid"); + if (warn_EE && (X509_get_extension_flags(cert) & EXFLAG_CA) == 0) + warn_cert_msg(uri, cert, "is not a CA cert"); } -static void warn_certs_expired(const char *file, STACK_OF(X509) **certs) +static void warn_certs(const char *uri, STACK_OF(X509) *certs, int warn_EE) { - int i, res; - X509 *cert; - char *subj; + int i; - for (i = 0; i < sk_X509_num(*certs); i++) { - cert = sk_X509_value(*certs, i); - res = X509_cmp_timeframe(vpm, X509_get0_notBefore(cert), - X509_get0_notAfter(cert)); - if (res != 0) { - subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); - CMP_warn3("certificate from '%s' with subject '%s' %s", file, subj, - res > 0 ? "has expired" : "not yet valid"); - OPENSSL_free(subj); - } - } + for (i = 0; i < sk_X509_num(certs); i++) + warn_cert(uri, sk_X509_value(certs, i), warn_EE); } -/* - * TODO potentially move this and related functions to apps/lib/ - * or even better extend OSSL_STORE with type OSSL_STORE_INFO_CERTS - */ -static int load_certs_autofmt(const char *infile, STACK_OF(X509) **certs, - int exclude_http, const char *pass, - const char *desc) +/* TODO potentially move this and related functions to apps/lib/apps.c */ +static int load_cert_certs(const char *uri, + X509 **pcert, STACK_OF(X509) **pcerts, + int exclude_http, const char *pass, const char *desc) { int ret = 0; char *pass_string; - BIO *bio_bak = bio_err; - int format = adjust_format(&infile, opt_certsform, 0); - if (exclude_http && format == FORMAT_HTTP) { + if (exclude_http && (strncasecmp(uri, "http://", 7) == 0 + || strncasecmp(uri, "https://", 8) == 0)) { BIO_printf(bio_err, "error: HTTP retrieval not allowed for %s\n", desc); return ret; } pass_string = get_passwd(pass, desc); - if (format != FORMAT_HTTP) - bio_err = NULL; /* do not show errors on more than one try */ - ret = load_certs_preliminary(infile, certs, format, pass_string, desc); - bio_err = bio_bak; - if (!ret && format != FORMAT_HTTP) { - int format2 = format == FORMAT_PEM ? FORMAT_ASN1 : FORMAT_PEM; - - ERR_clear_error(); - ret = load_certs_preliminary(infile, certs, format2, pass_string, desc); - } + ret = load_key_certs_crls(uri, 0, pass_string, desc, NULL, NULL, + pcert, pcerts, NULL, NULL); clear_free(pass_string); - if (ret) - warn_certs_expired(infile, certs); + if (ret) { + if (pcert != NULL) + warn_cert(uri, *pcert, 0); + warn_certs(uri, *pcerts, 1); + } else { + sk_X509_pop_free(*pcerts, X509_free); + *pcerts = NULL; + } return ret; } @@ -1044,72 +888,12 @@ static OSSL_CMP_MSG *read_write_req_resp(OSSL_CMP_CTX *ctx, return res; } -/* - * parse string as integer value, not allowing trailing garbage, see also - * https://www.gnu.org/software/libc/manual/html_node/Parsing-of-Integers.html - * - * returns integer value, or INT_MIN on error - */ -static int atoint(const char *str) -{ - char *tailptr; - long res = strtol(str, &tailptr, 10); - - if ((*tailptr != '\0') || (res < INT_MIN) || (res > INT_MAX)) - return INT_MIN; - else - return (int)res; -} - -static int parse_addr(char **opt_string, int port, const char *name) -{ - char *port_string; - - if (strncasecmp(*opt_string, OSSL_HTTP_PREFIX, - strlen(OSSL_HTTP_PREFIX)) == 0) { - *opt_string += strlen(OSSL_HTTP_PREFIX); - } else if (strncasecmp(*opt_string, OSSL_HTTPS_PREFIX, - strlen(OSSL_HTTPS_PREFIX)) == 0) { - *opt_string += strlen(OSSL_HTTPS_PREFIX); - if (port == 0) - port = 443; /* == integer value of OSSL_HTTPS_PORT */ - } - - if ((port_string = strrchr(*opt_string, ':')) == NULL) - return port; /* using default */ - *(port_string++) = '\0'; - port = atoint(port_string); - if ((port <= 0) || (port > 65535)) { - CMP_err2("invalid %s port '%s' given, sane range 1-65535", - name, port_string); - return -1; - } - return port; -} - -static int set1_store_parameters(X509_STORE *ts) -{ - if (ts == NULL) - return 0; - - /* copy vpm to store */ - if (!X509_STORE_set1_param(ts, vpm /* may be NULL */)) { - BIO_printf(bio_err, "error setting verification parameters\n"); - OSSL_CMP_CTX_print_errors(cmp_ctx); - return 0; - } - - X509_STORE_set_verify_cb(ts, X509_STORE_CTX_print_verify_cb); - - return 1; -} - static int set_name(const char *str, int (*set_fn) (OSSL_CMP_CTX *ctx, const X509_NAME *name), OSSL_CMP_CTX *ctx, const char *desc) { if (str != NULL) { - X509_NAME *n = parse_name(str, MBSTRING_ASC, 0, desc); + X509_NAME *n = parse_name(str, MBSTRING_ASC, 1, desc); if (n == NULL) return 0; @@ -1171,28 +955,42 @@ static X509_STORE *load_certstore(char *input, const char *desc) X509_STORE *store = NULL; STACK_OF(X509) *certs = NULL; - if (input == NULL) - goto err; - while (input != NULL) { - char *next = next_item(input); \ + char *next = next_item(input); + int ok; - if (!load_certs_autofmt(input, &certs, 1, opt_otherpass, desc) - || !(store = sk_X509_to_store(store, certs))) { - /* CMP_err("out of memory"); */ + if (!load_cert_certs(input, NULL, &certs, 1, opt_otherpass, desc)) { X509_STORE_free(store); - store = NULL; - goto err; + return NULL; } + ok = (store = sk_X509_to_store(store, certs)) != NULL; sk_X509_pop_free(certs, X509_free); certs = NULL; + if (!ok) + return NULL; input = next; } - err: - sk_X509_pop_free(certs, X509_free); return store; } +static X509_STORE *load_trusted(char *input, int for_new_cert, const char *desc) +{ + X509_STORE *ts = load_certstore(input, desc); + + if (ts == NULL) + return NULL; + X509_STORE_set_verify_cb(ts, X509_STORE_CTX_print_verify_cb); + + /* copy vpm to store */ + if (X509_STORE_set1_param(ts, vpm /* may be NULL */) + && (for_new_cert || truststore_set_host_etc(ts, NULL))) + return ts; + BIO_printf(bio_err, "error setting verification parameters\n"); + OSSL_CMP_CTX_print_errors(cmp_ctx); + X509_STORE_free(ts); + return NULL; +} + /* TODO potentially move to apps/lib/apps.c */ static STACK_OF(X509) *load_certs_multifile(char *files, const char *pass, const char *desc) @@ -1208,9 +1006,10 @@ static STACK_OF(X509) *load_certs_multifile(char *files, while (files != NULL) { char *next = next_item(files); - if (!load_certs_autofmt(files, &certs, 0, pass, desc)) + if (!load_cert_certs(files, NULL, &certs, 0, pass, desc)) goto err; - if (!sk_X509_add1_certs(result, certs, 0, 1 /* no dups */, 0)) + if (!X509_add_certs(result, certs, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) goto oom; sk_X509_pop_free(certs, X509_free); certs = NULL; @@ -1227,31 +1026,20 @@ static STACK_OF(X509) *load_certs_multifile(char *files, } typedef int (*add_X509_stack_fn_t)(void *ctx, const STACK_OF(X509) *certs); -typedef int (*add_X509_fn_t)(void *ctx, const X509 *cert); static int setup_certs(char *files, const char *desc, void *ctx, - add_X509_stack_fn_t addn_fn, add_X509_fn_t add1_fn) + add_X509_stack_fn_t set1_fn) { - int ret = 1; + STACK_OF(X509) *certs; + int ok; - if (files != NULL) { - STACK_OF(X509) *certs = load_certs_multifile(files, opt_otherpass, - desc); - if (certs == NULL) { - ret = 0; - } else { - if (addn_fn != NULL) { - ret = (*addn_fn)(ctx, certs); - } else { - int i; - - for (i = 0; i < sk_X509_num(certs /* may be NULL */); i++) - ret &= (*add1_fn)(ctx, sk_X509_value(certs, i)); - } - sk_X509_pop_free(certs, X509_free); - } - } - return ret; + if (files == NULL) + return 1; + if ((certs = load_certs_multifile(files, opt_otherpass, desc)) == NULL) + return 0; + ok = (*set1_fn)(ctx, certs); + sk_X509_pop_free(certs, X509_free); + return ok; } @@ -1303,20 +1091,14 @@ static int transform_opts(void) return 0; } - if (opt_certsform_s != NULL - && !opt_format(opt_certsform_s, OPT_FMT_PEMDER | OPT_FMT_PKCS12, - &opt_certsform)) { - CMP_err("unknown option given for certificate list loading format"); - return 0; - } - return 1; } static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) { OSSL_CMP_CTX *ctx; /* extra CMP (client) ctx partly used by server */ - OSSL_CMP_SRV_CTX *srv_ctx = ossl_cmp_mock_srv_new(); + OSSL_CMP_SRV_CTX *srv_ctx = ossl_cmp_mock_srv_new(app_get0_libctx(), + app_get0_propq()); if (srv_ctx == NULL) return NULL; @@ -1383,22 +1165,18 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) if (opt_srv_trusted != NULL) { X509_STORE *ts = - load_certstore(opt_srv_trusted, "certificates trusted by server"); + load_trusted(opt_srv_trusted, 0, "certs trusted by server"); - if (ts == NULL) - goto err; - if (!set1_store_parameters(ts) - || !truststore_set_host_etc(ts, NULL) - || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { + if (ts == NULL || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { X509_STORE_free(ts); goto err; } } else { CMP_warn("server will not be able to handle signature-protected requests since -srv_trusted is not given"); } - if (!setup_certs(opt_srv_untrusted, "untrusted certificates", ctx, - (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted_certs, - NULL)) + if (!setup_certs(opt_srv_untrusted, + "untrusted certificates for mock server", ctx, + (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted)) goto err; if (opt_rsp_cert == NULL) { @@ -1420,12 +1198,10 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) /* TODO find a cleaner solution not requiring type casts */ if (!setup_certs(opt_rsp_extracerts, "CMP extra certificates for mock server", srv_ctx, - (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_chainOut, - NULL)) + (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_chainOut)) goto err; if (!setup_certs(opt_rsp_capubs, "caPubs for mock server", srv_ctx, - (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_caPubsOut, - NULL)) + (add_X509_stack_fn_t)ossl_cmp_mock_srv_set1_caPubsOut)) goto err; (void)ossl_cmp_mock_srv_set_pollCount(srv_ctx, opt_poll_count); (void)ossl_cmp_mock_srv_set_checkAfterTime(srv_ctx, opt_check_after); @@ -1479,16 +1255,15 @@ static OSSL_CMP_SRV_CTX *setup_srv_ctx(ENGINE *engine) static int setup_verification_ctx(OSSL_CMP_CTX *ctx) { if (!setup_certs(opt_untrusted, "untrusted certificates", ctx, - (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted_certs, - NULL)) - goto err; + (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_untrusted)) + return 0; if (opt_srvcert != NULL || opt_trusted != NULL) { - X509_STORE *ts = NULL; + X509 *srvcert; + X509_STORE *ts; + int ok; if (opt_srvcert != NULL) { - X509 *srvcert; - if (opt_trusted != NULL) { CMP_warn("-trusted option is ignored since -srvcert option is present"); opt_trusted = NULL; @@ -1499,33 +1274,22 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) } srvcert = load_cert_pwd(opt_srvcert, opt_otherpass, "directly trusted CMP server certificate"); - if (srvcert == NULL) - /* - * opt_otherpass is needed in case - * opt_srvcert is an encrypted PKCS#12 file - */ - goto err; - if (!OSSL_CMP_CTX_set1_srvCert(ctx, srvcert)) { - X509_free(srvcert); - goto oom; - } + ok = srvcert != NULL && OSSL_CMP_CTX_set1_srvCert(ctx, srvcert); X509_free(srvcert); - if ((ts = X509_STORE_new()) == NULL) - goto oom; + if (!ok) + return 0; } - if (opt_trusted != NULL - && (ts = load_certstore(opt_trusted, "trusted certificates")) - == NULL) - goto err; - if (!set1_store_parameters(ts) /* also copies vpm */ - /* - * clear any expected host/ip/email address; - * opt_expect_sender is used instead - */ - || !truststore_set_host_etc(ts, NULL) - || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { - X509_STORE_free(ts); - goto oom; + if (opt_trusted != NULL) { + /* + * the 0 arg below clears any expected host/ip/email address; + * opt_expect_sender is used instead + */ + ts = load_trusted(opt_trusted, 0, "certs trusted by client"); + + if (ts == NULL || !OSSL_CMP_CTX_set0_trustedStore(ctx, ts)) { + X509_STORE_free(ts); + return 0; + } } } @@ -1538,14 +1302,11 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) if (opt_out_trusted != NULL) { /* for use in OSSL_CMP_certConf_cb() */ X509_VERIFY_PARAM *out_vpm = NULL; X509_STORE *out_trusted = - load_certstore(opt_out_trusted, - "trusted certs for verifying newly enrolled cert"); + load_trusted(opt_out_trusted, 1, + "trusted certs for verifying newly enrolled cert"); if (out_trusted == NULL) - goto err; - /* any -verify_hostname, -verify_ip, and -verify_email apply here */ - if (!set1_store_parameters(out_trusted)) - goto oom; + return 0; /* ignore any -attime here, new certs are current anyway */ out_vpm = X509_STORE_get0_param(out_trusted); X509_VERIFY_PARAM_clear_flags(out_vpm, X509_V_FLAG_USE_CHECK_TIME); @@ -1559,14 +1320,7 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) if (opt_implicit_confirm) (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM, 1); - (void)OSSL_CMP_CTX_set_certConf_cb(ctx, OSSL_CMP_certConf_cb); - return 1; - - oom: - CMP_err("out of memory"); - err: - return 0; } #ifndef OPENSSL_NO_SOCK @@ -1576,7 +1330,7 @@ static int setup_verification_ctx(OSSL_CMP_CTX *ctx) */ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) { - STACK_OF(X509) *untrusted_certs = OSSL_CMP_CTX_get0_untrusted_certs(ctx); + STACK_OF(X509) *untrusted = OSSL_CMP_CTX_get0_untrusted(ctx); EVP_PKEY *pkey = NULL; X509_STORE *trust_store = NULL; SSL_CTX *ssl_ctx; @@ -1600,46 +1354,57 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (opt_tls_cert != NULL && opt_tls_key != NULL) { X509 *cert; STACK_OF(X509) *certs = NULL; + int ok; - if (!load_certs_autofmt(opt_tls_cert, &certs, 0, opt_tls_keypass, - "TLS client certificate (optionally with chain)")) - /* - * opt_tls_keypass is needed in case opt_tls_cert is an encrypted - * PKCS#12 file - */ + if (!load_cert_certs(opt_tls_cert, &cert, &certs, 0, opt_tls_keypass, + "TLS client certificate (optionally with chain)")) + /* need opt_tls_keypass if opt_tls_cert is encrypted PKCS#12 file */ goto err; - cert = sk_X509_delete(certs, 0); - if (cert == NULL || SSL_CTX_use_certificate(ssl_ctx, cert) <= 0) { - CMP_err1("unable to use client TLS certificate file '%s'", - opt_tls_cert); - X509_free(cert); - sk_X509_pop_free(certs, X509_free); - goto err; - } - X509_free(cert); /* we do not need the handle any more */ + ok = SSL_CTX_use_certificate(ssl_ctx, cert) > 0; + X509_free(cert); /* * Any further certs and any untrusted certs are used for constructing * the chain to be provided with the TLS client cert to the TLS server. */ - if (!SSL_CTX_set0_chain(ssl_ctx, certs)) { - CMP_err("could not set TLS client cert chain"); + if (!ok || !SSL_CTX_set0_chain(ssl_ctx, certs)) { + CMP_err1("unable to use client TLS certificate file '%s'", + opt_tls_cert); sk_X509_pop_free(certs, X509_free); goto err; } - for (i = 0; i < sk_X509_num(untrusted_certs); i++) { - cert = sk_X509_value(untrusted_certs, i); + for (i = 0; i < sk_X509_num(untrusted); i++) { + cert = sk_X509_value(untrusted, i); if (!SSL_CTX_add1_chain_cert(ssl_ctx, cert)) { CMP_err("could not add untrusted cert to TLS client cert chain"); goto err; } } - if (!SSL_CTX_build_cert_chain(ssl_ctx, - SSL_BUILD_CHAIN_FLAG_UNTRUSTED | - SSL_BUILD_CHAIN_FLAG_NO_ROOT)) { - CMP_warn("could not build cert chain for own TLS cert"); - OSSL_CMP_CTX_print_errors(ctx); + + { + X509_VERIFY_PARAM *tls_vpm = NULL; + unsigned long bak_flags = 0; /* compiler warns without init */ + + if (trust_store != NULL) { + tls_vpm = X509_STORE_get0_param(trust_store); + bak_flags = X509_VERIFY_PARAM_get_flags(tls_vpm); + /* disable any cert status/revocation checking etc. */ + X509_VERIFY_PARAM_clear_flags(tls_vpm, + ~(X509_V_FLAG_USE_CHECK_TIME + | X509_V_FLAG_NO_CHECK_TIME)); + } + CMP_debug("trying to build cert chain for own TLS cert"); + if (SSL_CTX_build_cert_chain(ssl_ctx, + SSL_BUILD_CHAIN_FLAG_UNTRUSTED | + SSL_BUILD_CHAIN_FLAG_NO_ROOT)) { + CMP_debug("success building cert chain for own TLS cert"); + } else { + OSSL_CMP_CTX_print_errors(ctx); + CMP_warn("could not build cert chain for own TLS cert"); + } + if (trust_store != NULL) + X509_VERIFY_PARAM_set_flags(tls_vpm, bak_flags); } /* If present we append to the list also the certs from opt_tls_extra */ @@ -1714,19 +1479,19 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) */ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) { - if (!opt_unprotected_requests && opt_secret == NULL && opt_cert == NULL) { - CMP_err("must give client credentials unless -unprotected_requests is set"); - goto err; + if (!opt_unprotected_requests && opt_secret == NULL && opt_key == NULL) { + CMP_err("must give -key or -secret unless -unprotected_requests is used"); + return 0; } if (opt_ref == NULL && opt_cert == NULL && opt_subject == NULL) { /* cert or subject should determine the sender */ CMP_err("must give -ref if no -cert and no -subject given"); - goto err; + return 0; } if (!opt_secret && ((opt_cert == NULL) != (opt_key == NULL))) { CMP_err("must give both -cert and -key options or neither"); - goto err; + return 0; } if (opt_secret != NULL) { char *pass_string = get_passwd(opt_secret, "PBMAC"); @@ -1739,15 +1504,15 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) strlen(pass_string)); clear_free(pass_string); if (res == 0) - goto err; + return 0; } if (opt_cert != NULL || opt_key != NULL) - CMP_warn("no signature-based protection used since -secret is given"); + CMP_warn("-cert and -key not used for protection since -secret is given"); } if (opt_ref != NULL && !OSSL_CMP_CTX_set1_referenceValue(ctx, (unsigned char *)opt_ref, strlen(opt_ref))) - goto err; + return 0; if (opt_key != NULL) { EVP_PKEY *pkey = load_key_pwd(opt_key, opt_keyform, opt_keypass, engine, @@ -1755,50 +1520,46 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (pkey == NULL || !OSSL_CMP_CTX_set1_pkey(ctx, pkey)) { EVP_PKEY_free(pkey); - goto err; + return 0; } EVP_PKEY_free(pkey); } - if (opt_secret == NULL && opt_srvcert == NULL && opt_trusted == NULL) { - CMP_err("missing -secret or -srvcert or -trusted"); - goto err; - } + if (opt_secret == NULL && opt_srvcert == NULL && opt_trusted == NULL) + CMP_warn("will not authenticate server due to missing -secret, -trusted, or -srvcert"); if (opt_cert != NULL) { X509 *cert; STACK_OF(X509) *certs = NULL; + X509_STORE *own_trusted = NULL; int ok; - if (!load_certs_autofmt(opt_cert, &certs, 0, opt_keypass, - "CMP client certificate (and optionally extra certs)")) + if (!load_cert_certs(opt_cert, &cert, &certs, 0, opt_keypass, + "CMP client certificate (optionally with chain)")) /* opt_keypass is needed if opt_cert is an encrypted PKCS#12 file */ - goto err; - - cert = sk_X509_delete(certs, 0); - if (cert == NULL) { - CMP_err("no client certificate found"); - sk_X509_pop_free(certs, X509_free); - goto err; - } + return 0; ok = OSSL_CMP_CTX_set1_cert(ctx, cert); X509_free(cert); - - if (ok) { - /* add any remaining certs to the list of untrusted certs */ - STACK_OF(X509) *untrusted = OSSL_CMP_CTX_get0_untrusted_certs(ctx); - ok = untrusted != NULL ? - sk_X509_add1_certs(untrusted, certs, 0, 1 /* no dups */, 0) : - OSSL_CMP_CTX_set1_untrusted_certs(ctx, certs); + if (!ok) { + CMP_err("out of memory"); + } else { + if (opt_own_trusted != NULL) { + own_trusted = load_trusted(opt_own_trusted, 0, + "trusted certs for verifying own CMP signer cert"); + ok = own_trusted != NULL; + } + ok = ok && OSSL_CMP_CTX_build_cert_chain(ctx, own_trusted, certs); } + X509_STORE_free(own_trusted); sk_X509_pop_free(certs, X509_free); if (!ok) - goto oom; + return 0; + } else if (opt_own_trusted != NULL) { + CMP_warn("-own_trusted option is ignored without -cert"); } if (!setup_certs(opt_extracerts, "extra certificates for CMP", ctx, - (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_extraCertsOut, - NULL)) - goto err; + (add_X509_stack_fn_t)OSSL_CMP_CTX_set1_extraCertsOut)) + return 0; cleanse(opt_otherpass); if (opt_unprotected_requests) @@ -1809,26 +1570,24 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if (digest == NID_undef) { CMP_err1("digest algorithm name not recognized: '%s'", opt_digest); - goto err; + return 0; + } + if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest) + || !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest)) { + CMP_err1("digest algorithm name not supported: '%s'", opt_digest); + return 0; } - (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_DIGEST_ALGNID, digest); - (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_OWF_ALGNID, digest); } if (opt_mac != NULL) { int mac = OBJ_ln2nid(opt_mac); if (mac == NID_undef) { CMP_err1("MAC algorithm name not recognized: '%s'", opt_mac); - goto err; + return 0; } (void)OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_MAC_ALGNID, mac); } return 1; - - oom: - CMP_err("out of memory"); - err: - return 0; } /* @@ -1838,11 +1597,12 @@ static int setup_protection_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) */ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) { - if (opt_subject == NULL && opt_oldcert == NULL && opt_cert == NULL) + if (opt_subject == NULL && opt_oldcert == NULL && opt_cert == NULL + && opt_cmd != CMP_RR && opt_cmd != CMP_GENM) CMP_warn("no -subject given, neither -oldcert nor -cert available as default"); if (!set_name(opt_subject, OSSL_CMP_CTX_set1_subjectName, ctx, "subject") || !set_name(opt_issuer, OSSL_CMP_CTX_set1_issuer, ctx, "issuer")) - goto err; + return 0; if (opt_newkey != NULL) { const char *file = opt_newkey; @@ -1860,7 +1620,7 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) cleanse(opt_newkeypass); if (pkey == NULL || !OSSL_CMP_CTX_set0_newPkey(ctx, priv, pkey)) { EVP_PKEY_free(pkey); - goto err; + return 0; } } @@ -1868,12 +1628,12 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) && !OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_VALIDITY_DAYS, opt_days)) { CMP_err("could not set requested cert validity period"); - goto err; + return 0; } if (opt_policies != NULL && opt_policy_oids != NULL) { CMP_err("cannot have policies both via -policies and via -policy_oids"); - goto err; + return 0; } if (opt_reqexts != NULL || opt_policies != NULL) { @@ -1881,7 +1641,7 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) X509_EXTENSIONS *exts = sk_X509_EXTENSION_new_null(); if (exts == NULL) - goto err; + return 0; X509V3_set_ctx(&ext_ctx, NULL, NULL, NULL, NULL, 0); X509V3_set_nconf(&ext_ctx, conf); if (opt_reqexts != NULL @@ -1889,24 +1649,24 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) CMP_err1("cannot load certificate request extension section '%s'", opt_reqexts); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - goto err; + return 0; } if (opt_policies != NULL && !X509V3_EXT_add_nconf_sk(conf, &ext_ctx, opt_policies, &exts)) { CMP_err1("cannot load policy cert request extension section '%s'", opt_policies); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - goto err; + return 0; } OSSL_CMP_CTX_set0_reqExtensions(ctx, exts); } if (OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) && opt_sans != NULL) { CMP_err("cannot have Subject Alternative Names both via -reqexts and via -sans"); - goto err; + return 0; } if (!set_gennames(ctx, opt_sans, "Subject Alternative Name")) - goto err; + return 0; if (opt_san_nodefault) { if (opt_sans != NULL) @@ -1928,19 +1688,19 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) if ((policy = OBJ_txt2obj(opt_policy_oids, 1)) == 0) { CMP_err1("unknown policy OID '%s'", opt_policy_oids); - goto err; + return 0; } if ((pinfo = POLICYINFO_new()) == NULL) { ASN1_OBJECT_free(policy); - goto err; + return 0; } pinfo->policyid = policy; if (!OSSL_CMP_CTX_push0_policy(ctx, pinfo)) { CMP_err1("cannot add policy with OID '%s'", opt_policy_oids); POLICYINFO_free(pinfo); - goto err; + return 0; } opt_policy_oids = next; } @@ -1956,7 +1716,7 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) load_csr_autofmt(opt_csr, "PKCS#10 CSR for p10cr"); if (csr == NULL) - goto err; + return 0; if (!OSSL_CMP_CTX_set1_p10CSR(ctx, csr)) { X509_REQ_free(csr); goto oom; @@ -1971,7 +1731,7 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) /* opt_keypass is needed if opt_oldcert is an encrypted PKCS#12 file */ if (oldcert == NULL) - goto err; + return 0; if (!OSSL_CMP_CTX_set1_oldCert(ctx, oldcert)) { X509_free(oldcert); goto oom; @@ -1987,7 +1747,6 @@ static int setup_request_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) oom: CMP_err("out of memory"); - err: return 0; } @@ -2063,33 +1822,36 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) { int ret = 0; + char *server = NULL, *port = NULL, *path = NULL, *used_path; + int portnum, ssl; char server_buf[200] = { '\0' }; char proxy_buf[200] = { '\0' }; char *proxy_host = NULL; char *proxy_port_str = NULL; if (opt_server == NULL) { - CMP_err("missing server address[:port]"); + CMP_err("missing -server option"); + goto err; + } + if (!OSSL_HTTP_parse_url(opt_server, &server, &port, &portnum, &path, &ssl)) goto err; - } else if ((server_port = - parse_addr(&opt_server, server_port, "server")) < 0) { + if (ssl && !opt_tls_used) { + CMP_err("missing -tls_used option since -server URL indicates https"); goto err; } - if (server_port != 0) - BIO_snprintf(server_port_s, sizeof(server_port_s), "%d", server_port); - if (!OSSL_CMP_CTX_set1_server(ctx, opt_server) - || !OSSL_CMP_CTX_set_serverPort(ctx, server_port) - || !OSSL_CMP_CTX_set1_serverPath(ctx, opt_path)) + BIO_snprintf(server_port, sizeof(server_port), "%s", port); + used_path = opt_path != NULL ? opt_path : path; + if (!OSSL_CMP_CTX_set1_server(ctx, server) + || !OSSL_CMP_CTX_set_serverPort(ctx, portnum) + || !OSSL_CMP_CTX_set1_serverPath(ctx, used_path)) goto oom; if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy)) goto oom; if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy)) goto oom; - (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s%s%s/%s", - opt_tls_used ? "s" : "", opt_server, - server_port == 0 ? "" : ":", server_port_s, - opt_path == NULL ? "" : - opt_path[0] == '/' ? opt_path + 1 : opt_path); + (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s:%s/%s", + opt_tls_used ? "s" : "", server, port, + *used_path == '/' ? used_path + 1 : used_path); if (opt_proxy != NULL) (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", opt_proxy); @@ -2190,7 +1952,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) (void)OSSL_CMP_CTX_set_http_cb_arg(ctx, info); /* info will be freed along with CMP ctx */ info->server = opt_server; - info->port = server_port_s; + info->port = server_port; info->use_proxy = opt_proxy != NULL; info->timeout = OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_MSG_TIMEOUT); info->ssl_ctx = setup_ssl_ctx(ctx, engine); @@ -2220,6 +1982,9 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *engine) ret = 1; err: + OPENSSL_free(server); + OPENSSL_free(port); + OPENSSL_free(path); OPENSSL_free(proxy_host); OPENSSL_free(proxy_port_str); return ret; @@ -2246,18 +2011,21 @@ static int write_cert(BIO *bio, X509 *cert) } /* - * writes out a stack of certs to the given file. + * If destFile != NULL writes out a stack of certs to the given file. + * In any case frees the certs. * Depending on options use either PEM or DER format, * where DER does not make much sense for writing more than one cert! - * Returns number of written certificates on success, 0 on error. + * Returns number of written certificates on success, -1 on error. */ -static int save_certs(OSSL_CMP_CTX *ctx, - STACK_OF(X509) *certs, char *destFile, char *desc) +static int save_free_certs(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *certs, char *destFile, char *desc) { BIO *bio = NULL; int i; int n = sk_X509_num(certs); + if (destFile == NULL) + goto end; CMP_info3("received %d %s certificate(s), saving to file '%s'", n, desc, destFile); if (n > 1 && opt_certform != FORMAT_PEM) @@ -2267,19 +2035,20 @@ static int save_certs(OSSL_CMP_CTX *ctx, || !BIO_write_filename(bio, (char *)destFile)) { CMP_err1("could not open file '%s' for writing", destFile); n = -1; - goto err; + goto end; } for (i = 0; i < n; i++) { if (!write_cert(bio, sk_X509_value(certs, i))) { CMP_err1("cannot write certificate to file '%s'", destFile); n = -1; - goto err; + goto end; } } - err: + end: BIO_free(bio); + sk_X509_pop_free(certs, X509_free); return n; } @@ -2287,7 +2056,7 @@ static void print_itavs(STACK_OF(OSSL_CMP_ITAV) *itavs) { OSSL_CMP_ITAV *itav = NULL; char buf[128]; - int i; + int i, r; int n = sk_OSSL_CMP_ITAV_num(itavs); /* itavs == NULL leads to 0 */ if (n == 0) { @@ -2297,8 +2066,13 @@ static void print_itavs(STACK_OF(OSSL_CMP_ITAV) *itavs) for (i = 0; i < n; i++) { itav = sk_OSSL_CMP_ITAV_value(itavs, i); - OBJ_obj2txt(buf, 128, OSSL_CMP_ITAV_get0_type(itav), 0); - CMP_info1("genp contains ITAV of type: %s", buf); + r = OBJ_obj2txt(buf, 128, OSSL_CMP_ITAV_get0_type(itav), 0); + if (r < 0) + CMP_err("could not get ITAV details"); + else if (r == 0) + CMP_info("genp contains empty ITAV"); + else + CMP_info1("genp contains ITAV of type: %s", buf); } } @@ -2374,12 +2148,23 @@ static int read_config(void) const OPTIONS *opt; int provider_option; int verification_option; - + int start = OPT_VERBOSITY; /* - * starting with offset OPT_SECTION because OPT_CONFIG and OPT_SECTION would - * not make sense within the config file. They have already been handled. + * starting with offset OPT_VERBOSITY because OPT_CONFIG and OPT_SECTION + * would not make sense within the config file. + * Moreover, these two options and OPT_VERBOSITY have already been handled. */ - for (i = OPT_SECTION - OPT_HELP, opt = &cmp_options[OPT_SECTION]; + int n_options = OSSL_NELEM(cmp_options) - 1; + + for (i = start - OPT_HELP, opt = &cmp_options[start]; + opt->name; i++, opt++) + if (!strcmp(opt->name, OPT_SECTION_STR) + || !strcmp(opt->name, OPT_MORE_STR)) + n_options--; + OPENSSL_assert(OSSL_NELEM(cmp_vars) == n_options + + OPT_PROV__FIRST + 1 - OPT_PROV__LAST + + OPT_V__FIRST + 1 - OPT_V__LAST); + for (i = start - OPT_HELP, opt = &cmp_options[start]; opt->name; i++, opt++) { if (!strcmp(opt->name, OPT_SECTION_STR) || !strcmp(opt->name, OPT_MORE_STR)) { @@ -2392,10 +2177,6 @@ static int read_config(void) && opt->retval < OPT_V__LAST); if (provider_option || verification_option) i--; - if (cmp_vars[i].txt == NULL) { - CMP_err1("internal: cmp_vars array too short, i=%d", i); - return 0; - } switch (opt->valtype) { case '-': case 'n': @@ -2405,11 +2186,6 @@ static int read_config(void) continue; /* option not provided */ } break; - /* - * do not use '<' in cmp_options. Incorrect treatment - * somewhere in args_verify() can wrongly set badarg = 1 - */ - case '<': case 's': case 'M': txt = conf_get_string(conf, opt_section, opt->name); @@ -2518,8 +2294,8 @@ static int get_opts(int argc, char **argv) opt_help(cmp_options); return -1; case OPT_CONFIG: /* has already been handled */ - break; case OPT_SECTION: /* has already been handled */ + case OPT_VERBOSITY: /* has already been handled */ break; case OPT_SERVER: opt_server = opt_str("server"); @@ -2571,6 +2347,9 @@ static int get_opts(int argc, char **argv) case OPT_CERT: opt_cert = opt_str("cert"); break; + case OPT_OWN_TRUSTED: + opt_own_trusted = opt_str("own_trusted"); + break; case OPT_KEY: opt_key = opt_str("key"); break; @@ -2689,6 +2468,9 @@ static int get_opts(int argc, char **argv) case OPT_CERTOUT: opt_certout = opt_str("certout"); break; + case OPT_CHAINOUT: + opt_chainout = opt_str("chainout"); + break; case OPT_OLDCERT: opt_oldcert = opt_str("oldcert"); break; @@ -2707,9 +2489,6 @@ static int get_opts(int argc, char **argv) case OPT_KEYFORM: opt_keyform_s = opt_str("keyform"); break; - case OPT_CERTSFORM: - opt_certsform_s = opt_str("certsform"); - break; case OPT_OTHERPASS: opt_otherpass = opt_str("otherpass"); break; @@ -2853,15 +2632,20 @@ int cmp_main(int argc, char **argv) } /* - * handle OPT_CONFIG and OPT_SECTION upfront to take effect for other opts + * handle options -config, -section, and -verbosity upfront + * to take effect for other options */ for (i = 1; i < argc - 1; i++) { if (*argv[i] == '-') { if (!strcmp(argv[i] + 1, cmp_options[OPT_CONFIG - OPT_HELP].name)) - opt_config = argv[i + 1]; + opt_config = argv[++i]; else if (!strcmp(argv[i] + 1, cmp_options[OPT_SECTION - OPT_HELP].name)) - opt_section = argv[i + 1]; + opt_section = argv[++i]; + else if (strcmp(argv[i] + 1, + cmp_options[OPT_VERBOSITY - OPT_HELP].name) == 0 + && !set_verbosity(atoi(argv[++i]))) + goto err; } } if (opt_section[0] == '\0') /* empty string */ @@ -2933,10 +2717,10 @@ int cmp_main(int argc, char **argv) } } - if ((cmp_ctx = OSSL_CMP_CTX_new()) == NULL) { - CMP_err("out of memory"); + cmp_ctx = OSSL_CMP_CTX_new(app_get0_libctx(), app_get0_propq()); + if (cmp_ctx == NULL) goto err; - } + OSSL_CMP_CTX_set_log_verbosity(cmp_ctx, opt_verbosity); if (!OSSL_CMP_CTX_set_log_cb(cmp_ctx, print_to_bio_out)) { CMP_err1("cannot set up error reporting and logging for %s", prog); goto err; @@ -3028,11 +2812,6 @@ int cmp_main(int argc, char **argv) } opt_server = mock_server; opt_proxy = "API"; - } else { - if (opt_server == NULL) { - CMP_err("missing -server option"); - goto err; - } } if (!setup_client_ctx(cmp_ctx, engine)) { @@ -3044,27 +2823,27 @@ int cmp_main(int argc, char **argv) switch (opt_cmd) { case CMP_IR: newcert = OSSL_CMP_exec_IR_ses(cmp_ctx); - if (newcert == NULL) - goto err; + if (newcert != NULL) + ret = 1; break; case CMP_KUR: newcert = OSSL_CMP_exec_KUR_ses(cmp_ctx); - if (newcert == NULL) - goto err; + if (newcert != NULL) + ret = 1; break; case CMP_CR: newcert = OSSL_CMP_exec_CR_ses(cmp_ctx); - if (newcert == NULL) - goto err; + if (newcert != NULL) + ret = 1; break; case CMP_P10CR: newcert = OSSL_CMP_exec_P10CR_ses(cmp_ctx); - if (newcert == NULL) - goto err; + if (newcert != NULL) + ret = 1; break; case CMP_RR: - if (OSSL_CMP_exec_RR_ses(cmp_ctx) == NULL) - goto err; + if (OSSL_CMP_exec_RR_ses(cmp_ctx) != NULL) + ret = 1; break; case CMP_GENM: { @@ -3078,10 +2857,11 @@ int cmp_main(int argc, char **argv) OSSL_CMP_CTX_push0_genm_ITAV(cmp_ctx, itav); } - if ((itavs = OSSL_CMP_exec_GENM_ses(cmp_ctx)) == NULL) - goto err; - print_itavs(itavs); - sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); + if ((itavs = OSSL_CMP_exec_GENM_ses(cmp_ctx)) != NULL) { + print_itavs(itavs); + sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); + ret = 1; + } break; } default: @@ -3089,7 +2869,7 @@ int cmp_main(int argc, char **argv) } { - /* print PKIStatusInfo (this is in case there has been no error) */ + /* print PKIStatusInfo */ int status = OSSL_CMP_CTX_get_status(cmp_ctx); char *buf = app_malloc(OSSL_CMP_PKISI_BUFLEN, "PKIStatusInfo buf"); const char *string = @@ -3097,6 +2877,11 @@ int cmp_main(int argc, char **argv) OSSL_CMP_PKISI_BUFLEN); CMP_print(bio_err, + status == OSSL_CMP_PKISTATUS_accepted + ? OSSL_CMP_LOG_INFO : + status == OSSL_CMP_PKISTATUS_rejection + || status == OSSL_CMP_PKISTATUS_waiting + ? OSSL_CMP_LOG_ERR : OSSL_CMP_LOG_WARNING, status == OSSL_CMP_PKISTATUS_accepted ? "info" : status == OSSL_CMP_PKISTATUS_rejection ? "server error" : status == OSSL_CMP_PKISTATUS_waiting ? "internal error" @@ -3106,39 +2891,29 @@ int cmp_main(int argc, char **argv) OPENSSL_free(buf); } - if (opt_cacertsout != NULL) { - STACK_OF(X509) *certs = OSSL_CMP_CTX_get1_caPubs(cmp_ctx); - - if (sk_X509_num(certs) > 0 - && save_certs(cmp_ctx, certs, opt_cacertsout, "CA") < 0) { - sk_X509_pop_free(certs, X509_free); - goto err; - } - sk_X509_pop_free(certs, X509_free); - } - - if (opt_extracertsout != NULL) { - STACK_OF(X509) *certs = OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx); - if (sk_X509_num(certs) > 0 - && save_certs(cmp_ctx, certs, opt_extracertsout, - "extra") < 0) { - sk_X509_pop_free(certs, X509_free); - goto err; - } - sk_X509_pop_free(certs, X509_free); - } - - if (opt_certout != NULL && newcert != NULL) { + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_extraCertsIn(cmp_ctx), + opt_extracertsout, "extra") < 0) + ret = 0; + if (!ret) + goto err; + ret = 0; + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_caPubs(cmp_ctx), + opt_cacertsout, "CA") < 0) + goto err; + if (newcert != NULL) { STACK_OF(X509) *certs = sk_X509_new_null(); - if (certs == NULL || !sk_X509_push(certs, newcert) - || save_certs(cmp_ctx, certs, opt_certout, - "enrolled") < 0) { + if (!X509_add_cert(certs, newcert, X509_ADD_FLAG_UP_REF)) { sk_X509_free(certs); goto err; } - sk_X509_free(certs); + if (save_free_certs(cmp_ctx, certs, opt_certout, "enrolled") < 0) + goto err; } + if (save_free_certs(cmp_ctx, OSSL_CMP_CTX_get1_newChain(cmp_ctx), + opt_chainout, "chain") < 0) + goto err; + if (!OSSL_CMP_CTX_reinit(cmp_ctx)) goto err; } @@ -3175,5 +2950,5 @@ int cmp_main(int argc, char **argv) NCONF_free(conf); /* must not do as long as opt_... variables are used */ OSSL_CMP_log_close(); - return ret == 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return ret == 0 ? EXIT_FAILURE : EXIT_SUCCESS; /* ret == -1 for -help */ } diff --git a/apps/cmp_mock_srv.c b/apps/cmp_mock_srv.c index c63e5f9943..78d6a98e15 100644 --- a/apps/cmp_mock_srv.c +++ b/apps/cmp_mock_srv.c @@ -14,10 +14,6 @@ #include #include #include - -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(OSSL_CMP_ITAV) -DEFINE_STACK_OF(ASN1_UTF8STRING) /* the context for the CMP mock server */ typedef struct @@ -388,9 +384,9 @@ static int process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx, return 1; } -OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void) +OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, const char *propq) { - OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(); + OSSL_CMP_SRV_CTX *srv_ctx = OSSL_CMP_SRV_CTX_new(libctx, propq); mock_srv_ctx *ctx = mock_srv_ctx_new(); if (srv_ctx != NULL && ctx != NULL diff --git a/apps/cmp_mock_srv.h b/apps/cmp_mock_srv.h index bddc44df5b..7c844a5391 100644 --- a/apps/cmp_mock_srv.h +++ b/apps/cmp_mock_srv.h @@ -16,7 +16,8 @@ # include -OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(void); +OSSL_CMP_SRV_CTX *ossl_cmp_mock_srv_new(OSSL_LIB_CTX *libctx, + const char *propq); void ossl_cmp_mock_srv_free(OSSL_CMP_SRV_CTX *srv_ctx); int ossl_cmp_mock_srv_set1_certOut(OSSL_CMP_SRV_CTX *srv_ctx, X509 *cert); diff --git a/apps/cms.c b/apps/cms.c index 2cb92ab85f..4589a24f06 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -23,18 +23,12 @@ # include # include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(CMS_SignerInfo) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(GENERAL_NAMES) -DEFINE_STACK_OF_STRING() - static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int cms_cb(int ok, X509_STORE_CTX *ctx); static void receipt_request_print(CMS_ContentInfo *cms); -static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) - *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) - *rr_from); +static CMS_ReceiptRequest *make_receipt_request( + STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, + STACK_OF(OPENSSL_STRING) *rr_from, OSSL_LIB_CTX *libctx, const char *propq); static int cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param); @@ -89,7 +83,7 @@ typedef enum OPTION_choice { OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP, OPT_3DES_WRAP, OPT_WRAP, OPT_ENGINE, OPT_R_ENUM, - OPT_PROV_ENUM, + OPT_PROV_ENUM, OPT_CONFIG, OPT_V_ENUM, OPT_CIPHER, OPT_ORIGINATOR @@ -124,6 +118,7 @@ const OPTIONS cms_options[] = { # ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, # endif + OPT_CONFIG_OPTION, OPT_SECTION("Action"), {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, @@ -236,8 +231,45 @@ const OPTIONS cms_options[] = { {NULL} }; +static CMS_ContentInfo *load_content_info(int informat, BIO *in, BIO **indata, + const char *name, + OSSL_LIB_CTX *libctx, + const char *propq) +{ + CMS_ContentInfo *ret, *ci; + + ret = CMS_ContentInfo_new_ex(libctx, propq); + if (ret == NULL) { + BIO_printf(bio_err, "Error allocating CMS_contentinfo\n"); + return NULL; + } + switch (informat) { + case FORMAT_SMIME: + ci = SMIME_read_CMS_ex(in, indata, &ret); + break; + case FORMAT_PEM: + ci = PEM_read_bio_CMS(in, &ret, NULL, NULL); + break; + case FORMAT_ASN1: + ci = d2i_CMS_bio(in, &ret); + break; + default: + BIO_printf(bio_err, "Bad input format for %s\n", name); + goto err; + } + if (ci == NULL) { + BIO_printf(bio_err, "Error reading %s Content Info\n", name); + goto err; + } + return ret; +err: + CMS_ContentInfo_free(ret); + return NULL; +} + int cms_main(int argc, char **argv) { + CONF *conf = NULL; ASN1_OBJECT *econtent_type = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; @@ -270,6 +302,8 @@ int cms_main(int argc, char **argv) long ltmp; const char *mime_eol = "\n"; OPTION_CHOICE o; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; @@ -417,14 +451,14 @@ int cms_main(int argc, char **argv) rr_allorfirst = 1; break; case OPT_RCTFORM: - if (rctformat == FORMAT_SMIME) - rcms = SMIME_read_CMS(rctin, NULL); - else if (rctformat == FORMAT_PEM) - rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); - else if (rctformat == FORMAT_ASN1) + if (rctformat == FORMAT_ASN1) { if (!opt_format(opt_arg(), OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat)) goto opthelp; + } else { + rcms = load_content_info(rctformat, rctin, NULL, "recipient", + libctx, propq); + } break; case OPT_CERTFILE: certfile = opt_arg(); @@ -614,9 +648,11 @@ int cms_main(int argc, char **argv) if (key_param == NULL || key_param->idx != keyidx) { cms_key_param *nparam; nparam = app_malloc(sizeof(*nparam), "key param buffer"); - nparam->idx = keyidx; - if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) + if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) { + OPENSSL_free(nparam); goto end; + } + nparam->idx = keyidx; nparam->next = NULL; if (key_first == NULL) key_first = nparam; @@ -639,6 +675,11 @@ int cms_main(int argc, char **argv) if (!opt_provider(o)) goto end; break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; + break; case OPT_3DES_WRAP: # ifndef OPENSSL_NO_DES wrap_cipher = EVP_des_ede3_wrap(); @@ -778,8 +819,7 @@ int cms_main(int argc, char **argv) } if (certfile != NULL) { - if (!load_certs(certfile, &other, FORMAT_PEM, NULL, - "certificate file")) { + if (!load_certs(certfile, &other, NULL, "certificate file")) { ERR_print_errors(bio_err); goto end; } @@ -820,7 +860,7 @@ int cms_main(int argc, char **argv) } if (keyfile != NULL) { - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; } @@ -830,21 +870,9 @@ int cms_main(int argc, char **argv) goto end; if (operation & SMIME_IP) { - if (informat == FORMAT_SMIME) { - cms = SMIME_read_CMS(in, &indata); - } else if (informat == FORMAT_PEM) { - cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); - } else if (informat == FORMAT_ASN1) { - cms = d2i_CMS_bio(in, NULL); - } else { - BIO_printf(bio_err, "Bad input format for CMS file\n"); - goto end; - } - - if (cms == NULL) { - BIO_printf(bio_err, "Error reading S/MIME message\n"); + cms = load_content_info(informat, in, &indata, "SMIME", libctx, propq); + if (cms == NULL) goto end; - } if (contfile != NULL) { BIO_free(indata); if ((indata = BIO_new_file(contfile, "rb")) == NULL) { @@ -872,21 +900,10 @@ int cms_main(int argc, char **argv) goto end; } - if (rctformat == FORMAT_SMIME) { - rcms = SMIME_read_CMS(rctin, NULL); - } else if (rctformat == FORMAT_PEM) { - rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); - } else if (rctformat == FORMAT_ASN1) { - rcms = d2i_CMS_bio(rctin, NULL); - } else { - BIO_printf(bio_err, "Bad input format for receipt\n"); + rcms = load_content_info(rctformat, rctin, NULL, "recipient", libctx, + propq); + if (rcms == NULL) goto end; - } - - if (rcms == NULL) { - BIO_printf(bio_err, "Error reading receipt\n"); - goto end; - } } out = bio_open_default(outfile, 'w', outformat); @@ -905,15 +922,15 @@ int cms_main(int argc, char **argv) ret = 3; if (operation == SMIME_DATA_CREATE) { - cms = CMS_data_create(in, flags); + cms = CMS_data_create_ex(in, flags, libctx, propq); } else if (operation == SMIME_DIGEST_CREATE) { - cms = CMS_digest_create(in, sign_md, flags); + cms = CMS_digest_create_ex(in, sign_md, flags, libctx, propq); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { int i; flags |= CMS_PARTIAL; - cms = CMS_encrypt(NULL, in, cipher, flags); + cms = CMS_encrypt_ex(NULL, in, cipher, flags, libctx, propq); if (cms == NULL) goto end; for (i = 0; i < sk_X509_num(encerts); i++) { @@ -978,8 +995,8 @@ int cms_main(int argc, char **argv) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { - cms = CMS_EncryptedData_encrypt(in, cipher, - secret_key, secret_keylen, flags); + cms = CMS_EncryptedData_encrypt_ex(in, cipher, secret_key, + secret_keylen, flags, libctx, propq); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; @@ -1007,14 +1024,15 @@ int cms_main(int argc, char **argv) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; - cms = CMS_sign(NULL, NULL, other, in, flags); + cms = CMS_sign_ex(NULL, NULL, other, in, flags, libctx, propq); if (cms == NULL) goto end; if (econtent_type != NULL) CMS_set1_eContentType(cms, econtent_type); if (rr_to != NULL) { - rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); + rr = make_receipt_request(rr_to, rr_allorfirst, rr_from, libctx, + propq); if (rr == NULL) { BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); @@ -1037,11 +1055,12 @@ int cms_main(int argc, char **argv) ret = 2; goto end; } - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) { ret = 2; goto end; } + for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { tflags |= CMS_KEY_PARAM; @@ -1231,6 +1250,7 @@ int cms_main(int argc, char **argv) BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); + NCONF_free(conf); return ret; } @@ -1367,9 +1387,10 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns) return NULL; } -static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) - *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING) - *rr_from) +static CMS_ReceiptRequest *make_receipt_request( + STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst, + STACK_OF(OPENSSL_STRING) *rr_from, + OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL; CMS_ReceiptRequest *rr; @@ -1383,8 +1404,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) } else { rct_from = NULL; } - rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from, - rct_to); + rr = CMS_ReceiptRequest_create0_ex(NULL, -1, rr_allorfirst, rct_from, + rct_to, libctx, propq); return rr; err: sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free); diff --git a/apps/crl2p7.c b/apps/crl2p7.c index e0de95a12a..9137f87239 100644 --- a/apps/crl2p7.c +++ b/apps/crl2p7.c @@ -19,11 +19,6 @@ #include #include -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_INFO) -DEFINE_STACK_OF_STRING() - static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile); typedef enum OPTION_choice { diff --git a/apps/dgst.c b/apps/dgst.c index da162e6ed6..badcfdf0e2 100644 --- a/apps/dgst.c +++ b/apps/dgst.c @@ -21,8 +21,6 @@ #include #include -DEFINE_STACK_OF_STRING() - #undef BUFSIZE #define BUFSIZE 1024*8 @@ -270,9 +268,9 @@ int dgst_main(int argc, char **argv) int type; if (want_pub) - sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); + sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); else - sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); + sigkey = load_key(keyfile, keyform, 0, passin, e, "private key"); if (sigkey == NULL) { /* * load_[pub]key() has already printed an appropriate message @@ -293,7 +291,7 @@ int dgst_main(int argc, char **argv) if (mac_name != NULL) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; - if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) + if (!init_gen_str(&mac_ctx, mac_name, impl, 0, NULL, NULL)) goto mac_end; if (macopts != NULL) { char *macopt; @@ -321,7 +319,8 @@ int dgst_main(int argc, char **argv) if (hmac_key != NULL) { sigkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, impl, - (unsigned char *)hmac_key, -1); + (unsigned char *)hmac_key, + strlen(hmac_key)); if (sigkey == NULL) goto end; } @@ -407,13 +406,8 @@ int dgst_main(int argc, char **argv) } else { const char *sig_name = NULL; if (!out_bin) { - if (sigkey != NULL) { - 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); - } + if (sigkey != NULL) + sig_name = EVP_PKEY_get0_first_alg_name(sigkey); } ret = 0; for (i = 0; i < argc; i++) { diff --git a/apps/dsa.c b/apps/dsa.c index 8ef802e0da..75a0504548 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -165,9 +165,9 @@ int dsa_main(int argc, char **argv) BIO_printf(bio_err, "read DSA key\n"); if (pubin) - pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); + pkey = load_pubkey(infile, informat, 1, passin, e, "public key"); else - pkey = load_key(infile, informat, 1, passin, e, "Private Key"); + pkey = load_key(infile, informat, 1, passin, e, "private key"); if (pkey != NULL) dsa = EVP_PKEY_get1_DSA(pkey); diff --git a/apps/ec.c b/apps/ec.c index 43e2be1346..79951cc8d6 100644 --- a/apps/ec.c +++ b/apps/ec.c @@ -194,9 +194,9 @@ int ec_main(int argc, char **argv) } else if (informat == FORMAT_ENGINE) { EVP_PKEY *pkey; if (pubin) - pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key"); + pkey = load_pubkey(infile, informat, 1, passin, e, "public key"); else - pkey = load_key(infile, informat, 1, passin, e, "Private Key"); + pkey = load_key(infile, informat, 1, passin, e, "private key"); if (pkey != NULL) { eckey = EVP_PKEY_get1_EC_KEY(pkey); EVP_PKEY_free(pkey); diff --git a/apps/engine.c b/apps/engine.c index d51586d855..393008d5ce 100644 --- a/apps/engine.c +++ b/apps/engine.c @@ -22,9 +22,6 @@ #include #include -DEFINE_STACK_OF_STRING() -DEFINE_STACK_OF_CSTRING() - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST, diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index bd1cd68477..cb78489eef 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -19,8 +19,6 @@ #include "apps.h" #include "progs.h" -DEFINE_STACK_OF_STRING() - #define BUFSIZE 4096 /* Configuration file values */ @@ -38,7 +36,9 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_IN, OPT_OUT, OPT_MODULE, OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY, - OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG + OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG, + OPT_NO_CONDITIONAL_ERRORS, + OPT_NO_SECURITY_CHECKS } OPTION_CHOICE; const OPTIONS fipsinstall_options[] = { @@ -50,7 +50,11 @@ const OPTIONS fipsinstall_options[] = { {"provider_name", OPT_PROV_NAME, 's', "FIPS provider name"}, {"section_name", OPT_SECTION_NAME, 's', "FIPS Provider config section name (optional)"}, - + {"no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-', + "Disable the ability of the fips module to enter an error state if" + " any conditional self tests fail"}, + {"no_security_checks", OPT_NO_SECURITY_CHECKS, '-', + "Disable the run-time FIPS security checks in the module"}, OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input config file, used when verifying"}, @@ -132,32 +136,38 @@ static int write_config_header(BIO *out, const char *prov_name, /* * Outputs a fips related config file that contains entries for the fips - * module checksum and the installation indicator checksum. + * module checksum, installation indicator checksum and the options + * conditional_errors and security_checks. * * Returns 1 if the config file is written otherwise it returns 0 on error. */ static int write_config_fips_section(BIO *out, const char *section, unsigned char *module_mac, size_t module_mac_len, + int conditional_errors, + int security_checks, unsigned char *install_mac, size_t install_mac_len) { int ret = 0; - if (!(BIO_printf(out, "[%s]\n", section) > 0 - && BIO_printf(out, "activate = 1\n") > 0 - && BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION, - VERSION_VAL) > 0 - && print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac, - module_mac_len))) + if (BIO_printf(out, "[%s]\n", section) <= 0 + || BIO_printf(out, "activate = 1\n") <= 0 + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION, + VERSION_VAL) <= 0 + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS, + conditional_errors ? "1" : "0") <= 0 + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS, + security_checks ? "1" : "0") <= 0 + || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac, + module_mac_len)) goto end; if (install_mac != NULL) { - if (!(print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac, - install_mac_len) - && BIO_printf(out, "%s = %s\n", - OSSL_PROV_FIPS_PARAM_INSTALL_STATUS, - INSTALL_STATUS_VAL) > 0)) + if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac, + install_mac_len) + || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS, + INSTALL_STATUS_VAL) <= 0) goto end; } ret = 1; @@ -168,7 +178,9 @@ static int write_config_fips_section(BIO *out, const char *section, static CONF *generate_config_and_load(const char *prov_name, const char *section, unsigned char *module_mac, - size_t module_mac_len) + size_t module_mac_len, + int conditional_errors, + int security_checks) { BIO *mem_bio = NULL; CONF *conf = NULL; @@ -177,8 +189,11 @@ static CONF *generate_config_and_load(const char *prov_name, if (mem_bio == NULL) return 0; if (!write_config_header(mem_bio, prov_name, section) - || !write_config_fips_section(mem_bio, section, module_mac, - module_mac_len, NULL, 0)) + || !write_config_fips_section(mem_bio, section, + module_mac, module_mac_len, + conditional_errors, + security_checks, + NULL, 0)) goto end; conf = app_load_config_bio(mem_bio, NULL); @@ -205,7 +220,7 @@ static void free_config_and_unload(CONF *conf) static int verify_module_load(const char *parent_config_file) { - return OPENSSL_CTX_load_config(NULL, parent_config_file); + return OSSL_LIB_CTX_load_config(NULL, parent_config_file); } /* @@ -272,12 +287,14 @@ static int verify_config(const char *infile, const char *section, int fipsinstall_main(int argc, char **argv) { int ret = 1, verify = 0, gotkey = 0, gotdigest = 0; + int enable_conditional_errors = 1, enable_security_checks = 1; const char *section_name = "fips_sect"; const char *mac_name = "HMAC"; const char *prov_name = "fips"; BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL; char *in_fname = NULL, *out_fname = NULL, *prog; - char *module_fname = NULL, *parent_config = NULL; + char *module_fname = NULL, *parent_config = NULL, *module_path = NULL; + const char *tail; EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL; STACK_OF(OPENSSL_STRING) *opts = NULL; OPTION_CHOICE o; @@ -310,6 +327,12 @@ int fipsinstall_main(int argc, char **argv) case OPT_OUT: out_fname = opt_arg(); break; + case OPT_NO_CONDITIONAL_ERRORS: + enable_conditional_errors = 0; + break; + case OPT_NO_SECURITY_CHECKS: + enable_security_checks = 0; + break; case OPT_QUIET: quiet = 1; /* FALLTHROUGH */ @@ -368,6 +391,16 @@ int fipsinstall_main(int argc, char **argv) || argc != 0) goto opthelp; + tail = opt_path_end(module_fname); + if (tail != NULL) { + module_path = OPENSSL_strdup(module_fname); + if (module_path == NULL) + goto end; + module_path[tail - module_fname] = '\0'; + if (!OSSL_PROVIDER_set_default_search_path(NULL, module_path)) + goto end; + } + if (self_test_log || self_test_corrupt_desc != NULL || self_test_corrupt_type != NULL) @@ -446,7 +479,9 @@ int fipsinstall_main(int argc, char **argv) } else { conf = generate_config_and_load(prov_name, section_name, module_mac, - module_mac_len); + module_mac_len, + enable_conditional_errors, + enable_security_checks); if (conf == NULL) goto end; if (!load_fips_prov_and_run_self_test(prov_name)) @@ -457,9 +492,11 @@ int fipsinstall_main(int argc, char **argv) BIO_printf(bio_err, "Failed to open file\n"); goto end; } - if (!write_config_fips_section(fout, section_name, module_mac, - module_mac_len, install_mac, - install_mac_len)) + if (!write_config_fips_section(fout, section_name, + module_mac, module_mac_len, + enable_conditional_errors, + enable_security_checks, + install_mac, install_mac_len)) goto end; if (!quiet) BIO_printf(bio_out, "INSTALL PASSED\n"); @@ -474,6 +511,7 @@ int fipsinstall_main(int argc, char **argv) } cleanup: + OPENSSL_free(module_path); BIO_free(fout); BIO_free(mem_bio); BIO_free(module_bio); diff --git a/apps/genpkey.c b/apps/genpkey.c index 389f0e620c..1682c661c6 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -21,13 +21,15 @@ # include #endif -static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e); +static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e, + OSSL_LIB_CTX *libctx, const char *propq); static int genpkey_cb(EVP_PKEY_CTX *ctx); typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE, OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER, + OPT_CONFIG, OPT_PROV_ENUM } OPTION_CHOICE; @@ -41,6 +43,7 @@ const OPTIONS genpkey_options[] = { {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"}, {"pkeyopt", OPT_PKEYOPT, 's', "Set the public key algorithm option as opt:value"}, + OPT_CONFIG_OPTION, OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output file"}, @@ -60,6 +63,7 @@ const OPTIONS genpkey_options[] = { int genpkey_main(int argc, char **argv) { + CONF *conf = NULL; BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; @@ -69,6 +73,8 @@ int genpkey_main(int argc, char **argv) OPTION_CHOICE o; int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0; int private = 0; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); prog = opt_init(argc, argv, genpkey_options); while ((o = opt_next()) != OPT_EOF) { @@ -98,11 +104,11 @@ int genpkey_main(int argc, char **argv) case OPT_PARAMFILE: if (do_param == 1) goto opthelp; - if (!init_keygen_file(&ctx, opt_arg(), e)) + if (!init_keygen_file(&ctx, opt_arg(), e, libctx, propq)) goto end; break; case OPT_ALGORITHM: - if (!init_gen_str(&ctx, opt_arg(), e, do_param)) + if (!init_gen_str(&ctx, opt_arg(), e, do_param, libctx, propq)) goto end; break; case OPT_PKEYOPT: @@ -119,8 +125,12 @@ int genpkey_main(int argc, char **argv) } break; case OPT_GENPARAM: - if (ctx != NULL) + if (ctx != NULL) { + BIO_printf(bio_err, + "%s: '-genparam' option must be set before" + " the '-algorithm' option.\n", prog); goto opthelp; + } do_param = 1; break; case OPT_TEXT: @@ -138,6 +148,11 @@ int genpkey_main(int argc, char **argv) goto end; } break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; + break; case OPT_PROV_CASES: if (!opt_provider(o)) goto end; @@ -220,10 +235,12 @@ int genpkey_main(int argc, char **argv) BIO_free(in); release_engine(e); OPENSSL_free(pass); + NCONF_free(conf); return ret; } -static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) +static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *pbio; EVP_PKEY *pkey = NULL; @@ -247,7 +264,10 @@ static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) return 0; } - ctx = EVP_PKEY_CTX_new(pkey, e); + if (e != NULL) + ctx = EVP_PKEY_CTX_new(pkey, e); + else + ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (ctx == NULL) goto err; if (EVP_PKEY_keygen_init(ctx) <= 0) @@ -266,7 +286,8 @@ static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e) } int init_gen_str(EVP_PKEY_CTX **pctx, - const char *algname, ENGINE *e, int do_param) + const char *algname, ENGINE *e, int do_param, + OSSL_LIB_CTX *libctx, const char *propq) { EVP_PKEY_CTX *ctx = NULL; const EVP_PKEY_ASN1_METHOD *ameth; @@ -278,25 +299,27 @@ int init_gen_str(EVP_PKEY_CTX **pctx, return 0; } - ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); + if (libctx == NULL || e != NULL) { + ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1); #if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) - if (!ameth && e) - ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); + if (ameth == NULL && e != NULL) + ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1); #endif + if (ameth == NULL) { + BIO_printf(bio_err, "Algorithm %s not found\n", algname); + return 0; + } + ERR_clear_error(); - 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); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); #if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) - ENGINE_finish(tmpeng); + ENGINE_finish(tmpeng); #endif - ctx = EVP_PKEY_CTX_new_id(pkey_id, e); + ctx = EVP_PKEY_CTX_new_id(pkey_id, e); + } else { + ctx = EVP_PKEY_CTX_new_from_name(libctx, algname, propq); + } if (!ctx) goto err; diff --git a/apps/genrsa.c b/apps/genrsa.c index 9a9130125e..f471814e08 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -38,7 +38,7 @@ typedef enum OPTION_choice { #endif OPT_F4, OPT_ENGINE, OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE, - OPT_R_ENUM, OPT_PROV_ENUM + OPT_R_ENUM, OPT_PROV_ENUM, OPT_TRADITIONAL } OPTION_CHOICE; const OPTIONS genrsa_options[] = { @@ -62,6 +62,8 @@ const OPTIONS genrsa_options[] = { {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, {"primes", OPT_PRIMES, 'p', "Specify number of primes"}, {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"traditional", OPT_TRADITIONAL, '-', + "Use traditional format for private keys"}, {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"}, OPT_R_OPTIONS, @@ -88,7 +90,7 @@ int genrsa_main(int argc, char **argv) char *outfile = NULL, *passoutarg = NULL, *passout = NULL; char *prog, *hexe, *dece; OPTION_CHOICE o; - unsigned char *ebuf = NULL; + int traditional = 0; if (bn == NULL || cb == NULL) goto end; @@ -141,6 +143,9 @@ int genrsa_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_TRADITIONAL: + traditional = 1; + break; } } argc = opt_num_rest(); @@ -169,7 +174,7 @@ int genrsa_main(int argc, char **argv) if (out == NULL) goto end; - if (!init_gen_str(&ctx, "RSA", eng, 0)) + if (!init_gen_str(&ctx, "RSA", eng, 0, NULL, NULL)) goto end; EVP_PKEY_CTX_set_cb(ctx, genrsa_cb); @@ -183,7 +188,7 @@ int genrsa_main(int argc, char **argv) BIO_printf(bio_err, "Error allocating RSA public exponent\n"); goto end; } - if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, bn) <= 0) { + if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, bn) <= 0) { BIO_printf(bio_err, "Error setting RSA public exponent\n"); goto end; } @@ -214,8 +219,14 @@ int genrsa_main(int argc, char **argv) OPENSSL_free(hexe); OPENSSL_free(dece); } - if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout)) - goto end; + if (traditional) { + if (!PEM_write_bio_PrivateKey_traditional(out, pkey, enc, NULL, 0, + NULL, passout)) + goto end; + } else { + if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout)) + goto end; + } ret = 0; end: @@ -226,7 +237,6 @@ int genrsa_main(int argc, char **argv) BIO_free_all(out); release_engine(eng); OPENSSL_free(passout); - OPENSSL_free(ebuf); if (ret != 0) ERR_print_errors(bio_err); return ret; diff --git a/apps/include/app_params.h b/apps/include/app_params.h index 2060b5200e..79f8f58b31 100644 --- a/apps/include/app_params.h +++ b/apps/include/app_params.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,4 +10,5 @@ #include int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent); +void print_param_value(const OSSL_PARAM *p, int indent); diff --git a/apps/include/apps.h b/apps/include/apps.h index 554d33e1c9..195f226910 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -75,6 +75,9 @@ int has_stdin_waiting(void); void corrupt_signature(const ASN1_STRING *signature); int set_cert_times(X509 *x, const char *startdate, const char *enddate, int days); +int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate); +int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate, + long days, long hours, long secs); typedef struct args_st { int size; @@ -105,7 +108,7 @@ X509_REQ *load_csr(const char *file, int format, const char *desc); X509 *load_cert_pass(const char *uri, int maybe_stdin, const char *pass, const char *desc); /* the format parameter is meanwhile not needed anymore and thus ignored */ -X509 *load_cert(const char *uri, int format, const char *desc); +#define load_cert(uri, format, desc) load_cert_pass(uri, 0, NULL, desc) X509_CRL *load_crl(const char *uri, int format, const char *desc); void cleanse(char *str); void clear_free(char *str); @@ -113,13 +116,19 @@ EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *desc); EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, const char *pass, ENGINE *e, const char *desc); -int load_certs(const char *file, STACK_OF(X509) **certs, int format, +int load_certs(const char *uri, STACK_OF(X509) **certs, const char *pass, const char *desc); -int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, +int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, const char *pass, const char *desc); +int load_key_certs_crls(const char *uri, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + X509 **pcert, STACK_OF(X509) **pcerts, + X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls); int load_key_cert_crl(const char *uri, int maybe_stdin, const char *pass, const char *desc, - EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl); + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + X509 **pcert, X509_CRL **pcrl); X509_STORE *setup_verify(const char *CAfile, int noCAfile, const char *CApath, int noCApath, const char *CAstore, int noCAstore); @@ -142,6 +151,12 @@ __owur int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path); ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug); # define setup_engine(e, debug) setup_engine_methods(e, (unsigned int)-1, debug) void release_engine(ENGINE *e); +int init_engine(ENGINE *e); +int finish_engine(ENGINE *e); +EVP_PKEY *load_engine_private_key(ENGINE *e, const char *keyid, + const char *pass, const char *desc); +EVP_PKEY *load_engine_public_key(ENGINE *e, const char *keyid, + const char *pass, const char *desc); # ifndef OPENSSL_NO_OCSP OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, @@ -209,7 +224,8 @@ int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value); int x509_ctrl_string(X509 *x, const char *value); int x509_req_ctrl_string(X509_REQ *x, const char *value); int init_gen_str(EVP_PKEY_CTX **pctx, - const char *algname, ENGINE *e, int do_param); + const char *algname, ENGINE *e, int do_param, + OSSL_LIB_CTX *libctx, const char *propq); int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts); int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts); @@ -292,15 +308,15 @@ typedef struct verify_options_st { extern VERIFY_CB_ARGS verify_args; -OPENSSL_CTX *app_create_libctx(void); -OPENSSL_CTX *app_get0_libctx(void); +OSSL_LIB_CTX *app_create_libctx(void); +OSSL_LIB_CTX *app_get0_libctx(void); OSSL_PARAM *app_params_new_from_opts(STACK_OF(OPENSSL_STRING) *opts, const OSSL_PARAM *paramdefs); void app_params_free(OSSL_PARAM *params); -int app_provider_load(OPENSSL_CTX *libctx, const char *provider_name); +int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name); void app_providers_cleanup(void); -OPENSSL_CTX *app_get0_libctx(void); +OSSL_LIB_CTX *app_get0_libctx(void); const char *app_get0_propq(void); #endif diff --git a/apps/include/opt.h b/apps/include/opt.h index ad629c0199..56de57cf4c 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -278,7 +278,7 @@ # define OPT_PROV_OPTIONS \ OPT_SECTION("Provider"), \ - { "provider_path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \ + { "provider-path", OPT_PROV_PROVIDER_PATH, 's', "Provider load path (must be before 'provider' argument if required)" }, \ { "provider", OPT_PROV_PROVIDER, 's', "Provider to load (can be specified multiple times)" } # define OPT_PROV_CASES \ @@ -339,6 +339,7 @@ typedef struct string_int_pair_st { #define OPT_SECTION(sec) { OPT_SECTION_STR, 1, '-', sec " options:\n" } #define OPT_PARAMETERS() { OPT_PARAM_STR, 1, '-', "Parameters:\n" } +const char *opt_path_end(const char *filename); char *opt_progname(const char *argv0); char *opt_getprog(void); char *opt_init(int ac, char **av, const OPTIONS * o); diff --git a/apps/kdf.c b/apps/kdf.c index 8d11807f5f..ba14cfdc76 100644 --- a/apps/kdf.c +++ b/apps/kdf.c @@ -17,8 +17,6 @@ #include #include -DEFINE_STACK_OF_STRING() - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_KDFOPT, OPT_BIN, OPT_KEYLEN, OPT_OUT, diff --git a/apps/lib/app_params.c b/apps/lib/app_params.c index ba50707926..95e1298ee9 100644 --- a/apps/lib/app_params.c +++ b/apps/lib/app_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -75,7 +75,7 @@ static int describe_param_type(char *buf, size_t bufsz, const OSSL_PARAM *param) int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent) { if (pdefs == NULL) { - BIO_printf(bio_out, "%*sNo declared %s\n", indent, "", thing); + return 1; } else if (pdefs->key == NULL) { /* * An empty list? This shouldn't happen, but let's just make sure to @@ -94,3 +94,39 @@ int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent) return 1; } +void print_param_value(const OSSL_PARAM *p, int indent) +{ + int64_t i; + uint64_t u; + + printf("%*s%s: ", indent, "", p->key); + switch (p->data_type) { + case OSSL_PARAM_UNSIGNED_INTEGER: + if (OSSL_PARAM_get_uint64(p, &u)) + BIO_printf(bio_out, "%llu\n", (unsigned long long int)u); + else + BIO_printf(bio_out, "error getting value\n"); + break; + case OSSL_PARAM_INTEGER: + if (OSSL_PARAM_get_int64(p, &i)) + BIO_printf(bio_out, "%lld\n", (long long int)i); + else + BIO_printf(bio_out, "error getting value\n"); + break; + case OSSL_PARAM_UTF8_PTR: + BIO_printf(bio_out, "'%s'\n", *(char **)(p->data)); + break; + case OSSL_PARAM_UTF8_STRING: + BIO_printf(bio_out, "'%s'\n", (char *)p->data); + break; + case OSSL_PARAM_OCTET_PTR: + case OSSL_PARAM_OCTET_STRING: + BIO_printf(bio_out, "<%zu bytes>\n", p->data_size); + break; + default: + BIO_printf(bio_out, "unknown type (%u) of %zu bytes\n", + p->data_type, p->data_size); + break; + } +} + diff --git a/apps/lib/app_provider.c b/apps/lib/app_provider.c index 60645e21d7..490960521c 100644 --- a/apps/lib/app_provider.c +++ b/apps/lib/app_provider.c @@ -27,7 +27,7 @@ static void provider_free(OSSL_PROVIDER *prov) OSSL_PROVIDER_unload(prov); } -int app_provider_load(OPENSSL_CTX *libctx, const char *provider_name) +int app_provider_load(OSSL_LIB_CTX *libctx, const char *provider_name) { OSSL_PROVIDER *prov; diff --git a/apps/lib/apps.c b/apps/lib/apps.c index e8592c4880..d90ef6a192 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -7,9 +7,6 @@ * https://www.openssl.org/source/license.html */ -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) /* * On VMS, you need to define this to get the declaration of fileno(). The @@ -36,9 +33,6 @@ #include #include #include -#ifndef OPENSSL_NO_ENGINE -# include -#endif #ifndef OPENSSL_NO_RSA # include #endif @@ -62,15 +56,6 @@ static int WIN32_rename(const char *from, const char *to); #define PASS_SOURCE_SIZE_MAX 4 DEFINE_STACK_OF(CONF) -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509_INFO) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(X509_POLICY_NODE) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(DIST_POINT) -DEFINE_STACK_OF_STRING() typedef struct { const char *name; @@ -78,7 +63,7 @@ typedef struct { unsigned long mask; } NAME_EX_TBL; -static OPENSSL_CTX *app_libctx = NULL; +static OSSL_LIB_CTX *app_libctx = NULL; static int set_table_opts(unsigned long *flags, const char *arg, const NAME_EX_TBL * in_tbl); @@ -337,7 +322,7 @@ static char *app_get_pass(const char *arg, int keepbio) return OPENSSL_strdup(tpass); } -OPENSSL_CTX *app_get0_libctx(void) +OSSL_LIB_CTX *app_get0_libctx(void) { return app_libctx; } @@ -348,7 +333,7 @@ const char *app_get0_propq(void) return NULL; } -OPENSSL_CTX *app_create_libctx(void) +OSSL_LIB_CTX *app_create_libctx(void) { /* * Load the NULL provider into the default library context and create a @@ -360,7 +345,7 @@ OPENSSL_CTX *app_create_libctx(void) BIO_puts(bio_err, "Failed to create null provider\n"); return NULL; } - app_libctx = OPENSSL_CTX_new(); + app_libctx = OSSL_LIB_CTX_new(); } if (app_libctx == NULL) BIO_puts(bio_err, "Failed to create library context\n"); @@ -373,7 +358,7 @@ CONF *app_load_config_bio(BIO *in, const char *filename) CONF *conf; int i; - conf = NCONF_new_with_libctx(app_libctx, NULL); + conf = NCONF_new_ex(app_libctx, NULL); i = NCONF_load_bio(conf, in, &errorline); if (i > 0) return conf; @@ -389,7 +374,6 @@ CONF *app_load_config_bio(BIO *in, const char *filename) else BIO_printf(bio_err, "config input"); - CONF_modules_load(conf, NULL, 0); NCONF_free(conf); return NULL; } @@ -491,7 +475,8 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin, if (desc == NULL) desc = "certificate"; - (void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL); + (void)load_key_certs_crls(uri, maybe_stdin, pass, desc, + NULL, NULL, &cert, NULL, NULL, NULL); if (cert == NULL) { BIO_printf(bio_err, "Unable to load %s\n", desc); ERR_print_errors(bio_err); @@ -499,12 +484,6 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin, return cert; } -/* the format parameter is meanwhile not needed anymore and thus ignored */ -X509 *load_cert(const char *uri, int format, const char *desc) -{ - return load_cert_pass(uri, 1, NULL, desc); -} - /* the format parameter is meanwhile not needed anymore and thus ignored */ X509_CRL *load_crl(const char *uri, int format, const char *desc) { @@ -512,7 +491,8 @@ X509_CRL *load_crl(const char *uri, int format, const char *desc) if (desc == NULL) desc = "CRL"; - (void)load_key_cert_crl(uri, 0, NULL, desc, NULL, NULL, &crl); + (void)load_key_certs_crls(uri, 0, NULL, desc, + NULL, NULL, NULL, NULL, &crl, NULL); if (crl == NULL) { BIO_printf(bio_err, "Unable to load %s\n", desc); ERR_print_errors(bio_err); @@ -571,27 +551,15 @@ EVP_PKEY *load_key(const char *uri, int format, int may_stdin, if (e == NULL) { BIO_printf(bio_err, "No engine specified for loading %s\n", desc); } else { -#ifndef OPENSSL_NO_ENGINE - PW_CB_DATA cb_data; - - cb_data.password = pass; - cb_data.prompt_info = uri; - if (ENGINE_init(e)) { - pkey = ENGINE_load_private_key(e, uri, - (UI_METHOD *)get_ui_method(), - &cb_data); - ENGINE_finish(e); - } + pkey = load_engine_private_key(e, uri, pass, desc); if (pkey == NULL) { BIO_printf(bio_err, "Cannot load %s from engine\n", desc); ERR_print_errors(bio_err); } -#else - BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); -#endif } } else { - (void)load_key_cert_crl(uri, may_stdin, pass, desc, &pkey, NULL, NULL); + (void)load_key_certs_crls(uri, may_stdin, pass, desc, + &pkey, NULL, NULL, NULL, NULL, NULL); } if (pkey == NULL) { @@ -613,24 +581,15 @@ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, if (e == NULL) { BIO_printf(bio_err, "No engine specified for loading %s\n", desc); } else { -#ifndef OPENSSL_NO_ENGINE - PW_CB_DATA cb_data; - - cb_data.password = pass; - cb_data.prompt_info = uri; - pkey = ENGINE_load_public_key(e, uri, (UI_METHOD *)get_ui_method(), - &cb_data); + pkey = load_engine_public_key(e, uri, pass, desc); if (pkey == NULL) { BIO_printf(bio_err, "Cannot load %s from engine\n", desc); ERR_print_errors(bio_err); } -#else - BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); -#endif } } else { - (void)load_key_cert_crl(uri, maybe_stdin, pass, desc, &pkey, - NULL, NULL); + (void)load_key_certs_crls(uri, maybe_stdin, pass, desc, + NULL, &pkey, NULL, NULL, NULL, NULL); } if (pkey == NULL) { BIO_printf(bio_err, "Unable to load %s\n", desc); @@ -639,89 +598,6 @@ EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin, return pkey; } -static int load_certs_crls(const char *file, int format, - const char *pass, const char *desc, - STACK_OF(X509) **pcerts, - STACK_OF(X509_CRL) **pcrls) -{ - int i; - BIO *bio; - STACK_OF(X509_INFO) *xis = NULL; - X509_INFO *xi; - PW_CB_DATA cb_data; - int rv = 0; - - cb_data.password = pass; - cb_data.prompt_info = file; - - if (format != FORMAT_PEM) { - BIO_printf(bio_err, "Bad input format specified for %s\n", desc); - return 0; - } - - bio = bio_open_default(file, 'r', FORMAT_PEM); - if (bio == NULL) - return 0; - - xis = PEM_X509_INFO_read_bio_with_libctx(bio, NULL, - (pem_password_cb *)password_callback, - &cb_data, - app_get0_libctx(), - app_get0_propq()); - - BIO_free(bio); - - if (pcerts != NULL && *pcerts == NULL) { - *pcerts = sk_X509_new_null(); - if (*pcerts == NULL) - goto end; - } - - if (pcrls != NULL && *pcrls == NULL) { - *pcrls = sk_X509_CRL_new_null(); - if (*pcrls == NULL) - goto end; - } - - for (i = 0; i < sk_X509_INFO_num(xis); i++) { - xi = sk_X509_INFO_value(xis, i); - if (xi->x509 != NULL && pcerts != NULL) { - if (!sk_X509_push(*pcerts, xi->x509)) - goto end; - xi->x509 = NULL; - } - if (xi->crl != NULL && pcrls != NULL) { - if (!sk_X509_CRL_push(*pcrls, xi->crl)) - goto end; - xi->crl = NULL; - } - } - - if (pcerts != NULL && sk_X509_num(*pcerts) > 0) - rv = 1; - - if (pcrls != NULL && sk_X509_CRL_num(*pcrls) > 0) - rv = 1; - - end: - - sk_X509_INFO_pop_free(xis, X509_INFO_free); - - if (rv == 0) { - if (pcerts != NULL) { - sk_X509_pop_free(*pcerts, X509_free); - *pcerts = NULL; - } - if (pcrls != NULL) { - sk_X509_CRL_pop_free(*pcrls, X509_CRL_free); - *pcrls = NULL; - } - BIO_printf(bio_err, "Unable to load %s\n", desc != NULL ? desc : - pcerts != NULL ? "certificates" : "CRLs"); - } - return rv; -} - void app_bail_out(char *fmt, ...) { va_list args; @@ -745,48 +621,96 @@ void* app_malloc(int sz, const char *what) /* * Initialize or extend, if *certs != NULL, a certificate stack. + * The caller is responsible for freeing *certs if its value is left not NULL. */ -int load_certs(const char *file, STACK_OF(X509) **certs, int format, +int load_certs(const char *uri, STACK_OF(X509) **certs, const char *pass, const char *desc) { - return load_certs_crls(file, format, pass, desc, certs, NULL); + int was_NULL = *certs == NULL; + int ret = load_key_certs_crls(uri, 0, pass, desc, NULL, NULL, + NULL, certs, NULL, NULL); + + if (!ret && was_NULL) { + sk_X509_pop_free(*certs, X509_free); + *certs = NULL; + } + return ret; } /* * Initialize or extend, if *crls != NULL, a certificate stack. + * The caller is responsible for freeing *crls if its value is left not NULL. */ -int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format, +int load_crls(const char *uri, STACK_OF(X509_CRL) **crls, const char *pass, const char *desc) { - return load_certs_crls(file, format, pass, desc, NULL, crls); + int was_NULL = *crls == NULL; + int ret = load_key_certs_crls(uri, 0, pass, desc, NULL, NULL, + NULL, NULL, NULL, crls); + + if (!ret && was_NULL) { + sk_X509_CRL_pop_free(*crls, X509_CRL_free); + *crls = NULL; + } + return ret; } /* * Load those types of credentials for which the result pointer is not NULL. * Reads from stdio if uri is NULL and maybe_stdin is nonzero. - * For each type the first credential found in the store is loaded. - * May yield partial result even if rv == 0. + * For non-NULL ppkey, pcert, and pcrl the first suitable value found is loaded. + * If pcerts is non-NULL and *pcerts == NULL then a new cert list is allocated. + * If pcerts is non-NULL then all available certificates are appended to *pcerts + * except any certificate assigned to *pcert. + * If pcrls is non-NULL and *pcrls == NULL then a new list of CRLs is allocated. + * If pcrls is non-NULL then all available CRLs are appended to *pcerts + * except any CRL assigned to *pcrl. + * In any case (also on error) the caller is responsible for freeing all members + * of *pcerts and *pcrls (as far as they are not NULL). */ -int load_key_cert_crl(const char *uri, int maybe_stdin, - const char *pass, const char *desc, - EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl) +int load_key_certs_crls(const char *uri, int maybe_stdin, + const char *pass, const char *desc, + EVP_PKEY **ppkey, EVP_PKEY **ppubkey, + X509 **pcert, STACK_OF(X509) **pcerts, + X509_CRL **pcrl, STACK_OF(X509_CRL) **pcrls) { PW_CB_DATA uidata; OSSL_STORE_CTX *ctx = NULL; - OPENSSL_CTX *libctx = app_get0_libctx(); + OSSL_LIB_CTX *libctx = app_get0_libctx(); const char *propq = app_get0_propq(); - int ret = 0; + int ncerts = 0; + int ncrls = 0; + const char *failed = + ppkey != NULL ? "key" : ppubkey != NULL ? "public key" : + pcert != NULL ? "cert" : pcrl != NULL ? "CRL" : + pcerts != NULL ? "certs" : pcrls != NULL ? "CRLs" : NULL; /* TODO make use of the engine reference 'eng' when loading pkeys */ if (ppkey != NULL) *ppkey = NULL; + if (ppubkey != NULL) + *ppubkey = NULL; if (pcert != NULL) *pcert = NULL; + if (failed == NULL) { + BIO_printf(bio_err, "Internal error: nothing to load into from %s\n", + uri != NULL ? uri : ""); + return 0; + } + + if (pcerts != NULL && *pcerts == NULL + && (*pcerts = sk_X509_new_null()) == NULL) { + BIO_printf(bio_err, "Out of memory loading"); + goto end; + } if (pcrl != NULL) *pcrl = NULL; + if (pcrls != NULL && *pcrls == NULL + && (*pcrls = sk_X509_CRL_new_null()) == NULL) { + BIO_printf(bio_err, "Out of memory loading"); + goto end; + } - if (desc == NULL) - desc = "key/certificate/CRL"; uidata.password = pass; uidata.prompt_info = uri; @@ -794,69 +718,112 @@ int load_key_cert_crl(const char *uri, int maybe_stdin, BIO *bio; if (!maybe_stdin) { - BIO_printf(bio_err, "No filename or uri specified for loading %s\n", - desc); + BIO_printf(bio_err, "No filename or uri specified for loading"); goto end; } + uri = ""; unbuffer(stdin); bio = BIO_new_fp(stdin, 0); if (bio != NULL) ctx = OSSL_STORE_attach(bio, "file", libctx, propq, get_ui_method(), &uidata, NULL, NULL); - uri = ""; } else { - ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq, get_ui_method(), - &uidata, NULL, NULL); + ctx = OSSL_STORE_open_ex(uri, libctx, propq, get_ui_method(), &uidata, + NULL, NULL); } if (ctx == NULL) { - BIO_printf(bio_err, "Could not open file or uri %s for loading %s\n", - uri, desc); + BIO_printf(bio_err, "Could not open file or uri for loading"); goto end; } - for (;;) { + failed = NULL; + while (!OSSL_STORE_eof(ctx)) { OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); - int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info); - const char *infostr = - info == NULL ? NULL : OSSL_STORE_INFO_type_string(type); - int err = 0; - - if (info == NULL) { - if (OSSL_STORE_eof(ctx)) - ret = 1; - break; - } + int type, ok = 1; + if (info == NULL) + break; + type = OSSL_STORE_INFO_get_type(info); switch (type) { case OSSL_STORE_INFO_PKEY: if (ppkey != NULL && *ppkey == NULL) - err = ((*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) == NULL); + ok = (*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL; + + /* + * An EVP_PKEY with private parts also holds the public parts, + * so if the caller asked for a public key, and we got a private + * key, we can still pass it back. + */ + if (ok && ppubkey != NULL && *ppubkey == NULL) + ok = ((*ppubkey = OSSL_STORE_INFO_get1_PKEY(info)) != NULL); + break; + case OSSL_STORE_INFO_PUBKEY: + if (ppubkey != NULL && *ppubkey == NULL) + ok = ((*ppubkey = OSSL_STORE_INFO_get1_PUBKEY(info)) != NULL); break; case OSSL_STORE_INFO_CERT: if (pcert != NULL && *pcert == NULL) - err = ((*pcert = OSSL_STORE_INFO_get1_CERT(info)) == NULL); + ok = (*pcert = OSSL_STORE_INFO_get1_CERT(info)) != NULL; + else if (pcerts != NULL) + ok = X509_add_cert(*pcerts, + OSSL_STORE_INFO_get1_CERT(info), + X509_ADD_FLAG_DEFAULT); + ncerts += ok; break; case OSSL_STORE_INFO_CRL: if (pcrl != NULL && *pcrl == NULL) - err = ((*pcrl = OSSL_STORE_INFO_get1_CRL(info)) == NULL); + ok = (*pcrl = OSSL_STORE_INFO_get1_CRL(info)) != NULL; + else if (pcrls != NULL) + ok = sk_X509_CRL_push(*pcrls, OSSL_STORE_INFO_get1_CRL(info)); + ncrls += ok; break; default: /* skip any other type */ break; } OSSL_STORE_INFO_free(info); - if (err) { - BIO_printf(bio_err, "Could not read %s of %s from %s\n", - infostr, desc, uri); + if (!ok) { + failed = info == NULL ? NULL : OSSL_STORE_INFO_type_string(type); + BIO_printf(bio_err, "Error reading"); break; } } end: OSSL_STORE_close(ctx); - if (!ret) + if (failed == NULL) { + int any = 0; + + if (ppkey != NULL && *ppkey == NULL) { + failed = "key"; + } else if ((pcert != NULL || pcerts != NULL) && ncerts == 0) { + if (pcert == NULL) + any = 1; + failed = "cert"; + } else if ((pcrl != NULL || pcrls != NULL) && ncrls == 0) { + if (pcrl == NULL) + any = 1; + failed = "CRL"; + } + if (failed != NULL) + BIO_printf(bio_err, "Could not read"); + if (any) + BIO_printf(bio_err, " any"); + } + if (failed != NULL) { + if (desc != NULL && strstr(desc, failed) != NULL) { + BIO_printf(bio_err, " %s", desc); + } else { + BIO_printf(bio_err, " %s", failed); + if (desc != NULL) + BIO_printf(bio_err, " of %s", desc); + } + if (uri != NULL) + BIO_printf(bio_err, " from %s", uri); + BIO_printf(bio_err, "\n"); ERR_print_errors(bio_err); - return ret; + } + return failed == NULL; } @@ -1110,7 +1077,7 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile, { X509_STORE *store = X509_STORE_new(); X509_LOOKUP *lookup; - OPENSSL_CTX *libctx = app_get0_libctx(); + OSSL_LIB_CTX *libctx = app_get0_libctx(); const char *propq = app_get0_propq(); if (store == NULL) @@ -1121,16 +1088,14 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile, if (lookup == NULL) goto end; if (CAfile != NULL) { - if (!X509_LOOKUP_load_file_with_libctx(lookup, CAfile, - X509_FILETYPE_PEM, - libctx, propq)) { + if (!X509_LOOKUP_load_file_ex(lookup, CAfile, X509_FILETYPE_PEM, + libctx, propq)) { BIO_printf(bio_err, "Error loading file %s\n", CAfile); goto end; } } else { - X509_LOOKUP_load_file_with_libctx(lookup, NULL, - X509_FILETYPE_DEFAULT, - libctx, propq); + X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, + libctx, propq); } } @@ -1152,7 +1117,7 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile, lookup = X509_STORE_add_lookup(store, X509_LOOKUP_store()); if (lookup == NULL) goto end; - if (!X509_LOOKUP_add_store_with_libctx(lookup, CAstore, libctx, propq)) { + if (!X509_LOOKUP_add_store_ex(lookup, CAstore, libctx, propq)) { if (CAstore != NULL) BIO_printf(bio_err, "Error loading store URI %s\n", CAstore); goto end; @@ -1167,64 +1132,6 @@ X509_STORE *setup_verify(const char *CAfile, int noCAfile, return NULL; } -#ifndef OPENSSL_NO_ENGINE -/* Try to load an engine in a shareable library */ -static ENGINE *try_load_engine(const char *engine) -{ - ENGINE *e = ENGINE_by_id("dynamic"); - if (e) { - if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) - || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { - ENGINE_free(e); - e = NULL; - } - } - return e; -} -#endif - -ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug) -{ - ENGINE *e = NULL; - -#ifndef OPENSSL_NO_ENGINE - if (id != NULL) { - if (strcmp(id, "auto") == 0) { - BIO_printf(bio_err, "Enabling auto ENGINE support\n"); - ENGINE_register_all_complete(); - return NULL; - } - if ((e = ENGINE_by_id(id)) == NULL - && (e = try_load_engine(id)) == NULL) { - BIO_printf(bio_err, "Invalid engine \"%s\"\n", id); - ERR_print_errors(bio_err); - return NULL; - } - if (debug) - (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); - if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, - (void *)get_ui_method(), 0, 1) - || !ENGINE_set_default(e, methods)) { - BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e)); - ERR_print_errors(bio_err); - ENGINE_free(e); - return NULL; - } - - BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e)); - } -#endif - return e; -} - -void release_engine(ENGINE *e) -{ -#ifndef OPENSSL_NO_ENGINE - /* Free our "structural" reference. */ - ENGINE_free(e); -#endif -} - static unsigned long index_serial_hash(const OPENSSL_CSTRING *a) { const char *n; @@ -1668,7 +1575,8 @@ int parse_yesno(const char *str, int def) /* * name is expected to be in the format /type0=value0/type1=value1/type2=... - * where characters may be escaped by \ + * where + can be used instead of / to form multi-valued RDNs if canmulti + * and characters may be escaped by \ */ X509_NAME *parse_name(const char *cp, int chtype, int canmulti, const char *desc) @@ -1721,6 +1629,7 @@ X509_NAME *parse_name(const char *cp, int chtype, int canmulti, /* Collect the value. */ valstr = (unsigned char *)bp; for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) { + /* unescaped '+' symbol string signals further member of multiRDN */ if (canmulti && *cp == '+') { nextismulti = 1; break; @@ -1744,6 +1653,9 @@ X509_NAME *parse_name(const char *cp, int chtype, int canmulti, BIO_printf(bio_err, "%s: Skipping unknown %s name attribute \"%s\"\n", opt_getprog(), desc, typestr); + if (ismulti) + BIO_printf(bio_err, + "Hint: a '+' in a value string needs be escaped using '\\' else a new member of a multi-valued RDN is expected\n"); continue; } if (*valstr == '\0') { @@ -2105,7 +2017,7 @@ ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy, return NULL; } - if (!OSSL_HTTP_parse_url(url, &server, &port, NULL /* ppath */, &use_ssl)) + if (!OSSL_HTTP_parse_url(url, &server, &port, NULL, NULL, &use_ssl)) return NULL; if (use_ssl && ssl_ctx == NULL) { HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); @@ -2415,6 +2327,11 @@ int raw_read_stdin(void *buf, int siz) return recv(fileno_stdin(), buf, siz, 0); } #else +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif int raw_read_stdin(void *buf, int siz) { return read(fileno_stdin(), buf, siz); @@ -2430,7 +2347,22 @@ int raw_write_stdout(const void *buf, int siz) else return -1; } +#elif defined(OPENSSL_SYS_TANDEM) && defined(OPENSSL_THREADS) && defined(_SPT_MODEL_) +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif +int raw_write_stdout(const void *buf,int siz) +{ + return write(fileno(stdout),(void*)buf,siz); +} #else +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif int raw_write_stdout(const void *buf, int siz) { return write(fileno_stdout(), buf, siz); @@ -2720,6 +2652,57 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate, return 1; } +int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate) +{ + int ret = 0; + ASN1_TIME *tm = ASN1_TIME_new(); + + if (tm == NULL) + goto end; + + if (lastupdate == NULL) { + if (X509_gmtime_adj(tm, 0) == NULL) + goto end; + } else { + if (!ASN1_TIME_set_string_X509(tm, lastupdate)) + goto end; + } + + if (!X509_CRL_set1_lastUpdate(crl, tm)) + goto end; + + ret = 1; +end: + ASN1_TIME_free(tm); + return ret; +} + +int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate, + long days, long hours, long secs) +{ + int ret = 0; + ASN1_TIME *tm = ASN1_TIME_new(); + + if (tm == NULL) + goto end; + + if (nextupdate == NULL) { + if (X509_time_adj_ex(tm, days, hours * 60 * 60 + secs, NULL) == NULL) + goto end; + } else { + if (!ASN1_TIME_set_string_X509(tm, nextupdate)) + goto end; + } + + if (!X509_CRL_set1_nextUpdate(crl, tm)) + goto end; + + ret = 1; +end: + ASN1_TIME_free(tm); + return ret; +} + void make_uppercase(char *string) { int i; diff --git a/apps/lib/apps_ui.c b/apps/lib/apps_ui.c index 13f8670d9f..880e9a4f6d 100644 --- a/apps/lib/apps_ui.c +++ b/apps/lib/apps_ui.c @@ -15,7 +15,6 @@ static UI_METHOD *ui_method = NULL; static const UI_METHOD *ui_fallback_method = NULL; - static int ui_open(UI *ui) { int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method); @@ -72,7 +71,8 @@ static int ui_write(UI *ui, UI_STRING *uis) { const char *password = ((PW_CB_DATA *)UI_get0_user_data(ui))->password; - if (password && password[0] != '\0') + + if (password != NULL) return 1; } break; @@ -99,6 +99,19 @@ static int ui_close(UI *ui) return 1; } +/* object_name defaults to prompt_info from ui user data if present */ +static char *ui_prompt_construct(UI *ui, const char *phrase_desc, + const char *object_name) +{ + PW_CB_DATA *cb_data = (PW_CB_DATA *)UI_get0_user_data(ui); + + if (phrase_desc == NULL) + phrase_desc = "pass phrase"; + if (object_name == NULL && cb_data != NULL) + object_name = cb_data->prompt_info; + return UI_construct_prompt(NULL, phrase_desc, object_name); +} + int setup_ui_method(void) { ui_fallback_method = UI_null(); @@ -106,11 +119,13 @@ int setup_ui_method(void) ui_fallback_method = UI_OpenSSL(); #endif 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; + return ui_method != NULL + && 0 == UI_method_set_opener(ui_method, ui_open) + && 0 == UI_method_set_reader(ui_method, ui_read) + && 0 == UI_method_set_writer(ui_method, ui_write) + && 0 == UI_method_set_closer(ui_method, ui_close) + && 0 == UI_method_set_prompt_constructor(ui_method, + ui_prompt_construct); } void destroy_ui_method(void) diff --git a/apps/lib/build.info b/apps/lib/build.info index 22db095c51..9930ad6212 100644 --- a/apps/lib/build.info +++ b/apps/lib/build.info @@ -9,7 +9,8 @@ ENDIF # Source for libapps $LIBAPPSSRC=apps.c apps_ui.c opt.c fmt.c s_cb.c s_socket.c app_rand.c \ - columns.c app_params.c names.c app_provider.c app_x509.c http_server.c + columns.c app_params.c names.c app_provider.c app_x509.c http_server.c \ + engine.c IF[{- !$disabled{apps} -}] LIBS{noinst}=../libapps.a diff --git a/apps/lib/engine.c b/apps/lib/engine.c new file mode 100644 index 0000000000..e6682f5e8f --- /dev/null +++ b/apps/lib/engine.c @@ -0,0 +1,145 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Here is a set of wrappers for the ENGINE API, which are no-ops when the + * ENGINE API is disabled / removed. + * We need to suppress deprecation warnings to make this work. + */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include /* Ensure we have the ENGINE type, regardless */ +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "apps.h" + +#ifndef OPENSSL_NO_ENGINE +/* Try to load an engine in a shareable library */ +static ENGINE *try_load_engine(const char *engine) +{ + ENGINE *e = NULL; + + if ((e = ENGINE_by_id("dynamic")) != NULL) { + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0) + || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) { + ENGINE_free(e); + e = NULL; + } + } + return e; +} +#endif + +ENGINE *setup_engine_methods(const char *id, unsigned int methods, int debug) +{ + ENGINE *e = NULL; + +#ifndef OPENSSL_NO_ENGINE + if (id != NULL) { + if (strcmp(id, "auto") == 0) { + BIO_printf(bio_err, "Enabling auto ENGINE support\n"); + ENGINE_register_all_complete(); + return NULL; + } + if ((e = ENGINE_by_id(id)) == NULL + && (e = try_load_engine(id)) == NULL) { + BIO_printf(bio_err, "Invalid engine \"%s\"\n", id); + ERR_print_errors(bio_err); + return NULL; + } + if (debug) + (void)ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0); + if (!ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, + (void *)get_ui_method(), 0, 1) + || !ENGINE_set_default(e, methods)) { + BIO_printf(bio_err, "Cannot use engine \"%s\"\n", ENGINE_get_id(e)); + ERR_print_errors(bio_err); + ENGINE_free(e); + return NULL; + } + + BIO_printf(bio_err, "Engine \"%s\" set.\n", ENGINE_get_id(e)); + } +#endif + return e; +} + +void release_engine(ENGINE *e) +{ +#ifndef OPENSSL_NO_ENGINE + /* Free our "structural" reference. */ + ENGINE_free(e); +#endif +} + +int init_engine(ENGINE *e) +{ + int rv = 1; + +#ifndef OPENSSL_NO_ENGINE + rv = ENGINE_init(e); +#endif + return rv; +} + +int finish_engine(ENGINE *e) +{ + int rv = 1; + +#ifndef OPENSSL_NO_ENGINE + rv = ENGINE_finish(e); +#endif + return rv; +} + +EVP_PKEY *load_engine_private_key(ENGINE *e, const char *keyid, + const char *pass, const char *desc) +{ + EVP_PKEY *rv = NULL; + +#ifndef OPENSSL_NO_ENGINE + if (init_engine(e)) { + PW_CB_DATA cb_data; + + cb_data.password = pass; + cb_data.prompt_info = keyid; + + rv = ENGINE_load_private_key(e, keyid, + (UI_METHOD *)get_ui_method(), &cb_data); + finish_engine(e); + } +#else + BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); +#endif + return rv; +} + +EVP_PKEY *load_engine_public_key(ENGINE *e, const char *keyid, + const char *pass, const char *desc) +{ + EVP_PKEY *rv = NULL; + +#ifndef OPENSSL_NO_ENGINE + if (init_engine(e)) { + PW_CB_DATA cb_data; + + cb_data.password = pass; + cb_data.prompt_info = keyid; + + rv = ENGINE_load_public_key(e, keyid, + (UI_METHOD *)get_ui_method(), &cb_data); + finish_engine(e); + } +#else + BIO_printf(bio_err, "Engines not supported for loading %s\n", desc); +#endif + return rv; +} + diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c index 5c009b9990..b7d9842013 100644 --- a/apps/lib/http_server.c +++ b/apps/lib/http_server.c @@ -24,6 +24,12 @@ #include #include +#if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +#endif + int multi = 0; /* run multiple responder processes */ #ifdef HTTP_DAEMON diff --git a/apps/lib/names.c b/apps/lib/names.c index 42b9e9065c..5e2e7e147c 100644 --- a/apps/lib/names.c +++ b/apps/lib/names.c @@ -12,8 +12,6 @@ #include #include "names.h" -DEFINE_STACK_OF_CSTRING() - #ifdef _WIN32 # define strcasecmp _stricmp #endif diff --git a/apps/lib/opt.c b/apps/lib/opt.c index d6bfecc8ff..260ff3b1c2 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -46,18 +46,27 @@ static char prog[40]; * Return the simple name of the program; removing various platform gunk. */ #if defined(OPENSSL_SYS_WIN32) -char *opt_progname(const char *argv0) + +const char *opt_path_end(const char *filename) { - size_t i, n; const char *p; - char *q; /* find the last '/', '\' or ':' */ - for (p = argv0 + strlen(argv0); --p > argv0;) + for (p = filename + strlen(filename); --p > filename; ) if (*p == '/' || *p == '\\' || *p == ':') { p++; break; } + return p; +} + +char *opt_progname(const char *argv0) +{ + size_t i, n; + const char *p; + char *q; + + p = opt_path_end(argv0); /* Strip off trailing nonsense. */ n = strlen(p); @@ -76,17 +85,25 @@ char *opt_progname(const char *argv0) #elif defined(OPENSSL_SYS_VMS) -char *opt_progname(const char *argv0) +const char *opt_path_end(const char *filename) { - const char *p, *q; + const char *p; /* Find last special character sys:[foo.bar]openssl */ - for (p = argv0 + strlen(argv0); --p > argv0;) + for (p = filename + strlen(filename); --p > filename;) if (*p == ':' || *p == ']' || *p == '>') { p++; break; } + return p; +} +char *opt_progname(const char *argv0) +{ + const char *p, *q; + + /* Find last special character sys:[foo.bar]openssl */ + p = opt_path_end(argv0); q = strrchr(p, '.'); strncpy(prog, p, sizeof(prog) - 1); prog[sizeof(prog) - 1] = '\0'; @@ -97,16 +114,24 @@ char *opt_progname(const char *argv0) #else -char *opt_progname(const char *argv0) +const char *opt_path_end(const char *filename) { const char *p; /* Could use strchr, but this is like the ones above. */ - for (p = argv0 + strlen(argv0); --p > argv0;) + for (p = filename + strlen(filename); --p > filename;) if (*p == '/') { p++; break; } + return p; +} + +char *opt_progname(const char *argv0) +{ + const char *p; + + p = opt_path_end(argv0); strncpy(prog, p, sizeof(prog) - 1); prog[sizeof(prog) - 1] = '\0'; return prog; diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index ba9ef12afb..142659d05e 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -26,11 +26,6 @@ #define COOKIE_SECRET_LENGTH 16 -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509_NAME) -DEFINE_STACK_OF_STRING() - VERIFY_CB_ARGS verify_args = { -1, 0, X509_V_OK, 0 }; #ifndef OPENSSL_NO_SOCK @@ -570,8 +565,8 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, { BIO *bio = arg; const char *str_write_p = write_p ? ">>>" : "<<<"; - const char *str_version = lookup(version, ssl_versions, "???"); - const char *str_content_type = "", *str_details1 = "", *str_details2 = ""; + char tmpbuf[128]; + const char *str_version, *str_content_type = "", *str_details1 = "", *str_details2 = ""; const unsigned char* bp = buf; if (version == SSL3_VERSION || @@ -580,11 +575,14 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, version == TLS1_2_VERSION || version == TLS1_3_VERSION || version == DTLS1_VERSION || version == DTLS1_BAD_VER) { + str_version = lookup(version, ssl_versions, "???"); switch (content_type) { - case 20: + case SSL3_RT_CHANGE_CIPHER_SPEC: + /* type 20 */ str_content_type = ", ChangeCipherSpec"; break; - case 21: + case SSL3_RT_ALERT: + /* type 21 */ str_content_type = ", Alert"; str_details1 = ", ???"; if (len == 2) { @@ -599,16 +597,32 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, str_details2 = lookup((int)bp[1], alert_types, " ???"); } break; - case 22: + case SSL3_RT_HANDSHAKE: + /* type 22 */ str_content_type = ", Handshake"; str_details1 = "???"; if (len > 0) str_details1 = lookup((int)bp[0], handshakes, "???"); break; - case 23: + case SSL3_RT_APPLICATION_DATA: + /* type 23 */ str_content_type = ", ApplicationData"; break; + case SSL3_RT_HEADER: + /* type 256 */ + str_content_type = ", RecordHeader"; + break; + case SSL3_RT_INNER_CONTENT_TYPE: + /* type 257 */ + str_content_type = ", InnerContent"; + break; + default: + BIO_snprintf(tmpbuf, sizeof(tmpbuf)-1, ", Unknown (content_type=%d)", content_type); + str_content_type = tmpbuf; } + } else { + BIO_snprintf(tmpbuf, sizeof(tmpbuf)-1, "Not TLS data or unknown version (version=%d, content_type=%d)", version, content_type); + str_version = tmpbuf; } BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, @@ -772,6 +786,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie, /* Create buffer with peer's address and port */ if (!BIO_ADDR_rawaddress(peer, NULL, &length)) { BIO_printf(bio_err, "Failed getting peer address\n"); + BIO_ADDR_free(lpeer); return 0; } OPENSSL_assert(length != 0); @@ -1032,16 +1047,15 @@ int load_excert(SSL_EXCERT **pexc) return 0; if (exc->keyfile != NULL) { exc->key = load_key(exc->keyfile, exc->keyform, - 0, NULL, NULL, "Server Key"); + 0, NULL, NULL, "server key"); } else { exc->key = load_key(exc->certfile, exc->certform, - 0, NULL, NULL, "Server Key"); + 0, NULL, NULL, "server key"); } if (exc->key == NULL) return 0; if (exc->chainfile != NULL) { - if (!load_certs(exc->chainfile, &exc->chain, FORMAT_PEM, NULL, - "Server Chain")) + if (!load_certs(exc->chainfile, &exc->chain, NULL, "server chain")) return 0; } } diff --git a/apps/lib/s_socket.c b/apps/lib/s_socket.c index b9baef913d..890bd39414 100644 --- a/apps/lib/s_socket.c +++ b/apps/lib/s_socket.c @@ -32,6 +32,12 @@ typedef unsigned int u_int; # include "s_apps.h" # include "internal/sockets.h" +# if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# endif + # include # include diff --git a/apps/list.c b/apps/list.c index 69a516763c..ec9e24dfb8 100644 --- a/apps/list.c +++ b/apps/list.c @@ -16,22 +16,26 @@ #include #include #include -#include -#include +#include +#include #include +#include #include "apps.h" #include "app_params.h" #include "progs.h" #include "opt.h" #include "names.h" -DEFINE_STACK_OF_CSTRING() - static int verbose = 0; +static const char *select_name = NULL; static void legacy_cipher_fn(const EVP_CIPHER *c, const char *from, const char *to, void *arg) { + if (select_name != NULL + && (c == NULL + || strcasecmp(select_name, EVP_CIPHER_name(c)) != 0)) + return; if (c != NULL) { BIO_printf(arg, " %s\n", EVP_CIPHER_name(c)); } else { @@ -81,18 +85,20 @@ static void list_ciphers(void) sk_EVP_CIPHER_sort(ciphers); for (i = 0; i < sk_EVP_CIPHER_num(ciphers); i++) { const EVP_CIPHER *c = sk_EVP_CIPHER_value(ciphers, i); - STACK_OF(OPENSSL_CSTRING) *names = - sk_OPENSSL_CSTRING_new(name_cmp); + STACK_OF(OPENSSL_CSTRING) *names = NULL; - EVP_CIPHER_names_do_all(c, collect_names, names); + if (select_name != NULL && !EVP_CIPHER_is_a(c, select_name)) + continue; + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_CIPHER_names_do_all(c, collect_names, names); BIO_printf(bio_out, " "); print_names(bio_out, names); + sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s\n", OSSL_PROVIDER_name(EVP_CIPHER_provider(c))); - sk_OPENSSL_CSTRING_free(names); - if (verbose) { print_param_types("retrievable algorithm parameters", EVP_CIPHER_gettable_params(c), 4); @@ -156,18 +162,19 @@ static void list_digests(void) sk_EVP_MD_sort(digests); for (i = 0; i < sk_EVP_MD_num(digests); i++) { const EVP_MD *m = sk_EVP_MD_value(digests, i); - STACK_OF(OPENSSL_CSTRING) *names = - sk_OPENSSL_CSTRING_new(name_cmp); + STACK_OF(OPENSSL_CSTRING) *names = NULL; - EVP_MD_names_do_all(m, collect_names, names); + if (select_name != NULL && !EVP_MD_is_a(m, select_name)) + continue; + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_MD_names_do_all(m, collect_names, names); BIO_printf(bio_out, " "); print_names(bio_out, names); - BIO_printf(bio_out, " @ %s\n", - OSSL_PROVIDER_name(EVP_MD_provider(m))); - sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s\n", OSSL_PROVIDER_name(EVP_MD_provider(m))); + if (verbose) { print_param_types("retrievable algorithm parameters", EVP_MD_gettable_params(m), 4); @@ -214,18 +221,19 @@ static void list_macs(void) sk_EVP_MAC_sort(macs); for (i = 0; i < sk_EVP_MAC_num(macs); i++) { const EVP_MAC *m = sk_EVP_MAC_value(macs, i); - STACK_OF(OPENSSL_CSTRING) *names = - sk_OPENSSL_CSTRING_new(name_cmp); + STACK_OF(OPENSSL_CSTRING) *names = NULL; - EVP_MAC_names_do_all(m, collect_names, names); + if (select_name != NULL && !EVP_MAC_is_a(m, select_name)) + continue; + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_MAC_names_do_all(m, collect_names, names); BIO_printf(bio_out, " "); print_names(bio_out, names); - BIO_printf(bio_out, " @ %s\n", - OSSL_PROVIDER_name(EVP_MAC_provider(m))); - sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s\n", OSSL_PROVIDER_name(EVP_MAC_provider(m))); + if (verbose) { print_param_types("retrievable algorithm parameters", EVP_MAC_gettable_params(m), 4); @@ -275,18 +283,19 @@ static void list_kdfs(void) sk_EVP_KDF_sort(kdfs); for (i = 0; i < sk_EVP_KDF_num(kdfs); i++) { const EVP_KDF *k = sk_EVP_KDF_value(kdfs, i); - STACK_OF(OPENSSL_CSTRING) *names = - sk_OPENSSL_CSTRING_new(name_cmp); + STACK_OF(OPENSSL_CSTRING) *names = NULL; - EVP_KDF_names_do_all(k, collect_names, names); + if (select_name != NULL && !EVP_KDF_is_a(k, select_name)) + continue; + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_KDF_names_do_all(k, collect_names, names); BIO_printf(bio_out, " "); print_names(bio_out, names); - BIO_printf(bio_out, " @ %s\n", - OSSL_PROVIDER_name(EVP_KDF_provider(k))); - sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s\n", OSSL_PROVIDER_name(EVP_KDF_provider(k))); + if (verbose) { print_param_types("retrievable algorithm parameters", EVP_KDF_gettable_params(k), 4); @@ -338,9 +347,11 @@ static void list_random_generators(void) for (i = 0; i < sk_EVP_RAND_num(rands); i++) { const EVP_RAND *m = sk_EVP_RAND_value(rands, i); + if (select_name != NULL + && strcasecmp(EVP_RAND_name(m), select_name) != 0) + continue; BIO_printf(bio_out, " %s", EVP_RAND_name(m)); - BIO_printf(bio_out, " @ %s\n", - OSSL_PROVIDER_name(EVP_RAND_provider(m))); + BIO_printf(bio_out, " @ %s\n", OSSL_PROVIDER_name(EVP_RAND_provider(m))); if (verbose) { print_param_types("retrievable algorithm parameters", @@ -354,125 +365,481 @@ static void list_random_generators(void) sk_EVP_RAND_pop_free(rands, EVP_RAND_free); } +static void display_random(const char *name, EVP_RAND_CTX *drbg) +{ + EVP_RAND *rand; + uint64_t u; + const char *p; + const OSSL_PARAM *gettables; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + unsigned char buf[1000]; + + BIO_printf(bio_out, "%s:\n", name); + if (drbg != NULL) { + rand = EVP_RAND_CTX_rand(drbg); + + BIO_printf(bio_out, " %s", EVP_RAND_name(rand)); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_RAND_provider(rand))); + + switch (EVP_RAND_state(drbg)) { + case EVP_RAND_STATE_UNINITIALISED: + p = "uninitialised"; + break; + case EVP_RAND_STATE_READY: + p = "ready"; + break; + case EVP_RAND_STATE_ERROR: + p = "error"; + break; + default: + p = "unknown"; + break; + } + BIO_printf(bio_out, " state = %s\n", p); + + gettables = EVP_RAND_gettable_ctx_params(rand); + if (gettables != NULL) + for (; gettables->key != NULL; gettables++) { + /* State has been dealt with already, so ignore */ + if (strcasecmp(gettables->key, OSSL_RAND_PARAM_STATE) == 0) + continue; + /* Outside of verbose mode, we skip non-string values */ + if (gettables->data_type != OSSL_PARAM_UTF8_STRING + && gettables->data_type != OSSL_PARAM_UTF8_PTR + && !verbose) + continue; + params->key = gettables->key; + params->data_type = gettables->data_type; + if (gettables->data_type == OSSL_PARAM_UNSIGNED_INTEGER + || gettables->data_type == OSSL_PARAM_INTEGER) { + params->data = &u; + params->data_size = sizeof(u); + } else { + params->data = buf; + params->data_size = sizeof(buf); + } + params->return_size = 0; + if (EVP_RAND_get_ctx_params(drbg, params)) + print_param_value(params, 2); + } + } +} + +static void list_random_instances(void) +{ + display_random("primary", RAND_get0_primary(NULL)); + display_random("public", RAND_get0_public(NULL)); + display_random("private", RAND_get0_private(NULL)); +} + /* - * Serializers + * Encoders */ -DEFINE_STACK_OF(OSSL_SERIALIZER) -static int serializer_cmp(const OSSL_SERIALIZER * const *a, - const OSSL_SERIALIZER * const *b) +DEFINE_STACK_OF(OSSL_ENCODER) +static int encoder_cmp(const OSSL_ENCODER * const *a, + const OSSL_ENCODER * const *b) { - int ret = OSSL_SERIALIZER_number(*a) - OSSL_SERIALIZER_number(*b); + int ret = OSSL_ENCODER_number(*a) - OSSL_ENCODER_number(*b); if (ret == 0) - ret = strcmp(OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(*a)), - OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(*b))); + ret = strcmp(OSSL_PROVIDER_name(OSSL_ENCODER_provider(*a)), + OSSL_PROVIDER_name(OSSL_ENCODER_provider(*b))); return ret; } -static void collect_serializers(OSSL_SERIALIZER *serializer, void *stack) +static void collect_encoders(OSSL_ENCODER *encoder, void *stack) { - STACK_OF(OSSL_SERIALIZER) *serializer_stack = stack; + STACK_OF(OSSL_ENCODER) *encoder_stack = stack; - sk_OSSL_SERIALIZER_push(serializer_stack, serializer); - OSSL_SERIALIZER_up_ref(serializer); + sk_OSSL_ENCODER_push(encoder_stack, encoder); + OSSL_ENCODER_up_ref(encoder); } -static void list_serializers(void) +static void list_encoders(void) { - STACK_OF(OSSL_SERIALIZER) *serializers; + STACK_OF(OSSL_ENCODER) *encoders; int i; - serializers = sk_OSSL_SERIALIZER_new(serializer_cmp); - if (serializers == NULL) { + encoders = sk_OSSL_ENCODER_new(encoder_cmp); + if (encoders == NULL) { BIO_printf(bio_err, "ERROR: Memory allocation\n"); return; } - BIO_printf(bio_out, "Provided SERIALIZERs:\n"); - OSSL_SERIALIZER_do_all_provided(NULL, collect_serializers, serializers); - sk_OSSL_SERIALIZER_sort(serializers); + BIO_printf(bio_out, "Provided ENCODERs:\n"); + OSSL_ENCODER_do_all_provided(NULL, collect_encoders, encoders); + sk_OSSL_ENCODER_sort(encoders); - for (i = 0; i < sk_OSSL_SERIALIZER_num(serializers); i++) { - OSSL_SERIALIZER *k = sk_OSSL_SERIALIZER_value(serializers, i); - STACK_OF(OPENSSL_CSTRING) *names = - sk_OPENSSL_CSTRING_new(name_cmp); + for (i = 0; i < sk_OSSL_ENCODER_num(encoders); i++) { + OSSL_ENCODER *k = sk_OSSL_ENCODER_value(encoders, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; - OSSL_SERIALIZER_names_do_all(k, collect_names, names); + if (select_name != NULL && !OSSL_ENCODER_is_a(k, select_name)) + continue; + names = sk_OPENSSL_CSTRING_new(name_cmp); + OSSL_ENCODER_names_do_all(k, collect_names, names); BIO_printf(bio_out, " "); print_names(bio_out, names); - BIO_printf(bio_out, " @ %s (%s)\n", - OSSL_PROVIDER_name(OSSL_SERIALIZER_provider(k)), - OSSL_SERIALIZER_properties(k)); - sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s (%s)\n", + OSSL_PROVIDER_name(OSSL_ENCODER_provider(k)), + OSSL_ENCODER_properties(k)); + if (verbose) { print_param_types("settable operation parameters", - OSSL_SERIALIZER_settable_ctx_params(k), 4); + OSSL_ENCODER_settable_ctx_params(k), 4); } } - sk_OSSL_SERIALIZER_pop_free(serializers, OSSL_SERIALIZER_free); + sk_OSSL_ENCODER_pop_free(encoders, OSSL_ENCODER_free); } /* - * Deserializers + * Decoders */ -DEFINE_STACK_OF(OSSL_DESERIALIZER) -static int deserializer_cmp(const OSSL_DESERIALIZER * const *a, - const OSSL_DESERIALIZER * const *b) +DEFINE_STACK_OF(OSSL_DECODER) +static int decoder_cmp(const OSSL_DECODER * const *a, + const OSSL_DECODER * const *b) { - int ret = OSSL_DESERIALIZER_number(*a) - OSSL_DESERIALIZER_number(*b); + int ret = OSSL_DECODER_number(*a) - OSSL_DECODER_number(*b); if (ret == 0) - ret = strcmp(OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(*a)), - OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(*b))); + ret = strcmp(OSSL_PROVIDER_name(OSSL_DECODER_provider(*a)), + OSSL_PROVIDER_name(OSSL_DECODER_provider(*b))); return ret; } -static void collect_deserializers(OSSL_DESERIALIZER *deserializer, void *stack) +static void collect_decoders(OSSL_DECODER *decoder, void *stack) { - STACK_OF(OSSL_DESERIALIZER) *deserializer_stack = stack; + STACK_OF(OSSL_DECODER) *decoder_stack = stack; - sk_OSSL_DESERIALIZER_push(deserializer_stack, deserializer); - OSSL_DESERIALIZER_up_ref(deserializer); + sk_OSSL_DECODER_push(decoder_stack, decoder); + OSSL_DECODER_up_ref(decoder); } -static void list_deserializers(void) +static void list_decoders(void) { - STACK_OF(OSSL_DESERIALIZER) *deserializers; + STACK_OF(OSSL_DECODER) *decoders; int i; - deserializers = sk_OSSL_DESERIALIZER_new(deserializer_cmp); - if (deserializers == NULL) { + decoders = sk_OSSL_DECODER_new(decoder_cmp); + if (decoders == NULL) { BIO_printf(bio_err, "ERROR: Memory allocation\n"); return; } - BIO_printf(bio_out, "Provided DESERIALIZERs:\n"); - OSSL_DESERIALIZER_do_all_provided(NULL, collect_deserializers, - deserializers); - sk_OSSL_DESERIALIZER_sort(deserializers); + BIO_printf(bio_out, "Provided DECODERs:\n"); + OSSL_DECODER_do_all_provided(NULL, collect_decoders, + decoders); + sk_OSSL_DECODER_sort(decoders); - for (i = 0; i < sk_OSSL_DESERIALIZER_num(deserializers); i++) { - OSSL_DESERIALIZER *k = sk_OSSL_DESERIALIZER_value(deserializers, i); - STACK_OF(OPENSSL_CSTRING) *names = - sk_OPENSSL_CSTRING_new(name_cmp); + for (i = 0; i < sk_OSSL_DECODER_num(decoders); i++) { + OSSL_DECODER *k = sk_OSSL_DECODER_value(decoders, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; - OSSL_DESERIALIZER_names_do_all(k, collect_names, names); + if (select_name != NULL && !OSSL_DECODER_is_a(k, select_name)) + continue; + names = sk_OPENSSL_CSTRING_new(name_cmp); + OSSL_DECODER_names_do_all(k, collect_names, names); BIO_printf(bio_out, " "); print_names(bio_out, names); + sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s (%s)\n", - OSSL_PROVIDER_name(OSSL_DESERIALIZER_provider(k)), - OSSL_DESERIALIZER_properties(k)); + OSSL_PROVIDER_name(OSSL_DECODER_provider(k)), + OSSL_DECODER_properties(k)); + + if (verbose) { + print_param_types("settable operation parameters", + OSSL_DECODER_settable_ctx_params(k), 4); + } + } + sk_OSSL_DECODER_pop_free(decoders, OSSL_DECODER_free); +} + +DEFINE_STACK_OF(EVP_KEYMGMT) +static int keymanager_cmp(const EVP_KEYMGMT * const *a, + const EVP_KEYMGMT * const *b) +{ + int ret = EVP_KEYMGMT_number(*a) - EVP_KEYMGMT_number(*b); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_KEYMGMT_provider(*a)), + OSSL_PROVIDER_name(EVP_KEYMGMT_provider(*b))); + return ret; +} + +static void collect_keymanagers(EVP_KEYMGMT *km, void *stack) +{ + STACK_OF(EVP_KEYMGMT) *km_stack = stack; + + sk_EVP_KEYMGMT_push(km_stack, km); + EVP_KEYMGMT_up_ref(km); +} + +static void list_keymanagers(void) +{ + int i; + STACK_OF(EVP_KEYMGMT) *km_stack = sk_EVP_KEYMGMT_new(keymanager_cmp); + + EVP_KEYMGMT_do_all_provided(NULL, collect_keymanagers, km_stack); + sk_EVP_KEYMGMT_sort(km_stack); + + for (i = 0; i < sk_EVP_KEYMGMT_num(km_stack); i++) { + EVP_KEYMGMT *k = sk_EVP_KEYMGMT_value(km_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KEYMGMT_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_KEYMGMT_names_do_all(k, collect_names, names); + BIO_printf(bio_out, " "); + print_names(bio_out, names); + sk_OPENSSL_CSTRING_free(names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_KEYMGMT_provider(k))); + + if (verbose) { + print_param_types("settable key generation parameters", + EVP_KEYMGMT_gen_settable_params(k), 4); + print_param_types("settable operation parameters", + EVP_KEYMGMT_settable_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KEYMGMT_gettable_params(k), 4); + } + } + sk_EVP_KEYMGMT_pop_free(km_stack, EVP_KEYMGMT_free); +} + +DEFINE_STACK_OF(EVP_SIGNATURE) +static int signature_cmp(const EVP_SIGNATURE * const *a, + const EVP_SIGNATURE * const *b) +{ + int ret = EVP_SIGNATURE_number(*a) - EVP_SIGNATURE_number(*b); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_SIGNATURE_provider(*a)), + OSSL_PROVIDER_name(EVP_SIGNATURE_provider(*b))); + return ret; +} + +static void collect_signatures(EVP_SIGNATURE *km, void *stack) +{ + STACK_OF(EVP_SIGNATURE) *km_stack = stack; + + sk_EVP_SIGNATURE_push(km_stack, km); + EVP_SIGNATURE_up_ref(km); +} + +static void list_signatures(void) +{ + int i, count = 0; + STACK_OF(EVP_SIGNATURE) *sig_stack = sk_EVP_SIGNATURE_new(signature_cmp); + + EVP_SIGNATURE_do_all_provided(NULL, collect_signatures, sig_stack); + sk_EVP_SIGNATURE_sort(sig_stack); + + for (i = 0; i < sk_EVP_SIGNATURE_num(sig_stack); i++) { + EVP_SIGNATURE *k = sk_EVP_SIGNATURE_value(sig_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_SIGNATURE_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_SIGNATURE_names_do_all(k, collect_names, names); + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + sk_OPENSSL_CSTRING_free(names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_SIGNATURE_provider(k))); + if (verbose) { + print_param_types("settable operation parameters", + EVP_SIGNATURE_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_SIGNATURE_gettable_ctx_params(k), 4); + } + } + sk_EVP_SIGNATURE_pop_free(sig_stack, EVP_SIGNATURE_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +DEFINE_STACK_OF(EVP_KEM) +static int kem_cmp(const EVP_KEM * const *a, + const EVP_KEM * const *b) +{ + int ret = EVP_KEM_number(*a) - EVP_KEM_number(*b); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_KEM_provider(*a)), + OSSL_PROVIDER_name(EVP_KEM_provider(*b))); + return ret; +} + +static void collect_kem(EVP_KEM *km, void *stack) +{ + STACK_OF(EVP_KEM) *km_stack = stack; + + sk_EVP_KEM_push(km_stack, km); + EVP_KEM_up_ref(km); +} + +static void list_kems(void) +{ + int i, count = 0; + STACK_OF(EVP_KEM) *kem_stack = sk_EVP_KEM_new(kem_cmp); + + EVP_KEM_do_all_provided(NULL, collect_kem, kem_stack); + sk_EVP_KEM_sort(kem_stack); + + for (i = 0; i < sk_EVP_KEM_num(kem_stack); i++) { + EVP_KEM *k = sk_EVP_KEM_value(kem_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KEM_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_KEM_names_do_all(k, collect_names, names); + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + sk_OPENSSL_CSTRING_free(names); + + BIO_printf(bio_out, " @ %s\n", OSSL_PROVIDER_name(EVP_KEM_provider(k))); + + if (verbose) { + print_param_types("settable operation parameters", + EVP_KEM_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KEM_gettable_ctx_params(k), 4); + } + } + sk_EVP_KEM_pop_free(kem_stack, EVP_KEM_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +DEFINE_STACK_OF(EVP_ASYM_CIPHER) +static int asymcipher_cmp(const EVP_ASYM_CIPHER * const *a, + const EVP_ASYM_CIPHER * const *b) +{ + int ret = EVP_ASYM_CIPHER_number(*a) - EVP_ASYM_CIPHER_number(*b); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_ASYM_CIPHER_provider(*a)), + OSSL_PROVIDER_name(EVP_ASYM_CIPHER_provider(*b))); + return ret; +} + +static void collect_asymciph(EVP_ASYM_CIPHER *km, void *stack) +{ + STACK_OF(EVP_ASYM_CIPHER) *km_stack = stack; + + sk_EVP_ASYM_CIPHER_push(km_stack, km); + EVP_ASYM_CIPHER_up_ref(km); +} + +static void list_asymciphers(void) +{ + int i, count = 0; + STACK_OF(EVP_ASYM_CIPHER) *asymciph_stack = + sk_EVP_ASYM_CIPHER_new(asymcipher_cmp); + + EVP_ASYM_CIPHER_do_all_provided(NULL, collect_asymciph, asymciph_stack); + sk_EVP_ASYM_CIPHER_sort(asymciph_stack); + + for (i = 0; i < sk_EVP_ASYM_CIPHER_num(asymciph_stack); i++) { + EVP_ASYM_CIPHER *k = sk_EVP_ASYM_CIPHER_value(asymciph_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_ASYM_CIPHER_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_ASYM_CIPHER_names_do_all(k, collect_names, names); + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); + sk_OPENSSL_CSTRING_free(names); + + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_ASYM_CIPHER_provider(k))); + + if (verbose) { + print_param_types("settable operation parameters", + EVP_ASYM_CIPHER_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_ASYM_CIPHER_gettable_ctx_params(k), 4); + } + } + sk_EVP_ASYM_CIPHER_pop_free(asymciph_stack, EVP_ASYM_CIPHER_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); +} + +DEFINE_STACK_OF(EVP_KEYEXCH) +static int kex_cmp(const EVP_KEYEXCH * const *a, + const EVP_KEYEXCH * const *b) +{ + int ret = EVP_KEYEXCH_number(*a) - EVP_KEYEXCH_number(*b); + + if (ret == 0) + ret = strcmp(OSSL_PROVIDER_name(EVP_KEYEXCH_provider(*a)), + OSSL_PROVIDER_name(EVP_KEYEXCH_provider(*b))); + return ret; +} + +static void collect_kex(EVP_KEYEXCH *ke, void *stack) +{ + STACK_OF(EVP_KEYEXCH) *kex_stack = stack; + + sk_EVP_KEYEXCH_push(kex_stack, ke); + EVP_KEYEXCH_up_ref(ke); +} + +static void list_keyexchanges(void) +{ + int i, count = 0; + STACK_OF(EVP_KEYEXCH) *kex_stack = sk_EVP_KEYEXCH_new(kex_cmp); + + EVP_KEYEXCH_do_all_provided(NULL, collect_kex, kex_stack); + sk_EVP_KEYEXCH_sort(kex_stack); + + for (i = 0; i < sk_EVP_KEYEXCH_num(kex_stack); i++) { + EVP_KEYEXCH *k = sk_EVP_KEYEXCH_value(kex_stack, i); + STACK_OF(OPENSSL_CSTRING) *names = NULL; + + if (select_name != NULL && !EVP_KEYEXCH_is_a(k, select_name)) + continue; + + names = sk_OPENSSL_CSTRING_new(name_cmp); + EVP_KEYEXCH_names_do_all(k, collect_names, names); + count++; + BIO_printf(bio_out, " "); + print_names(bio_out, names); sk_OPENSSL_CSTRING_free(names); + BIO_printf(bio_out, " @ %s\n", + OSSL_PROVIDER_name(EVP_KEYEXCH_provider(k))); + if (verbose) { print_param_types("settable operation parameters", - OSSL_DESERIALIZER_settable_ctx_params(k), 4); + EVP_KEYEXCH_settable_ctx_params(k), 4); + print_param_types("retrievable operation parameters", + EVP_KEYEXCH_gettable_ctx_params(k), 4); } } - sk_OSSL_DESERIALIZER_pop_free(deserializers, OSSL_DESERIALIZER_free); + sk_EVP_KEYEXCH_pop_free(kex_stack, EVP_KEYEXCH_free); + if (count == 0) + BIO_printf(bio_out, " -\n"); } static void list_missing_help(void) @@ -554,7 +921,7 @@ static void list_options_for_command(const char *command) break; if (fp->name == NULL) { BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", - command); + command); return; } @@ -606,50 +973,69 @@ static void list_type(FUNC_TYPE ft, int one) static void list_pkey(void) { +#ifndef OPENSSL_NO_DEPRECATED_3_0 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(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(bio_out, "\tAlias for: %s\n", - OBJ_nid2ln(pkey_base_id)); - } else { - BIO_printf(bio_out, "Name: %s\n", pinfo); - BIO_printf(bio_out, "\tType: %s Algorithm\n", - pkey_flags & ASN1_PKEY_DYNAMIC ? - "External" : "Builtin"); - BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); - if (pem_str == NULL) - pem_str = "(none)"; - BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); + if (select_name == NULL) { + BIO_printf(bio_out, "Legacy:\n"); + 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(bio_out, " Name: %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tAlias for: %s\n", + OBJ_nid2ln(pkey_base_id)); + } else { + BIO_printf(bio_out, " Name: %s\n", pinfo); + BIO_printf(bio_out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? + "External" : "Builtin"); + BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id)); + if (pem_str == NULL) + pem_str = "(none)"; + BIO_printf(bio_out, "\tPEM string: %s\n", pem_str); + } } - } +#endif + BIO_printf(bio_out, "Provided:\n"); + BIO_printf(bio_out, " Key Managers:\n"); + list_keymanagers(); } -#ifndef OPENSSL_NO_DEPRECATED_3_0 static void list_pkey_meth(void) { +#ifndef OPENSSL_NO_DEPRECATED_3_0 size_t i; size_t meth_count = EVP_PKEY_meth_get_count(); - for (i = 0; i < meth_count; i++) { - const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); - int pkey_id, pkey_flags; + if (select_name == NULL) { + BIO_printf(bio_out, "Legacy:\n"); + for (i = 0; i < meth_count; i++) { + const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i); + int pkey_id, pkey_flags; - EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); - BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id)); - BIO_printf(bio_out, "\tType: %s Algorithm\n", - pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); + EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth); + BIO_printf(bio_out, " %s\n", OBJ_nid2ln(pkey_id)); + BIO_printf(bio_out, "\tType: %s Algorithm\n", + pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin"); + } } -} #endif + BIO_printf(bio_out, "Provided:\n"); + BIO_printf(bio_out, " Encryption:\n"); + list_asymciphers(); + BIO_printf(bio_out, " Key Exchange:\n"); + list_keyexchanges(); + BIO_printf(bio_out, " Signatures:\n"); + list_signatures(); + BIO_printf(bio_out, " Key encapsulation:\n"); + list_kems(); +} #ifndef OPENSSL_NO_DEPRECATED_3_0 static void list_engines(void) @@ -821,9 +1207,10 @@ typedef enum HELPLIST_CHOICE { OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS, OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS, OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, - OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_SERIALIZERS, - OPT_DESERIALIZERS, - OPT_MISSING_HELP, OPT_OBJECTS, + OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS, + OPT_ENCODERS, OPT_DECODERS, OPT_KEYMANAGERS, OPT_KEYEXCHANGE_ALGORITHMS, + OPT_KEM_ALGORITHMS, OPT_SIGNATURE_ALGORITHMS, OPT_ASYM_CIPHER_ALGORITHMS, + OPT_MISSING_HELP, OPT_OBJECTS, OPT_SELECT_NAME, #ifndef OPENSSL_NO_DEPRECATED_3_0 OPT_ENGINES, #endif @@ -838,6 +1225,7 @@ const OPTIONS list_options[] = { OPT_SECTION("Output"), {"1", OPT_ONE, '-', "List in one column"}, {"verbose", OPT_VERBOSE, '-', "Verbose listing"}, + {"select", OPT_SELECT_NAME, 's', "Select a single algorithm"}, {"commands", OPT_COMMANDS, '-', "List of standard commands"}, {"standard-commands", OPT_COMMANDS, '-', "List of standard commands"}, {"digest-commands", OPT_DIGEST_COMMANDS, '-', @@ -846,21 +1234,31 @@ const OPTIONS list_options[] = { "List of message digest algorithms"}, {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-', "List of key derivation and pseudo random function algorithms"}, + {"random-instances", OPT_RANDOM_INSTANCES, '-', + "List the primary, pubic and private random number generator details"}, {"random-generators", OPT_RANDOM_GENERATORS, '-', - "List of random number generators"}, + "List of random number generators"}, {"mac-algorithms", OPT_MAC_ALGORITHMS, '-', "List of message authentication code algorithms"}, {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"}, {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-', "List of cipher algorithms"}, - {"serializers", OPT_SERIALIZERS, '-', "List of serialization methods" }, - {"deserializers", OPT_DESERIALIZERS, '-', - "List of deserialization methods" }, + {"encoders", OPT_ENCODERS, '-', "List of encoding methods" }, + {"decoders", OPT_DECODERS, '-', "List of decoding methods" }, + {"key-managers", OPT_KEYMANAGERS, '-', "List of key managers" }, + {"key-exchange-algorithms", OPT_KEYEXCHANGE_ALGORITHMS, '-', + "List of key exchange algorithms" }, + {"kem-algorithms", OPT_KEM_ALGORITHMS, '-', + "List of key encapsulation mechanism algorithms" }, + {"signature-algorithms", OPT_SIGNATURE_ALGORITHMS, '-', + "List of signature algorithms" }, + { "asymcipher-algorithms", OPT_ASYM_CIPHER_ALGORITHMS, '-', + "List of asymmetric cipher algorithms" }, {"public-key-algorithms", OPT_PK_ALGORITHMS, '-', "List of public key algorithms"}, -#ifndef OPENSSL_NO_DEPRECATED_3_0 {"public-key-methods", OPT_PK_METHOD, '-', "List of public key methods"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 {"engines", OPT_ENGINES, '-', "List of loaded engines"}, #endif @@ -883,6 +1281,7 @@ int list_main(int argc, char **argv) int one = 0, done = 0; struct { unsigned int commands:1; + unsigned int random_instances:1; unsigned int random_generators:1; unsigned int digest_commands:1; unsigned int digest_algorithms:1; @@ -890,8 +1289,13 @@ int list_main(int argc, char **argv) unsigned int mac_algorithms:1; unsigned int cipher_commands:1; unsigned int cipher_algorithms:1; - unsigned int serializer_algorithms:1; - unsigned int deserializer_algorithms:1; + unsigned int encoder_algorithms:1; + unsigned int decoder_algorithms:1; + unsigned int keymanager_algorithms:1; + unsigned int signature_algorithms:1; + unsigned int keyexchange_algorithms:1; + unsigned int kem_algorithms:1; + unsigned int asym_cipher_algorithms:1; unsigned int pk_algorithms:1; unsigned int pk_method:1; #ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -931,6 +1335,9 @@ int list_main(int argc, char **argv) case OPT_KDF_ALGORITHMS: todo.kdf_algorithms = 1; break; + case OPT_RANDOM_INSTANCES: + todo.random_instances = 1; + break; case OPT_RANDOM_GENERATORS: todo.random_generators = 1; break; @@ -943,11 +1350,26 @@ int list_main(int argc, char **argv) case OPT_CIPHER_ALGORITHMS: todo.cipher_algorithms = 1; break; - case OPT_SERIALIZERS: - todo.serializer_algorithms = 1; + case OPT_ENCODERS: + todo.encoder_algorithms = 1; + break; + case OPT_DECODERS: + todo.decoder_algorithms = 1; + break; + case OPT_KEYMANAGERS: + todo.keymanager_algorithms = 1; break; - case OPT_DESERIALIZERS: - todo.deserializer_algorithms = 1; + case OPT_SIGNATURE_ALGORITHMS: + todo.signature_algorithms = 1; + break; + case OPT_KEYEXCHANGE_ALGORITHMS: + todo.keyexchange_algorithms = 1; + break; + case OPT_KEM_ALGORITHMS: + todo.kem_algorithms = 1; + break; + case OPT_ASYM_CIPHER_ALGORITHMS: + todo.asym_cipher_algorithms = 1; break; case OPT_PK_ALGORITHMS: todo.pk_algorithms = 1; @@ -975,6 +1397,9 @@ int list_main(int argc, char **argv) case OPT_VERBOSE: verbose = 1; break; + case OPT_SELECT_NAME: + select_name = opt_arg(); + break; case OPT_PROV_CASES: if (!opt_provider(o)) return 1; @@ -989,6 +1414,8 @@ int list_main(int argc, char **argv) if (todo.commands) list_type(FT_general, one); + if (todo.random_instances) + list_random_instances(); if (todo.random_generators) list_random_generators(); if (todo.digest_commands) @@ -1003,15 +1430,25 @@ int list_main(int argc, char **argv) list_type(FT_cipher, one); if (todo.cipher_algorithms) list_ciphers(); - if (todo.serializer_algorithms) - list_serializers(); - if (todo.deserializer_algorithms) - list_deserializers(); + if (todo.encoder_algorithms) + list_encoders(); + if (todo.decoder_algorithms) + list_decoders(); + if (todo.keymanager_algorithms) + list_keymanagers(); + if (todo.signature_algorithms) + list_signatures(); + if (todo.asym_cipher_algorithms) + list_asymciphers(); + if (todo.keyexchange_algorithms) + list_keyexchanges(); + if (todo.kem_algorithms) + list_kems(); if (todo.pk_algorithms) list_pkey(); -#ifndef OPENSSL_NO_DEPRECATED_3_0 if (todo.pk_method) list_pkey_meth(); +#ifndef OPENSSL_NO_DEPRECATED_3_0 if (todo.engines) list_engines(); #endif diff --git a/apps/mac.c b/apps/mac.c index 30f0daabcc..e751dcf0b1 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -16,8 +16,6 @@ #include #include -DEFINE_STACK_OF_STRING() - #undef BUFSIZE #define BUFSIZE 1024*8 diff --git a/apps/nseq.c b/apps/nseq.c index de189632b2..92ae7bd34d 100644 --- a/apps/nseq.c +++ b/apps/nseq.c @@ -14,8 +14,6 @@ #include #include -DEFINE_STACK_OF(X509) - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_TOSEQ, OPT_IN, OPT_OUT, diff --git a/apps/ocsp.c b/apps/ocsp.c index 4660a7fe5a..4d01e99c15 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -33,10 +33,11 @@ #include #include -DEFINE_STACK_OF(OCSP_CERTID) -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF_STRING() +#if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +#endif #if defined(OPENSSL_SYS_VXWORKS) /* not supported */ @@ -61,7 +62,7 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, const EVP_MD *cert_id_md, X509 *issuer, STACK_OF(OCSP_CERTID) *ids); -static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, +static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage); @@ -275,7 +276,7 @@ int ocsp_main(int argc, char **argv) OPENSSL_free(tpath); thost = tport = tpath = NULL; if (!OSSL_HTTP_parse_url(opt_arg(), - &host, &port, &path, &use_ssl)) { + &host, &port, NULL, &path, &use_ssl)) { BIO_printf(bio_err, "%s Error parsing URL\n", prog); goto end; } @@ -567,11 +568,10 @@ int ocsp_main(int argc, char **argv) BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } - if (!load_certs(rca_filename, &rca_cert, FORMAT_PEM, - NULL, "CA certificate")) + if (!load_certs(rca_filename, &rca_cert, NULL, "CA certificates")) goto end; if (rcertfile != NULL) { - if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL, + if (!load_certs(rcertfile, &rother, NULL, "responder other certificates")) goto end; } @@ -665,7 +665,7 @@ int ocsp_main(int argc, char **argv) goto end; } if (sign_certfile != NULL) { - if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL, + if (!load_certs(sign_certfile, &sign_other, NULL, "signer certificates")) goto end; } @@ -774,8 +774,8 @@ int ocsp_main(int argc, char **argv) if (vpmtouched) X509_STORE_set1_param(store, vpm); if (verify_certfile != NULL) { - if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL, - "validator certificate")) + if (!load_certs(verify_certfile, &verify_other, NULL, + "validator certificates")) goto end; } @@ -813,7 +813,8 @@ int ocsp_main(int argc, char **argv) } } - print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage); + if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) + ret = 1; end: ERR_print_errors(bio_err); @@ -929,7 +930,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, return 0; } -static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, +static int print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, STACK_OF(OPENSSL_STRING) *names, STACK_OF(OCSP_CERTID) *ids, long nsec, long maxage) @@ -938,10 +939,13 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, const char *name; int i, status, reason; ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; + int ret = 1; + + if (req == NULL || !sk_OPENSSL_STRING_num(names)) + return 1; - if (bs == NULL || req == NULL || !sk_OPENSSL_STRING_num(names) - || !sk_OCSP_CERTID_num(ids)) - return; + if (bs == NULL || !sk_OCSP_CERTID_num(ids)) + return 0; for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) { id = sk_OCSP_CERTID_value(ids, i); @@ -951,6 +955,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, if (!OCSP_resp_find_status(bs, id, &status, &reason, &rev, &thisupd, &nextupd)) { BIO_puts(out, "ERROR: No Status found.\n"); + ret = 0; continue; } @@ -984,6 +989,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req, ASN1_GENERALIZEDTIME_print(out, rev); BIO_puts(out, "\n"); } + return ret; } static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req, diff --git a/apps/openssl.c b/apps/openssl.c index 6b2c2b9c6b..307303b257 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -7,7 +7,6 @@ * https://www.openssl.org/source/license.html */ -#include #include #include #include @@ -68,7 +67,7 @@ static int apps_startup(void) | OPENSSL_INIT_LOAD_CONFIG, NULL)) return 0; - setup_ui_method(); + (void)setup_ui_method(); /* * NOTE: This is an undocumented feature required for testing only. @@ -89,7 +88,7 @@ static int apps_startup(void) static void apps_shutdown(void) { app_providers_cleanup(); - OPENSSL_CTX_free(app_get0_libctx()); + OSSL_LIB_CTX_free(app_get0_libctx()); destroy_ui_method(); } @@ -110,8 +109,10 @@ static size_t internal_trace_cb(const char *buf, size_t cnt, switch (cmd) { case OSSL_TRACE_CTRL_BEGIN: - if (!ossl_assert(!trace_data->ingroup)) + if (trace_data->ingroup) { + BIO_printf(bio_err, "ERROR: tracing already started\n"); return 0; + } trace_data->ingroup = 1; tid = CRYPTO_THREAD_get_current_id(); @@ -123,14 +124,18 @@ static size_t internal_trace_cb(const char *buf, size_t cnt, BIO_set_prefix(trace_data->bio, buffer); break; case OSSL_TRACE_CTRL_WRITE: - if (!ossl_assert(trace_data->ingroup)) + if (!trace_data->ingroup) { + BIO_printf(bio_err, "ERROR: writing when tracing not started\n"); return 0; + } ret = BIO_write(trace_data->bio, buf, cnt); break; case OSSL_TRACE_CTRL_END: - if (!ossl_assert(trace_data->ingroup)) + if (!trace_data->ingroup) { + BIO_printf(bio_err, "ERROR: finishing when tracing not started\n"); return 0; + } trace_data->ingroup = 0; BIO_set_prefix(trace_data->bio, NULL); diff --git a/apps/pkcs12.c b/apps/pkcs12.c index ca83e2d1be..1432d2b930 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -18,12 +18,7 @@ #include #include #include - -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(PKCS7) -DEFINE_STACK_OF(PKCS12_SAFEBAG) -DEFINE_STACK_OF(X509_ATTRIBUTE) -DEFINE_STACK_OF_STRING() +#include #define NOKEYS 0x1 #define NOCERTS 0x2 @@ -34,6 +29,7 @@ DEFINE_STACK_OF_STRING() #define PASSWD_BUF_SIZE 2048 static int get_cert_chain(X509 *cert, X509_STORE *store, + STACK_OF(X509) *untrusted_certs, STACK_OF(X509) **chain); int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass, int passlen, int options, @@ -58,20 +54,22 @@ typedef enum OPTION_choice { OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER, OPT_DESCERT, OPT_EXPORT, OPT_ITER, OPT_NOITER, OPT_MACITER, OPT_NOMACITER, OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_NOENC, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE, - OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME, + OPT_INKEY, OPT_CERTFILE, OPT_UNTRUSTED, OPT_PASSCERTS, + OPT_NAME, OPT_CSP, OPT_CANAME, OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_ENGINE, - OPT_R_ENUM, OPT_PROV_ENUM + OPT_R_ENUM, OPT_PROV_ENUM, OPT_LEGACY_ALG } OPTION_CHOICE; const OPTIONS pkcs12_options[] = { OPT_SECTION("General"), {"help", OPT_HELP, '-', "Display this summary"}, + {"legacy", OPT_LEGACY_ALG, '-', "use legacy algorithms"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif - OPT_SECTION("CA"), + OPT_SECTION("CA input for export with the -chain option"), {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"}, {"CAstore", OPT_CASTORE, ':', "URI to store of CA's"}, @@ -83,43 +81,47 @@ const OPTIONS pkcs12_options[] = { "Do not load certificates from the default certificates store"}, OPT_SECTION("Input"), - {"inkey", OPT_INKEY, 's', "Private key if not infile"}, - {"certfile", OPT_CERTFILE, '<', "Load certs from file"}, + {"in", OPT_IN, '<', "Input file for PKCS12 parsing or certs and possibly key"}, + {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, + {"inkey", OPT_INKEY, 's', "Private key, else read from -in input file"}, + {"certfile", OPT_CERTFILE, '<', "Extra certificates for PKCS12 output"}, + {"untrusted", OPT_UNTRUSTED, '<', "Untrusted certificates for chain building"}, + {"passcerts", OPT_PASSCERTS, 's', "Certificate file pass phrase source"}, {"name", OPT_NAME, 's', "Use name as friendly name"}, {"CSP", OPT_CSP, 's', "Microsoft CSP name"}, {"caname", OPT_CANAME, 's', "Use name as CA friendly name (can be repeated)"}, - {"in", OPT_IN, '<', "Input filename"}, - {"passin", OPT_PASSIN, 's', "Input file pass phrase source"}, OPT_SECTION("Output"), {"export", OPT_EXPORT, '-', "Output PKCS12 file"}, {"LMK", OPT_LMK, '-', "Add local machine keyset attribute to private key"}, {"macalg", OPT_MACALG, 's', - "Digest algorithm used in MAC (default SHA1)"}, + "Digest algorithm to use in MAC (default SHA1)"}, {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"}, {"out", OPT_OUT, '>', "Output filename"}, - {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"}, + {"passout", OPT_PASSOUT, 's', "Output pass phrase source"}, {"password", OPT_PASSWORD, 's', "Set import/export password source"}, {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"}, {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"}, {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"}, - {"noout", OPT_NOOUT, '-', "Don't output anything, just verify"}, - {"chain", OPT_CHAIN, '-', "Add certificate chain"}, + {"noout", OPT_NOOUT, '-', "Don't output anything, just verify PKCS#12 input"}, + {"chain", OPT_CHAIN, '-', "Build and add certificate chain for EE cert,"}, + {OPT_MORE_STR, 0, 0, + "which is the 1st cert from -in matching the private key (if given)"}, {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"}, {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"}, {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"}, {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"}, - {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"}, - {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"}, + {"keyex", OPT_KEYEX, '-', "Set key type to MS key exchange"}, + {"keysig", OPT_KEYSIG, '-', "Set key type to MS key signature"}, - OPT_SECTION("Encryption"), + OPT_SECTION("PKCS12 output encryption and MAC"), #ifndef OPENSSL_NO_RC2 {"descert", OPT_DESCERT, '-', - "Encrypt output with 3DES (default RC2-40)"}, + "Encrypt output with 3DES (default PBES2 with PBKDF2 and AES-256 CBC)"}, {"certpbe", OPT_CERTPBE, 's', - "Certificate PBE algorithm (default RC2-40)"}, + "Certificate PBE algorithm (default PBES2 with PBKDF2 and AES-256 CBC)"}, #else {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"}, {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"}, @@ -141,16 +143,14 @@ const OPTIONS pkcs12_options[] = { int pkcs12_main(int argc, char **argv) { char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL; + char *untrusted = NULL; + char *passcertsarg = NULL, *passcerts = NULL; char *name = NULL, *csp_name = NULL; char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = ""; - int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0; + int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0, use_legacy = 0; int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER; -#ifndef OPENSSL_NO_RC2 - int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; -#else - int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -#endif - int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + int cert_pbe = NID_aes_256_cbc; + int key_pbe = NID_aes_256_cbc; int ret = 1, macver = 1, add_lmk = 0, private = 0; int noprompt = 0; char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; @@ -162,7 +162,7 @@ int pkcs12_main(int argc, char **argv) BIO *in = NULL, *out = NULL; PKCS12 *p12 = NULL; STACK_OF(OPENSSL_STRING) *canames = NULL; - const EVP_CIPHER *enc = EVP_des_ede3_cbc(); + const EVP_CIPHER *enc = EVP_aes_256_cbc(); OPTION_CHOICE o; prog = opt_init(argc, argv, pkcs12_options); @@ -262,6 +262,12 @@ int pkcs12_main(int argc, char **argv) case OPT_CERTFILE: certfile = opt_arg(); break; + case OPT_UNTRUSTED: + untrusted = opt_arg(); + break; + case OPT_PASSCERTS: + passcertsarg = opt_arg(); + break; case OPT_NAME: name = opt_arg(); break; @@ -313,6 +319,9 @@ int pkcs12_main(int argc, char **argv) case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; + case OPT_LEGACY_ALG: + use_legacy = 1; + break; case OPT_PROV_CASES: if (!opt_provider(o)) goto end; @@ -320,11 +329,70 @@ int pkcs12_main(int argc, char **argv) } } argc = opt_num_rest(); + + if (!export_cert) { + if (chain) + BIO_printf(bio_err, "Warning: -chain option ignored without -export\n"); + if (certfile != NULL) + BIO_printf(bio_err, "Warning: -certfile option ignored without -export\n"); + if (untrusted != NULL) + BIO_printf(bio_err, "Warning: -untrusted option ignored without -export\n"); + if (passcertsarg != NULL) + BIO_printf(bio_err, + "Warning: -passcerts option ignored without -export\n"); + if (CApath != NULL || noCApath) + BIO_printf(bio_err, "Warning: -[no-]CApath option ignored without -export\n"); + if (CAfile != NULL || noCAfile) + BIO_printf(bio_err, "Warning: -[no-]CAfile option ignored without -export\n"); + if (CAstore != NULL || noCAstore) + BIO_printf(bio_err, "Warning: -[no-]CAstore option ignored without -export\n"); + if (add_lmk) + BIO_printf(bio_err, "Warning: -LMK option ignored without -export\n"); + if (name != NULL) + BIO_printf(bio_err, "Warning: -name option ignored without -export\n"); + if (csp_name != NULL) + BIO_printf(bio_err, "Warning: -CSP option ignored without -export\n"); + if (canames != NULL) + BIO_printf(bio_err, "Warning: -caname option ignored without -export\n"); + if (keyname != NULL) + BIO_printf(bio_err, "Warning: -inkey option ignored without -export\n"); + if (keytype != 0) + BIO_printf(bio_err, "Warning: -keyex and -keysig options ignored without -export\n"); + if (macalg != NULL) + BIO_printf(bio_err, "Warning: -macalg option ignored without -export\n"); + } + if (use_legacy) { + /* load the legacy provider if not loaded already*/ + if (!OSSL_PROVIDER_available(app_get0_libctx(), "legacy")) { + if (!app_provider_load(app_get0_libctx(), "legacy")) + goto end; + /* load the default provider explicitly */ + if (!app_provider_load(app_get0_libctx(), "default")) + goto end; + } + if (cert_pbe != NID_pbe_WithSHA1And3_Key_TripleDES_CBC) { + /* Restore default algorithms */ +#ifndef OPENSSL_NO_RC2 + cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; +#else + cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +#endif + } + + key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + enc = EVP_des_ede3_cbc(); + } + if (argc != 0) goto opthelp; private = 1; + if (!app_passwd(passcertsarg, NULL, &passcerts, NULL)) { + BIO_printf(bio_err, "Error getting certificate file password\n"); + goto end; + } + if (passarg != NULL) { if (export_cert) passoutarg = passarg; @@ -377,95 +445,121 @@ int pkcs12_main(int argc, char **argv) if (export_cert) { EVP_PKEY *key = NULL; - X509 *ucert = NULL, *x = NULL; + X509 *ee_cert = NULL, *x = NULL; STACK_OF(X509) *certs = NULL; + STACK_OF(X509) *untrusted_certs = NULL; const EVP_MD *macmd = NULL; unsigned char *catmp = NULL; int i; if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) { - BIO_printf(bio_err, "Nothing to do!\n"); + BIO_printf(bio_err, "Nothing to export due to -nocerts and -nokeys or -noout!\n"); goto export_end; } - if (options & NOCERTS) + if ((options & NOCERTS) != 0) { chain = 0; + BIO_printf(bio_err, "Warning: -chain option ignored with -nocerts\n"); + } if (!(options & NOKEYS)) { key = load_key(keyname ? keyname : infile, - FORMAT_PEM, 1, passin, e, "private key"); + FORMAT_PEM, 1, passin, e, + keyname ? + "private key from -inkey file" : + "private key from -in file"); if (key == NULL) goto export_end; } - /* Load in all certs in input file */ + /* Load all certs in input file */ if (!(options & NOCERTS)) { - if (!load_certs(infile, &certs, FORMAT_PEM, NULL, - "certificates")) + if (!load_certs(infile, &certs, passin, + "certificates from -in file")) goto export_end; + if (sk_X509_num(certs) < 1) { + BIO_printf(bio_err, "No certificate in -in file %s\n", infile); + goto export_end; + } if (key != NULL) { /* Look for matching private key */ for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); if (X509_check_private_key(x, key)) { - ucert = x; + ee_cert = x; /* Zero keyid and alias */ - X509_keyid_set1(ucert, NULL, 0); - X509_alias_set1(ucert, NULL, 0); + X509_keyid_set1(ee_cert, NULL, 0); + X509_alias_set1(ee_cert, NULL, 0); /* Remove from list */ (void)sk_X509_delete(certs, i); break; } } - if (ucert == NULL) { + if (ee_cert == NULL) { BIO_printf(bio_err, - "No certificate matches private key\n"); + "No cert in -in file '%s' matches private key\n", + infile); goto export_end; } + } else { + ee_cert = X509_dup(sk_X509_value(certs, 0)); /* take 1st cert */ } - } - /* Add any more certificates asked for */ - if (certfile != NULL) { - if (!load_certs(certfile, &certs, FORMAT_PEM, NULL, - "certificates from certfile")) + /* Load any untrusted certificates for chain building */ + if (untrusted != NULL) { + if (!load_certs(untrusted, &untrusted_certs, passcerts, + "untrusted certificates")) goto export_end; } - /* If chaining get chain from user cert */ + /* If chaining get chain from end entity cert */ if (chain) { int vret; STACK_OF(X509) *chain2; X509_STORE *store; + + if (ee_cert == NULL) { + BIO_printf(bio_err, + "No end entity certificate to check with -chain\n"); + goto export_end; + } + if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath, CAstore, noCAstore)) == NULL) goto export_end; - vret = get_cert_chain(ucert, store, &chain2); + vret = get_cert_chain(ee_cert, store, untrusted_certs, &chain2); X509_STORE_free(store); if (vret == X509_V_OK) { - /* Exclude verified certificate */ - for (i = 1; i < sk_X509_num(chain2); i++) - sk_X509_push(certs, sk_X509_value(chain2, i)); - /* Free first certificate */ - X509_free(sk_X509_value(chain2, 0)); - sk_X509_free(chain2); + int add_certs; + /* Remove from chain2 the first (end entity) certificate */ + X509_free(sk_X509_shift(chain2)); + /* Add the remaining certs (except for duplicates) */ + add_certs = X509_add_certs(certs, chain2, X509_ADD_FLAG_UP_REF + | X509_ADD_FLAG_NO_DUP); + sk_X509_pop_free(chain2, X509_free); + if (!add_certs) + goto export_end; } else { if (vret != X509_V_ERR_UNSPECIFIED) - BIO_printf(bio_err, "Error %s getting chain.\n", + BIO_printf(bio_err, "Error getting chain: %s\n", X509_verify_cert_error_string(vret)); - else - ERR_print_errors(bio_err); goto export_end; } } - /* Add any CA names */ + /* Add any extra certificates asked for */ + if (certfile != NULL) { + if (!load_certs(certfile, &certs, passcerts, + "extra certificates from -certfile")) + goto export_end; + } + /* Add any CA names */ for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) { catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i); X509_alias_set1(sk_X509_value(certs, i), catmp, -1); @@ -498,7 +592,7 @@ int pkcs12_main(int argc, char **argv) if (!twopass) OPENSSL_strlcpy(macpass, pass, sizeof(macpass)); - p12 = PKCS12_create(cpass, name, key, ucert, certs, + p12 = PKCS12_create(cpass, name, key, ee_cert, certs, key_pbe, cert_pbe, iter, -1, keytype); if (p12 == NULL) { @@ -506,7 +600,7 @@ int pkcs12_main(int argc, char **argv) goto export_end; } - if (macalg) { + if (macalg != NULL) { if (!opt_md(macalg, &macmd)) goto opthelp; } @@ -528,7 +622,8 @@ int pkcs12_main(int argc, char **argv) EVP_PKEY_free(key); sk_X509_pop_free(certs, X509_free); - X509_free(ucert); + sk_X509_pop_free(untrusted_certs, X509_free); + X509_free(ee_cert); goto end; @@ -628,6 +723,7 @@ int pkcs12_main(int argc, char **argv) BIO_free_all(out); sk_OPENSSL_STRING_free(canames); OPENSSL_free(badpass); + OPENSSL_free(passcerts); OPENSSL_free(passin); OPENSSL_free(passout); return ret; @@ -765,6 +861,16 @@ int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag, X509_free(x509); break; + case NID_secretBag: + if (options & INFO) + BIO_printf(bio_err, "Secret bag\n"); + print_attribs(out, attrs, "Bag Attributes"); + BIO_printf(bio_err, "Bag Type: "); + i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_bag_type(bag)); + BIO_printf(bio_err, "\nBag Value: "); + print_attribute(out, PKCS12_SAFEBAG_get0_bag_obj(bag)); + return 1; + case NID_safeContentsBag: if (options & INFO) BIO_printf(bio_err, "Safe Contents bag\n"); @@ -784,18 +890,19 @@ int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag, /* Given a single certificate return a verified chain or NULL if error */ static int get_cert_chain(X509 *cert, X509_STORE *store, + STACK_OF(X509) *untrusted_certs, STACK_OF(X509) **chain) { X509_STORE_CTX *store_ctx = NULL; STACK_OF(X509) *chn = NULL; int i = 0; - store_ctx = X509_STORE_CTX_new(); + store_ctx = X509_STORE_CTX_new_ex(app_get0_libctx(), app_get0_propq()); if (store_ctx == NULL) { i = X509_V_ERR_UNSPECIFIED; goto end; } - if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) { + if (!X509_STORE_CTX_init(store_ctx, store, cert, untrusted_certs)) { i = X509_V_ERR_UNSPECIFIED; goto end; } @@ -930,6 +1037,10 @@ void print_attribute(BIO *out, const ASN1_TYPE *av) OPENSSL_free(value); break; + case V_ASN1_UTF8STRING: + BIO_printf(out, "%s\n", av->value.utf8string->data); + break; + case V_ASN1_OCTET_STRING: hex_prin(out, av->value.octet_string->data, av->value.octet_string->length); diff --git a/apps/pkcs7.c b/apps/pkcs7.c index 2416584dd6..f09994df6d 100644 --- a/apps/pkcs7.c +++ b/apps/pkcs7.c @@ -20,9 +20,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) - typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT, @@ -57,12 +54,14 @@ const OPTIONS pkcs7_options[] = { int pkcs7_main(int argc, char **argv) { ENGINE *e = NULL; - PKCS7 *p7 = NULL; + PKCS7 *p7 = NULL, *p7i; BIO *in = NULL, *out = NULL; int informat = FORMAT_PEM, outformat = FORMAT_PEM; char *infile = NULL, *outfile = NULL, *prog; int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; OPTION_CHOICE o; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); prog = opt_init(argc, argv, pkcs7_options); while ((o = opt_next()) != OPT_EOF) { @@ -119,11 +118,18 @@ int pkcs7_main(int argc, char **argv) if (in == NULL) goto end; + p7 = PKCS7_new_ex(libctx, propq); + if (p7 == NULL) { + BIO_printf(bio_err, "unable to allocate PKCS7 object\n"); + ERR_print_errors(bio_err); + goto end; + } + if (informat == FORMAT_ASN1) - p7 = d2i_PKCS7_bio(in, NULL); + p7i = d2i_PKCS7_bio(in, &p7); else - p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); - if (p7 == NULL) { + p7i = PEM_read_bio_PKCS7(in, &p7, NULL, NULL); + if (p7i == NULL) { BIO_printf(bio_err, "unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 4de2a56590..f7449503b9 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -15,8 +15,6 @@ #include #include -DEFINE_STACK_OF_STRING() - #define KEY_NONE 0 #define KEY_PRIVKEY 1 #define KEY_PUBKEY 2 @@ -26,7 +24,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, const char *keyfile, int keyform, int key_type, char *passinarg, int pkey_op, ENGINE *e, const int impl, int rawin, EVP_PKEY **ppkey, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, ENGINE *e); @@ -126,7 +124,7 @@ int pkeyutl_main(int argc, char **argv) int rawin = 0; const EVP_MD *md = NULL; int filesize = -1; - OPENSSL_CTX *libctx = app_get0_libctx(); + OSSL_LIB_CTX *libctx = app_get0_libctx(); const char *propq = NULL; prog = opt_init(argc, argv, pkeyutl_options); @@ -331,9 +329,18 @@ int pkeyutl_main(int argc, char **argv) if (passin == NULL) { /* Get password interactively */ char passwd_buf[4096]; + int r; + BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt); - EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1, - passwd_buf, 0); + r = EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1, + passwd_buf, 0); + if (r < 0) { + if (r == -2) + BIO_puts(bio_err, "user abort\n"); + else + BIO_puts(bio_err, "entry failed\n"); + goto end; + } passwd = OPENSSL_strdup(passwd_buf); if (passwd == NULL) { BIO_puts(bio_err, "out of memory\n"); @@ -505,7 +512,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, char *passinarg, int pkey_op, ENGINE *e, const int engine_impl, int rawin, EVP_PKEY **ppkey, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; @@ -525,11 +532,11 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize, } switch (key_type) { case KEY_PRIVKEY: - pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); + pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); break; case KEY_PUBKEY: - pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key"); + pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "public key"); break; case KEY_CERT: @@ -637,7 +644,7 @@ static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file, if (peerform == FORMAT_ENGINE) engine = e; - peer = load_pubkey(file, peerform, 0, NULL, engine, "Peer Key"); + peer = load_pubkey(file, peerform, 0, NULL, engine, "peer key"); if (peer == NULL) { BIO_printf(bio_err, "Error reading peer key %s\n", file); ERR_print_errors(bio_err); diff --git a/apps/provider.c b/apps/provider.c deleted file mode 100644 index 83fb2f3aee..0000000000 --- a/apps/provider.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include - -#include "apps.h" -#include "app_params.h" -#include "progs.h" -#include "names.h" -#include -#include -#include -#include -#include -#include - -DEFINE_STACK_OF_CSTRING() - -typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_V = 100, OPT_VV, OPT_VVV -} OPTION_CHOICE; - -const OPTIONS provider_options[] = { - {OPT_HELP_STR, 1, '-', "Usage: %s [options] [provider...]\n"}, - - OPT_SECTION("General"), - {"help", OPT_HELP, '-', "Display this summary"}, - - OPT_SECTION("Output"), - {"v", OPT_V, '-', "List the algorithm names of specified provider"}, - {"vv", OPT_VV, '-', "List the algorithm names of specified providers,"}, - {OPT_MORE_STR, 0, '-', "categorised by operation type"}, - {"vvv", OPT_VVV, '-', "List the algorithm names of specified provider"}, - {OPT_MORE_STR, 0, '-', "one at a time, and list all known parameters"}, - - OPT_PARAMETERS(), - {"provider", 0, 0, "Provider(s) to load"}, - {NULL} -}; - -typedef struct info_st INFO; -typedef struct meta_st META; - -struct info_st { - void (*collect_names_fn)(void *method, STACK_OF(OPENSSL_CSTRING) *names); - void *method; - const OSSL_PARAM *gettable_params; - const OSSL_PARAM *gettable_ctx_params; - const OSSL_PARAM *settable_ctx_params; -}; - -struct meta_st { - int first; /* For prints */ - int total; - int indent; - int subindent; - int verbose; - const char *label; - OSSL_PROVIDER *prov; - void (*fn)(META *meta, INFO *info); -}; - -static void collect_cipher_names(void *method, - STACK_OF(OPENSSL_CSTRING) *names) -{ - EVP_CIPHER_names_do_all(method, collect_names, names); -} - -static void collect_digest_names(void *method, - STACK_OF(OPENSSL_CSTRING) *names) -{ - EVP_MD_names_do_all(method, collect_names, names); -} - -static void collect_mac_names(void *method, - STACK_OF(OPENSSL_CSTRING) *names) -{ - EVP_MAC_names_do_all(method, collect_names, names); -} - -static void collect_keymgmt_names(void *method, - STACK_OF(OPENSSL_CSTRING) *names) -{ - EVP_KEYMGMT_names_do_all(method, collect_names, names); -} - -static void collect_keyexch_names(void *method, - STACK_OF(OPENSSL_CSTRING) *names) -{ - EVP_KEYEXCH_names_do_all(method, collect_names, names); -} - -static void collect_signature_names(void *method, - STACK_OF(OPENSSL_CSTRING) *names) -{ - EVP_SIGNATURE_names_do_all(method, collect_names, names); -} - -static void print_method_names(BIO *out, INFO *info) -{ - STACK_OF(OPENSSL_CSTRING) *names = sk_OPENSSL_CSTRING_new(name_cmp); - - info->collect_names_fn(info->method, names); - print_names(out, names); - sk_OPENSSL_CSTRING_free(names); -} - -static void print_caps(META *meta, INFO *info) -{ - switch (meta->verbose) { - case 1: - if (!meta->first) - BIO_printf(bio_out, "; "); - print_method_names(bio_out, info); - break; - case 2: - if (meta->first) { - if (meta->total > 0) - BIO_printf(bio_out, "\n"); - BIO_printf(bio_out, "%*s%ss:", meta->indent, "", meta->label); - } - BIO_printf(bio_out, " "); - print_method_names(bio_out, info); - break; - case 3: - default: - BIO_printf(bio_out, "%*s%s ", meta->indent, "", meta->label); - print_method_names(bio_out, info); - BIO_printf(bio_out, "\n"); - print_param_types("retrievable algorithm parameters", - info->gettable_params, meta->subindent); - print_param_types("retrievable operation parameters", - info->gettable_ctx_params, meta->subindent); - print_param_types("settable operation parameters", - info->settable_ctx_params, meta->subindent); - break; - } - meta->first = 0; -} - -static void do_method(void *method, - void (*collect_names_fn)(void *method, - STACK_OF(OPENSSL_CSTRING) *names), - const OSSL_PARAM *gettable_params, - const OSSL_PARAM *gettable_ctx_params, - const OSSL_PARAM *settable_ctx_params, - META *meta) -{ - INFO info; - - info.collect_names_fn = collect_names_fn; - info.method = method; - info.gettable_params = gettable_params; - info.gettable_ctx_params = gettable_ctx_params; - info.settable_ctx_params = settable_ctx_params; - meta->fn(meta, &info); - meta->total++; -} - -static void do_cipher(EVP_CIPHER *cipher, void *meta) -{ - do_method(cipher, collect_cipher_names, - EVP_CIPHER_gettable_params(cipher), - EVP_CIPHER_gettable_ctx_params(cipher), - EVP_CIPHER_settable_ctx_params(cipher), - meta); -} - -static void do_digest(EVP_MD *digest, void *meta) -{ - do_method(digest, collect_digest_names, - EVP_MD_gettable_params(digest), - EVP_MD_gettable_ctx_params(digest), - EVP_MD_settable_ctx_params(digest), - meta); -} - -static void do_mac(EVP_MAC *mac, void *meta) -{ - do_method(mac, collect_mac_names, - EVP_MAC_gettable_params(mac), - EVP_MAC_gettable_ctx_params(mac), - EVP_MAC_settable_ctx_params(mac), - meta); -} - -static void do_keymgmt(EVP_KEYMGMT *keymgmt, void *meta) -{ - do_method(keymgmt, collect_keymgmt_names, -/* - * TODO(3.0) Enable when KEYMGMT and KEYEXCH have gettables and settables - */ -#if 0 - EVP_KEYMGMT_gettable_params(keymgmt), - EVP_KEYMGMT_gettable_ctx_params(keymgmt), - EVP_KEYMGMT_settable_ctx_params(keymgmt), -#else - NULL, NULL, NULL, -#endif - meta); -} - -static void do_keyexch(EVP_KEYEXCH *keyexch, void *meta) -{ - do_method(keyexch, collect_keyexch_names, -/* - * TODO(3.0) Enable when KEYMGMT and KEYEXCH have gettables and settables - */ -#if 0 - EVP_KEYEXCH_gettable_params(keyexch), - EVP_KEYEXCH_gettable_ctx_params(keyexch), - EVP_KEYEXCH_settable_ctx_params(keyexch), -#else - NULL, NULL, NULL, -#endif - meta); -} - -static void do_signature(EVP_SIGNATURE *signature, void *meta) -{ - do_method(signature, collect_signature_names, -/* - * TODO(3.0) Enable when KEYMGMT and SIGNATURE have gettables and settables - */ -#if 0 - EVP_SIGNATURE_gettable_params(signature), - EVP_SIGNATURE_gettable_ctx_params(signature), - EVP_SIGNATURE_settable_ctx_params(signature), -#else - NULL, NULL, NULL, -#endif - meta); -} - -int provider_main(int argc, char **argv) -{ - int ret = 1, i; - int verbose = 0; - STACK_OF(OPENSSL_CSTRING) *providers = sk_OPENSSL_CSTRING_new_null(); - OPTION_CHOICE o; - char *prog; - - prog = opt_init(argc, argv, provider_options); - while ((o = opt_next()) != OPT_EOF) { - switch (o) { - default: /* Catching OPT_ERR & covering OPT_EOF which isn't possible */ - BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); - goto end; - case OPT_HELP: - opt_help(provider_options); - ret = 0; - goto end; - case OPT_VVV: - case OPT_VV: - case OPT_V: - /* Convert to an integer from one to four. */ - i = (int)(o - OPT_V) + 1; - if (verbose < i) - verbose = i; - break; - } - } - - /* Allow any trailing parameters as provider names. */ - argc = opt_num_rest(); - argv = opt_rest(); - for ( ; *argv; argv++) { - /* This isn't necessary since -- is supported. */ - if (**argv == '-') { - BIO_printf(bio_err, "%s: Cannot mix flags and provider names.\n", - prog); - BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); - goto end; - } - sk_OPENSSL_CSTRING_push(providers, *argv); - } - - ret = 0; - for (i = 0; i < sk_OPENSSL_CSTRING_num(providers); i++) { - const char *name = sk_OPENSSL_CSTRING_value(providers, i); - OSSL_PROVIDER *prov = OSSL_PROVIDER_load(NULL, name); - - if (prov != NULL) { - BIO_printf(bio_out, verbose == 0 ? "%s\n" : "[ %s ]\n", name); - - if (verbose > 0) { - META data; - - data.total = 0; - data.first = 1; - data.verbose = verbose; - data.prov = prov; - data.fn = print_caps; - - switch (verbose) { - case 1: - BIO_printf(bio_out, " "); - break; - case 2: - data.indent = 4; - break; - case 3: - default: - data.indent = 4; - data.subindent = 10; - break; - } - - if (verbose > 1) { - data.first = 1; - data.label = "Cipher"; - } - EVP_CIPHER_do_all_provided(NULL, do_cipher, &data); - if (verbose > 1) { - data.first = 1; - data.label = "Digest"; - } - EVP_MD_do_all_provided(NULL, do_digest, &data); - if (verbose > 1) { - data.first = 1; - data.label = "MAC"; - } - EVP_MAC_do_all_provided(NULL, do_mac, &data); - - if (verbose > 1) { - data.first = 1; - data.label = "Key manager"; - } - EVP_KEYMGMT_do_all_provided(NULL, do_keymgmt, &data); - if (verbose > 1) { - data.first = 1; - data.label = "Key exchange"; - } - EVP_KEYEXCH_do_all_provided(NULL, do_keyexch, &data); - if (verbose > 1) { - data.first = 1; - data.label = "Signature"; - } - EVP_SIGNATURE_do_all_provided(NULL, do_signature, &data); - - switch (verbose) { - default: - break; - case 2: - case 1: - BIO_printf(bio_out, "\n"); - break; - } - } - OSSL_PROVIDER_unload(prov); - } else { - ERR_print_errors(bio_err); - ret = 1; - /* - * Just because one provider module failed, there's no reason to - * stop, if there are more to try. - */ - } - } - - end: - - ERR_print_errors(bio_err); - sk_OPENSSL_CSTRING_free(providers); - return ret; -} diff --git a/apps/rehash.c b/apps/rehash.c index 866b8cfe20..3cbd65c860 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -42,9 +42,6 @@ # include # include -DEFINE_STACK_OF(X509_INFO) -DEFINE_STACK_OF_STRING() - # ifndef PATH_MAX # define PATH_MAX 4096 # endif diff --git a/apps/req.c b/apps/req.c index 46739554bd..9fa3429baf 100644 --- a/apps/req.c +++ b/apps/req.c @@ -7,9 +7,6 @@ * https://www.openssl.org/source/license.html */ -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - #include #include #include @@ -35,9 +32,6 @@ # include #endif -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF_STRING() - #define BITS "default_bits" #define KEYFILE "default_keyfile" #define PROMPT "prompt" @@ -127,7 +121,7 @@ const OPTIONS req_options[] = { {"subj", OPT_SUBJ, 's', "Set or modify request subject"}, {"subject", OPT_SUBJECT, '-', "Output the request's subject"}, {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-', - "Enable support for multivalued RDNs"}, + "Deprecated; multi-valued RDNs support is always on."}, {"days", OPT_DAYS, 'p', "Number of days cert is valid for"}, {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, {"addext", OPT_ADDEXT, 's', @@ -257,7 +251,7 @@ int req_main(int argc, char **argv) int ret = 1, x509 = 0, days = 0, i = 0, newreq = 0, verbose = 0; int pkey_type = -1, private = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_PEM; - int modulus = 0, multirdn = 0, verify = 0, noout = 0, text = 0; + int modulus = 0, multirdn = 1, verify = 0, noout = 0, text = 0; int noenc = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0; long newkey = -1; unsigned long chtype = MBSTRING_ASC, reqflag = 0; @@ -291,7 +285,7 @@ int req_main(int argc, char **argv) break; case OPT_KEYGEN_ENGINE: #ifndef OPENSSL_NO_ENGINE - gen_eng = ENGINE_by_id(opt_arg()); + gen_eng = setup_engine(opt_arg(), 0); if (gen_eng == NULL) { BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv); goto opthelp; @@ -421,7 +415,7 @@ int req_main(int argc, char **argv) subj = opt_arg(); break; case OPT_MULTIVALUE_RDN: - multirdn = 1; + /* obsolete */ break; case OPT_ADDEXT: p = opt_arg(); @@ -594,7 +588,7 @@ int req_main(int argc, char **argv) } if (keyfile != NULL) { - pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key"); + pkey = load_key(keyfile, keyform, 0, passin, e, "private key"); if (pkey == NULL) goto end; app_RAND_load_conf(req_conf, section); @@ -744,8 +738,7 @@ int req_main(int argc, char **argv) if (x509) { EVP_PKEY *tmppkey; X509V3_CTX ext_ctx; - if ((x509ss = X509_new_with_libctx(app_get0_libctx(), - app_get0_propq())) == NULL) + if ((x509ss = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; /* Set version to V3 */ @@ -995,7 +988,7 @@ int req_main(int argc, char **argv) lh_OPENSSL_STRING_doall(addexts, exts_cleanup); lh_OPENSSL_STRING_free(addexts); #ifndef OPENSSL_NO_ENGINE - ENGINE_free(gen_eng); + release_engine(gen_eng); #endif OPENSSL_free(keyalgstr); X509_REQ_free(req); @@ -1514,7 +1507,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth); #ifndef OPENSSL_NO_ENGINE - ENGINE_finish(tmpeng); + finish_engine(tmpeng); #endif if (*pkey_type == EVP_PKEY_RSA) { if (p != NULL) { @@ -1575,7 +1568,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth); *palgnam = OPENSSL_strdup(anam); #ifndef OPENSSL_NO_ENGINE - ENGINE_finish(tmpeng); + finish_engine(tmpeng); #endif } diff --git a/apps/rsa.c b/apps/rsa.c index 0464729f71..558b126560 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -31,7 +31,7 @@ typedef enum OPTION_choice { /* Do not change the order here; see case statements below */ OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG, OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER, - OPT_PROV_ENUM + OPT_PROV_ENUM, OPT_TRADITIONAL } OPTION_CHOICE; const OPTIONS rsa_options[] = { @@ -59,6 +59,8 @@ const OPTIONS rsa_options[] = { {"noout", OPT_NOOUT, '-', "Don't print key out"}, {"text", OPT_TEXT, '-', "Print the key in text"}, {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, + {"traditional", OPT_TRADITIONAL, '-', + "Use traditional format for private keys"}, #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) OPT_SECTION("PVK"), @@ -88,6 +90,7 @@ int rsa_main(int argc, char **argv) int pvk_encr = 2; #endif OPTION_CHOICE o; + int traditional = 0; prog = opt_init(argc, argv, rsa_options); while ((o = opt_next()) != OPT_EOF) { @@ -163,6 +166,9 @@ int rsa_main(int argc, char **argv) if (!opt_provider(o)) goto end; break; + case OPT_TRADITIONAL: + traditional = 1; + break; } } argc = opt_num_rest(); @@ -192,9 +198,9 @@ int rsa_main(int argc, char **argv) tmpformat = informat; } - pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key"); + pkey = load_pubkey(infile, tmpformat, 1, passin, e, "public key"); } else { - pkey = load_key(infile, informat, 1, passin, e, "Private Key"); + pkey = load_key(infile, informat, 1, passin, e, "private key"); } if (pkey != NULL) @@ -280,8 +286,13 @@ int rsa_main(int argc, char **argv) i = PEM_write_bio_RSA_PUBKEY(out, rsa); } else { assert(private); - i = PEM_write_bio_RSAPrivateKey(out, rsa, - enc, NULL, 0, NULL, passout); + if (traditional) { + i = PEM_write_bio_PrivateKey_traditional(out, pkey, enc, NULL, 0, + NULL, passout); + } else { + i = PEM_write_bio_PrivateKey(out, pkey, + enc, NULL, 0, NULL, passout); + } } #ifndef OPENSSL_NO_DSA } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { diff --git a/apps/rsautl.c b/apps/rsautl.c index 0f9789c39c..49d9fcfea4 100644 --- a/apps/rsautl.c +++ b/apps/rsautl.c @@ -189,11 +189,11 @@ int rsautl_main(int argc, char **argv) switch (key_type) { case KEY_PRIVKEY: - pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key"); + pkey = load_key(keyfile, keyformat, 0, passin, e, "private key"); break; case KEY_PUBKEY: - pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key"); + pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "public key"); break; case KEY_CERT: diff --git a/apps/s_client.c b/apps/s_client.c index a1b80f4c5f..512ac0547b 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -8,9 +8,6 @@ * https://www.openssl.org/source/license.html */ -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - #include "e_os.h" #include #include @@ -59,12 +56,6 @@ typedef unsigned int u_int; # endif #endif -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509_NAME) -DEFINE_STACK_OF(SCT) -DEFINE_STACK_OF_STRING() - #undef BUFSIZZ #define BUFSIZZ 1024*8 #define S_CLIENT_IRC_READ_TIMEOUT 8 @@ -612,7 +603,7 @@ const OPTIONS s_client_options[] = { {"host", OPT_HOST, 's', "Use -connect instead"}, {"port", OPT_PORT, 'p', "Use -connect instead"}, {"connect", OPT_CONNECT, 's', - "TCP/IP where to connect (default is :" PORT ")"}, + "TCP/IP where to connect; default: " PORT ")"}, {"bind", OPT_BIND, 's', "bind local address for connection"}, {"proxy", OPT_PROXY, 's', "Connect to via specified proxy to the real server"}, @@ -643,9 +634,9 @@ const OPTIONS s_client_options[] = { {"cert_chain", OPT_CERT_CHAIN, '<', "Client certificate chain file (in PEM format)"}, {"build_chain", OPT_BUILD_CHAIN, '-', "Build client certificate chain"}, - {"key", OPT_KEY, 's', "Private key file to use; default is: -cert file"}, + {"key", OPT_KEY, 's', "Private key file to use; default: -cert file"}, {"keyform", OPT_KEYFORM, 'E', "Key format (ENGINE, other values ignored)"}, - {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + {"pass", OPT_PASS, 's', "Private key and cert file pass phrase source"}, {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"}, {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, @@ -702,7 +693,7 @@ const OPTIONS s_client_options[] = { {"keymatexport", OPT_KEYMATEXPORT, 's', "Export keying material using label"}, {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', - "Export len bytes of keying material (default 20)"}, + "Export len bytes of keying material; default 20"}, {"security_debug", OPT_SECURITY_DEBUG, '-', "Enable security debug messages"}, {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-', @@ -790,7 +781,7 @@ const OPTIONS s_client_options[] = { OPT_V_OPTIONS, {"CRL", OPT_CRL, '<', "CRL file to use"}, {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"}, - {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"}, + {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER); default PEM"}, {"verify_return_error", OPT_VERIFY_RET_ERROR, '-', "Close connection on verification error"}, {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"}, @@ -1210,7 +1201,7 @@ int s_client_main(int argc, char **argv) break; case OPT_SSL_CLIENT_ENGINE: #ifndef OPENSSL_NO_ENGINE - ssl_client_engine = ENGINE_by_id(opt_arg()); + ssl_client_engine = setup_engine(opt_arg(), 0); if (ssl_client_engine == NULL) { BIO_printf(bio_err, "Error getting client auth engine\n"); goto opthelp; @@ -1734,20 +1725,19 @@ int s_client_main(int argc, char **argv) if (key_file != NULL) { key = load_key(key_file, key_format, 0, pass, e, - "client certificate private key file"); + "client certificate private key"); if (key == NULL) goto end; } if (cert_file != NULL) { - cert = load_cert(cert_file, cert_format, "client certificate file"); + cert = load_cert_pass(cert_file, cert_format, pass, "client certificate"); if (cert == NULL) goto end; } if (chain_file != NULL) { - if (!load_certs(chain_file, &chain, FORMAT_PEM, NULL, - "client certificate chain")) + if (!load_certs(chain_file, &chain, pass, "client certificate chain")) goto end; } @@ -1888,10 +1878,10 @@ int s_client_main(int argc, char **argv) if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) { BIO_puts(bio_err, "Error setting client auth engine\n"); ERR_print_errors(bio_err); - ENGINE_free(ssl_client_engine); + release_engine(ssl_client_engine); goto end; } - ENGINE_free(ssl_client_engine); + release_engine(ssl_client_engine); } #endif diff --git a/apps/s_server.c b/apps/s_server.c index 5f16dcdea4..dee38584c4 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -60,12 +60,6 @@ typedef unsigned int u_int; #endif #include "internal/sockets.h" -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(SSL_CIPHER) -DEFINE_STACK_OF_STRING() - static int not_resumable_sess_cb(SSL *s, int is_forward_secure); static int sv_body(int s, int stype, int prot, unsigned char *context); static int www_body(int s, int stype, int prot, unsigned char *context); @@ -535,7 +529,7 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, aia = X509_get1_ocsp(x); if (aia != NULL) { if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0), - &host, &port, &path, &use_ssl)) { + &host, &port, NULL, &path, &use_ssl)) { BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); goto err; } @@ -809,9 +803,9 @@ const OPTIONS s_server_options[] = { {"Verify", OPT_UPPER_V_VERIFY, 'n', "Turn on peer certificate verification, must have a cert"}, {"nameopt", OPT_NAMEOPT, 's', "Certificate subject/issuer name printing options"}, - {"cert", OPT_CERT, '<', "Server certificate file to use; default is " TEST_CERT}, + {"cert", OPT_CERT, '<', "Server certificate file to use; default " TEST_CERT}, {"cert2", OPT_CERT2, '<', - "Certificate file to use for servername; default is" TEST_CERT2}, + "Certificate file to use for servername; default " TEST_CERT2}, {"certform", OPT_CERTFORM, 'F', "Server certificate file format (PEM/DER/P12); has no effect"}, {"cert_chain", OPT_CERT_CHAIN, '<', @@ -824,7 +818,7 @@ const OPTIONS s_server_options[] = { {"key2", OPT_KEY2, '<', "-Private Key file to use for servername if not in -cert2"}, {"keyform", OPT_KEYFORM, 'f', "Key format (ENGINE, other values ignored)"}, - {"pass", OPT_PASS, 's', "Private key file pass phrase source"}, + {"pass", OPT_PASS, 's', "Private key and cert file pass phrase source"}, {"dcert", OPT_DCERT, '<', "Second server certificate file to use (usually for DSA)"}, {"dcertform", OPT_DCERTFORM, 'F', @@ -835,16 +829,14 @@ const OPTIONS s_server_options[] = { "Second private key file to use (usually for DSA)"}, {"dkeyform", OPT_DKEYFORM, 'F', "Second key file format (ENGINE, other values ignored)"}, - {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"}, + {"dpass", OPT_DPASS, 's', "Second private key and cert file pass phrase source"}, {"dhparam", OPT_DHPARAM, '<', "DH parameters file to use"}, {"servername", OPT_SERVERNAME, 's', "Servername for HostName TLS extension"}, {"servername_fatal", OPT_SERVERNAME_FATAL, '-', "mismatch send fatal alert (default warning alert)"}, - {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"}, {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"}, - {"quiet", OPT_QUIET, '-', "No server output"}, {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-', "Disable caching and tickets if ephemeral (EC)DH is used"}, @@ -860,7 +852,7 @@ const OPTIONS s_server_options[] = { {"keymatexport", OPT_KEYMATEXPORT, 's', "Export keying material using label"}, {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p', - "Export len bytes of keying material (default 20)"}, + "Export len bytes of keying material; default 20"}, {"CRL", OPT_CRL, '<', "CRL file to use"}, {"CRLform", OPT_CRLFORM, 'F', "CRL file format (PEM or DER); default PEM"}, {"crl_download", OPT_CRL_DOWNLOAD, '-', @@ -1407,7 +1399,7 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_OCSP s_tlsextstatus = 1; if (!OSSL_HTTP_parse_url(opt_arg(), - &tlscstatp.host, &tlscstatp.port, + &tlscstatp.host, &tlscstatp.port, NULL, &tlscstatp.path, &tlscstatp.use_ssl)) { BIO_printf(bio_err, "Error parsing URL\n"); goto end; @@ -1748,29 +1740,29 @@ int s_server_main(int argc, char *argv[]) if (nocert == 0) { s_key = load_key(s_key_file, s_key_format, 0, pass, engine, - "server certificate private key file"); + "server certificate private key"); if (s_key == NULL) goto end; - s_cert = load_cert(s_cert_file, s_cert_format, - "server certificate file"); + s_cert = load_cert_pass(s_cert_file, s_cert_format, pass, + "server certificate"); if (s_cert == NULL) goto end; if (s_chain_file != NULL) { - if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL, + if (!load_certs(s_chain_file, &s_chain, NULL, "server certificate chain")) goto end; } if (tlsextcbp.servername != NULL) { s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine, - "second server certificate private key file"); + "second server certificate private key"); if (s_key2 == NULL) goto end; - s_cert2 = load_cert(s_cert_file2, s_cert_format, - "second server certificate file"); + s_cert2 = load_cert_pass(s_cert_file2, s_cert_format, pass, + "second server certificate"); if (s_cert2 == NULL) goto end; @@ -1810,19 +1802,19 @@ int s_server_main(int argc, char *argv[]) s_dkey_file = s_dcert_file; s_dkey = load_key(s_dkey_file, s_dkey_format, - 0, dpass, engine, "second certificate private key file"); + 0, dpass, engine, "second certificate private key"); if (s_dkey == NULL) goto end; - s_dcert = load_cert(s_dcert_file, s_dcert_format, - "second server certificate file"); + s_dcert = load_cert_pass(s_dcert_file, s_dcert_format, dpass, + "second server certificate"); if (s_dcert == NULL) { ERR_print_errors(bio_err); goto end; } if (s_dchain_file != NULL) { - if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL, + if (!load_certs(s_dchain_file, &s_dchain, NULL, "second server certificate chain")) goto end; } diff --git a/apps/s_time.c b/apps/s_time.c index ac9c72e622..3730ca540a 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -416,12 +416,19 @@ static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx) if ((conn = BIO_new(BIO_s_connect())) == NULL) return NULL; - BIO_set_conn_hostname(conn, host); - BIO_set_conn_mode(conn, BIO_SOCK_NODELAY); + if (BIO_set_conn_hostname(conn, host) <= 0 + || BIO_set_conn_mode(conn, BIO_SOCK_NODELAY) <= 0) { + BIO_free(conn); + return NULL; + } - if (scon == NULL) + if (scon == NULL) { serverCon = SSL_new(ctx); - else { + if (serverCon == NULL) { + BIO_free(conn); + return NULL; + } + } else { serverCon = scon; SSL_set_connect_state(serverCon); } diff --git a/apps/smime.c b/apps/smime.c index 6b7d51b76a..89dc0eac96 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -19,9 +19,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF_STRING() - static int save_certs(char *signerfile, STACK_OF(X509) *signers); static int smime_cb(int ok, X509_STORE_CTX *ctx); @@ -45,7 +42,7 @@ typedef enum OPTION_choice { OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD, OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE, OPT_CAPATH, OPT_CASTORE, OPT_NOCAFILE, OPT_NOCAPATH, OPT_NOCASTORE, - OPT_R_ENUM, OPT_PROV_ENUM, + OPT_R_ENUM, OPT_PROV_ENUM, OPT_CONFIG, OPT_V_ENUM, OPT_IN, OPT_INFORM, OPT_OUT, OPT_OUTFORM, OPT_CONTENT @@ -70,6 +67,7 @@ const OPTIONS smime_options[] = { {"stream", OPT_STREAM, '-', "Enable CMS streaming" }, {"indef", OPT_INDEF, '-', "Same as -stream" }, {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"}, + OPT_CONFIG_OPTION, OPT_SECTION("Action"), {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"}, @@ -133,6 +131,7 @@ const OPTIONS smime_options[] = { int smime_main(int argc, char **argv) { + CONF *conf = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; EVP_PKEY *key = NULL; PKCS7 *p7 = NULL; @@ -155,6 +154,8 @@ int smime_main(int argc, char **argv) int vpmtouched = 0, rv = 0; ENGINE *e = NULL; const char *mime_eol = "\n"; + OSSL_LIB_CTX *libctx = app_get0_libctx(); + const char *propq = app_get0_propq(); if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; @@ -252,6 +253,11 @@ int smime_main(int argc, char **argv) if (!opt_provider(o)) goto end; break; + case OPT_CONFIG: + conf = app_load_config_modules(opt_arg()); + if (conf == NULL) + goto end; + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; @@ -440,8 +446,7 @@ int smime_main(int argc, char **argv) } if (certfile != NULL) { - if (!load_certs(certfile, &other, FORMAT_PEM, NULL, - "certificate file")) { + if (!load_certs(certfile, &other, NULL, "certificates")) { ERR_print_errors(bio_err); goto end; } @@ -466,9 +471,17 @@ int smime_main(int argc, char **argv) } if (keyfile != NULL) { - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; + + /* + * TODO: Remove this when CMS has full support for provider-native + * EVP_PKEYs + */ + if (EVP_PKEY_get0(key) == NULL) + goto end; + } in = bio_open_default(infile, 'r', informat); @@ -476,18 +489,25 @@ int smime_main(int argc, char **argv) goto end; if (operation & SMIME_IP) { + PKCS7 *p7_in = NULL; + + p7 = PKCS7_new_ex(libctx, propq); + if (p7 == NULL) { + BIO_printf(bio_err, "Error allocating PKCS7 object\n"); + goto end; + } if (informat == FORMAT_SMIME) { - p7 = SMIME_read_PKCS7(in, &indata); + p7_in = SMIME_read_PKCS7_ex(in, &indata, &p7); } else if (informat == FORMAT_PEM) { - p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); + p7_in = PEM_read_bio_PKCS7(in, &p7, NULL, NULL); } else if (informat == FORMAT_ASN1) { - p7 = d2i_PKCS7_bio(in, NULL); + p7_in = d2i_PKCS7_bio(in, &p7); } else { BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); goto end; } - if (p7 == NULL) { + if (p7_in == NULL) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } @@ -518,7 +538,7 @@ int smime_main(int argc, char **argv) if (operation == SMIME_ENCRYPT) { if (indef) flags |= PKCS7_STREAM; - p7 = PKCS7_encrypt(encerts, in, cipher, flags); + p7 = PKCS7_encrypt_ex(encerts, in, cipher, flags, libctx, propq); } else if (operation & SMIME_SIGNERS) { int i; /* @@ -533,7 +553,7 @@ int smime_main(int argc, char **argv) flags |= PKCS7_STREAM; } flags |= PKCS7_PARTIAL; - p7 = PKCS7_sign(NULL, NULL, other, in, flags); + p7 = PKCS7_sign_ex(NULL, NULL, other, in, flags, libctx, propq); if (p7 == NULL) goto end; if (flags & PKCS7_NOCERTS) { @@ -552,9 +572,17 @@ int smime_main(int argc, char **argv) "signer certificate"); if (signer == NULL) goto end; - key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); + key = load_key(keyfile, keyform, 0, passin, e, "signing key"); if (key == NULL) goto end; + + /* + * TODO: Remove this when CMS has full support for provider-native + * EVP_PKEYs + */ + if (EVP_PKEY_get0(key) == NULL) + goto end; + if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) goto end; X509_free(signer); @@ -643,6 +671,7 @@ int smime_main(int argc, char **argv) BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); + NCONF_free(conf); return ret; } diff --git a/apps/speed.c b/apps/speed.c index 4bd42d4e42..46187010d5 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -37,6 +37,12 @@ # include #endif +#if defined(__TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +#endif + #if defined(_WIN32) # include #endif @@ -3420,6 +3426,7 @@ int speed_main(int argc, char **argv) } EVP_PKEY_free(ed_pkey); + ed_pkey = NULL; } if (st == 0) { BIO_printf(bio_err, "EdDSA failure.\n"); diff --git a/apps/storeutl.c b/apps/storeutl.c index 66fd423ab0..fcd874ea5d 100644 --- a/apps/storeutl.c +++ b/apps/storeutl.c @@ -19,7 +19,7 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, int expected, int criterion, OSSL_STORE_SEARCH *search, int text, int noout, int recursive, int indent, BIO *out, - const char *prog, OPENSSL_CTX *libctx, const char *propq); + const char *prog, OSSL_LIB_CTX *libctx, const char *propq); typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN, @@ -84,7 +84,7 @@ int storeutl_main(int argc, char *argv[]) char *alias = NULL; OSSL_STORE_SEARCH *search = NULL; const EVP_MD *digest = NULL; - OPENSSL_CTX *libctx = app_get0_libctx(); + OSSL_LIB_CTX *libctx = app_get0_libctx(); const char *propq = app_get0_propq(); while ((o = opt_next()) != OPT_EOF) { @@ -351,13 +351,13 @@ static int indent_printf(int indent, BIO *bio, const char *format, ...) static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, int expected, int criterion, OSSL_STORE_SEARCH *search, int text, int noout, int recursive, int indent, BIO *out, - const char *prog, OPENSSL_CTX *libctx, const char *propq) + const char *prog, OSSL_LIB_CTX *libctx, const char *propq) { OSSL_STORE_CTX *store_ctx = NULL; int ret = 1, items = 0; - if ((store_ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq, - uimeth, uidata, NULL, NULL)) + if ((store_ctx = OSSL_STORE_open_ex(uri, libctx, propq, uimeth, uidata, + NULL, NULL)) == NULL) { BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri); ERR_print_errors(bio_err); @@ -450,6 +450,13 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, PEM_write_bio_Parameters(out, OSSL_STORE_INFO_get0_PARAMS(info)); break; + case OSSL_STORE_INFO_PUBKEY: + if (text) + EVP_PKEY_print_public(out, OSSL_STORE_INFO_get0_PUBKEY(info), + 0, NULL); + if (!noout) + PEM_write_bio_PUBKEY(out, OSSL_STORE_INFO_get0_PUBKEY(info)); + break; case OSSL_STORE_INFO_PKEY: if (text) EVP_PKEY_print_private(out, OSSL_STORE_INFO_get0_PKEY(info), diff --git a/apps/verify.c b/apps/verify.c index c28f44571a..3d4e7d4060 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -18,10 +18,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF_STRING() - static int cb(int ok, X509_STORE_CTX *ctx); static int check(X509_STORE *ctx, const char *file, STACK_OF(X509) *uchain, STACK_OF(X509) *tchain, @@ -149,7 +145,7 @@ int verify_main(int argc, char **argv) break; case OPT_UNTRUSTED: /* Zero or more times */ - if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL, + if (!load_certs(opt_arg(), &untrusted, NULL, "untrusted certificates")) goto end; break; @@ -158,14 +154,12 @@ int verify_main(int argc, char **argv) noCAfile = 1; noCApath = 1; noCAstore = 1; - if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL, - "trusted certificates")) + if (!load_certs(opt_arg(), &trusted, NULL, "trusted certificates")) goto end; break; case OPT_CRLFILE: /* Zero or more times */ - if (!load_crls(opt_arg(), &crls, FORMAT_PEM, NULL, - "other CRLs")) + if (!load_crls(opt_arg(), &crls, NULL, "other CRLs")) goto end; break; case OPT_CRL_DOWNLOAD: diff --git a/apps/version.c b/apps/version.c index ebdd03e0fe..4a289faca0 100644 --- a/apps/version.c +++ b/apps/version.c @@ -134,3 +134,16 @@ int version_main(int argc, char **argv) end: return ret; } + + +#if defined(__TANDEM) && defined(OPENSSL_VPROC) +/* + * Define a VPROC function for the openssl program. + * This is used by platform version identification tools. + * Do not inline this procedure or make it static. + */ +# define OPENSSL_VPROC_STRING_(x) x##_OPENSSL +# define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x) +# define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC) +void OPENSSL_VPROC_FUNC(void) {} +#endif diff --git a/apps/x509.c b/apps/x509.c index fbe4b8cefe..509d6e8741 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -28,10 +28,6 @@ # include #endif -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF_STRING() - #undef POSTFIX #define POSTFIX ".srl" #define DEF_DAYS 30 @@ -80,7 +76,7 @@ const OPTIONS x509_options[] = { {"inform", OPT_INFORM, 'f', "CSR input format (DER or PEM) - default PEM"}, {"in", OPT_IN, '<', "Input file - default stdin"}, - {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"}, + {"passin", OPT_PASSIN, 's', "Private key and cert file pass-phrase source"}, {"outform", OPT_OUTFORM, 'f', "Output format (DER or PEM) - default PEM"}, {"out", OPT_OUT, '>', "Output file - default stdout"}, @@ -179,7 +175,7 @@ int x509_main(int argc, char **argv) char *subj = NULL; X509_NAME *fsubj = NULL; const unsigned long chtype = MBSTRING_ASC; - const int multirdn = 0; + const int multirdn = 1; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL; X509 *x = NULL, *xca = NULL; @@ -510,8 +506,8 @@ int x509_main(int argc, char **argv) goto end; } - if (!X509_STORE_set_default_paths_with_libctx(ctx, app_get0_libctx(), - app_get0_propq())) { + if (!X509_STORE_set_default_paths_ex(ctx, app_get0_libctx(), + app_get0_propq())) { ERR_print_errors(bio_err); goto end; } @@ -526,7 +522,7 @@ int x509_main(int argc, char **argv) goto end; } if (fkeyfile != NULL) { - fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); + fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "forced key"); if (fkey == NULL) goto end; } @@ -609,7 +605,7 @@ int x509_main(int argc, char **argv) "We need a private key to sign with, use -signkey or -CAkey or -CA with private key\n"); goto end; } - if ((x = X509_new_with_libctx(app_get0_libctx(), app_get0_propq())) == NULL) + if ((x = X509_new_ex(app_get0_libctx(), app_get0_propq())) == NULL) goto end; if (sno == NULL) { @@ -633,7 +629,7 @@ int x509_main(int argc, char **argv) if (!X509_set_pubkey(x, fkey != NULL ? fkey : X509_REQ_get0_pubkey(req))) goto end; } else { - x = load_cert(infile, FORMAT_UNDEF, "Certificate"); + x = load_cert_pass(infile, FORMAT_UNDEF, passin, "certificate"); if (x == NULL) goto end; if (fkey != NULL && !X509_set_pubkey(x, fkey)) @@ -643,7 +639,7 @@ int x509_main(int argc, char **argv) } if (CA_flag) { - xca = load_cert(CAfile, CAformat, "CA Certificate"); + xca = load_cert_pass(CAfile, CAformat, passin, "CA certificate"); if (xca == NULL) goto end; } @@ -850,7 +846,7 @@ int x509_main(int argc, char **argv) BIO_printf(bio_err, "Getting Private key\n"); if (Upkey == NULL) { Upkey = load_key(keyfile, keyformat, 0, - passin, e, "Private key"); + passin, e, "private key"); if (Upkey == NULL) goto end; } @@ -862,7 +858,7 @@ int x509_main(int argc, char **argv) BIO_printf(bio_err, "Getting CA Private Key\n"); if (CAkeyfile != NULL) { CApkey = load_key(CAkeyfile, CAkeyformat, - 0, passin, e, "CA Private Key"); + 0, passin, e, "CA private key"); if (CApkey == NULL) goto end; } @@ -963,7 +959,7 @@ int x509_main(int argc, char **argv) sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); ASN1_OBJECT_free(objtmp); release_engine(e); - OPENSSL_free(passin); + clear_free(passin); return ret; } diff --git a/crypto/aes/asm/aesni-mb-x86_64.pl b/crypto/aes/asm/aesni-mb-x86_64.pl index 3c74df5f78..dde15b1ef7 100644 --- a/crypto/aes/asm/aesni-mb-x86_64.pl +++ b/crypto/aes/asm/aesni-mb-x86_64.pl @@ -76,7 +76,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/aes/asm/aesni-sha1-x86_64.pl b/crypto/aes/asm/aesni-sha1-x86_64.pl index 7d1f91295c..dbe33a3f1a 100644 --- a/crypto/aes/asm/aesni-sha1-x86_64.pl +++ b/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -109,7 +109,7 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && `ml64 2>&1` =~ /Version ([0-9]+)\./ && $1>=10); -$avx=1 if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); +$avx=1 if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); $shaext=1; ### set to zero if compiling for 1.0.1 diff --git a/crypto/aes/asm/aesni-sha256-x86_64.pl b/crypto/aes/asm/aesni-sha256-x86_64.pl index 38901feb66..5521766a6a 100644 --- a/crypto/aes/asm/aesni-sha256-x86_64.pl +++ b/crypto/aes/asm/aesni-sha256-x86_64.pl @@ -71,7 +71,7 @@ $avx = ($1>=10) + ($1>=12); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c index 186e7ec413..9da166f9f3 100644 --- a/crypto/asn1/a_d2i_fp.c +++ b/crypto/asn1/a_d2i_fp.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,6 +13,7 @@ #include "internal/numbers.h" #include #include +#include "internal/asn1.h" #include "crypto/asn1.h" #ifndef NO_OLD_ASN1 diff --git a/crypto/asn1/a_digest.c b/crypto/asn1/a_digest.c index 3e7b418a19..a9709e9bc1 100644 --- a/crypto/asn1/a_digest.c +++ b/crypto/asn1/a_digest.c @@ -53,17 +53,16 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, #endif -int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *md, - void *asn, unsigned char *data, - unsigned int *len, OPENSSL_CTX *libctx, - const char *propq) +int asn1_item_digest_ex(const ASN1_ITEM *it, const EVP_MD *md, void *asn, + unsigned char *data, unsigned int *len, + OSSL_LIB_CTX *libctx, const char *propq) { int i, ret = 0; unsigned char *str = NULL; EVP_MD *fetched_md = (EVP_MD *)md; i = ASN1_item_i2d(asn, &str, it); - if (str == NULL) + if (i < 0 || str == NULL) return 0; if (EVP_MD_provider(md) == NULL) { @@ -90,6 +89,6 @@ int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *md, int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *md, void *asn, unsigned char *data, unsigned int *len) { - return asn1_item_digest_with_libctx(it, md, asn, data, len, NULL, NULL); + return asn1_item_digest_ex(it, md, asn, data, len, NULL, NULL); } diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c index 300f30aa71..c4b7b63dd5 100644 --- a/crypto/asn1/a_sign.c +++ b/crypto/asn1/a_sign.c @@ -115,40 +115,50 @@ int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, #endif -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, - EVP_PKEY *pkey, const EVP_MD *type) +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey, const EVP_MD *md) { - int rv; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + return ASN1_item_sign_ex(it, algor1, algor2, signature, data, NULL, pkey, + md, NULL, NULL); +} + +int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, const ASN1_OCTET_STRING *id, + EVP_PKEY *pkey, const EVP_MD *md, OSSL_LIB_CTX *libctx, + const char *propq) +{ + int rv = 0; + EVP_MD_CTX *ctx = evp_md_ctx_new_ex(pkey, id, libctx, propq); if (ctx == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) { - EVP_MD_CTX_free(ctx); + ASN1err(0, ERR_R_MALLOC_FAILURE); return 0; } + if (!EVP_DigestSignInit(ctx, NULL, md, NULL, pkey)) + goto err; - rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx); + rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, data, ctx); + err: + EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(ctx)); EVP_MD_CTX_free(ctx); return rv; } -int ASN1_item_sign_ctx(const ASN1_ITEM *it, - X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, EVP_MD_CTX *ctx) { - const EVP_MD *type; + const EVP_MD *md; EVP_PKEY *pkey; unsigned char *buf_in = NULL, *buf_out = NULL; size_t inl = 0, outl = 0, outll = 0; int signid, paramtype, buf_len = 0; int rv, pkey_id; - type = EVP_MD_CTX_md(ctx); + md = EVP_MD_CTX_md(ctx); pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx)); if (pkey == NULL) { @@ -202,7 +212,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, rv = 3; } else if (pkey->ameth->item_sign) { - rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); + rv = pkey->ameth->item_sign(ctx, it, data, algor1, algor2, signature); if (rv == 1) outl = signature->length; /*- @@ -221,7 +231,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, } if (rv == 2) { - if (type == NULL) { + if (md == NULL) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); goto err; } @@ -232,7 +242,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, #endif pkey->ameth->pkey_id; - if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type), pkey_id)) { + if (!OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(md), pkey_id)) { ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); goto err; @@ -250,7 +260,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, } - buf_len = ASN1_item_i2d(asn, &buf_in, it); + buf_len = ASN1_item_i2d(data, &buf_in, it); if (buf_len <= 0) { outl = 0; ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_INTERNAL_ERROR); diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c index b2be461208..5fab787f38 100644 --- a/crypto/asn1/a_strnid.c +++ b/crypto/asn1/a_strnid.c @@ -12,8 +12,6 @@ #include #include -DEFINE_STACK_OF(ASN1_STRING_TABLE) - static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; static void st_free(ASN1_STRING_TABLE *tbl); static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c index eb024e79c0..834c3ab198 100644 --- a/crypto/asn1/a_verify.c +++ b/crypto/asn1/a_verify.c @@ -85,30 +85,31 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, #endif -int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey) { + return ASN1_item_verify_ex(it, alg, signature, data, NULL, pkey, NULL, NULL); +} + +int ASN1_item_verify_ex(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + const ASN1_OCTET_STRING *id, EVP_PKEY *pkey, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_MD_CTX *ctx; int rv = -1; - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (ctx == NULL || pctx == NULL) { - ASN1err(0, ERR_R_MALLOC_FAILURE); - goto err; + if ((ctx = evp_md_ctx_new_ex(pkey, id, libctx, propq)) != NULL) { + rv = ASN1_item_verify_ctx(it, alg, signature, data, ctx); + EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(ctx)); + EVP_MD_CTX_free(ctx); } - - EVP_MD_CTX_set_pkey_ctx(ctx, pctx); - - rv = ASN1_item_verify_ctx(it, a, signature, asn, ctx); - - err: - EVP_PKEY_CTX_free(pctx); - EVP_MD_CTX_free(ctx); return rv; } -int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, - ASN1_BIT_STRING *signature, void *asn, +int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, EVP_MD_CTX *ctx) { EVP_PKEY *pkey; @@ -130,7 +131,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, } /* Convert signature OID into digest and public key OIDs */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { + if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)) { ASN1err(0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } @@ -140,7 +141,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, ASN1err(0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); goto err; } - ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey); + ret = pkey->ameth->item_verify(ctx, it, data, alg, signature, pkey); /* * Return values meaning: * <=0: error. @@ -160,7 +161,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, } /* Check public key OID matches public key type */ - if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { + if (!EVP_PKEY_is_a(pkey, OBJ_nid2sn(pknid))) { ASN1err(0, ASN1_R_WRONG_PUBLIC_KEY_TYPE); goto err; } @@ -172,7 +173,7 @@ int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, } } - inl = ASN1_item_i2d(asn, &buf_in, it); + inl = ASN1_item_i2d(data, &buf_in, it); if (inl <= 0) { ASN1err(0, ERR_R_INTERNAL_ERROR); goto err; diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index 32074c460e..e473112d0b 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -361,13 +361,13 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, - void *asn, - X509_ALGOR *a, - ASN1_BIT_STRING *sig, + const void *data, + const X509_ALGOR *a, + const ASN1_BIT_STRING *sig, EVP_PKEY *pkey), int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, - void *asn, + const void *data, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig)) diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c index 96878e2a46..814cd91373 100644 --- a/crypto/asn1/asn1_err.c +++ b/crypto/asn1/asn1_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -171,6 +171,7 @@ static const ERR_STRING_DATA ASN1_str_reasons[] = { {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNEXPECTED_EOC), "unexpected eoc"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), "universalstring is wrong length"}, + {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_DIGEST), "unknown digest"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_FORMAT), "unknown format"}, {ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), "unknown message digest algorithm"}, diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c index 9723da0a3c..896fc89c46 100644 --- a/crypto/asn1/asn1_gen.c +++ b/crypto/asn1/asn1_gen.c @@ -23,9 +23,6 @@ #define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} -DEFINE_STACK_OF(ASN1_TYPE) -DEFINE_STACK_OF(CONF_VALUE) - #define ASN1_FLAG_EXP_MAX 20 /* Maximum number of nested sequences */ #define ASN1_GEN_SEQ_MAX_DEPTH 50 diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 47ae801b94..d6160ac979 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -13,8 +13,6 @@ #include #include "asn1_local.h" -DEFINE_STACK_OF(ASN1_UTF8STRING) - static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, long max); static void asn1_put_length(unsigned char **pp, int length); @@ -389,10 +387,12 @@ int ASN1_STRING_length(const ASN1_STRING *x) return x->length; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 void ASN1_STRING_length_set(ASN1_STRING *x, int len) { x->length = len; } +#endif int ASN1_STRING_type(const ASN1_STRING *x) { diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index dab89e57d5..ba9b1f30a4 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -14,13 +14,11 @@ #include #include #include +#include #include "crypto/evp.h" #include "internal/bio.h" #include "asn1_local.h" -DEFINE_STACK_OF(BIO) -DEFINE_STACK_OF(X509_ALGOR) - /* * Generalised MIME like utilities for streaming ASN1. Although many have a * PKCS7/CMS like flavour others are more general purpose. @@ -132,7 +130,7 @@ int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, return r; } -static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) +static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it, ASN1_VALUE **x) { BIO *b64; ASN1_VALUE *val; @@ -142,7 +140,7 @@ static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) return 0; } bio = BIO_push(b64, bio); - val = ASN1_item_d2i_bio(it, bio, NULL); + val = ASN1_item_d2i_bio(it, bio, x); if (!val) ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR); (void)BIO_flush(bio); @@ -231,14 +229,16 @@ static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) /* SMIME sender */ -int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, - int ctype_nid, int econt_nid, - STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) +int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq) { char bound[33], c; int i; const char *mime_prefix, *mime_eol, *cname = "smime.p7m"; const char *msg_type = NULL; + if (flags & SMIME_OLDMIME) mime_prefix = "application/x-pkcs7-"; else @@ -251,7 +251,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, if ((flags & SMIME_DETACHED) && data) { /* We want multipart/signed */ /* Generate a random boundary */ - if (RAND_bytes((unsigned char *)bound, 32) <= 0) + if (RAND_bytes_ex(libctx, (unsigned char *)bound, 32) <= 0) return 0; for (i = 0; i < 32; i++) { c = bound[i] & 0xf; @@ -321,6 +321,14 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, return 1; } +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) +{ + return SMIME_write_ASN1_ex(bio, val, data, flags, ctype_nid, econt_nid, + mdalgs, it, NULL, NULL); +} + /* Handle output of ASN1 data */ /* cannot constify val because of CMS_dataFinal() */ @@ -380,7 +388,8 @@ static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, * opaque this is set to NULL */ -ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) +ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, BIO **bcont, const ASN1_ITEM *it, + ASN1_VALUE **x) { BIO *asnin; STACK_OF(MIME_HEADER) *headers = NULL; @@ -394,14 +403,14 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) *bcont = NULL; if ((headers = mime_parse_hdr(bio)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR); + ASN1err(0, ASN1_R_MIME_PARSE_ERROR); return NULL; } if ((hdr = mime_hdr_find(headers, "content-type")) == NULL || hdr->value == NULL) { sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); + ASN1err(0, ASN1_R_NO_CONTENT_TYPE); return NULL; } @@ -412,13 +421,13 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) prm = mime_param_find(hdr, "boundary"); if (prm == NULL || prm->param_value == NULL) { sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); + ASN1err(0, ASN1_R_NO_MULTIPART_BOUNDARY); return NULL; } ret = multi_split(bio, prm->param_value, &parts); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); if (!ret || (sk_BIO_num(parts) != 2)) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); + ASN1err(0, ASN1_R_NO_MULTIPART_BODY_FAILURE); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -427,7 +436,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) asnin = sk_BIO_value(parts, 1); if ((headers = mime_parse_hdr(asnin)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR); + ASN1err(0, ASN1_R_MIME_SIG_PARSE_ERROR); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -437,14 +446,14 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) if ((hdr = mime_hdr_find(headers, "content-type")) == NULL || hdr->value == NULL) { sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); + ASN1err(0, ASN1_R_NO_SIG_CONTENT_TYPE); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } if (strcmp(hdr->value, "application/x-pkcs7-signature") && strcmp(hdr->value, "application/pkcs7-signature")) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE); + ASN1err(0, ASN1_R_SIG_INVALID_MIME_TYPE); ERR_add_error_data(2, "type: ", hdr->value); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); sk_BIO_pop_free(parts, BIO_vfree); @@ -452,8 +461,8 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) } sk_MIME_HEADER_pop_free(headers, mime_hdr_free); /* Read in ASN1 */ - if ((val = b64_read_asn1(asnin, it)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); + if ((val = b64_read_asn1(asnin, it, x)) == NULL) { + ASN1err(0, ASN1_R_ASN1_SIG_PARSE_ERROR); sk_BIO_pop_free(parts, BIO_vfree); return NULL; } @@ -471,7 +480,7 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) if (strcmp(hdr->value, "application/x-pkcs7-mime") && strcmp(hdr->value, "application/pkcs7-mime")) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE); + ASN1err(0, ASN1_R_INVALID_MIME_TYPE); ERR_add_error_data(2, "type: ", hdr->value); sk_MIME_HEADER_pop_free(headers, mime_hdr_free); return NULL; @@ -479,12 +488,16 @@ ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - if ((val = b64_read_asn1(bio, it)) == NULL) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); + if ((val = b64_read_asn1(bio, it, x)) == NULL) { + ASN1err(0, ASN1_R_ASN1_PARSE_ERROR); return NULL; } return val; +} +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) +{ + return SMIME_read_ASN1_ex(bio, bcont, it, NULL); } /* Copy text from one BIO to another making the output CRLF at EOL */ diff --git a/crypto/asn1/asn_moid.c b/crypto/asn1/asn_moid.c index 676d1eca2d..549f8f7cb1 100644 --- a/crypto/asn1/asn_moid.c +++ b/crypto/asn1/asn_moid.c @@ -16,8 +16,6 @@ #include "crypto/asn1.h" #include "crypto/objects.h" -DEFINE_STACK_OF(CONF_VALUE) - /* Simple ASN1 OID module: add all objects in a given section */ static int do_create(const char *value, const char *name); diff --git a/crypto/asn1/asn_mstbl.c b/crypto/asn1/asn_mstbl.c index fc21cb3098..ec08ecb3d8 100644 --- a/crypto/asn1/asn_mstbl.c +++ b/crypto/asn1/asn_mstbl.c @@ -13,7 +13,6 @@ #include #include -DEFINE_STACK_OF(CONF_VALUE) /* Multi string module: add table entries from a given section */ static int do_tcreate(const char *value, const char *name); diff --git a/crypto/asn1/d2i_param.c b/crypto/asn1/d2i_param.c index c82b4a8fa8..e755eedea2 100644 --- a/crypto/asn1/d2i_param.c +++ b/crypto/asn1/d2i_param.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,14 +11,14 @@ #include "internal/cryptlib.h" #include #include -#include "crypto/evp.h" +#include "internal/asn1.h" #include "crypto/asn1.h" +#include "crypto/evp.h" EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp, long length) { EVP_PKEY *ret = NULL; - const unsigned char *p = *pp; if ((a == NULL) || (*a == NULL)) { if ((ret = EVP_PKEY_new()) == NULL) @@ -34,7 +34,7 @@ EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp, goto err; } - if (!ret->ameth->param_decode(ret, &p, length)) + if (!ret->ameth->param_decode(ret, pp, length)) goto err; if (a != NULL) diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c index a4d240e7c4..9da8d8e4c0 100644 --- a/crypto/asn1/d2i_pr.c +++ b/crypto/asn1/d2i_pr.c @@ -21,9 +21,9 @@ #include "crypto/asn1.h" #include "crypto/evp.h" -DEFINE_STACK_OF(ASN1_TYPE) EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp, - long length, OPENSSL_CTX *libctx, const char *propq) + long length, OSSL_LIB_CTX *libctx, + const char *propq) { EVP_PKEY *ret; const unsigned char *p = *pp; @@ -46,27 +46,36 @@ EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp, goto err; } + ERR_set_mark(); if (!ret->ameth->old_priv_decode || !ret->ameth->old_priv_decode(ret, &p, length)) { if (ret->ameth->priv_decode != NULL - || ret->ameth->priv_decode_with_libctx != NULL) { + || ret->ameth->priv_decode_ex != NULL) { EVP_PKEY *tmp; PKCS8_PRIV_KEY_INFO *p8 = NULL; p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); - if (p8 == NULL) + if (p8 == NULL) { + ERR_clear_last_mark(); goto err; - tmp = evp_pkcs82pkey_int(p8, libctx, propq); + } + tmp = EVP_PKCS82PKEY_ex(p8, libctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); - if (tmp == NULL) + if (tmp == NULL) { + ERR_clear_last_mark(); goto err; + } EVP_PKEY_free(ret); ret = tmp; + ERR_pop_to_mark(); if (EVP_PKEY_type(type) != EVP_PKEY_base_id(ret)) goto err; } else { + ERR_clear_last_mark(); ASN1err(0, ERR_R_ASN1_LIB); goto err; } + } else { + ERR_clear_last_mark(); } *pp = p; if (a != NULL) @@ -90,7 +99,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, */ EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp, - long length, OPENSSL_CTX *libctx, + long length, OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(ASN1_TYPE) *inkey; @@ -122,7 +131,7 @@ EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp, ASN1err(0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); return NULL; } - ret = evp_pkcs82pkey_int(p8, libctx, propq); + ret = EVP_PKCS82PKEY_ex(p8, libctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); if (ret == NULL) return NULL; diff --git a/crypto/asn1/evp_asn1.c b/crypto/asn1/evp_asn1.c index c775a22181..844aabe603 100644 --- a/crypto/asn1/evp_asn1.c +++ b/crypto/asn1/evp_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include +#include "crypto/asn1.h" int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) { @@ -46,6 +47,34 @@ int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_l return ret; } +static ossl_inline void asn1_type_init_oct(ASN1_OCTET_STRING *oct, + unsigned char *data, int len) +{ + oct->data = data; + oct->type = V_ASN1_OCTET_STRING; + oct->length = len; + oct->flags = 0; +} + +static int asn1_type_get_int_oct(ASN1_OCTET_STRING *oct, int32_t anum, + long *num, unsigned char *data, int max_len) +{ + int ret = ASN1_STRING_length(oct), n; + + if (num != NULL) + *num = anum; + + if (max_len > ret) + n = ret; + else + n = max_len; + + if (data != NULL) + memcpy(data, ASN1_STRING_get0_data(oct), n); + + return ret; +} + typedef struct { int32_t num; ASN1_OCTET_STRING *oct; @@ -66,25 +95,18 @@ int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, atmp.num = num; atmp.oct = &oct; - oct.data = data; - oct.type = V_ASN1_OCTET_STRING; - oct.length = len; - oct.flags = 0; + asn1_type_init_oct(&oct, data, len); if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_int_oct), &atmp, &a)) return 1; return 0; } -/* - * we return the actual length... - */ -/* int max_len: for returned value */ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, unsigned char *data, int max_len) { asn1_int_oct *atmp = NULL; - int ret = -1, n; + int ret = -1; if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { goto err; @@ -95,17 +117,8 @@ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, if (atmp == NULL) goto err; - if (num != NULL) - *num = atmp->num; + ret = asn1_type_get_int_oct(atmp->oct, atmp->num, num, data, max_len); - ret = ASN1_STRING_length(atmp->oct); - if (max_len > ret) - n = ret; - else - n = max_len; - - if (data != NULL) - memcpy(data, ASN1_STRING_get0_data(atmp->oct), n); if (ret == -1) { err: ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG); @@ -113,3 +126,58 @@ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, M_ASN1_free_of(atmp, asn1_int_oct); return ret; } + +typedef struct { + ASN1_OCTET_STRING *oct; + int32_t num; +} asn1_oct_int; + +/* + * Defined in RFC 5084 - + * Section 2. "Content-Authenticated Encryption Algorithms" + */ +ASN1_SEQUENCE(asn1_oct_int) = { + ASN1_SIMPLE(asn1_oct_int, oct, ASN1_OCTET_STRING), + ASN1_EMBED(asn1_oct_int, num, INT32) +} static_ASN1_SEQUENCE_END(asn1_oct_int) + +DECLARE_ASN1_ITEM(asn1_oct_int) + +int asn1_type_set_octetstring_int(ASN1_TYPE *a, long num, unsigned char *data, + int len) +{ + asn1_oct_int atmp; + ASN1_OCTET_STRING oct; + + atmp.num = num; + atmp.oct = &oct; + asn1_type_init_oct(&oct, data, len); + + if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_oct_int), &atmp, &a)) + return 1; + return 0; +} + +int asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len) +{ + asn1_oct_int *atmp = NULL; + int ret = -1; + + if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) + goto err; + + atmp = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(asn1_oct_int), a); + + if (atmp == NULL) + goto err; + + ret = asn1_type_get_int_oct(atmp->oct, atmp->num, num, data, max_len); + + if (ret == -1) { + err: + ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING_INT, ASN1_R_DATA_IS_WRONG); + } + M_ASN1_free_of(atmp, asn1_oct_int); + return ret; +} diff --git a/crypto/asn1/i2d_pr.c b/crypto/asn1/i2d_pr.c index 545300cbab..80cfde9a22 100644 --- a/crypto/asn1/i2d_pr.c +++ b/crypto/asn1/i2d_pr.c @@ -8,9 +8,10 @@ */ #include +#include #include "internal/cryptlib.h" #include -#include +#include #include #include #include "crypto/asn1.h" @@ -30,34 +31,21 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp) } return ret; } - if (a->keymgmt != NULL) { - const char *serprop = OSSL_SERIALIZER_PrivateKey_TO_DER_PQ; - OSSL_SERIALIZER_CTX *ctx = - OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop); - BIO *out = BIO_new(BIO_s_mem()); - BUF_MEM *buf = NULL; + if (evp_pkey_is_provided(a)) { + /* |*pp| is unbounded, so we need an upper limit */ + size_t length = INT_MAX; + /* The private key includes everything */ + int selection = + OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_KEYPAIR; int ret = -1; + OSSL_ENCODER_CTX *ctx; - if (ctx != NULL - && out != NULL - && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL - && OSSL_SERIALIZER_to_bio(ctx, out) - && BIO_get_mem_ptr(out, &buf) > 0) { - ret = buf->length; - - if (pp != NULL) { - if (*pp == NULL) { - *pp = (unsigned char *)buf->data; - buf->length = 0; - buf->data = NULL; - } else { - memcpy(*pp, buf->data, ret); - *pp += ret; - } - } - } - BIO_free(out); - OSSL_SERIALIZER_CTX_free(ctx); + if ((ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, "DER", selection, + NULL, NULL)) != NULL + && OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0 + && OSSL_ENCODER_to_data(ctx, pp, &length)) + ret = (int)length; + OSSL_ENCODER_CTX_free(ctx); return ret; } ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); diff --git a/crypto/asn1/standard_methods.h b/crypto/asn1/standard_methods.h index d461461031..59fa726991 100644 --- a/crypto/asn1/standard_methods.h +++ b/crypto/asn1/standard_methods.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,10 +29,6 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { #endif #ifndef OPENSSL_NO_EC &eckey_asn1_meth, -#endif - &hmac_asn1_meth, -#ifndef OPENSSL_NO_CMAC - &cmac_asn1_meth, #endif #ifndef OPENSSL_NO_RSA &rsa_pss_asn1_meth, @@ -44,12 +40,6 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { &ecx25519_asn1_meth, &ecx448_asn1_meth, #endif -#ifndef OPENSSL_NO_POLY1305 - &poly1305_asn1_meth, -#endif -#ifndef OPENSSL_NO_SIPHASH - &siphash_asn1_meth, -#endif #ifndef OPENSSL_NO_EC &ed25519_asn1_meth, &ed448_asn1_meth, diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 379d1e6ee1..740707f853 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -17,8 +17,6 @@ #include "internal/numbers.h" #include "asn1_local.h" -DEFINE_STACK_OF(ASN1_VALUE) - /* * Constructed types with a recursive definition (such as can be found in PKCS7) * could eventually exceed the stack given malicious input with excessive diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c index 9bd2099c5e..3a5b29f37d 100644 --- a/crypto/asn1/tasn_fre.c +++ b/crypto/asn1/tasn_fre.c @@ -13,8 +13,6 @@ #include #include "asn1_local.h" -DEFINE_STACK_OF(ASN1_VALUE) - /* Free up an ASN1 structure */ void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c index 48ba9f3f74..5bdcf461a5 100644 --- a/crypto/asn1/tasn_new.c +++ b/crypto/asn1/tasn_new.c @@ -15,8 +15,6 @@ #include #include "asn1_local.h" -DEFINE_STACK_OF(ASN1_VALUE) - static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, diff --git a/crypto/asn1/tbl_standard.h b/crypto/asn1/tbl_standard.h index f1750fe78f..3e8fe81eeb 100644 --- a/crypto/asn1/tbl_standard.h +++ b/crypto/asn1/tbl_standard.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -56,6 +56,7 @@ static const ASN1_STRING_TABLE tbl_standard[] = { {NID_SNILS, 1, 11, B_ASN1_NUMERICSTRING, STABLE_NO_MASK}, {NID_countryCode3c, 3, 3, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_countryCode3n, 3, 3, B_ASN1_NUMERICSTRING, STABLE_NO_MASK}, - {NID_dnsName, 0, -1, B_ASN1_UTF8STRING, STABLE_NO_MASK} + {NID_dnsName, 0, -1, B_ASN1_UTF8STRING, STABLE_NO_MASK}, + {NID_id_on_SmtpUTF8Mailbox, 1, ub_email_address, B_ASN1_UTF8STRING, STABLE_NO_MASK} }; diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c index f29d26d91c..7e198a558c 100644 --- a/crypto/asn1/x_algor.c +++ b/crypto/asn1/x_algor.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include "crypto/asn1.h" #include "crypto/evp.h" ASN1_SEQUENCE(X509_ALGOR) = { @@ -125,3 +127,64 @@ int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src) return 1; } + +/* allocate and set algorithm ID from EVP_MD, default SHA1 */ +int x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md) +{ + /* Default is SHA1 so no need to create it - still success */ + if (md == NULL || EVP_MD_is_a(md, "SHA1")) + return 1; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + return 0; + X509_ALGOR_set_md(*palg, md); + return 1; +} + +/* convert algorithm ID to EVP_MD, default SHA1 */ +const EVP_MD *x509_algor_get_md(X509_ALGOR *alg) +{ + const EVP_MD *md; + + if (alg == NULL) + return EVP_sha1(); + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) + ASN1err(0, ASN1_R_UNKNOWN_DIGEST); + return md; +} + +X509_ALGOR *x509_algor_mgf1_decode(X509_ALGOR *alg) +{ + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) + return NULL; + return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), + alg->parameter); +} + +/* Allocate and set MGF1 algorithm ID from EVP_MD */ +int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) +{ + X509_ALGOR *algtmp = NULL; + ASN1_STRING *stmp = NULL; + + *palg = NULL; + if (mgf1md == NULL || EVP_MD_is_a(mgf1md, "SHA1")) + return 1; + /* need to embed algorithm ID inside another */ + if (!x509_algor_new_from_md(&algtmp, mgf1md)) + goto err; + if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) + goto err; + *palg = X509_ALGOR_new(); + if (*palg == NULL) + goto err; + X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + stmp = NULL; + err: + ASN1_STRING_free(stmp); + X509_ALGOR_free(algtmp); + if (*palg != NULL) + return 1; + return 0; +} diff --git a/crypto/asn1_dsa.c b/crypto/asn1_dsa.c index 34835a5214..cb48ae9956 100644 --- a/crypto/asn1_dsa.c +++ b/crypto/asn1_dsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -152,7 +152,7 @@ int encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s) * * Returns 1 on success or 0 on failure. */ -int decode_der_length(PACKET *pkt, PACKET *subpkt) +int ossl_decode_der_length(PACKET *pkt, PACKET *subpkt) { unsigned int byte; @@ -184,7 +184,7 @@ int decode_der_length(PACKET *pkt, PACKET *subpkt) * trailing garbage then it is up to the caller to verify that all bytes * were consumed. */ -int decode_der_integer(PACKET *pkt, BIGNUM *n) +int ossl_decode_der_integer(PACKET *pkt, BIGNUM *n) { PACKET contpkt, tmppkt; unsigned int tag, tmp; @@ -192,7 +192,7 @@ int decode_der_integer(PACKET *pkt, BIGNUM *n) /* Check we have an integer and get the content bytes */ if (!PACKET_get_1(pkt, &tag) || tag != ID_INTEGER - || !decode_der_length(pkt, &contpkt)) + || !ossl_decode_der_length(pkt, &contpkt)) return 0; /* Peek ahead at the first bytes to check for proper encoding */ @@ -230,8 +230,8 @@ int decode_der_integer(PACKET *pkt, BIGNUM *n) * trailing garbage then it is up to the caller to verify that all bytes * were consumed. */ -size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, - size_t len) +size_t ossl_decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, + const unsigned char **ppin, size_t len) { size_t consumed; PACKET pkt, contpkt; @@ -240,9 +240,9 @@ size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, if (!PACKET_buf_init(&pkt, *ppin, len) || !PACKET_get_1(&pkt, &tag) || tag != ID_SEQUENCE - || !decode_der_length(&pkt, &contpkt) - || !decode_der_integer(&contpkt, r) - || !decode_der_integer(&contpkt, s) + || !ossl_decode_der_length(&pkt, &contpkt) + || !ossl_decode_der_integer(&contpkt, r) + || !ossl_decode_der_integer(&contpkt, s) || PACKET_remaining(&contpkt) != 0) return 0; diff --git a/crypto/async/async.c b/crypto/async/async.c index b30f516d05..8eedad97ea 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -170,7 +170,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, int (*func)(void *), void *args, size_t size) { async_ctx *ctx; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) return ASYNC_ERR; @@ -208,7 +208,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, * Restore the default libctx to what it was the last time the * fibre ran */ - libctx = OPENSSL_CTX_set0_default(ctx->currjob->libctx); + libctx = OSSL_LIB_CTX_set0_default(ctx->currjob->libctx); /* Resume previous job */ if (!async_fibre_swapcontext(&ctx->dispatcher, &ctx->currjob->fibrectx, 1)) { @@ -221,7 +221,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, * again to what it was originally, and remember what it had * been changed to. */ - ctx->currjob->libctx = OPENSSL_CTX_set0_default(libctx); + ctx->currjob->libctx = OSSL_LIB_CTX_set0_default(libctx); continue; } @@ -252,7 +252,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, ctx->currjob->func = func; ctx->currjob->waitctx = wctx; - libctx = openssl_ctx_get_concrete(NULL); + libctx = ossl_lib_ctx_get_concrete(NULL); if (!async_fibre_swapcontext(&ctx->dispatcher, &ctx->currjob->fibrectx, 1)) { ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT); @@ -262,7 +262,7 @@ int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret, * In case the fibre changed the default libctx we set it back again * to what it was, and remember what it had been changed to. */ - ctx->currjob->libctx = OPENSSL_CTX_set0_default(libctx); + ctx->currjob->libctx = OSSL_LIB_CTX_set0_default(libctx); } err: diff --git a/crypto/async/async_local.h b/crypto/async/async_local.h index 8caa71cef4..c06f413cf6 100644 --- a/crypto/async/async_local.h +++ b/crypto/async/async_local.h @@ -43,7 +43,7 @@ struct async_job_st { int ret; int status; ASYNC_WAIT_CTX *waitctx; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; }; struct fd_lookup_st { diff --git a/crypto/bio/b_addr.c b/crypto/bio/b_addr.c index 4652003149..4a367ec54c 100644 --- a/crypto/bio/b_addr.c +++ b/crypto/bio/b_addr.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,10 @@ * https://www.openssl.org/source/license.html */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index 79f7743b2f..61dbf474f9 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c @@ -23,7 +23,13 @@ static int wsa_init_done = 0; # endif -# ifndef _WIN32 +# if defined __TANDEM +# include +# include /* select */ +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# endif +# elif !defined _WIN32 # include # include # else diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index 6cff2a99ac..e6972efd8d 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -377,11 +377,7 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) long ret = 1; BIO_CONNECT *data; # ifndef OPENSSL_NO_KTLS -# ifdef __FreeBSD__ - struct tls_enable *crypto_info; -# else - struct tls12_crypto_info_aes_gcm_128 *crypto_info; -# endif + ktls_crypto_info_t *crypto_info; # endif data = (BIO_CONNECT *)b->ptr; @@ -544,12 +540,8 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) break; # ifndef OPENSSL_NO_KTLS case BIO_CTRL_SET_KTLS: -# ifdef __FreeBSD__ - crypto_info = (struct tls_enable *)ptr; -# else - crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr; -# endif - ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num); + crypto_info = (ktls_crypto_info_t *)ptr; + ret = ktls_start(b->num, crypto_info, num); if (ret) BIO_set_ktls_flag(b, num); break; diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index ff2bde7a58..d3eaa6b19e 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -154,12 +154,7 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) long ret = 1; int *ip; # ifndef OPENSSL_NO_KTLS - size_t crypto_info_len; -# ifdef __FreeBSD__ - struct tls_enable *crypto_info; -# else - struct tls_crypto_info_all *crypto_info; -# endif + ktls_crypto_info_t *crypto_info; # endif switch (cmd) { @@ -190,14 +185,8 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) break; # ifndef OPENSSL_NO_KTLS case BIO_CTRL_SET_KTLS: -# ifdef __FreeBSD__ - crypto_info = (struct tls_enable *)ptr; - crypto_info_len = sizeof(*crypto_info); -# else - crypto_info = (struct tls_crypto_info_all *)ptr; - crypto_info_len = crypto_info->tls_crypto_info_len; -# endif - ret = ktls_start(b->num, crypto_info, crypto_info_len, num); + crypto_info = (ktls_crypto_info_t *)ptr; + ret = ktls_start(b->num, crypto_info, num); if (ret) BIO_set_ktls_flag(b, num); break; diff --git a/crypto/bn/asm/rsaz-avx2.pl b/crypto/bn/asm/rsaz-avx2.pl index fc2e8f587b..3d0e342a6b 100755 --- a/crypto/bn/asm/rsaz-avx2.pl +++ b/crypto/bn/asm/rsaz-avx2.pl @@ -67,7 +67,7 @@ $addx = ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $avx = ($ver>=3.0) + ($ver>=3.01); $addx = ($ver>=3.03); diff --git a/crypto/bn/asm/rsaz-x86_64.pl b/crypto/bn/asm/rsaz-x86_64.pl index 78df8adf98..5c7d526fa3 100755 --- a/crypto/bn/asm/rsaz-x86_64.pl +++ b/crypto/bn/asm/rsaz-x86_64.pl @@ -83,7 +83,7 @@ $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl index 187f29f8e2..140072b899 100755 --- a/crypto/bn/asm/x86_64-mont.pl +++ b/crypto/bn/asm/x86_64-mont.pl @@ -77,7 +77,7 @@ $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl index 1edf1f7174..c03473f13a 100755 --- a/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/bn/asm/x86_64-mont5.pl @@ -62,7 +62,7 @@ $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c index d6c55cb16c..05b266b090 100644 --- a/crypto/bn/bn_ctx.c +++ b/crypto/bn/bn_ctx.c @@ -87,7 +87,7 @@ struct bignum_ctx { /* Flags. */ int flags; /* The library context */ - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; }; #ifndef FIPS_MODULE @@ -128,7 +128,7 @@ static void ctxdbg(BIO *channel, const char *text, BN_CTX *ctx) # define CTXDBG(str, ctx) do {} while(0) #endif /* FIPS_MODULE */ -BN_CTX *BN_CTX_new_ex(OPENSSL_CTX *ctx) +BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx) { BN_CTX *ret; @@ -150,7 +150,7 @@ BN_CTX *BN_CTX_new(void) } #endif -BN_CTX *BN_CTX_secure_new_ex(OPENSSL_CTX *ctx) +BN_CTX *BN_CTX_secure_new_ex(OSSL_LIB_CTX *ctx) { BN_CTX *ret = BN_CTX_new_ex(ctx); @@ -249,7 +249,7 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) return ret; } -OPENSSL_CTX *bn_get_lib_ctx(BN_CTX *ctx) +OSSL_LIB_CTX *bn_get_libctx(BN_CTX *ctx) { if (ctx == NULL) return NULL; diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c index e603bb7030..cf0d802679 100644 --- a/crypto/bn/bn_rand.c +++ b/crypto/bn/bn_rand.c @@ -25,7 +25,7 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom, { unsigned char *buf = NULL; int b, ret = 0, bit, bytes, mask; - OPENSSL_CTX *libctx = bn_get_lib_ctx(ctx); + OSSL_LIB_CTX *libctx = bn_get_libctx(ctx); if (bits == 0) { if (top != BN_RAND_TOP_ANY || bottom != BN_RAND_BOTTOM_ANY) @@ -254,7 +254,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, unsigned char *k_bytes = NULL; int ret = 0; EVP_MD *md = NULL; - OPENSSL_CTX *libctx = bn_get_lib_ctx(ctx); + OSSL_LIB_CTX *libctx = bn_get_libctx(ctx); if (mdctx == NULL) goto err; diff --git a/crypto/bn/bn_rsa_fips186_4.c b/crypto/bn/bn_rsa_fips186_4.c index a8b0a69aee..ab1e1f14ae 100644 --- a/crypto/bn/bn_rsa_fips186_4.c +++ b/crypto/bn/bn_rsa_fips186_4.c @@ -65,7 +65,7 @@ static int bn_rsa_fips186_4_aux_prime_min_size(int nbits) { if (nbits >= 3072) return 171; - if (nbits == 2048) + if (nbits >= 2048) return 141; return 0; } @@ -83,7 +83,7 @@ static int bn_rsa_fips186_4_aux_prime_max_sum_size_for_prob_primes(int nbits) { if (nbits >= 3072) return 1518; - if (nbits == 2048) + if (nbits >= 2048) return 1007; return 0; } diff --git a/crypto/bn/build.info b/crypto/bn/build.info index a40bcdca0f..093cbcc7f1 100644 --- a/crypto/bn/build.info +++ b/crypto/bn/build.info @@ -126,8 +126,6 @@ DEFINE[../../providers/libfips.a]=$BNDEF DEFINE[../../providers/liblegacy.a]=$BNDEF DEFINE[../../providers/libimplementations.a]=$BNDEF -INCLUDE[../../libcrypto]=../../crypto/include - INCLUDE[bn_exp.o]=.. GENERATE[bn-586.s]=asm/bn-586.pl diff --git a/crypto/build.info b/crypto/build.info index 83625029c0..814d8dcab7 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ - err comp http ocsp cms ts srp cmac ct async ess crmf cmp serializer \ + err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \ ffc LIBS=../libcrypto @@ -71,13 +71,14 @@ $UTIL_COMMON=\ cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \ ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \ context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM \ - param_build_set.c der_writer.c + param_build_set.c der_writer.c passphrase.c $UTIL_DEFINE=$CPUIDDEF SOURCE[../libcrypto]=$UTIL_COMMON \ mem.c mem_sec.c \ cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ o_fopen.c getenv.c o_init.c init.c trace.c provider.c \ + punycode.c \ $UPLINKSRC SOURCE[../providers/libfips.a]=$UTIL_COMMON SOURCE[../providers/liblegacy.a]=$UTIL_COMMON diff --git a/crypto/buildinf.h b/crypto/buildinf.h index 1d10e39f52..694dd288e5 100644 --- a/crypto/buildinf.h +++ b/crypto/buildinf.h @@ -11,7 +11,7 @@ */ #define PLATFORM "platform: linux-armv4" -#define DATE "built on: Wed Aug 12 12:06:39 2020 UTC" +#define DATE "built on: Fri Oct 30 12:01:42 2020 UTC" /* * Generate compiler_flags as an array of individual characters. This is a diff --git a/crypto/chacha/asm/chacha-x86.pl b/crypto/chacha/asm/chacha-x86.pl index d88e88975b..d0e83d88ce 100755 --- a/crypto/chacha/asm/chacha-x86.pl +++ b/crypto/chacha/asm/chacha-x86.pl @@ -61,7 +61,7 @@ $1>=10); # first version supporting AVX $ymm=1 if ($xmm && !$ymm && - `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ && + `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); # first version supporting AVX $a="eax"; diff --git a/crypto/chacha/asm/chacha-x86_64.pl b/crypto/chacha/asm/chacha-x86_64.pl index 7c06a9b329..964c926fde 100755 --- a/crypto/chacha/asm/chacha-x86_64.pl +++ b/crypto/chacha/asm/chacha-x86_64.pl @@ -86,7 +86,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/cmac/build.info b/crypto/cmac/build.info index a2f6f218c2..0c0e50941f 100644 --- a/crypto/cmac/build.info +++ b/crypto/cmac/build.info @@ -2,5 +2,5 @@ LIBS=../../libcrypto $COMMON=cmac.c -SOURCE[../../libcrypto]=$COMMON cm_ameth.c +SOURCE[../../libcrypto]=$COMMON SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c deleted file mode 100644 index aa06cdc98a..0000000000 --- a/crypto/cmac/cm_ameth.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * CMAC low level APIs are deprecated for public use, but still ok for internal - * use. - */ -#include "internal/deprecated.h" - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" - -/* - * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output - * length and to free up a CMAC key. - */ - -static int cmac_size(const EVP_PKEY *pkey) -{ - return EVP_MAX_BLOCK_LENGTH; -} - -static void cmac_key_free(EVP_PKEY *pkey) -{ - EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey); - EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx); - - EVP_MAC_CTX_free(cmctx); - EVP_MAC_free(mac); -} - -const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { - EVP_PKEY_CMAC, - EVP_PKEY_CMAC, - 0, - - "CMAC", - "OpenSSL CMAC method", - - 0, 0, 0, 0, - - 0, 0, 0, - - cmac_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - cmac_key_free, - 0, - 0, 0 -}; diff --git a/crypto/cmp/cmp_asn.c b/crypto/cmp/cmp_asn.c index f109af0502..d9013911a0 100644 --- a/crypto/cmp/cmp_asn.c +++ b/crypto/cmp/cmp_asn.c @@ -17,8 +17,6 @@ #include #include -DEFINE_STACK_OF(OSSL_CMP_ITAV) - /* ASN.1 declarations from RFC4210 */ ASN1_SEQUENCE(OSSL_CMP_REVANNCONTENT) = { /* OSSL_CMP_PKISTATUS is effectively ASN1_INTEGER so it is used directly */ diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c index 37473c7a6c..ef256e6c72 100644 --- a/crypto/cmp/cmp_client.c +++ b/crypto/cmp/cmp_client.c @@ -21,12 +21,6 @@ #include "openssl/cmp_util.h" -DEFINE_STACK_OF(ASN1_UTF8STRING) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(OSSL_CMP_CERTRESPONSE) -DEFINE_STACK_OF(OSSL_CMP_PKISI) -DEFINE_STACK_OF(OSSL_CRMF_CERTID) - #define IS_CREP(t) ((t) == OSSL_CMP_PKIBODY_IP || (t) == OSSL_CMP_PKIBODY_CP \ || (t) == OSSL_CMP_PKIBODY_KUP) @@ -189,6 +183,11 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, */ ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt)); + /* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */ + if (bt != OSSL_CMP_PKIBODY_POLLREP && bt != OSSL_CMP_PKIBODY_PKICONF + && !ossl_cmp_ctx_set1_extraCertsIn(ctx, (*rep)->extraCerts)) + return 0; + if (!ossl_cmp_msg_check_update(ctx, *rep, unprotected_exception, expected_type)) return 0; @@ -425,10 +424,8 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype, goto err; case OSSL_CMP_PKISTATUS_grantedWithMods: ossl_cmp_warn(ctx, "received \"grantedWithMods\" for certificate"); - crt = ossl_cmp_certresponse_get1_certificate(privkey, crep); break; case OSSL_CMP_PKISTATUS_accepted: - crt = ossl_cmp_certresponse_get1_certificate(privkey, crep); break; /* get all information in case of a rejection before going to error */ case OSSL_CMP_PKISTATUS_rejection: @@ -438,19 +435,16 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype, case OSSL_CMP_PKISTATUS_revocationWarning: ossl_cmp_warn(ctx, "received \"revocationWarning\" - a revocation of the cert is imminent"); - crt = ossl_cmp_certresponse_get1_certificate(privkey, crep); break; case OSSL_CMP_PKISTATUS_revocationNotification: ossl_cmp_warn(ctx, "received \"revocationNotification\" - a revocation of the cert has occurred"); - crt = ossl_cmp_certresponse_get1_certificate(privkey, crep); break; case OSSL_CMP_PKISTATUS_keyUpdateWarning: if (bodytype != OSSL_CMP_PKIBODY_KUR) { CMPerr(0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING); goto err; } - crt = ossl_cmp_certresponse_get1_certificate(privkey, crep); break; default: ossl_cmp_log1(ERROR, ctx, @@ -459,6 +453,7 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype, CMPerr(0, CMP_R_UNKNOWN_PKISTATUS); goto err; } + crt = ossl_cmp_certresponse_get1_cert(crep, ctx, privkey); if (crt == NULL) /* according to PKIStatus, we can expect a cert */ CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND); @@ -473,7 +468,7 @@ static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype, /*- * Callback fn validating that the new certificate can be verified, using * ctx->certConf_cb_arg, which has been initialized using opt_out_trusted, and - * ctx->untrusted_certs, which at this point already contains ctx->extraCertsIn. + * ctx->untrusted, which at this point already contains msg->extraCerts. * Returns 0 on acceptance, else a bit field reflecting PKIFailureInfo. * Quoting from RFC 4210 section 5.1. Overall PKI Message: * The extraCerts field can contain certificates that may be useful to @@ -491,14 +486,35 @@ int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, const char **text) { X509_STORE *out_trusted = OSSL_CMP_CTX_get_certConf_cb_arg(ctx); + STACK_OF(X509) *chain = NULL; (void)text; /* make (artificial) use of var to prevent compiler warning */ if (fail_info != 0) /* accept any error flagged by CMP core library */ return fail_info; - if (out_trusted != NULL - && !OSSL_CMP_validate_cert_path(ctx, out_trusted, cert)) - fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData; + ossl_cmp_debug(ctx, "trying to build chain for newly enrolled cert"); + chain = ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq, + out_trusted /* may be NULL */, + ctx->untrusted, cert); + if (sk_X509_num(chain) > 0) + X509_free(sk_X509_shift(chain)); /* remove leaf (EE) cert */ + if (out_trusted != NULL) { + if (chain == NULL) { + ossl_cmp_err(ctx, "failed building chain for newly enrolled cert"); + fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData; + } else { + ossl_cmp_debug(ctx, + "succeeded building proper chain for newly enrolled cert"); + } + } else if (chain == NULL) { + ossl_cmp_warn(ctx, "could not build approximate chain for newly enrolled cert, resorting to received extraCerts"); + chain = OSSL_CMP_CTX_get1_extraCertsIn(ctx); + } else { + ossl_cmp_debug(ctx, + "success building approximate chain for newly enrolled cert"); + } + (void)ossl_cmp_ctx_set1_newChain(ctx, chain); + sk_X509_pop_free(chain, X509_free); return fail_info; } @@ -519,10 +535,14 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, const char *txt = NULL; OSSL_CMP_CERTREPMESSAGE *crepmsg; OSSL_CMP_CERTRESPONSE *crep; + OSSL_CMP_certConf_cb_t cb; X509 *cert; char *subj = NULL; int ret = 1; + if (!ossl_assert(ctx != NULL)) + return 0; + retry: crepmsg = (*resp)->body->value.ip; /* same for cp and kup */ if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) { @@ -573,10 +593,6 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, && !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs)) return 0; - /* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */ - if (!ossl_cmp_ctx_set1_extraCertsIn(ctx, (*resp)->extraCerts)) - return 0; - subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); if (rkey != NULL /* X509_check_private_key() also works if rkey is just public key */ @@ -584,25 +600,23 @@ static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid, fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData; txt = "public key in new certificate does not match our enrollment key"; /*- - * not callling (void)ossl_cmp_exchange_error(ctx, - * OSSL_CMP_PKISTATUS_rejection, fail_info, txt) + * not calling (void)ossl_cmp_exchange_error(ctx, + * OSSL_CMP_PKISTATUS_rejection, fail_info, txt) * not throwing CMP_R_CERTIFICATE_NOT_ACCEPTED with txt * not returning 0 - * since we better leave this for any ctx->certConf_cb to decide + * since we better leave this for the certConf_cb to decide */ } /* - * Execute the certification checking callback function possibly set in ctx, + * Execute the certification checking callback function, * which can determine whether to accept a newly enrolled certificate. * It may overrule the pre-decision reflected in 'fail_info' and '*txt'. */ - if (ctx->certConf_cb - && (fail_info = ctx->certConf_cb(ctx, ctx->newCert, - fail_info, &txt)) != 0) { - if (txt == NULL) - txt = "CMP client application did not accept it"; - } + cb = ctx->certConf_cb != NULL ? ctx->certConf_cb : OSSL_CMP_certConf_cb; + if ((fail_info = cb(ctx, ctx->newCert, fail_info, &txt)) != 0 + && txt == NULL) + txt = "CMP client did not accept it"; if (fail_info != 0) /* immediately log error before any certConf exchange */ ossl_cmp_log1(ERROR, ctx, "rejecting newly enrolled cert with subject: %s", subj); diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index 558414bb5c..97d76f0223 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -12,6 +12,7 @@ #include #include #include /* for OCSP_REVOKED_STATUS_* */ +#include "crypto/x509.h" /* for x509v3_cache_extensions() */ #include "cmp_local.h" @@ -20,13 +21,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(POLICYINFO) -DEFINE_STACK_OF(ASN1_UTF8STRING) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(OSSL_CMP_ITAV) - /* * Get current certificate store containing trusted root CA certs */ @@ -56,48 +50,67 @@ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store) } /* Get current list of non-trusted intermediate certs */ -STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx) +STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx) { if (ctx == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); return NULL; } - return ctx->untrusted_certs; + return ctx->untrusted; } /* * Set untrusted certificates for path construction in authentication of * the CMP server and potentially others (TLS server, newly enrolled cert). */ -int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) +int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) { - STACK_OF(X509) *untrusted_certs; + STACK_OF(X509) *untrusted; if (ctx == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); return 0; } - if ((untrusted_certs = sk_X509_new_null()) == NULL) + if ((untrusted = sk_X509_new_null()) == NULL) return 0; - if (ossl_cmp_sk_X509_add1_certs(untrusted_certs, certs, 0, 1, 0) != 1) + if (X509_add_certs(untrusted, certs, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP) != 1) goto err; - sk_X509_pop_free(ctx->untrusted_certs, X509_free); - ctx->untrusted_certs = untrusted_certs; + sk_X509_pop_free(ctx->untrusted, X509_free); + ctx->untrusted = untrusted; return 1; err: - sk_X509_pop_free(untrusted_certs, X509_free); + sk_X509_pop_free(untrusted, X509_free); return 0; } +static int cmp_ctx_set_md(OSSL_CMP_CTX *ctx, EVP_MD **pmd, int nid) +{ + EVP_MD *md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propq); + /* fetching in advance to be able to throw error early if unsupported */ + + if (md == NULL) { + CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + EVP_MD_free(*pmd); + *pmd = md; + return 1; +} + /* * Allocates and initializes OSSL_CMP_CTX context structure with default values. * Returns new context on success, NULL on error */ -OSSL_CMP_CTX *OSSL_CMP_CTX_new(void) +OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) { OSSL_CMP_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) - return NULL; + goto err; + + ctx->libctx = libctx; + if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) + goto err; ctx->log_verbosity = OSSL_CMP_LOG_INFO; @@ -106,15 +119,17 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void) ctx->msg_timeout = 2 * 60; - if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL) + if ((ctx->untrusted = sk_X509_new_null()) == NULL) goto err; ctx->pbm_slen = 16; - ctx->pbm_owf = NID_sha256; + if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, NID_sha256)) + goto err; ctx->pbm_itercnt = 500; ctx->pbm_mac = NID_hmac_sha1; - ctx->digest = NID_sha256; + if (!cmp_ctx_set_md(ctx, &ctx->digest, NID_sha256)) + goto err; ctx->popoMethod = OSSL_CRMF_POPO_SIGNATURE; ctx->revocationReason = CRL_REASON_NONE; @@ -123,6 +138,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void) err: OSSL_CMP_CTX_free(ctx); + X509err(0, ERR_R_MALLOC_FAILURE); return NULL; } @@ -139,6 +155,7 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) return ossl_cmp_ctx_set0_statusString(ctx, NULL) && ossl_cmp_ctx_set0_newCert(ctx, NULL) + && ossl_cmp_ctx_set1_newChain(ctx, NULL) && ossl_cmp_ctx_set1_caPubs(ctx, NULL) && ossl_cmp_ctx_set1_extraCertsIn(ctx, NULL) && ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL) @@ -162,16 +179,19 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) X509_free(ctx->validatedSrvCert); X509_NAME_free(ctx->expected_sender); X509_STORE_free(ctx->trusted); - sk_X509_pop_free(ctx->untrusted_certs, X509_free); + sk_X509_pop_free(ctx->untrusted, X509_free); X509_free(ctx->cert); + sk_X509_pop_free(ctx->chain, X509_free); EVP_PKEY_free(ctx->pkey); ASN1_OCTET_STRING_free(ctx->referenceValue); if (ctx->secretValue != NULL) OPENSSL_cleanse(ctx->secretValue->data, ctx->secretValue->length); ASN1_OCTET_STRING_free(ctx->secretValue); + EVP_MD_free(ctx->pbm_owf); X509_NAME_free(ctx->recipient); + EVP_MD_free(ctx->digest); ASN1_OCTET_STRING_free(ctx->transactionID); ASN1_OCTET_STRING_free(ctx->senderNonce); ASN1_OCTET_STRING_free(ctx->recipNonce); @@ -191,6 +211,7 @@ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) sk_ASN1_UTF8STRING_pop_free(ctx->statusString, ASN1_UTF8STRING_free); X509_free(ctx->newCert); + sk_X509_pop_free(ctx->newChain, X509_free); sk_X509_pop_free(ctx->caPubs, X509_free); sk_X509_pop_free(ctx->extraCertsIn, X509_free); @@ -395,6 +416,8 @@ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb) /* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */ void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx) { + if (ctx != NULL && OSSL_CMP_LOG_ERR > ctx->log_verbosity) + return; /* suppress output since severity is not sufficient */ OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb); } @@ -432,11 +455,35 @@ int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec, return 1; } +/* Returns the cert chain computed by OSSL_CMP_certConf_cb(), NULL on error */ +STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx) +{ + if (ctx == NULL) { + CMPerr(0, CMP_R_NULL_ARGUMENT); + return NULL; + } + if (ctx->newChain == NULL) + return sk_X509_new_null(); + return X509_chain_up_ref(ctx->newChain); +} + /* - * Returns the stack of certificates received in a response message. - * The stack is duplicated so the caller must handle freeing it! - * Returns pointer to created stack on success, NULL on error + * Copies any given stack of inbound X509 certificates to newChain + * of the OSSL_CMP_CTX structure so that they may be retrieved later. */ +int ossl_cmp_ctx_set1_newChain(OSSL_CMP_CTX *ctx, STACK_OF(X509) *newChain) +{ + if (!ossl_assert(ctx != NULL)) + return 0; + + sk_X509_pop_free(ctx->newChain, X509_free); + ctx->newChain= NULL; + if (newChain == NULL) + return 1; + return (ctx->newChain = X509_chain_up_ref(newChain)) != NULL; +} + +/* Returns the stack of extraCerts received in CertRepMessage, NULL on error */ STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx) { if (ctx == NULL) { @@ -466,7 +513,7 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, } /* - * Duplicate and set the given stack as the new stack of X509 + * Copies any given stack as the new stack of X509 * certificates to send out in the extraCerts field. */ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, @@ -539,7 +586,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx) } /* - * Duplicate and copy the given stack of certificates to the given + * Copies any given stack of certificates to the given * OSSL_CMP_CTX structure so that they may be retrieved later. */ int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs) @@ -573,6 +620,8 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, const TYPE *val) \ return 1; \ } +#define X509_invalid(cert) (!x509v3_cache_extensions(cert)) +#define EVP_PKEY_invalid(key) 0 #define DEFINE_OSSL_CMP_CTX_set1_up_ref(FIELD, TYPE) \ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ { \ @@ -581,6 +630,11 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ return 0; \ } \ \ + /* prevent misleading error later on malformed cert or provider issue */ \ + if (val != NULL && TYPE##_invalid(val)) { \ + CMPerr(0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE); \ + return 0; \ + } \ if (val != NULL && !TYPE##_up_ref(val)) \ return 0; \ TYPE##_free(ctx->FIELD); \ @@ -678,6 +732,34 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, */ DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509) +int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted, + STACK_OF(X509) *candidates) +{ + STACK_OF(X509) *chain; + + if (ctx == NULL) { + CMPerr(0, CMP_R_NULL_ARGUMENT); + return 0; + } + + if (ctx->untrusted != NULL ? + !X509_add_certs(ctx->untrusted, candidates, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP) : + !OSSL_CMP_CTX_set1_untrusted(ctx, candidates)) + return 0; + + ossl_cmp_debug(ctx, "trying to build chain for own CMP signer cert"); + chain = ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq, own_trusted, + ctx->untrusted, ctx->cert); + if (chain == NULL) { + CMPerr(0, CMP_R_FAILED_BUILDING_OWN_CHAIN); + return 0; + } + ossl_cmp_debug(ctx, "success building chain for own CMP signer cert"); + ctx->chain = chain; + return 1; +} + /* * Set the old certificate that we are updating in KUR * or the certificate to be revoked in RR, respectively. @@ -922,7 +1004,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) switch (opt) { case OSSL_CMP_OPT_LOG_VERBOSITY: - if (val > OSSL_CMP_LOG_DEBUG) { + if (val > OSSL_CMP_LOG_MAX) { CMPerr(0, CMP_R_VALUE_TOO_LARGE); return 0; } @@ -963,10 +1045,12 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) ctx->popoMethod = val; break; case OSSL_CMP_OPT_DIGEST_ALGNID: - ctx->digest = val; + if (!cmp_ctx_set_md(ctx, &ctx->digest, val)) + return 0; break; case OSSL_CMP_OPT_OWF_ALGNID: - ctx->pbm_owf = val; + if (!cmp_ctx_set_md(ctx, &ctx->pbm_owf, val)) + return 0; break; case OSSL_CMP_OPT_MAC_ALGNID: ctx->pbm_mac = val; @@ -1030,9 +1114,9 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt) case OSSL_CMP_OPT_POPO_METHOD: return ctx->popoMethod; case OSSL_CMP_OPT_DIGEST_ALGNID: - return ctx->digest; + return EVP_MD_type(ctx->digest); case OSSL_CMP_OPT_OWF_ALGNID: - return ctx->pbm_owf; + return EVP_MD_type(ctx->pbm_owf); case OSSL_CMP_OPT_MAC_ALGNID: return ctx->pbm_mac; case OSSL_CMP_OPT_MSG_TIMEOUT: diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index 87d0f0f1b0..260e8386d5 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -33,8 +33,6 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { "cert and key do not match"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE), "checkafter out of range"}, - {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE), - "checking pbm no secret available"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING), "encountered keyupdatewarning"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING), @@ -75,6 +73,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { "error validating protection"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE), "error validating signature"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN), + "failed building own chain"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY), "failed extracting pubkey"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM), @@ -88,6 +88,7 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE), "missing key usage digitalsignature"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_P10CSR), "missing p10csr"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PBM_SECRET), "missing pbm secret"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY), "missing private key"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PROTECTION), "missing protection"}, diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c index 364d89a9b0..947f984505 100644 --- a/crypto/cmp/cmp_hdr.c +++ b/crypto/cmp/cmp_hdr.c @@ -20,9 +20,6 @@ #include #include -DEFINE_STACK_OF(ASN1_UTF8STRING) -DEFINE_STACK_OF(OSSL_CMP_ITAV) - int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno) { if (!ossl_assert(hdr != NULL)) @@ -143,26 +140,16 @@ int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr) return ASN1_GENERALIZEDTIME_set(hdr->messageTime, time(NULL)) != NULL; } -/* assign to *tgt a copy of src (or if NULL a random byte array of given len) */ -static int set1_aostr_else_random(ASN1_OCTET_STRING **tgt, - const ASN1_OCTET_STRING *src, size_t len) +/* assign to *tgt a random byte array of given length */ +static int set_random(ASN1_OCTET_STRING **tgt, OSSL_CMP_CTX *ctx, size_t len) { - unsigned char *bytes = NULL; + unsigned char *bytes = OPENSSL_malloc(len); int res = 0; - if (src == NULL) { /* generate a random value if src == NULL */ - if ((bytes = OPENSSL_malloc(len)) == NULL) - goto err; - if (RAND_bytes(bytes, len) <= 0) { - CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM); - goto err; - } + if (bytes == NULL || RAND_bytes_ex(ctx->libctx, bytes, len) <= 0) + CMPerr(0, CMP_R_FAILURE_OBTAINING_RANDOM); + else res = ossl_cmp_asn1_octet_string_set1_bytes(tgt, bytes, len); - } else { - res = ossl_cmp_asn1_octet_string_set1(tgt, src); - } - - err: OPENSSL_free(bytes); return res; } @@ -287,8 +274,7 @@ int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr) int ossl_cmp_hdr_set_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) { if (ctx->transactionID == NULL - && !set1_aostr_else_random(&ctx->transactionID, NULL, - OSSL_CMP_TRANSACTIONID_LENGTH)) + && !set_random(&ctx->transactionID, ctx, OSSL_CMP_TRANSACTIONID_LENGTH)) return 0; return ossl_cmp_asn1_octet_string_set1(&hdr->transactionID, ctx->transactionID); @@ -355,8 +341,7 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) * is copied from the senderNonce of the previous message in the * transaction. */ - if (!set1_aostr_else_random(&hdr->senderNonce, NULL, - OSSL_CMP_SENDERNONCE_LENGTH)) + if (!set_random(&hdr->senderNonce, ctx, OSSL_CMP_SENDERNONCE_LENGTH)) return 0; /* store senderNonce - for cmp with recipNonce in next outgoing msg */ diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c index 3804f2498f..33b5f6af7a 100644 --- a/crypto/cmp/cmp_http.c +++ b/crypto/cmp/cmp_http.c @@ -28,8 +28,6 @@ #include #include -DEFINE_STACK_OF(CONF_VALUE) - /* * Send the PKIMessage req and on success return the response, else NULL. * Any previous error queue entries will likely be removed by ERR_clear_error(). @@ -40,6 +38,7 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, char server_port[32] = { '\0' }; STACK_OF(CONF_VALUE) *headers = NULL; const char *const content_type_pkix = "application/pkixcmp"; + int tls_used; OSSL_CMP_MSG *res; if (ctx == NULL || req == NULL) { @@ -53,16 +52,18 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, if (ctx->serverPort != 0) BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); + tls_used = OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL; + ossl_cmp_log2(DEBUG, ctx, "connecting to CMP server %s%s", + ctx->server, tls_used ? " using TLS" : ""); res = (OSSL_CMP_MSG *) OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath, - OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL, - ctx->proxy, ctx->no_proxy, NULL, NULL, + tls_used, ctx->proxy, ctx->no_proxy, NULL, NULL, ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx), headers, content_type_pkix, (const ASN1_VALUE *)req, ASN1_ITEM_rptr(OSSL_CMP_MSG), 0, 0, ctx->msg_timeout, content_type_pkix, ASN1_ITEM_rptr(OSSL_CMP_MSG)); - + ossl_cmp_debug(ctx, "disconnected from CMP server"); sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); return res; } diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index 4e33fd339c..c615865864 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -28,6 +28,8 @@ * this structure is used to store the context for CMP sessions */ struct ossl_cmp_ctx_st { + OSSL_LIB_CTX *libctx; + const char *propq; OSSL_CMP_log_cb_t log_cb; /* log callback for error/debug/etc. output */ OSSL_CMP_severity log_verbosity; /* level of verbosity of log output */ @@ -58,7 +60,7 @@ struct ossl_cmp_ctx_st { X509 *validatedSrvCert; /* caches any already validated server cert */ X509_NAME *expected_sender; /* expected sender in header of response */ X509_STORE *trusted; /* trust store maybe w CRLs and cert verify callback */ - STACK_OF(X509) *untrusted_certs; /* untrusted (intermediate) certs */ + STACK_OF(X509) *untrusted; /* untrusted (intermediate CA) certs */ int ignore_keyusage; /* ignore key usage entry when validating certs */ /* * permitTAInExtraCertsForIR allows use of root certs in extracerts @@ -69,18 +71,19 @@ struct ossl_cmp_ctx_st { /* client authentication */ int unprotectedSend; /* send unprotected PKI messages */ X509 *cert; /* protection cert used to identify and sign for MSG_SIG_ALG */ + STACK_OF(X509) *chain; /* (cached) chain of protection cert including it */ EVP_PKEY *pkey; /* the key pair corresponding to cert */ ASN1_OCTET_STRING *referenceValue; /* optional user name for MSG_MAC_ALG */ ASN1_OCTET_STRING *secretValue; /* password/shared secret for MSG_MAC_ALG */ /* PBMParameters for MSG_MAC_ALG */ - size_t pbm_slen; /* currently fixed to 16 */ - int pbm_owf; /* NID of one-way function (OWF), default: SHA256 */ - int pbm_itercnt; /* currently fixed to 500 */ + size_t pbm_slen; /* salt length, currently fixed to 16 */ + EVP_MD *pbm_owf; /* one-way function (OWF), default: SHA256 */ + int pbm_itercnt; /* OWF iteration count, currently fixed to 500 */ int pbm_mac; /* NID of MAC algorithm, default: HMAC-SHA1 as per RFC 4210 */ /* CMP message header and extra certificates */ X509_NAME *recipient; /* to set in recipient in pkiheader */ - int digest; /* NID of digest used in MSG_SIG_ALG and POPO, default SHA256 */ + EVP_MD *digest; /* digest used in MSG_SIG_ALG and POPO, default SHA256 */ ASN1_OCTET_STRING *transactionID; /* the current transaction ID */ ASN1_OCTET_STRING *senderNonce; /* last nonce sent */ ASN1_OCTET_STRING *recipNonce; /* last nonce received */ @@ -118,6 +121,7 @@ struct ossl_cmp_ctx_st { /* TODO: this should be a stack since there could be more than one */ X509 *newCert; /* newly enrolled cert received from the CA */ /* TODO: this should be a stack since there could be more than one */ + STACK_OF(X509) *newChain; /* chain of newly enrolled cert received */ STACK_OF(X509) *caPubs; /* CA certs received from server (in IP message) */ STACK_OF(X509) *extraCertsIn; /* extraCerts received from server */ @@ -732,11 +736,7 @@ const char *ossl_cmp_log_parse_metadata(const char *buf, char **file, int *line); # define ossl_cmp_add_error_data(txt) ERR_add_error_txt(" : ", txt) # define ossl_cmp_add_error_line(txt) ERR_add_error_txt("\n", txt) -/* functions manipulating lists of certificates etc could be generally useful */ -int ossl_cmp_sk_X509_add1_cert(STACK_OF(X509) *sk, X509 *cert, - int no_dup, int prepend); -int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, - int no_self_issued, int no_dups, int prepend); +/* The two functions manipulating X509_STORE could be generally useful */ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, int only_self_issued); STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store); @@ -746,7 +746,10 @@ int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, const ASN1_OCTET_STRING *src); int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, const unsigned char *bytes, int len); -STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert); +STACK_OF(X509) + *ossl_cmp_build_cert_chain(OSSL_LIB_CTX *libctx, const char *propq, + X509_STORE *store, + STACK_OF(X509) *certs, X509 *cert); /* from cmp_ctx.c */ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, @@ -780,6 +783,7 @@ int ossl_cmp_ctx_set0_statusString(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIFREETEXT *text); int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info); int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert); +int ossl_cmp_ctx_set1_newChain(OSSL_CMP_CTX *ctx, STACK_OF(X509) *newChain); int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs); int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, STACK_OF(X509) *extraCertsIn); @@ -894,14 +898,14 @@ ossl_cmp_pollrepcontent_get0_pollrep(const OSSL_CMP_POLLREPCONTENT *prc, OSSL_CMP_CERTRESPONSE * ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, int rid); -X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey, - const OSSL_CMP_CERTRESPONSE *crep); +X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, + const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey); +OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file); /* from cmp_protect.c */ -ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, - const ASN1_OCTET_STRING *secret, - EVP_PKEY *pkey); int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); +ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg); int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); /* from cmp_vfy.c */ @@ -910,7 +914,10 @@ typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx, int invalid_protection, int arg); int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); -int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified); +int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); +int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, int accept_RAVerified); /* from cmp_client.c */ int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info, diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index 6d6e3bd2b6..5ff8e9fc52 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -19,17 +19,7 @@ #include #include #include - -DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS) -DEFINE_STACK_OF(OSSL_CMP_ITAV) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(OSSL_CMP_PKISI) -DEFINE_STACK_OF(OSSL_CRMF_MSG) -DEFINE_STACK_OF(OSSL_CMP_CERTRESPONSE) -DEFINE_STACK_OF(OSSL_CRMF_CERTID) -DEFINE_STACK_OF(ASN1_UTF8STRING) +#include "crypto/x509.h" /* for x509_set0_libctx() */ OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg) { @@ -354,8 +344,9 @@ OSSL_CMP_MSG *ossl_cmp_certreq_new(OSSL_CMP_CTX *ctx, int type, type == OSSL_CMP_PKIBODY_KUR, OSSL_CMP_CERTREQID); if (local_crm == NULL - || !OSSL_CRMF_MSG_create_popo(local_crm, privkey, ctx->digest, - ctx->popoMethod)) + || !OSSL_CRMF_MSG_create_popo(ctx->popoMethod, local_crm, + privkey, ctx->digest, + ctx->libctx, ctx->propq)) goto err; } else { if ((local_crm = OSSL_CRMF_MSG_dup(crm)) == NULL) @@ -440,7 +431,8 @@ OSSL_CMP_MSG *ossl_cmp_certrep_new(OSSL_CMP_CTX *ctx, int bodytype, if (sk_X509_num(chain) > 0) { msg->extraCerts = sk_X509_new_reserve(NULL, sk_X509_num(chain)); if (msg->extraCerts == NULL - || !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0)) + || !X509_add_certs(msg->extraCerts, chain, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) goto err; } @@ -955,19 +947,18 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crm, return NULL; } -/* - * CMP_CERTRESPONSE_get1_certificate() attempts to retrieve the returned - * certificate from the given certResponse B. - * Uses the privkey in case of indirect POP from B. +/*- + * Retrieve the newly enrolled certificate from the given certResponse crep. + * In case of indirect POPO uses the libctx and propq from ctx and private key. * Returns a pointer to a copy of the found certificate, or NULL if not found. */ -X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey, - const OSSL_CMP_CERTRESPONSE *crep) +X509 *ossl_cmp_certresponse_get1_cert(const OSSL_CMP_CERTRESPONSE *crep, + const OSSL_CMP_CTX *ctx, EVP_PKEY *pkey) { OSSL_CMP_CERTORENCCERT *coec; X509 *crt = NULL; - if (!ossl_assert(crep != NULL)) + if (!ossl_assert(crep != NULL && ctx != NULL)) return NULL; if (crep->certifiedKeyPair @@ -978,13 +969,14 @@ X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey, break; case OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT: /* cert encrypted for indirect PoP; RFC 4210, 5.2.8.2 */ - if (privkey == NULL) { + if (pkey == NULL) { CMPerr(0, CMP_R_MISSING_PRIVATE_KEY); return NULL; } crt = OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(coec->value.encryptedCert, - privkey); + ctx->libctx, ctx->propq, + pkey); break; default: CMPerr(0, CMP_R_UNKNOWN_CERT_TYPE); @@ -993,6 +985,8 @@ X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey, } if (crt == NULL) CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND); + else + (void)x509_set0_libctx(crt, ctx->libctx, ctx->propq); return crt; } diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c index 880051d3dd..9b28f1b09b 100644 --- a/crypto/cmp/cmp_protect.c +++ b/crypto/cmp/cmp_protect.c @@ -18,70 +18,63 @@ #include #include -DEFINE_STACK_OF(X509) - /* - * This function is also used for verification from cmp_vfy. - * - * Calculate protection for given PKImessage utilizing the given credentials - * and the algorithm parameters set inside the message header's protectionAlg. + * This function is also used by the internal verify_PBMAC() in cmp_vfy.c. * - * secret or pkey must be set. Attempts doing PBMAC in case 'secret' is set - * and else signature if 'pkey' is set - but will only - * do the protection already marked in msg->header->protectionAlg. + * Calculate protection for given PKImessage according to + * the algorithm and parameters in the message header's protectionAlg + * using the credentials, library context, and property criteria in the ctx. * - * returns ptr to ASN1_BIT_STRING containing protection on success, else NULL + * returns ASN1_BIT_STRING representing the protection on success, else NULL */ -ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, - const ASN1_OCTET_STRING *secret, - EVP_PKEY *pkey) +ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg) { ASN1_BIT_STRING *prot = NULL; OSSL_CMP_PROTECTEDPART prot_part; const ASN1_OBJECT *algorOID = NULL; - int len; - size_t prot_part_der_len; - unsigned char *prot_part_der = NULL; - size_t sig_len; - unsigned char *protection = NULL; const void *ppval = NULL; int pptype = 0; - OSSL_CRMF_PBMPARAMETER *pbm = NULL; - ASN1_STRING *pbm_str = NULL; - const unsigned char *pbm_str_uc = NULL; - EVP_MD_CTX *evp_ctx = NULL; - int md_NID; - const EVP_MD *md = NULL; - if (!ossl_assert(msg != NULL)) + if (!ossl_assert(ctx != NULL && msg != NULL)) return NULL; /* construct data to be signed */ prot_part.header = msg->header; prot_part.body = msg->body; - len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der); - if (len < 0 || prot_part_der == NULL) { - CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); - goto end; - } - prot_part_der_len = (size_t) len; - if (msg->header->protectionAlg == NULL) { CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID); - goto end; + return NULL; } X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg); - if (secret != NULL) { + if (OBJ_obj2nid(algorOID) == NID_id_PasswordBasedMAC) { + int len; + size_t prot_part_der_len; + unsigned char *prot_part_der = NULL; + size_t sig_len; + unsigned char *protection = NULL; + OSSL_CRMF_PBMPARAMETER *pbm = NULL; + ASN1_STRING *pbm_str = NULL; + const unsigned char *pbm_str_uc = NULL; + + if (ctx->secretValue == NULL) { + CMPerr(0, CMP_R_MISSING_PBM_SECRET); + return NULL; + } if (ppval == NULL) { CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); - goto end; + return NULL; } - if (NID_id_PasswordBasedMAC != OBJ_obj2nid(algorOID)) { - CMPerr(0, CMP_R_WRONG_ALGORITHM_OID); + + len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der); + if (len < 0 || prot_part_der == NULL) { + CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); goto end; } + prot_part_der_len = (size_t)len; + pbm_str = (ASN1_STRING *)ppval; pbm_str_uc = pbm_str->data; pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, pbm_str->length); @@ -90,50 +83,49 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, goto end; } - if (!OSSL_CRMF_pbm_new(pbm, prot_part_der, prot_part_der_len, - secret->data, secret->length, + if (!OSSL_CRMF_pbm_new(ctx->libctx, ctx->propq, + pbm, prot_part_der, prot_part_der_len, + ctx->secretValue->data, ctx->secretValue->length, &protection, &sig_len)) goto end; - } else if (pkey != NULL) { - /* TODO combine this with large parts of CRMF_poposigningkey_init() */ - /* EVP_DigestSignInit() checks that pkey type is correct for the alg */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_NID, NULL) - || (md = EVP_get_digestbynid(md_NID)) == NULL - || (evp_ctx = EVP_MD_CTX_new()) == NULL) { - CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID); - goto end; - } - if (EVP_DigestSignInit(evp_ctx, NULL, md, NULL, pkey) <= 0 - || EVP_DigestSignUpdate(evp_ctx, prot_part_der, - prot_part_der_len) <= 0 - || EVP_DigestSignFinal(evp_ctx, NULL, &sig_len) <= 0 - || (protection = OPENSSL_malloc(sig_len)) == NULL - || EVP_DigestSignFinal(evp_ctx, protection, &sig_len) <= 0) { - CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); - goto end; + if ((prot = ASN1_BIT_STRING_new()) == NULL) + return NULL; + /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */ + prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + prot->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) { + ASN1_BIT_STRING_free(prot); + prot = NULL; } + end: + OSSL_CRMF_PBMPARAMETER_free(pbm); + OPENSSL_free(protection); + OPENSSL_free(prot_part_der); + return prot; } else { - CMPerr(0, CMP_R_INVALID_ARGS); - goto end; - } + int md_nid; + const EVP_MD *md = NULL; - if ((prot = ASN1_BIT_STRING_new()) == NULL) - goto end; - /* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */ - prot->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - prot->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (!ASN1_BIT_STRING_set(prot, protection, sig_len)) { + if (ctx->pkey == NULL) { + CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); + return NULL; + } + if (!OBJ_find_sigid_algs(OBJ_obj2nid(algorOID), &md_nid, NULL) + || (md = EVP_get_digestbynid(md_nid)) == NULL) { + CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID); + return NULL; + } + + if ((prot = ASN1_BIT_STRING_new()) == NULL) + return NULL; + if (ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), NULL, + NULL, prot, &prot_part, NULL, ctx->pkey, md, + ctx->libctx, ctx->propq)) + return prot; ASN1_BIT_STRING_free(prot); - prot = NULL; + return NULL; } - - end: - OSSL_CRMF_PBMPARAMETER_free(pbm); - EVP_MD_CTX_free(evp_ctx); - OPENSSL_free(protection); - OPENSSL_free(prot_part_der); - return prot; } int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) @@ -145,30 +137,47 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) && (msg->extraCerts = sk_X509_new_null()) == NULL) return 0; - if (ctx->cert != NULL && ctx->pkey != NULL) { - /* make sure that our own cert is included in the first position */ - if (!ossl_cmp_sk_X509_add1_cert(msg->extraCerts, ctx->cert, 1, 1)) - return 0; - /* if we have untrusted certs, try to add intermediate certs */ - if (ctx->untrusted_certs != NULL) { - STACK_OF(X509) *chain = - ossl_cmp_build_cert_chain(ctx->untrusted_certs, ctx->cert); - int res = ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, - 1 /* no self-issued */, - 1 /* no duplicates */, 0); - - sk_X509_pop_free(chain, X509_free); - if (res == 0) + /* Add first ctx->cert and its chain if using signature-based protection */ + if (!ctx->unprotectedSend && ctx->secretValue == NULL + && ctx->cert != NULL && ctx->pkey != NULL) { + int flags_prepend = X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND | X509_ADD_FLAG_NO_SS; + + /* if not yet done try to build chain using available untrusted certs */ + if (ctx->chain == NULL) { + ossl_cmp_debug(ctx, + "trying to build chain for own CMP signer cert"); + ctx->chain = + ossl_cmp_build_cert_chain(ctx->libctx, ctx->propq, NULL, + ctx->untrusted, ctx->cert); + if (ctx->chain != NULL) { + ossl_cmp_debug(ctx, + "success building chain for own CMP signer cert"); + } else { + /* dump errors to avoid confusion when printing further ones */ + OSSL_CMP_CTX_print_errors(ctx); + ossl_cmp_warn(ctx, + "could not build chain for own CMP signer cert"); + } + } + if (ctx->chain != NULL) { + if (!X509_add_certs(msg->extraCerts, ctx->chain, flags_prepend)) + return 0; + } else { + /* make sure that at least our own signer cert is included first */ + if (!X509_add_cert(msg->extraCerts, ctx->cert, flags_prepend)) return 0; + ossl_cmp_debug(ctx, + "fallback: adding just own CMP signer cert"); } } /* add any additional certificates from ctx->extraCertsOut */ - if (!ossl_cmp_sk_X509_add1_certs(msg->extraCerts, ctx->extraCertsOut, 0, - 1 /* no duplicates */, 0)) + if (!X509_add_certs(msg->extraCerts, ctx->extraCertsOut, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP)) return 0; - /* if none was found avoid empty ASN.1 sequence */ + /* in case extraCerts are empty list avoid empty ASN.1 sequence */ if (sk_X509_num(msg->extraCerts) == 0) { sk_X509_free(msg->extraCerts); msg->extraCerts = NULL; @@ -179,24 +188,22 @@ int ossl_cmp_msg_add_extraCerts(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) /* * Create an X509_ALGOR structure for PasswordBasedMAC protection based on * the pbm settings in the context - * returns pointer to X509_ALGOR on success, NULL on error */ -static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx) +static int set_pbmac_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) { - X509_ALGOR *alg = NULL; OSSL_CRMF_PBMPARAMETER *pbm = NULL; unsigned char *pbm_der = NULL; int pbm_der_len; ASN1_STRING *pbm_str = NULL; if (!ossl_assert(ctx != NULL)) - return NULL; + return 0; - alg = X509_ALGOR_new(); - pbm = OSSL_CRMF_pbmp_new(ctx->pbm_slen, ctx->pbm_owf, ctx->pbm_itercnt, + pbm = OSSL_CRMF_pbmp_new(ctx->libctx, ctx->pbm_slen, + EVP_MD_type(ctx->pbm_owf), ctx->pbm_itercnt, ctx->pbm_mac); pbm_str = ASN1_STRING_new(); - if (alg == NULL || pbm == NULL || pbm_str == NULL) + if (pbm == NULL || pbm_str == NULL) goto err; if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0) @@ -204,19 +211,49 @@ static X509_ALGOR *create_pbmac_algor(OSSL_CMP_CTX *ctx) if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len)) goto err; + if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) + goto err; OPENSSL_free(pbm_der); - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), + X509_ALGOR_set0(*alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), V_ASN1_SEQUENCE, pbm_str); OSSL_CRMF_PBMPARAMETER_free(pbm); - return alg; + return 1; err: ASN1_STRING_free(pbm_str); - X509_ALGOR_free(alg); OPENSSL_free(pbm_der); OSSL_CRMF_PBMPARAMETER_free(pbm); - return NULL; + return 0; +} + +static int set_sig_algor(const OSSL_CMP_CTX *ctx, X509_ALGOR **alg) +{ + int nid = 0; + ASN1_OBJECT *algo = NULL; + + if (!OBJ_find_sigid_by_algs(&nid, EVP_MD_type(ctx->digest), + EVP_PKEY_id(ctx->pkey))) { + CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE); + return 0; + } + if ((algo = OBJ_nid2obj(nid)) == NULL) + return 0; + if (*alg == NULL && (*alg = X509_ALGOR_new()) == NULL) + return 0; + + if (X509_ALGOR_set0(*alg, algo, V_ASN1_UNDEF, NULL)) + return 1; + ASN1_OBJECT_free(algo); + return 0; +} + +static int set_senderKID(const OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg, + const ASN1_OCTET_STRING *id) +{ + if (id == NULL) + id = ctx->referenceValue; /* standard for PBM, fallback for sig-based */ + return id == NULL || ossl_cmp_hdr_set1_senderKID(msg->header, id); } int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) @@ -233,25 +270,23 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) ASN1_BIT_STRING_free(msg->protection); msg->protection = NULL; - if (ctx->unprotectedSend) - return 1; - - /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */ - if (ctx->secretValue != NULL) { - if ((msg->header->protectionAlg = create_pbmac_algor(ctx)) == NULL) + if (ctx->unprotectedSend) { + if (!set_senderKID(ctx, msg, NULL)) goto err; - if (ctx->referenceValue != NULL - && !ossl_cmp_hdr_set1_senderKID(msg->header, - ctx->referenceValue)) + } else if (ctx->secretValue != NULL) { + /* use PasswordBasedMac according to 5.1.3.1 if secretValue is given */ + if (!set_pbmac_algor(ctx, &msg->header->protectionAlg)) goto err; - } else if (ctx->cert != NULL && ctx->pkey != NULL) { + if (!set_senderKID(ctx, msg, NULL)) + goto err; + /* - * use MSG_SIG_ALG according to 5.1.3.3 if client Certificate and - * private key is given + * will add any additional certificates from ctx->extraCertsOut + * while not needed to validate the protection certificate, + * the option to do this might be handy for certain use cases */ - const ASN1_OCTET_STRING *subjKeyIDStr = NULL; - int algNID = 0; - ASN1_OBJECT *alg = NULL; + } else if (ctx->cert != NULL && ctx->pkey != NULL) { + /* use MSG_SIG_ALG according to 5.1.3.3 if client cert and key given */ /* make sure that key and certificate match */ if (!X509_check_private_key(ctx->cert, ctx->pkey)) { @@ -259,41 +294,26 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } - if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL) + if (!set_sig_algor(ctx, &msg->header->protectionAlg)) goto err; - if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest, - EVP_PKEY_id(ctx->pkey))) { - CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE); - goto err; - } - if ((alg = OBJ_nid2obj(algNID)) == NULL) + /* set senderKID to keyIdentifier of the cert according to 5.1.1 */ + if (!set_senderKID(ctx, msg, X509_get0_subject_key_id(ctx->cert))) goto err; - if (!X509_ALGOR_set0(msg->header->protectionAlg, alg, - V_ASN1_UNDEF, NULL)) { - ASN1_OBJECT_free(alg); - goto err; - } /* - * set senderKID to keyIdentifier of the used certificate according - * to section 5.1.1 + * will add ctx->cert followed, if possible, by its chain built + * from ctx->untrusted, and then ctx->extraCertsOut */ - subjKeyIDStr = X509_get0_subject_key_id(ctx->cert); - if (subjKeyIDStr == NULL) - subjKeyIDStr = ctx->referenceValue; /* fallback */ - if (subjKeyIDStr != NULL - && !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr)) - goto err; } else { CMPerr(0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION); goto err; } - if ((msg->protection = - ossl_cmp_calc_protection(msg, ctx->secretValue, ctx->pkey)) == NULL) + if (!ctx->unprotectedSend + && ((msg->protection = ossl_cmp_calc_protection(ctx, msg)) == NULL)) goto err; /* - * If present, add ctx->cert followed by its chain as far as possible. + * For signature-based protection add ctx->cert followed by its chain. * Finally add any additional certificates from ctx->extraCertsOut; * even if not needed to validate the protection * the option to do this might be handy for certain use cases. @@ -306,11 +326,10 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) * to the client it set to NULL-DN. In this case for identification at least * the senderKID must be set, where we took the referenceValue as fallback. */ - if (ossl_cmp_general_name_is_NULL_DN(msg->header->sender) - && msg->header->senderKID == NULL) - CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION); - else + if (!(ossl_cmp_general_name_is_NULL_DN(msg->header->sender) + && msg->header->senderKID == NULL)) return 1; + CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION); err: CMPerr(0, CMP_R_ERROR_PROTECTING_MESSAGE); diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c index a9a86cb5de..102fe232f2 100644 --- a/crypto/cmp/cmp_server.c +++ b/crypto/cmp/cmp_server.c @@ -19,11 +19,6 @@ #include #include -DEFINE_STACK_OF(OSSL_CRMF_MSG) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(OSSL_CMP_ITAV) -DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS) - /* the context for the generic CMP server */ struct ossl_cmp_srv_ctx_st { @@ -53,14 +48,14 @@ void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx) OPENSSL_free(srv_ctx); } -OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void) +OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) { OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX)); if (ctx == NULL) goto err; - if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL) + if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL) goto err; /* all other elements are initialized to 0 or NULL, respectively */ @@ -206,7 +201,7 @@ static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, certReqId = OSSL_CRMF_MSG_get_certReqId(crm); } - if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) { + if (!ossl_cmp_verify_popo(srv_ctx->ctx, req, srv_ctx->acceptRAVerified)) { /* Proof of possession could not be verified */ si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, 1 << OSSL_CMP_PKIFAILUREINFO_badPOP, diff --git a/crypto/cmp/cmp_status.c b/crypto/cmp/cmp_status.c index 8f10a42fb9..c9809c5a3a 100644 --- a/crypto/cmp/cmp_status.c +++ b/crypto/cmp/cmp_status.c @@ -26,8 +26,6 @@ #include #include /* for ASN1_R_TOO_SMALL and ASN1_R_TOO_LARGE */ -DEFINE_STACK_OF(ASN1_UTF8STRING) - /* CMP functions related to PKIStatus */ int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si) diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c index d1128d7e66..9a2eecd998 100644 --- a/crypto/cmp/cmp_util.c +++ b/crypto/cmp/cmp_util.c @@ -16,10 +16,6 @@ #include /* should be implied by cmperr.h */ #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_OBJECT) -DEFINE_STACK_OF(ASN1_UTF8STRING) - /* * use trace API for CMP-specific logging, prefixed by "CMP " and severity */ @@ -184,60 +180,6 @@ void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn) } } -/* - * functions manipulating lists of certificates etc. - * these functions could be generally useful. - */ - -int ossl_cmp_sk_X509_add1_cert(STACK_OF(X509) *sk, X509 *cert, - int no_dup, int prepend) -{ - if (sk == NULL) { - CMPerr(0, CMP_R_NULL_ARGUMENT); - return 0; - } - if (no_dup) { - /* - * not using sk_X509_set_cmp_func() and sk_X509_find() - * because this re-orders the certs on the stack - */ - int i; - - for (i = 0; i < sk_X509_num(sk); i++) { - if (X509_cmp(sk_X509_value(sk, i), cert) == 0) - return 1; - } - } - if (!X509_up_ref(cert)) - return 0; - if (!sk_X509_insert(sk, cert, prepend ? 0 : -1)) { - X509_free(cert); - return 0; - } - return 1; -} - -int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, - int no_self_signed, int no_dups, int prepend) -/* compiler would allow 'const' for the list of certs, yet they are up-ref'ed */ -{ - int i; - - if (sk == NULL) { - CMPerr(0, CMP_R_NULL_ARGUMENT); - return 0; - } - for (i = 0; i < sk_X509_num(certs); i++) { /* certs may be NULL */ - X509 *cert = sk_X509_value(certs, i); - - if (!no_self_signed || X509_self_signed(cert, 0) != 1) { - if (!ossl_cmp_sk_X509_add1_cert(sk, cert, no_dups, prepend)) - return 0; - } - } - return 1; -} - int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, int only_self_signed) { @@ -260,67 +202,64 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, } /*- - * Builds up the certificate chain of certs as high up as possible using - * the given list of certs containing all possible intermediate certificates and - * optionally the (possible) trust anchor(s). See also ssl_add_cert_chain(). + * Builds a certificate chain starting from + * using the optional list of intermediate CA certificates . + * If is NULL builds the chain as far down as possible, ignoring errors. + * Else the chain must reach a trust anchor contained in . * - * Intended use of this function is to find all the certificates above the trust - * anchor needed to verify an EE's own certificate. Those are supposed to be - * included in the ExtraCerts field of every first sent message of a transaction - * when MSG_SIG_ALG is utilized. + * Returns NULL on error, else a pointer to a stack of (up_ref'ed) certificates + * starting with given EE certificate and followed by all available intermediate + * certificates down towards any trust anchor but without including the latter. * - * NOTE: This allocates a stack and increments the reference count of each cert, - * so when not needed any more the stack and all its elements should be freed. - * NOTE: in case there is more than one possibility for the chain, - * OpenSSL seems to take the first one, check X509_verify_cert() for details. - * - * returns a pointer to a stack of (up_ref'ed) X509 certificates containing: - * - the EE certificate given in the function arguments (cert) - * - all intermediate certificates up the chain toward the trust anchor - * whereas the (self-signed) trust anchor is not included - * returns NULL on error + * NOTE: If a non-NULL stack is returned the caller is responsible for freeing. + * NOTE: In case there is more than one possibility for the chain, + * OpenSSL seems to take the first one; check X509_verify_cert() for details. */ -STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert) +/* TODO this should be of more general interest and thus be exported. */ +STACK_OF(X509) + *ossl_cmp_build_cert_chain(OSSL_LIB_CTX *libctx, const char *propq, + X509_STORE *store, + STACK_OF(X509) *certs, X509 *cert) { STACK_OF(X509) *chain = NULL, *result = NULL; - X509_STORE *store = X509_STORE_new(); + X509_STORE *ts = store == NULL ? X509_STORE_new() : store; X509_STORE_CTX *csc = NULL; - if (certs == NULL || cert == NULL || store == NULL) { + if (ts == NULL || cert == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); goto err; } - csc = X509_STORE_CTX_new(); - if (csc == NULL) + if ((csc = X509_STORE_CTX_new_ex(libctx, propq)) == NULL) goto err; - - if (!ossl_cmp_X509_STORE_add1_certs(store, certs, 0) - || !X509_STORE_CTX_init(csc, store, cert, NULL)) + if (store == NULL && certs != NULL + && !ossl_cmp_X509_STORE_add1_certs(ts, certs, 0)) goto err; + if (!X509_STORE_CTX_init(csc, ts, cert, + store == NULL ? NULL : certs)) + goto err; + /* disable any cert status/revocation checking etc. */ + X509_VERIFY_PARAM_clear_flags(X509_STORE_CTX_get0_param(csc), + ~(X509_V_FLAG_USE_CHECK_TIME + | X509_V_FLAG_NO_CHECK_TIME)); - (void)ERR_set_mark(); - /* - * ignore return value as it would fail without trust anchor given in store - */ - (void)X509_verify_cert(csc); - - /* don't leave any new errors in the queue */ - (void)ERR_pop_to_mark(); - + if (X509_verify_cert(csc) <= 0 && store != NULL) + goto err; chain = X509_STORE_CTX_get0_chain(csc); - /* result list to store the up_ref'ed not self-issued certificates */ + /* result list to store the up_ref'ed not self-signed certificates */ if ((result = sk_X509_new_null()) == NULL) goto err; - if (!ossl_cmp_sk_X509_add1_certs(result, chain, 1 /* no self-issued */, - 1 /* no duplicates */, 0)) { + if (!X509_add_certs(result, chain, + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_NO_SS)) { sk_X509_free(result); result = NULL; } err: - X509_STORE_free(store); + if (store == NULL) + X509_STORE_free(ts); X509_STORE_CTX_free(csc); return result; } diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c index c702b2ec16..f9981c2330 100644 --- a/crypto/cmp/cmp_vfy.c +++ b/crypto/cmp/cmp_vfy.c @@ -22,25 +22,12 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(X509) - -/*- - * Verify a message protected by signature according to section 5.1.3.3 - * (sha1+RSA/DSA or any other algorithm supported by OpenSSL). - * - * Returns 1 on successful validation and 0 otherwise. - */ +/* Verify a message protected by signature according to RFC section 5.1.3.3 */ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, const OSSL_CMP_MSG *msg, X509 *cert) { - EVP_MD_CTX *ctx = NULL; OSSL_CMP_PROTECTEDPART prot_part; - int digest_nid, pk_nid; - const EVP_MD *digest = NULL; EVP_PKEY *pubkey = NULL; - int len; - size_t prot_part_der_len = 0; - unsigned char *prot_part_der = NULL; BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */ int res = 0; @@ -60,35 +47,13 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, goto sig_err; } - /* create the DER representation of protected part */ prot_part.header = msg->header; prot_part.body = msg->body; - len = i2d_OSSL_CMP_PROTECTEDPART(&prot_part, &prot_part_der); - if (len < 0 || prot_part_der == NULL) - goto end; - prot_part_der_len = (size_t) len; - - /* verify signature of protected part */ - if (!OBJ_find_sigid_algs(ossl_cmp_hdr_get_protection_nid(msg->header), - &digest_nid, &pk_nid) - || digest_nid == NID_undef || pk_nid == NID_undef - || (digest = EVP_get_digestbynid(digest_nid)) == NULL) { - CMPerr(0, CMP_R_ALGORITHM_NOT_SUPPORTED); - goto sig_err; - } - - /* check msg->header->protectionAlg is consistent with public key type */ - if (EVP_PKEY_type(pk_nid) != EVP_PKEY_base_id(pubkey)) { - CMPerr(0, CMP_R_WRONG_ALGORITHM_OID); - goto sig_err; - } - if ((ctx = EVP_MD_CTX_new()) == NULL) - goto end; - if (EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pubkey) - && EVP_DigestVerify(ctx, msg->protection->data, - msg->protection->length, - prot_part_der, prot_part_der_len) == 1) { + if (ASN1_item_verify_ex(ASN1_ITEM_rptr(OSSL_CMP_PROTECTEDPART), + msg->header->protectionAlg, msg->protection, + &prot_part, NULL, pubkey, cmp_ctx->libctx, + cmp_ctx->propq) > 0) { res = 1; goto end; } @@ -101,8 +66,6 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, res = 0; end: - EVP_MD_CTX_free(ctx); - OPENSSL_free(prot_part_der); EVP_PKEY_free(pubkey); BIO_free(bio); @@ -110,14 +73,13 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, } /* Verify a message protected with PBMAC */ -static int verify_PBMAC(const OSSL_CMP_MSG *msg, - const ASN1_OCTET_STRING *secret) +static int verify_PBMAC(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) { ASN1_BIT_STRING *protection = NULL; int valid = 0; /* generate expected protection for the message */ - if ((protection = ossl_cmp_calc_protection(msg, secret, NULL)) == NULL) + if ((protection = ossl_cmp_calc_protection(ctx, msg)) == NULL) return 0; /* failed to generate protection string! */ valid = msg->protection != NULL && msg->protection->length >= 0 @@ -156,9 +118,9 @@ int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, return 0; } - if ((csc = X509_STORE_CTX_new()) == NULL + if ((csc = X509_STORE_CTX_new_ex(ctx->libctx, ctx->propq)) == NULL || !X509_STORE_CTX_init(csc, trusted_store, - cert, ctx->untrusted_certs)) + cert, ctx->untrusted)) goto err; valid = X509_verify_cert(csc) > 0; @@ -304,18 +266,23 @@ static int cert_acceptable(const OSSL_CMP_CTX *ctx, if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID)) return 0; + /* prevent misleading error later in case x509v3_cache_extensions() fails */ + if (!x509v3_cache_extensions(cert)) { + ossl_cmp_warn(ctx, "cert appears to be invalid"); + return 0; + } + if (!verify_signature(ctx, msg, cert)) { + ossl_cmp_warn(ctx, "msg signature verification failed"); + return 0; + } /* acceptable also if there is no senderKID in msg header */ ossl_cmp_info(ctx, " cert seems acceptable"); return 1; } -static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store, - X509 *scrt, const OSSL_CMP_MSG *msg) +static int check_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *store, + X509 *scrt) { - if (!verify_signature(ctx, msg, scrt)) { - ossl_cmp_warn(ctx, "msg signature verification failed"); - return 0; - } if (OSSL_CMP_validate_cert_path(ctx, store, scrt)) return 1; @@ -328,11 +295,11 @@ static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store, * Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security * (NDS); Authentication Framework (AF)], only to use for IP messages * and if the ctx option is explicitly set: use self-issued certificates - * from extraCerts as trust anchor to validate sender cert and msg - + * from extraCerts as trust anchor to validate sender cert - * provided it also can validate the newly enrolled certificate */ -static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt, - const OSSL_CMP_MSG *msg) +static int check_cert_path_3gpp(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, X509 *scrt) { int valid = 0; X509_STORE *store; @@ -355,11 +322,11 @@ static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt, * verify that the newly enrolled certificate (which assumed rid == * OSSL_CMP_CERTREQID) can also be validated with the same trusted store */ - EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); + EVP_PKEY *pkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1); OSSL_CMP_CERTRESPONSE *crep = ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip, OSSL_CMP_CERTREQID); - X509 *newcrt = ossl_cmp_certresponse_get1_certificate(privkey, crep); + X509 *newcrt = ossl_cmp_certresponse_get1_cert(crep, ctx, pkey); /* * maybe better use get_cert_status() from cmp_client.c, which catches * errors @@ -378,8 +345,8 @@ static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert, { return cert_acceptable(ctx, "previously validated", "sender cert", cert, NULL, NULL, msg) - && (check_msg_valid_cert(ctx, ctx->trusted, cert, msg) - || check_msg_valid_cert_3gpp(ctx, cert, msg)); + && (check_cert_path(ctx, ctx->trusted, cert) + || check_cert_path_3gpp(ctx, msg, cert)); } /*- @@ -411,8 +378,8 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, already_checked1, already_checked2, msg)) continue; n_acceptable_certs++; - if (mode_3gpp ? check_msg_valid_cert_3gpp(ctx, cert, msg) - : check_msg_valid_cert(ctx, ctx->trusted, cert, msg)) { + if (mode_3gpp ? check_cert_path_3gpp(ctx, msg, cert) + : check_cert_path(ctx, ctx->trusted, cert)) { /* store successful sender cert for further msgs in transaction */ if (!X509_up_ref(cert)) return 0; @@ -429,7 +396,7 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, } /*- - * Verify msg trying first ctx->untrusted_certs, which should include extraCerts + * Verify msg trying first ctx->untrusted, which should include extraCerts * at its front, then trying the trusted certs in truststore (if any) of ctx. * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). */ @@ -449,7 +416,7 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts", NULL, NULL, msg, mode_3gpp)) return 1; - if (check_msg_with_certs(ctx, ctx->untrusted_certs, "untrusted certs", + if (check_msg_with_certs(ctx, ctx->untrusted, "untrusted certs", msg->extraCerts, NULL, msg, mode_3gpp)) return 1; @@ -461,7 +428,7 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, ret = check_msg_with_certs(ctx, trusted, mode_3gpp ? "self-issued extraCerts" : "certs in trusted store", - msg->extraCerts, ctx->untrusted_certs, + msg->extraCerts, ctx->untrusted, msg, mode_3gpp); sk_X509_pop_free(trusted, X509_free); } @@ -567,7 +534,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) * Validate the protection of the given PKIMessage using either password- * based mac (PBM) or a signature algorithm. In the case of signature algorithm, * the sender certificate can have been pinned by providing it in ctx->srvCert, - * else it is searched in msg->extraCerts, ctx->untrusted_certs, in ctx->trusted + * else it is searched in msg->extraCerts, ctx->untrusted, in ctx->trusted * (in this order) and is path is validated against ctx->trusted. * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). * @@ -583,6 +550,7 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) { X509 *scrt; + ossl_cmp_debug(ctx, "validating CMP message"); if (ctx == NULL || msg == NULL || msg->header == NULL || msg->body == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); @@ -598,13 +566,41 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) switch (ossl_cmp_hdr_get_protection_nid(msg->header)) { /* 5.1.3.1. Shared Secret Information */ case NID_id_PasswordBasedMAC: - if (ctx->secretValue == 0) { - CMPerr(0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE); - break; + if (ctx->secretValue == NULL) { + ossl_cmp_warn(ctx, "no secret available for verifying PBM-based CMP message protection"); + return 1; } - - if (verify_PBMAC(msg, ctx->secretValue)) + if (verify_PBMAC(ctx, msg)) { + /* + * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is + * "shared secret information", then any certificate transported in + * the caPubs field may be directly trusted as a root CA + * certificate by the initiator.' + */ + switch (ossl_cmp_msg_get_bodytype(msg)) { + case -1: + return 0; + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + case OSSL_CMP_PKIBODY_CCP: + if (ctx->trusted != NULL) { + STACK_OF(X509) *certs = msg->body->value.ip->caPubs; + /* value.ip is same for cp, kup, and ccp */ + + if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0)) + /* adds both self-issued and not self-issued certs */ + return 0; + } + break; + default: + break; + } + ossl_cmp_debug(ctx, + "sucessfully validated PBM-based CMP message protection"); return 1; + } + ossl_cmp_warn(ctx, "verifying PBM-based CMP message protection failed"); break; /* @@ -621,13 +617,21 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) default: scrt = ctx->srvCert; if (scrt == NULL) { + if (ctx->trusted == NULL) { + ossl_cmp_warn(ctx, "no trust store nor pinned server cert available for verifying signature-based CMP message protection"); + return 1; + } if (check_msg_find_cert(ctx, msg)) return 1; } else { /* use pinned sender cert */ /* use ctx->srvCert for signature check even if not acceptable */ - if (verify_signature(ctx, msg, scrt)) + if (verify_signature(ctx, msg, scrt)) { + ossl_cmp_debug(ctx, + "sucessfully validated signature-based CMP message protection"); + return 1; - ossl_cmp_warn(ctx, "msg signature verification failed"); + } + ossl_cmp_warn(ctx, "CMP message signature verification failed"); CMPerr(0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG); } break; @@ -638,7 +642,7 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) /*- * Check received message (i.e., response by server or request from client) - * Any msg->extraCerts are prepended to ctx->untrusted_certs. + * Any msg->extraCerts are prepended to ctx->untrusted. * * Ensures that: * its sender is of appropriate type (curently only X509_NAME) and @@ -695,9 +699,10 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, * extraCerts because they do not belong to the protected msg part anyway. * For efficiency, the extraCerts are prepended so they get used first. */ - if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts, - 0 /* this allows self-issued certs */, - 1 /* no_dups */, 1 /* prepend */)) + if (!X509_add_certs(ctx->untrusted, msg->extraCerts, + /* this allows self-signed certs */ + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND)) return 0; /* validate message protection */ @@ -768,7 +773,19 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, /* if not yet present, learn transactionID */ if (ctx->transactionID == NULL && !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID)) - return 0; + return -1; + + /* + * Store any provided extraCerts in ctx for future use, + * such that they are available to ctx->certConf_cb and + * the peer does not need to send them again in the same transaction. + * For efficiency, the extraCerts are prepended so they get used first. + */ + if (!X509_add_certs(ctx->untrusted, msg->extraCerts, + /* this allows self-signed certs */ + X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP + | X509_ADD_FLAG_PREPEND)) + return -1; if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) { /* @@ -789,7 +806,7 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0)) /* adds both self-issued and not self-issued certs */ return 0; - } + } break; default: break; @@ -798,7 +815,8 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, return 1; } -int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified) +int ossl_cmp_verify_popo(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, int acceptRAVerified) { if (!ossl_assert(msg != NULL && msg->body != NULL)) return 0; @@ -807,7 +825,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified) { X509_REQ *req = msg->body->value.p10cr; - if (X509_REQ_verify(req, X509_REQ_get0_pubkey(req)) <= 0) { + if (X509_REQ_verify_ex(req, X509_REQ_get0_pubkey(req), ctx->libctx, + ctx->propq) <= 0) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_REQUEST_NOT_ACCEPTED); return 0; @@ -819,7 +838,8 @@ int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified) case OSSL_CMP_PKIBODY_CR: case OSSL_CMP_PKIBODY_KUR: if (!OSSL_CRMF_MSGS_verify_popo(msg->body->value.ir, OSSL_CMP_CERTREQID, - accept_RAVerified)) { + acceptRAVerified, + ctx->libctx, ctx->propq)) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION return 0; #endif diff --git a/crypto/cms/build.info b/crypto/cms/build.info index cb675436ef..c7579f78c1 100644 --- a/crypto/cms/build.info +++ b/crypto/cms/build.info @@ -2,4 +2,11 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]= \ cms_lib.c cms_asn1.c cms_att.c cms_io.c cms_smime.c cms_err.c \ cms_sd.c cms_dd.c cms_cd.c cms_env.c cms_enc.c cms_ess.c \ - cms_pwri.c cms_kari.c + cms_pwri.c cms_kari.c cms_rsa.c + +IF[{- !$disabled{dh} -}] + SOURCE[../../libcrypto]=cms_dh.c +ENDIF +IF[{- !$disabled{ec} || !$disabled{dsa}-}] + SOURCE[../../libcrypto]=cms_ec.c +ENDIF diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c index 082885dca8..72cd14317d 100644 --- a/crypto/cms/cms_asn1.c +++ b/crypto/cms/cms_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -245,6 +245,17 @@ ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = { ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1) } ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData) +/* Defined in RFC 5083 - Section 2.1. AuthEnvelopedData Type */ +ASN1_NDEF_SEQUENCE(CMS_AuthEnvelopedData) = { + ASN1_EMBED(CMS_AuthEnvelopedData, version, INT32), + ASN1_IMP_OPT(CMS_AuthEnvelopedData, originatorInfo, CMS_OriginatorInfo, 0), + ASN1_SET_OF(CMS_AuthEnvelopedData, recipientInfos, CMS_RecipientInfo), + ASN1_SIMPLE(CMS_AuthEnvelopedData, authEncryptedContentInfo, CMS_EncryptedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, authAttrs, X509_ALGOR, 2), + ASN1_SIMPLE(CMS_AuthEnvelopedData, mac, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(CMS_AuthEnvelopedData, unauthAttrs, X509_ALGOR, 3) +} ASN1_NDEF_SEQUENCE_END(CMS_AuthEnvelopedData) + ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { ASN1_EMBED(CMS_AuthenticatedData, version, INT32), ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0), @@ -273,6 +284,7 @@ ASN1_ADB(CMS_ContentInfo) = { ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)), ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)), ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)), + ADB_ENTRY(NID_id_smime_ct_authEnvelopedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authEnvelopedData, CMS_AuthEnvelopedData, 0)), ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)), ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), } ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); diff --git a/crypto/cms/cms_cd.c b/crypto/cms/cms_cd.c index ac40275b63..c806a472d5 100644 --- a/crypto/cms/cms_cd.c +++ b/crypto/cms/cms_cd.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,10 +21,12 @@ /* CMS CompressedData Utilities */ -CMS_ContentInfo *cms_CompressedData_create(int comp_nid) +CMS_ContentInfo *cms_CompressedData_create(int comp_nid, OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; CMS_CompressedData *cd; + /* * Will need something cleverer if there is ever more than one * compression algorithm or parameters have some meaning... @@ -34,7 +36,7 @@ CMS_ContentInfo *cms_CompressedData_create(int comp_nid) CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); return NULL; } - cms = CMS_ContentInfo_new(); + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) return NULL; @@ -64,6 +66,7 @@ BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms) { CMS_CompressedData *cd; const ASN1_OBJECT *compoid; + if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) { CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c index 9da26476e0..0353c2276f 100644 --- a/crypto/cms/cms_dd.c +++ b/crypto/cms/cms_dd.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,11 +17,14 @@ /* CMS DigestedData Utilities */ -CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; CMS_DigestedData *dd; - cms = CMS_ContentInfo_new(); + + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) return NULL; @@ -47,9 +50,9 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms) { - CMS_DigestedData *dd; - dd = cms->d.digestedData; - return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); + CMS_DigestedData *dd = cms->d.digestedData; + + return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm, cms_get0_cmsctx(cms)); } int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify) diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c new file mode 100644 index 0000000000..0d9eac50b3 --- /dev/null +++ b/crypto/cms/cms_dh.c @@ -0,0 +1,320 @@ +/* + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "cms_local.h" + +static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, + X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) +{ + const ASN1_OBJECT *aoid; + int atype; + const void *aval; + ASN1_INTEGER *public_key = NULL; + int rv = 0; + EVP_PKEY *pkpeer = NULL, *pk = NULL; + const unsigned char *p; + int plen; + + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) + goto err; + /* Only absent parameters allowed in RFC XXXX */ + if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) + goto err; + + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (pk == NULL || !EVP_PKEY_is_a(pk, "DHX")) + goto err; + + /* Get public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_get0_data(pubkey); + if (p == NULL || plen == 0) + goto err; + + pkpeer = EVP_PKEY_new(); + if (pkpeer == NULL + || !EVP_PKEY_copy_parameters(pkpeer, pk) + /* + * TODO(3.0): This is badly named!! Can we make this more + * generic and not TLS specific? + */ + || !EVP_PKEY_set1_tls_encodedpoint(pkpeer, p, plen)) + goto err; + + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + ASN1_INTEGER_free(public_key); + EVP_PKEY_free(pkpeer); + return rv; +} + +static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + int rv = 0; + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *dukm = NULL; + size_t dukmlen = 0; + int keylen, plen; + const EVP_CIPHER *kekcipher; + EVP_CIPHER_CTX *kekctx; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + goto err; + + /* + * For DH we only have one OID permissible. If ever any more get defined + * we will need something cleverer. + */ + if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { + CMSerr(0, CMS_R_KDF_PARAMETER_ERROR); + goto err; + } + + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0 + || EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) + goto err; + + if (alg->parameter->type != V_ASN1_SEQUENCE) + goto err; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (kekalg == NULL) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (kekctx == NULL) + goto err; + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + if (kekcipher == NULL || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_key_length(kekctx); + if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) + goto err; + /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ + if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, + OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) + <= 0) + goto err; + + if (ukm != NULL) { + dukmlen = ASN1_STRING_length(ukm); + dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); + if (dukm == NULL) + goto err; + } + + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + goto err; + dukm = NULL; + + rv = 1; + err: + X509_ALGOR_free(kekalg); + OPENSSL_free(dukm); + return rv; +} + +static int dh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + + if (pctx == NULL) + return 0; + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (alg == NULL || pubkey == NULL) + return 0; + if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { + DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR); + return 0; + } + } + /* Set DH derivation parameters and initialise unwrap context */ + if (!dh_cms_set_shared_info(pctx, ri)) { + DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR); + return 0; + } + return 1; +} + +static int dh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + const ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL, *dukm = NULL; + int penclen; + size_t dukmlen = 0; + int rv = 0; + int kdf_type, wrap_nid; + const EVP_MD *kdf_md; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pctx == NULL) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + + /* Is everything uninitialised? */ + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + if (aoid == OBJ_nid2obj(NID_undef)) { + BIGNUM *bn_pub_key = NULL; + ASN1_INTEGER *pubk; + + if (!EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, &bn_pub_key)) + goto err; + + pubk = BN_to_ASN1_INTEGER(bn_pub_key, NULL); + BN_free(bn_pub_key); + if (pubk == NULL) + goto err; + + /* Set the key */ + penclen = i2d_ASN1_INTEGER(pubk, &penc); + ASN1_INTEGER_free(pubk); + if (penclen <= 0) + goto err; + ASN1_STRING_set0(pubkey, penc, penclen); + pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), + V_ASN1_UNDEF, NULL); + } + + /* See if custom parameters set */ + kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); + if (kdf_type <= 0 || !EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) + goto err; + + if (kdf_type == EVP_PKEY_DH_KDF_NONE) { + kdf_type = EVP_PKEY_DH_KDF_X9_42; + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) + /* Unknown KDF */ + goto err; + if (kdf_md == NULL) { + /* Only SHA1 supported */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } else if (EVP_MD_type(kdf_md) != NID_sha1) + /* Unsupported digest */ + goto err; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_type(ctx); + if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) + goto err; + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (wrap_alg == NULL) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (wrap_alg->parameter == NULL) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + if (ukm != NULL) { + dukmlen = ASN1_STRING_length(ukm); + dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); + if (dukm == NULL) + goto err; + } + + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + goto err; + dukm = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penc = NULL; + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (penc == NULL || penclen == 0) + goto err; + wrap_str = ASN1_STRING_new(); + if (wrap_str == NULL) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), + V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + OPENSSL_free(penc); + X509_ALGOR_free(wrap_alg); + OPENSSL_free(dukm); + return rv; +} + +int cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt) +{ + assert(decrypt == 0 || decrypt == 1); + + if (decrypt == 1) + return dh_cms_decrypt(ri); + + if (decrypt == 0) + return dh_cms_encrypt(ri); + + CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c new file mode 100644 index 0000000000..79d603adcb --- /dev/null +++ b/crypto/cms/cms_ec.c @@ -0,0 +1,419 @@ +/* + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "cms_local.h" +#include "crypto/evp.h" + +#ifndef OPENSSL_NO_EC +static EVP_PKEY *pkey_type2param(int ptype, const void *pval, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = NULL; + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *pstr = pval; + const unsigned char *pm = pstr->data; + int pmlen = pstr->length; + OSSL_DECODER_CTX *ctx = NULL; + BIO *membio = NULL; + + /* TODO(3.0): Need to be able to specify here that only params will do */ + ctx = OSSL_DECODER_CTX_new_by_EVP_PKEY(&pkey, "DER", "EC", libctx, + propq); + if (ctx == NULL) + goto err; + + membio = BIO_new_mem_buf(pm, pmlen); + if (membio == NULL) { + OSSL_DECODER_CTX_free(ctx); + goto err; + } + OSSL_DECODER_from_bio(ctx, membio); + BIO_free(membio); + OSSL_DECODER_CTX_free(ctx); + } else if (ptype == V_ASN1_OBJECT) { + const ASN1_OBJECT *poid = pval; + const char *groupname; + + /* type == V_ASN1_OBJECT => the parameters are given by an asn1 OID */ + pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", propq); + if (pctx == NULL || EVP_PKEY_paramgen_init(pctx) <= 0) + goto err; + groupname = OBJ_nid2sn(OBJ_obj2nid(poid)); + if (groupname == NULL + || !EVP_PKEY_CTX_set_group_name(pctx, groupname)) { + CMSerr(0, CMS_R_DECODE_ERROR); + goto err; + } + if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) + goto err; + } else { + CMSerr(0, CMS_R_DECODE_ERROR); + goto err; + } + + return pkey; + + err: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(pctx); + return NULL; +} + +static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, + X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) +{ + const ASN1_OBJECT *aoid; + int atype; + const void *aval; + int rv = 0; + EVP_PKEY *pkpeer = NULL; + const unsigned char *p; + int plen; + + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) + goto err; + + /* If absent parameters get group from main key */ + if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { + EVP_PKEY *pk; + + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (pk == NULL) + goto err; + + pkpeer = EVP_PKEY_new(); + if (pkpeer == NULL) + goto err; + if (!EVP_PKEY_copy_parameters(pkpeer, pk)) + goto err; + } else { + pkpeer = pkey_type2param(atype, aval, + EVP_PKEY_CTX_get0_libctx(pctx), + EVP_PKEY_CTX_get0_propq(pctx)); + if (pkpeer == NULL) + goto err; + } + /* We have parameters now set public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_get0_data(pubkey); + if (p == NULL || plen == 0) + goto err; + + /* TODO(3.0): Terrible name. We need a non-tls specific name */ + if (!EVP_PKEY_set1_tls_encodedpoint(pkpeer, p, plen)) + goto err; + + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + EVP_PKEY_free(pkpeer); + return rv; +} + +/* Set KDF parameters based on KDF NID */ +static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) +{ + int kdf_nid, kdfmd_nid, cofactor; + const EVP_MD *kdf_md; + + if (eckdf_nid == NID_undef) + return 0; + + /* Lookup KDF type, cofactor mode and digest */ + if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) + return 0; + + if (kdf_nid == NID_dh_std_kdf) + cofactor = 0; + else if (kdf_nid == NID_dh_cofactor_kdf) + cofactor = 1; + else + return 0; + + if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) + return 0; + + kdf_md = EVP_get_digestbynid(kdfmd_nid); + if (!kdf_md) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + return 0; + return 1; +} + +static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + int rv = 0; + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *der = NULL; + int plen, keylen; + EVP_CIPHER *kekcipher = NULL; + EVP_CIPHER_CTX *kekctx; + const char *name; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + return 0; + + if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { + CMSerr(0, CMS_R_KDF_PARAMETER_ERROR); + return 0; + } + + if (alg->parameter->type != V_ASN1_SEQUENCE) + return 0; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (kekalg == NULL) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (kekctx == NULL) + goto err; + name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm)); + kekcipher = EVP_CIPHER_fetch(pctx->libctx, name, pctx->propquery); + if (kekcipher == NULL || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_key_length(kekctx); + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); + + if (plen <= 0) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) + goto err; + der = NULL; + + rv = 1; + err: + EVP_CIPHER_free(kekcipher); + X509_ALGOR_free(kekalg); + OPENSSL_free(der); + return rv; +} + +static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pctx == NULL) + return 0; + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (alg == NULL || pubkey == NULL) + return 0; + if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { + CMSerr(0, CMS_R_PEER_KEY_ERROR); + return 0; + } + } + /* Set ECDH derivation parameters and initialise unwrap context */ + if (!ecdh_cms_set_shared_info(pctx, ri)) { + CMSerr(0, CMS_R_SHARED_INFO_ERROR); + return 0; + } + return 1; +} + +static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + const ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL; + size_t penclen; + int rv = 0; + int ecdh_nid, kdf_type, kdf_nid, wrap_nid; + const EVP_MD *kdf_md; + + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pctx == NULL) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + /* Is everything uninitialised? */ + if (aoid == OBJ_nid2obj(NID_undef)) { + /* Set the key */ + + /* TODO(3.0): Terrible name. Needs a non TLS specific name */ + penclen = EVP_PKEY_get1_tls_encodedpoint(pkey, &penc); + ASN1_STRING_set0(pubkey, penc, penclen); + pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), + V_ASN1_UNDEF, NULL); + } + + /* See if custom parameters set */ + kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); + if (kdf_type <= 0) + goto err; + if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) + goto err; + ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); + if (ecdh_nid < 0) + goto err; + else if (ecdh_nid == 0) + ecdh_nid = NID_dh_std_kdf; + else if (ecdh_nid == 1) + ecdh_nid = NID_dh_cofactor_kdf; + + if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { + kdf_type = EVP_PKEY_ECDH_KDF_X9_63; + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else + /* Unknown KDF */ + goto err; + if (kdf_md == NULL) { + /* Fixme later for better MD */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Lookup NID for KDF+cofactor+digest */ + + if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) + goto err; + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_type(ctx); + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (wrap_alg == NULL) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (wrap_alg->parameter == NULL) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); + + if (penclen == 0) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) + goto err; + penc = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (penc == NULL || penclen == 0) + goto err; + wrap_str = ASN1_STRING_new(); + if (wrap_str == NULL) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + OPENSSL_free(penc); + X509_ALGOR_free(wrap_alg); + return rv; +} + +int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt) +{ + assert(decrypt == 0 || decrypt == 1); + + if (decrypt == 1) + return ecdh_cms_decrypt(ri); + + if (decrypt == 0) + return ecdh_cms_encrypt(ri); + + CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} +#endif + +/* ECDSA and DSA implementation is the same */ +int cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify) +{ + assert(verify == 0 || verify == 1); + + if (verify == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + EVP_PKEY *pkey = si->pkey; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +} diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index 3eb2f41a6a..ef87fac8ef 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -14,25 +14,28 @@ #include #include #include +#include "crypto/evp.h" #include "cms_local.h" /* CMS EncryptedData Utilities */ /* Return BIO based on EncryptedContentInfo and key */ -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, + const CMS_CTX *cms_ctx) { BIO *b; EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *ciph; + EVP_CIPHER *fetched_ciph = NULL; + const EVP_CIPHER *cipher = NULL; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + evp_cipher_aead_asn1_params aparams; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; int len; + int ivlen = 0; size_t tkeylen = 0; - int ok = 0; - int enc, keep_key = 0; enc = ec->cipher ? 1 : 0; @@ -45,42 +48,59 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) BIO_get_cipher_ctx(b, &ctx); + (void)ERR_set_mark(); if (enc) { - ciph = ec->cipher; + cipher = ec->cipher; /* * If not keeping key set cipher to NULL so subsequent calls decrypt. */ - if (ec->key) + if (ec->key != NULL) ec->cipher = NULL; } else { - ciph = EVP_get_cipherbyobj(calg->algorithm); - - if (!ciph) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); - goto err; - } + cipher = EVP_get_cipherbyobj(calg->algorithm); } + if (cipher != NULL) { + fetched_ciph = EVP_CIPHER_fetch(cms_ctx->libctx, EVP_CIPHER_name(cipher), + cms_ctx->propq); + if (fetched_ciph != NULL) + cipher = fetched_ciph; + } + if (cipher == NULL) { + (void)ERR_clear_last_mark(); + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); + goto err; + } + (void)ERR_pop_to_mark(); - if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { - int ivlen; calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(cms_ctx->libctx, iv, ivlen) <= 0) goto err; piv = iv; } - } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; + } else { + if (evp_cipher_asn1_to_param_ex(ctx, calg->parameter, &aparams) <= 0) { + CMSerr(0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + piv = aparams.iv; + if (ec->taglen > 0 + && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + ec->taglen, ec->tag) <= 0) { + CMSerr(0, CMS_R_CIPHER_AEAD_SET_TAG_ERROR); + goto err; + } + } } len = EVP_CIPHER_CTX_key_length(ctx); if (len <= 0) @@ -142,7 +162,15 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { + if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + memcpy(aparams.iv, piv, ivlen); + aparams.iv_len = ivlen; + aparams.tag_len = EVP_CIPHER_CTX_tag_length(ctx); + if (aparams.tag_len <= 0) + goto err; + } + + if (evp_cipher_param_to_asn1_ex(ctx, calg->parameter, &aparams) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; @@ -156,6 +184,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) ok = 1; err: + EVP_CIPHER_free(fetched_ciph); if (!keep_key || !ok) { OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; @@ -169,7 +198,8 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen) + const unsigned char *key, size_t keylen, + const CMS_CTX *cms_ctx) { ec->cipher = cipher; if (key) { @@ -180,7 +210,7 @@ int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, memcpy(ec->key, key, keylen); } ec->keylen = keylen; - if (cipher) + if (cipher != NULL) ec->contentType = OBJ_nid2obj(NID_pkcs7_data); return 1; } @@ -189,6 +219,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, const unsigned char *key, size_t keylen) { CMS_EncryptedContentInfo *ec; + if (!key || !keylen) { CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); return 0; @@ -206,7 +237,7 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, return 0; } ec = cms->d.encryptedData->encryptedContentInfo; - return cms_EncryptedContent_init(ec, ciph, key, keylen); + return cms_EncryptedContent_init(ec, ciph, key, keylen, cms_get0_cmsctx(cms)); } BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms) @@ -214,5 +245,6 @@ BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms) CMS_EncryptedData *enc = cms->d.encryptedData; if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) enc->version = 2; - return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); + return cms_EncryptedContent_init_bio(enc->encryptedContentInfo, + cms_get0_cmsctx(cms)); } diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index a5ef2ddee5..83826beb51 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -14,18 +14,34 @@ #include #include #include -#include "cms_local.h" #include "crypto/asn1.h" #include "crypto/evp.h" - -DEFINE_STACK_OF(CMS_RecipientInfo) -DEFINE_STACK_OF(CMS_RevocationInfoChoice) -DEFINE_STACK_OF(X509_ATTRIBUTE) +#include "crypto/x509.h" +#include "cms_local.h" /* CMS EnvelopedData Utilities */ - static void cms_env_set_version(CMS_EnvelopedData *env); +#define CMS_ENVELOPED_STANDARD 1 +#define CMS_ENVELOPED_AUTH 2 + +static int cms_get_enveloped_type(const CMS_ContentInfo *cms) +{ + int nid = OBJ_obj2nid(cms->contentType); + + switch (nid) { + case NID_pkcs7_enveloped: + return CMS_ENVELOPED_STANDARD; + + case NID_id_smime_ct_authEnvelopedData: + return CMS_ENVELOPED_AUTH; + + default: + CMSerr(0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return 0; + } +} + CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) { if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { @@ -36,11 +52,20 @@ CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) return cms->d.envelopedData; } +CMS_AuthEnvelopedData *cms_get0_auth_enveloped(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_authEnvelopedData) { + CMSerr(0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return NULL; + } + return cms->d.authEnvelopedData; +} + static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) { if (cms->d.other == NULL) { cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); - if (!cms->d.envelopedData) { + if (cms->d.envelopedData == NULL) { CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); return NULL; } @@ -54,6 +79,26 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) return cms_get0_enveloped(cms); } +static CMS_AuthEnvelopedData * +cms_auth_enveloped_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData); + if (cms->d.authEnvelopedData == NULL) { + CMSerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */ + cms->d.authEnvelopedData->version = 0; + cms->d.authEnvelopedData->authEncryptedContentInfo->contentType = + OBJ_nid2obj(NID_pkcs7_data); + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_id_smime_ct_authEnvelopedData); + return cms->d.authEnvelopedData; + } + return cms_get0_auth_enveloped(cms); +} + int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) { EVP_PKEY *pkey; @@ -70,6 +115,21 @@ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) return 0; } else return 0; + +#ifndef OPENSSL_NO_DH + if (EVP_PKEY_is_a(pkey, "DHX")) + return cms_dh_envelope(ri, cmd); + else +#endif +#ifndef OPENSSL_NO_EC + if (EVP_PKEY_is_a(pkey, "EC")) + return cms_ecdh_envelope(ri, cmd); + else +#endif + if (EVP_PKEY_is_a(pkey, "RSA")) + return cms_rsa_envelope(ri, cmd); + + /* Something else? We'll give engines etc a chance to handle this */ if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) return 1; i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); @@ -85,13 +145,63 @@ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) return 1; } +CMS_EncryptedContentInfo* cms_get0_env_enc_content(const CMS_ContentInfo *cms) +{ + switch (cms_get_enveloped_type(cms)) { + case CMS_ENVELOPED_STANDARD: + return cms->d.envelopedData->encryptedContentInfo; + + case CMS_ENVELOPED_AUTH: + return cms->d.authEnvelopedData->authEncryptedContentInfo; + + default: + return NULL; + } +} + STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) { - CMS_EnvelopedData *env; - env = cms_get0_enveloped(cms); - if (!env) + switch (cms_get_enveloped_type(cms)) { + case CMS_ENVELOPED_STANDARD: + return cms->d.envelopedData->recipientInfos; + + case CMS_ENVELOPED_AUTH: + return cms->d.authEnvelopedData->recipientInfos; + + default: return NULL; - return env->recipientInfos; + } +} + +void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms) +{ + int i; + CMS_RecipientInfo *ri; + const CMS_CTX *ctx = cms_get0_cmsctx(cms); + STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms); + + for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { + ri = sk_CMS_RecipientInfo_value(rinfos, i); + if (ri != NULL) { + switch (ri->type) { + case CMS_RECIPINFO_AGREE: + ri->d.kari->cms_ctx = ctx; + break; + case CMS_RECIPINFO_TRANS: + ri->d.ktri->cms_ctx = ctx; + x509_set0_libctx(ri->d.ktri->recip, ctx->libctx, ctx->propq); + break; + case CMS_RECIPINFO_KEK: + ri->d.kekri->cms_ctx = ctx; + break; + case CMS_RECIPINFO_PASS: + ri->d.pwri->cms_ctx = ctx; + break; + default: + break; + } + } + } } int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) @@ -108,65 +218,62 @@ EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) return NULL; } -CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) +CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; CMS_EnvelopedData *env; - cms = CMS_ContentInfo_new(); + + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) goto merr; env = cms_enveloped_data_init(cms); if (env == NULL) goto merr; - if (!cms_EncryptedContent_init(env->encryptedContentInfo, - cipher, NULL, 0)) + + if (!cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL, 0, + cms_get0_cmsctx(cms))) goto merr; return cms; merr: CMS_ContentInfo_free(cms); - CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); + CMSerr(0, ERR_R_MALLOC_FAILURE); return NULL; } -int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) { - CMS_EnvelopedData *env = NULL; - EVP_CIPHER_CTX *ctx = NULL; - BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER); - - env = cms_get0_enveloped(cms); - if (env == NULL) - return 0; - - if (mbio == NULL) { - CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CONTENT_NOT_FOUND); - return 0; - } + return CMS_EnvelopedData_create_ex(cipher, NULL, NULL); +} - BIO_get_cipher_ctx(mbio, &ctx); +CMS_ContentInfo * +CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx, + const char *propq) +{ + CMS_ContentInfo *cms; + CMS_AuthEnvelopedData *aenv; - /* - * If the selected cipher supports unprotected attributes, - * deal with it using special ctrl function - */ - if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) { - if (cms->d.envelopedData->unprotectedAttrs == NULL) - cms->d.envelopedData->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); + cms = CMS_ContentInfo_new_ex(libctx, propq); + if (cms == NULL) + goto merr; + aenv = cms_auth_enveloped_data_init(cms); + if (aenv == NULL) + goto merr; + if (!cms_EncryptedContent_init(aenv->authEncryptedContentInfo, + cipher, NULL, 0, cms_get0_cmsctx(cms))) + goto merr; + return cms; + merr: + CMS_ContentInfo_free(cms); + CMSerr(0, ERR_R_MALLOC_FAILURE); + return NULL; +} - if (cms->d.envelopedData->unprotectedAttrs == NULL) { - CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, ERR_R_MALLOC_FAILURE); - return 0; - } - if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, - 1, env->unprotectedAttrs) <= 0) { - CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CTRL_FAILURE); - return 0; - } - } - - cms_env_set_version(cms->d.envelopedData); - return 1; +CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher) +{ + return CMS_AuthEnvelopedData_create_ex(cipher, NULL, NULL); } /* Key Transport Recipient Info (KTRI) routines */ @@ -174,7 +281,8 @@ int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) /* Initialise a ktri based on passed certificate and key */ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags) + EVP_PKEY *pk, unsigned int flags, + const CMS_CTX *ctx) { CMS_KeyTransRecipientInfo *ktri; int idtype; @@ -185,6 +293,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, ri->type = CMS_RECIPINFO_TRANS; ktri = ri->d.ktri; + ktri->cms_ctx = ctx; if (flags & CMS_USE_KEYID) { ktri->version = 2; @@ -199,7 +308,7 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, * structure. */ - if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) + if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx)) return 0; X509_up_ref(recip); @@ -209,7 +318,8 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, ktri->recip = recip; if (flags & CMS_KEY_PARAM) { - ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey, + ctx->propq); if (ktri->pctx == NULL) return 0; if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) @@ -228,15 +338,17 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, X509 *originator, unsigned int flags) { CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; + STACK_OF(CMS_RecipientInfo) *ris; EVP_PKEY *pk = NULL; - env = cms_get0_enveloped(cms); - if (!env) + const CMS_CTX *ctx = cms_get0_cmsctx(cms); + + ris = CMS_get0_RecipientInfos(cms); + if (ris == NULL) goto err; /* Initialize recipient info */ ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) + if (ri == NULL) goto merr; pk = X509_get0_pubkey(recip); @@ -248,12 +360,13 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, switch (cms_pkey_get_ri_type(pk)) { case CMS_RECIPINFO_TRANS: - if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) + if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx)) goto err; break; case CMS_RECIPINFO_AGREE: - if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, originatorPrivKey, flags)) + if (!cms_RecipientInfo_kari_init(ri, recip, pk, originator, + originatorPrivKey, flags, ctx)) goto err; break; @@ -264,7 +377,7 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, } - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + if (!sk_CMS_RecipientInfo_push(ris, ri)) goto merr; return ri; @@ -277,8 +390,8 @@ CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, } -CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - X509 *recip, unsigned int flags) +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, + unsigned int flags) { return CMS_add1_recipient(cms, recip, NULL, NULL, flags); } @@ -352,6 +465,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, EVP_PKEY_CTX *pctx; unsigned char *ek = NULL; size_t eklen; + const CMS_CTX *ctx = cms_get0_cmsctx(cms); int ret = 0; @@ -360,7 +474,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, return 0; } ktri = ri->d.ktri; - ec = cms->d.envelopedData->encryptedContentInfo; + ec = cms_get0_env_enc_content(cms); pctx = ktri->pctx; @@ -368,7 +482,7 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, if (!cms_env_asn1_ctrl(ri, 0)) goto err; } else { - pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ktri->pkey, ctx->propq); if (pctx == NULL) return 0; @@ -405,7 +519,6 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, ktri->pctx = NULL; OPENSSL_free(ek); return ret; - } /* Decrypt content key from KTRI */ @@ -419,8 +532,12 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, size_t eklen; int ret = 0; size_t fixlen = 0; + const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *fetched_cipher = NULL; CMS_EncryptedContentInfo *ec; - ec = cms->d.envelopedData->encryptedContentInfo; + const CMS_CTX *ctx = cms_get0_cmsctx(cms); + + ec = cms_get0_env_enc_content(cms); if (ktri->pkey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); @@ -430,19 +547,29 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, if (cms->d.envelopedData->encryptedContentInfo->havenocert && !cms->d.envelopedData->encryptedContentInfo->debug) { X509_ALGOR *calg = ec->contentEncryptionAlgorithm; - const EVP_CIPHER *ciph = EVP_get_cipherbyobj(calg->algorithm); + const char *name = OBJ_nid2sn(OBJ_obj2nid(calg->algorithm)); + + (void)ERR_set_mark(); + fetched_cipher = EVP_CIPHER_fetch(ctx->libctx, name, ctx->propq); - if (ciph == NULL) { + if (fetched_cipher != NULL) + cipher = fetched_cipher; + else + cipher = EVP_get_cipherbyobj(calg->algorithm); + if (cipher == NULL) { + (void)ERR_clear_last_mark(); CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_UNKNOWN_CIPHER); return 0; } + (void)ERR_pop_to_mark(); - fixlen = EVP_CIPHER_key_length(ciph); + fixlen = EVP_CIPHER_key_length(cipher); + EVP_CIPHER_free(fetched_cipher); } - ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); + ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq); if (ktri->pctx == NULL) - return 0; + goto err; if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) goto err; @@ -462,7 +589,6 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, goto err; ek = OPENSSL_malloc(eklen); - if (ek == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; @@ -538,10 +664,10 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, ASN1_TYPE *otherType) { CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; CMS_KEKRecipientInfo *kekri; - env = cms_get0_enveloped(cms); - if (!env) + STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms); + + if (ris == NULL) goto err; if (nid == NID_undef) { @@ -598,7 +724,7 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, goto merr; } - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + if (!sk_CMS_RecipientInfo_push(ris, ri)) goto merr; /* After this point no calls can fail */ @@ -627,7 +753,6 @@ CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, err: M_ASN1_free_of(ri, CMS_RecipientInfo); return NULL; - } int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, @@ -679,20 +804,24 @@ int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, return 1; } -static const EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen) +static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx) { + const char *alg = NULL; + switch(keylen) { case 16: - return EVP_aes_128_wrap(); - + alg = "AES-128-WRAP"; + break; case 24: - return EVP_aes_192_wrap(); - + alg = "AES-192-WRAP"; + break; case 32: - return EVP_aes_256_wrap(); + alg = "AES-256-WRAP"; + break; + default: + return NULL; } - - return NULL; + return EVP_CIPHER_fetch(ctx->libctx, alg, ctx->propq); } @@ -706,11 +835,14 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, unsigned char *wkey = NULL; int wkeylen; int r = 0; - const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *cipher = NULL; int outlen = 0; EVP_CIPHER_CTX *ctx = NULL; + const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms); - ec = cms->d.envelopedData->encryptedContentInfo; + ec = cms_get0_env_enc_content(cms); + if (ec == NULL) + return 0; kekri = ri->d.kekri; @@ -719,7 +851,7 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, return 0; } - cipher = cms_get_key_wrap_cipher(kekri->keylen); + cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx); if (cipher == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_INVALID_KEY_LENGTH); goto err; @@ -756,12 +888,12 @@ static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms, r = 1; err: + EVP_CIPHER_free(cipher); if (!r) OPENSSL_free(wkey); EVP_CIPHER_CTX_free(ctx); return r; - } /* Decrypt content key in KEK recipient info */ @@ -774,11 +906,14 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, unsigned char *ukey = NULL; int ukeylen; int r = 0, wrap_nid; - const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *cipher = NULL; int outlen = 0; EVP_CIPHER_CTX *ctx = NULL; + const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms); - ec = cms->d.envelopedData->encryptedContentInfo; + ec = cms_get0_env_enc_content(cms); + if (ec == NULL) + return 0; kekri = ri->d.kekri; @@ -802,7 +937,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, goto err; } - cipher = cms_get_key_wrap_cipher(kekri->keylen); + cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx); if (cipher == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH); goto err; @@ -836,12 +971,12 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, r = 1; err: + EVP_CIPHER_free(cipher); if (!r) OPENSSL_free(ukey); EVP_CIPHER_CTX_free(ctx); return r; - } int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) @@ -948,10 +1083,32 @@ static void cms_env_set_version(CMS_EnvelopedData *env) env->version = 0; } +static int cms_env_encrypt_content_key(const CMS_ContentInfo *cms, + STACK_OF(CMS_RecipientInfo) *ris) +{ + int i; + CMS_RecipientInfo *ri; + + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) + return -1; + } + return 1; +} + +static void cms_env_clear_ec(CMS_EncryptedContentInfo *ec) +{ + ec->cipher = NULL; + OPENSSL_clear_free(ec->key, ec->keylen); + ec->key = NULL; + ec->keylen = 0; +} + static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) { CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo; - BIO *contentBio = cms_EncryptedContent_init_bio(ec); + BIO *contentBio = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms)); EVP_CIPHER_CTX *ctx = NULL; if (contentBio == NULL) @@ -962,10 +1119,10 @@ static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms) BIO_free(contentBio); return NULL; } -/* - * If the selected cipher supports unprotected attributes, - * deal with it using special ctrl function - */ + /* + * If the selected cipher supports unprotected attributes, + * deal with it using special ctrl function + */ if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0, cms->d.envelopedData->unprotectedAttrs) <= 0) { @@ -979,38 +1136,34 @@ static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms) { CMS_EncryptedContentInfo *ec; STACK_OF(CMS_RecipientInfo) *rinfos; - CMS_RecipientInfo *ri; - int i, ok = 0; + int ok = 0; BIO *ret; + CMS_EnvelopedData *env = cms->d.envelopedData; /* Get BIO first to set up key */ - ec = cms->d.envelopedData->encryptedContentInfo; - ret = cms_EncryptedContent_init_bio(ec); + ec = env->encryptedContentInfo; + ret = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms)); /* If error end of processing */ if (!ret) return ret; /* Now encrypt content key according to each RecipientInfo type */ - rinfos = cms->d.envelopedData->recipientInfos; - - for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { - ri = sk_CMS_RecipientInfo_value(rinfos, i); - if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { - CMSerr(0, CMS_R_ERROR_SETTING_RECIPIENTINFO); - goto err; - } + rinfos = env->recipientInfos; + if (cms_env_encrypt_content_key(cms, rinfos) < 0) { + CMSerr(CMS_F_CMS_ENVELOPEDDATA_ENCRYPTION_INIT_BIO, + CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; } - cms_env_set_version(cms->d.envelopedData); + + /* And finally set the version */ + cms_env_set_version(env); ok = 1; err: - ec->cipher = NULL; - OPENSSL_clear_free(ec->key, ec->keylen); - ec->key = NULL; - ec->keylen = 0; + cms_env_clear_ec(ec); if (ok) return ret; BIO_free(ret); @@ -1028,6 +1181,121 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) return cms_EnvelopedData_Decryption_init_bio(cms); } +BIO *cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedContentInfo *ec; + STACK_OF(CMS_RecipientInfo) *rinfos; + int ok = 0; + BIO *ret; + CMS_AuthEnvelopedData *aenv = cms->d.authEnvelopedData; + + /* Get BIO first to set up key */ + ec = aenv->authEncryptedContentInfo; + /* Set tag for decryption */ + if (ec->cipher == NULL) { + ec->tag = aenv->mac->data; + ec->taglen = aenv->mac->length; + } + ret = cms_EncryptedContent_init_bio(ec, cms_get0_cmsctx(cms)); + + /* If error or no cipher end of processing */ + if (ret == NULL || ec->cipher == NULL) + return ret; + + /* Now encrypt content key according to each RecipientInfo type */ + rinfos = aenv->recipientInfos; + if (cms_env_encrypt_content_key(cms, rinfos) < 0) { + CMSerr(0, CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; + } + + /* And finally set the version */ + aenv->version = 0; + + ok = 1; + + err: + cms_env_clear_ec(ec); + if (ok) + return ret; + BIO_free(ret); + return NULL; +} + +int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain) +{ + CMS_EnvelopedData *env = NULL; + EVP_CIPHER_CTX *ctx = NULL; + BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER); + + env = cms_get0_enveloped(cms); + if (env == NULL) + return 0; + + if (mbio == NULL) { + CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CONTENT_NOT_FOUND); + return 0; + } + + BIO_get_cipher_ctx(mbio, &ctx); + + /* + * If the selected cipher supports unprotected attributes, + * deal with it using special ctrl function + */ + if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) { + if (env->unprotectedAttrs == NULL) + env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null(); + + if (env->unprotectedAttrs == NULL) { + CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, + 1, env->unprotectedAttrs) <= 0) { + CMSerr(CMS_F_CMS_ENVELOPEDDATA_FINAL, CMS_R_CTRL_FAILURE); + return 0; + } + } + + cms_env_set_version(cms->d.envelopedData); + return 1; +} + +int cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio) +{ + EVP_CIPHER_CTX *ctx; + unsigned char *tag = NULL; + int taglen, ok = 0; + + BIO_get_cipher_ctx(cmsbio, &ctx); + + /* + * The tag is set only for encryption. There is nothing to do for + * decryption. + */ + if (!EVP_CIPHER_CTX_encrypting(ctx)) + return 1; + + taglen = EVP_CIPHER_CTX_tag_length(ctx); + if (taglen <= 0 + || (tag = OPENSSL_malloc(taglen)) == NULL + || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, + tag) <= 0) { + CMSerr(0, CMS_R_CIPHER_GET_TAG); + goto err; + } + + if (!ASN1_OCTET_STRING_set(cms->d.authEnvelopedData->mac, tag, taglen)) + goto err; + + ok = 1; +err: + OPENSSL_free(tag); + return ok; +} + /* * Get RecipientInfo type (if any) supported by a key (public or private). To * retain compatibility with previous behaviour if the ctrl value isn't @@ -1035,6 +1303,20 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) */ int cms_pkey_get_ri_type(EVP_PKEY *pk) { + /* Check types that we know about */ + if (EVP_PKEY_is_a(pk, "DH")) + return CMS_RECIPINFO_AGREE; + else if (EVP_PKEY_is_a(pk, "DSA")) + return CMS_RECIPINFO_NONE; + else if (EVP_PKEY_is_a(pk, "EC")) + return CMS_RECIPINFO_AGREE; + else if (EVP_PKEY_is_a(pk, "RSA")) + return CMS_RECIPINFO_TRANS; + + /* + * Otherwise this might ben an engine implementation, so see if we can get + * the type from the ameth. + */ if (pk->ameth && pk->ameth->pkey_ctrl) { int i, r; i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); @@ -1051,7 +1333,8 @@ int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type) if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) { int i, r; - i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, ri_type, &r); + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED, + ri_type, &r); if (i > 0) return r; } diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index 16e25afc7f..fdb2b7f5c8 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -22,6 +22,9 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "certificate has no keyid"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_SET_TAG_ERROR), + "cipher aead set tag error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_GET_TAG), "cipher get tag"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_INITIALISATION_ERROR), "cipher initialisation error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), @@ -44,6 +47,7 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "content verify error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECODE_ERROR), "decode error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"}, @@ -61,6 +65,11 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), "invalid key encryption parameter"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_LABEL), "invalid label"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_OAEP_PARAMETERS), + "invalid oaep parameters"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_KDF_PARAMETER_ERROR), + "kdf parameter error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), "messagedigest attribute wrong length"}, @@ -99,11 +108,13 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SHARED_INFO_ERROR), "shared info error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error"}, @@ -128,10 +139,14 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { "unsupported compression algorithm"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE), + "unsupported encryption type"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM), "unsupported kek algorithm"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), "unsupported key encryption algorithm"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_LABEL_SOURCE), + "unsupported label source"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE), "unsupported recipientinfo type"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE), diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index e3604f7db8..287bcf86c0 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -15,15 +15,10 @@ #include #include #include -#include "cms_local.h" #include "crypto/ess.h" #include "crypto/cms.h" - -DEFINE_STACK_OF(GENERAL_NAMES) -DEFINE_STACK_OF(CMS_SignerInfo) -DEFINE_STACK_OF(ESS_CERT_ID) -DEFINE_STACK_OF(ESS_CERT_ID_V2) -DEFINE_STACK_OF(X509) +#include "crypto/x509.h" +#include "cms_local.h" IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) @@ -119,11 +114,10 @@ int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain) return ret; } -CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, - int allorfirst, - STACK_OF(GENERAL_NAMES) - *receiptList, STACK_OF(GENERAL_NAMES) - *receiptsTo) +CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo, + OSSL_LIB_CTX *libctx, const char *propq) { CMS_ReceiptRequest *rr; @@ -135,14 +129,14 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, else { if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) goto merr; - if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0) + if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32) <= 0) goto err; } sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); rr->receiptsTo = receiptsTo; - if (receiptList) { + if (receiptList != NULL) { rr->receiptsFrom->type = 1; rr->receiptsFrom->d.receiptList = receiptList; } else { @@ -153,7 +147,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, return rr; merr: - CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); + CMSerr(0, ERR_R_MALLOC_FAILURE); err: CMS_ReceiptRequest_free(rr); @@ -161,6 +155,14 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, } +CMS_ReceiptRequest *CMS_ReceiptRequest_create0( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo) +{ + return CMS_ReceiptRequest_create0_ex(id, idlen, allorfirst, receiptList, + receiptsTo, NULL, NULL); +} + int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) { unsigned char *rrder = NULL; @@ -192,20 +194,20 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, STACK_OF(GENERAL_NAMES) **plist, STACK_OF(GENERAL_NAMES) **prto) { - if (pcid) + if (pcid != NULL) *pcid = rr->signedContentIdentifier; if (rr->receiptsFrom->type == 0) { - if (pallorfirst) + if (pallorfirst != NULL) *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; - if (plist) + if (plist != NULL) *plist = NULL; } else { - if (pallorfirst) + if (pallorfirst != NULL) *pallorfirst = -1; - if (plist) + if (plist != NULL) *plist = rr->receiptsFrom->d.receiptList; } - if (prto) + if (prto != NULL) *prto = rr->receiptsTo; } @@ -214,13 +216,13 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, static int cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen) { - const EVP_MD *md; + const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); if (md == NULL) return 0; - if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, - si->signedAttrs, dig, diglen)) + if (!asn1_item_digest_ex(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, + si->signedAttrs, dig, diglen, si->cms_ctx->libctx, + si->cms_ctx->propq)) return 0; return 1; } @@ -421,12 +423,12 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc) { ASN1_STRING *seq = NULL; - unsigned char *p, *pp; + unsigned char *p, *pp = NULL; int len; /* Add SigningCertificateV2 signed attribute to the signer info. */ len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); - if ((pp = OPENSSL_malloc(len)) == NULL) + if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL) goto err; p = pp; i2d_ESS_SIGNING_CERT_V2(sc, &p); @@ -453,12 +455,12 @@ int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc) int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc) { ASN1_STRING *seq = NULL; - unsigned char *p, *pp; + unsigned char *p, *pp = NULL; int len; /* Add SigningCertificate signed attribute to the signer info. */ len = i2d_ESS_SIGNING_CERT(sc, NULL); - if ((pp = OPENSSL_malloc(len)) == NULL) + if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL) goto err; p = pp; i2d_ESS_SIGNING_CERT(sc, &p); diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c index ef72164181..9b62e4874f 100644 --- a/crypto/cms/cms_io.c +++ b/crypto/cms/cms_io.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -35,7 +35,12 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); + CMS_ContentInfo *ci; + + ci = ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); + if (ci != NULL && cms != NULL) + cms_resolve_libctx(ci); + return ci; } int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) @@ -71,19 +76,33 @@ int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) STACK_OF(X509_ALGOR) *mdalgs; int ctype_nid = OBJ_obj2nid(cms->contentType); int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); + const CMS_CTX *ctx = cms_get0_cmsctx(cms); + if (ctype_nid == NID_pkcs7_signed) mdalgs = cms->d.signedData->digestAlgorithms; else mdalgs = NULL; - return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, - ctype_nid, econt_nid, mdalgs, - ASN1_ITEM_rptr(CMS_ContentInfo)); + return SMIME_write_ASN1_ex(bio, (ASN1_VALUE *)cms, data, flags, ctype_nid, + econt_nid, mdalgs, + ASN1_ITEM_rptr(CMS_ContentInfo), + cms_ctx_get0_libctx(ctx), + cms_ctx_get0_propq(ctx)); +} + +CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **cms) +{ + CMS_ContentInfo *ci; + + ci = (CMS_ContentInfo *)SMIME_read_ASN1_ex(bio, bcont, + ASN1_ITEM_rptr(CMS_ContentInfo), + (ASN1_VALUE **)cms); + if (ci != NULL && cms != NULL) + cms_resolve_libctx(ci); + return ci; } CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) { - return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, - ASN1_ITEM_rptr - (CMS_ContentInfo)); + return SMIME_read_CMS_ex(bio, bcont, NULL); } diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c index 30d38b5fd6..13f7e78d37 100644 --- a/crypto/cms/cms_kari.c +++ b/crypto/cms/cms_kari.c @@ -23,8 +23,6 @@ #include "cms_local.h" #include "crypto/asn1.h" -DEFINE_STACK_OF(CMS_RecipientEncryptedKey) - /* Key Agreement Recipient Info (KARI) routines */ int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, @@ -64,6 +62,7 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, ASN1_INTEGER **sno) { CMS_OriginatorIdentifierOrKey *oik; + if (ri->type != CMS_RECIPINFO_AGREE) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, CMS_R_NOT_KEY_AGREEMENT); @@ -101,6 +100,7 @@ int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) { CMS_OriginatorIdentifierOrKey *oik; + if (ri->type != CMS_RECIPINFO_AGREE) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, CMS_R_NOT_KEY_AGREEMENT); @@ -121,6 +121,7 @@ int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, X509_NAME **issuer, ASN1_INTEGER **sno) { CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + if (rid->type == CMS_REK_ISSUER_SERIAL) { if (issuer) *issuer = rid->d.issuerAndSerialNumber->issuer; @@ -152,6 +153,7 @@ int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, X509 *cert) { CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + if (rid->type == CMS_REK_ISSUER_SERIAL) return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); else if (rid->type == CMS_REK_KEYIDENTIFIER) @@ -170,7 +172,8 @@ int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri, EVP_PKEY *p if (pk == NULL) return 1; - pctx = EVP_PKEY_CTX_new(pk, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(kari->cms_ctx->libctx, pk, + kari->cms_ctx->propq); if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0) goto err; @@ -215,6 +218,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, int rv = 0; unsigned char *out = NULL; int outlen; + keklen = EVP_CIPHER_CTX_key_length(kari->ctx); if (keklen > EVP_MAX_KEY_LENGTH) return 0; @@ -257,26 +261,6 @@ int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, size_t ceklen; CMS_EncryptedContentInfo *ec; - { - /* - * TODO(3.0) Remove this when we have functionality to deserialize - * parameters in EVP_PKEY form from an X509_ALGOR. - * This is needed to be able to replace the EC_KEY specific decoding - * that happens in ecdh_cms_set_peerkey() (crypto/ec/ec_ameth.c) - * - * THIS IS TEMPORARY - */ - EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - - EVP_PKEY_get0(pkey); - if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - } - } - enckeylen = rek->encryptedKey->length; enckey = rek->encryptedKey->data; /* Setup all parameters to derive KEK */ @@ -285,7 +269,7 @@ int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, /* Attempt to decrypt CEK */ if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) goto err; - ec = cms->d.envelopedData->encryptedContentInfo; + ec = cms_get0_env_enc_content(cms); OPENSSL_clear_free(ec->key, ec->keylen); ec->key = cek; ec->keylen = ceklen; @@ -303,8 +287,9 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY_CTX *pctx = NULL; EVP_PKEY *ekey = NULL; int rv = 0; + const CMS_CTX *ctx = kari->cms_ctx; - pctx = EVP_PKEY_CTX_new(pk, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pk, ctx->propq); if (pctx == NULL) goto err; if (EVP_PKEY_keygen_init(pctx) <= 0) @@ -312,7 +297,7 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, if (EVP_PKEY_keygen(pctx, &ekey) <= 0) goto err; EVP_PKEY_CTX_free(pctx); - pctx = EVP_PKEY_CTX_new(ekey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, ekey, ctx->propq); if (pctx == NULL) goto err; if (EVP_PKEY_derive_init(pctx) <= 0) @@ -327,12 +312,14 @@ static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, } /* Set originator private key and initialise context based on it */ -static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari, EVP_PKEY *originatorPrivKey ) +static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari, + EVP_PKEY *originatorPrivKey ) { EVP_PKEY_CTX *pctx = NULL; int rv = 0; + const CMS_CTX *ctx = kari->cms_ctx; - pctx = EVP_PKEY_CTX_new(originatorPrivKey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, originatorPrivKey, ctx->propq); if (pctx == NULL) goto err; if (EVP_PKEY_derive_init(pctx) <= 0) @@ -348,18 +335,22 @@ static int cms_kari_set_originator_private_key(CMS_KeyAgreeRecipientInfo *kari, /* Initialise a kari based on passed certificate and key */ -int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *recipPubKey, X509 * originator, EVP_PKEY *originatorPrivKey, unsigned int flags) +int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *recipPubKey, X509 *originator, + EVP_PKEY *originatorPrivKey, unsigned int flags, + const CMS_CTX *ctx) { CMS_KeyAgreeRecipientInfo *kari; CMS_RecipientEncryptedKey *rek = NULL; ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo); - if (!ri->d.kari) + if (ri->d.kari == NULL) return 0; ri->type = CMS_RECIPINFO_AGREE; kari = ri->d.kari; kari->version = 3; + kari->cms_ctx = ctx; rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); if (rek == NULL) @@ -419,8 +410,11 @@ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *r static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, const EVP_CIPHER *cipher) { + const CMS_CTX *cms_ctx = kari->cms_ctx; EVP_CIPHER_CTX *ctx = kari->ctx; const EVP_CIPHER *kekcipher; + EVP_CIPHER *fetched_kekcipher; + const char *kekcipher_name; int keylen; int ret; @@ -444,8 +438,8 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, if (kekcipher != NULL) { if (EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) return 0; - - return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); + kekcipher_name = EVP_CIPHER_name(kekcipher); + goto enc; } } @@ -455,16 +449,23 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, */ #ifndef OPENSSL_NO_DES if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) - kekcipher = EVP_des_ede3_wrap(); + kekcipher_name = SN_id_smime_alg_CMS3DESwrap; else #endif if (keylen <= 16) - kekcipher = EVP_aes_128_wrap(); + kekcipher_name = SN_id_aes128_wrap; else if (keylen <= 24) - kekcipher = EVP_aes_192_wrap(); + kekcipher_name = SN_id_aes192_wrap; else - kekcipher = EVP_aes_256_wrap(); - return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); + kekcipher_name = SN_id_aes256_wrap; +enc: + fetched_kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, kekcipher_name, + cms_ctx->propq); + if (fetched_kekcipher == NULL) + return 0; + ret = EVP_EncryptInit_ex(ctx, fetched_kekcipher, NULL, NULL, NULL); + EVP_CIPHER_free(fetched_kekcipher); + return ret; } /* Encrypt content key in key agreement recipient info */ @@ -478,39 +479,13 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms, STACK_OF(CMS_RecipientEncryptedKey) *reks; int i; - { - /* - * TODO(3.0) Remove this when we have figured out all the details - * need to set up encryption right. With legacy keys, a *lot* is - * happening in the CMS specific EVP_PKEY_ASN1_METHOD functions, - * such as automatically setting a default KDF type, KDF digest, - * all that kind of stuff. - * With EVP_SIGNATURE, setting a default digest is done by getting - * the default MD for the key, and then inject that back into the - * signature implementation... we could do something similar with - * CMS, possibly using CMS specific OSSL_PARAM keys, just like we - * have for certain AlgorithmIdentifier retrievals. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - - EVP_PKEY_get0(pkey); - if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - return 0; - } - } - if (ri->type != CMS_RECIPINFO_AGREE) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT); return 0; } kari = ri->d.kari; reks = kari->recipientEncryptedKeys; - ec = cms->d.envelopedData->encryptedContentInfo; + ec = cms_get0_env_enc_content(cms); /* Initialise wrap algorithm parameters */ if (!cms_wrap_init(kari, ec->cipher)) return 0; @@ -542,5 +517,4 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms, } return 1; - } diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c index 6e2a20c4b3..6713c8674a 100644 --- a/crypto/cms/cms_lib.c +++ b/crypto/cms/cms_lib.c @@ -14,24 +14,113 @@ #include #include #include +#include +#include "crypto/x509.h" #include "cms_local.h" -DEFINE_STACK_OF(CMS_RevocationInfoChoice) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) +static STACK_OF(CMS_CertificateChoices) +**cms_get0_certificate_choices(CMS_ContentInfo *cms); -IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) +CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, + const unsigned char **in, long len) +{ + CMS_ContentInfo *ci; + + ci = (CMS_ContentInfo *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, + (CMS_ContentInfo_it())); + if (ci != NULL && a != NULL) + cms_resolve_libctx(ci); + return ci; +} + +int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out) +{ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it())); +} + +CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + CMS_ContentInfo *ci; + + ci = (CMS_ContentInfo *)ASN1_item_new(ASN1_ITEM_rptr(CMS_ContentInfo)); + if (ci != NULL) { + ci->ctx.libctx = libctx; + ci->ctx.propq = NULL; + if (propq != NULL) { + ci->ctx.propq = OPENSSL_strdup(propq); + if (ci->ctx.propq == NULL) { + CMS_ContentInfo_free(ci); + ci = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } + } + } + return ci; +} + +CMS_ContentInfo *CMS_ContentInfo_new(void) +{ + return CMS_ContentInfo_new_ex(NULL, NULL); +} + +void CMS_ContentInfo_free(CMS_ContentInfo *cms) +{ + if (cms != NULL) { + OPENSSL_free(cms->ctx.propq); + ASN1_item_free((ASN1_VALUE *)cms, ASN1_ITEM_rptr(CMS_ContentInfo)); + } +} + +const CMS_CTX *cms_get0_cmsctx(const CMS_ContentInfo *cms) +{ + return cms != NULL ? &cms->ctx : NULL; +} + +OSSL_LIB_CTX *cms_ctx_get0_libctx(const CMS_CTX *ctx) +{ + return ctx->libctx; +} + +const char *cms_ctx_get0_propq(const CMS_CTX *ctx) +{ + return ctx->propq; +} + +void cms_resolve_libctx(CMS_ContentInfo *ci) +{ + int i; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + const CMS_CTX *ctx; + + if (ci == NULL) + return; + + ctx = cms_get0_cmsctx(ci); + cms_SignerInfos_set_cmsctx(ci); + cms_RecipientInfos_set_cmsctx(ci); + + pcerts = cms_get0_certificate_choices(ci); + if (pcerts != NULL) { + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == CMS_CERTCHOICE_CERT) + x509_set0_libctx(cch->d.certificate, ctx->libctx, ctx->propq); + } + } +} + const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms) { return cms->contentType; } -CMS_ContentInfo *cms_Data_create(void) +CMS_ContentInfo *cms_Data_create(OSSL_LIB_CTX *libctx, const char *propq) { - CMS_ContentInfo *cms; - cms = CMS_ContentInfo_new(); + CMS_ContentInfo *cms = CMS_ContentInfo_new_ex(libctx, propq); + if (cms != NULL) { cms->contentType = OBJ_nid2obj(NID_pkcs7_data); /* Never detached */ @@ -95,6 +184,10 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) cmsbio = cms_EnvelopedData_init_bio(cms); break; + case NID_id_smime_ct_authEnvelopedData: + cmsbio = cms_AuthEnvelopedData_init_bio(cms); + break; + default: CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); goto err; @@ -145,6 +238,9 @@ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) case NID_pkcs7_enveloped: return cms_EnvelopedData_final(cms, cmsbio); + case NID_id_smime_ct_authEnvelopedData: + return cms_AuthEnvelopedData_final(cms, cmsbio); + case NID_pkcs7_signed: return cms_SignedData_final(cms, cmsbio); @@ -181,6 +277,10 @@ ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) case NID_pkcs7_encrypted: return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; + case NID_id_smime_ct_authEnvelopedData: + return &cms->d.authEnvelopedData->authEncryptedContentInfo + ->encryptedContent; + case NID_id_smime_ct_authData: return &cms->d.authenticatedData->encapContentInfo->eContent; @@ -217,6 +317,9 @@ static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) case NID_pkcs7_encrypted: return &cms->d.encryptedData->encryptedContentInfo->contentType; + case NID_id_smime_ct_authEnvelopedData: + return &cms->d.authEnvelopedData->authEncryptedContentInfo + ->contentType; case NID_id_smime_ct_authData: return &cms->d.authenticatedData->encapContentInfo->eContentType; @@ -295,25 +398,42 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached) /* Create a digest BIO from an X509_ALGOR structure */ -BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm, + const CMS_CTX *ctx) { BIO *mdbio = NULL; const ASN1_OBJECT *digestoid; - const EVP_MD *digest; + const EVP_MD *digest = NULL; + EVP_MD *fetched_digest = NULL; + const char *alg; + X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); - digest = EVP_get_digestbyobj(digestoid); - if (!digest) { + alg = OBJ_nid2sn(OBJ_obj2nid(digestoid)); + + (void)ERR_set_mark(); + fetched_digest = EVP_MD_fetch(ctx->libctx, alg, ctx->propq); + + if (fetched_digest != NULL) + digest = fetched_digest; + else + digest = EVP_get_digestbyobj(digestoid); + if (digest == NULL) { + (void)ERR_clear_last_mark(); CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_UNKNOWN_DIGEST_ALGORITHM); goto err; } + (void)ERR_pop_to_mark(); + mdbio = BIO_new(BIO_f_md()); if (mdbio == NULL || !BIO_set_md(mdbio, digest)) { CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); goto err; } + EVP_MD_free(fetched_digest); return mdbio; err: + EVP_MD_free(fetched_digest); BIO_free(mdbio); return NULL; } @@ -361,6 +481,11 @@ static STACK_OF(CMS_CertificateChoices) return NULL; return &cms->d.envelopedData->originatorInfo->certificates; + case NID_id_smime_ct_authEnvelopedData: + if (cms->d.authEnvelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.authEnvelopedData->originatorInfo->certificates; + default: CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, CMS_R_UNSUPPORTED_CONTENT_TYPE); @@ -440,6 +565,11 @@ static STACK_OF(CMS_RevocationInfoChoice) return NULL; return &cms->d.envelopedData->originatorInfo->crls; + case NID_id_smime_ct_authEnvelopedData: + if (cms->d.authEnvelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.authEnvelopedData->originatorInfo->crls; + default: CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, CMS_R_UNSUPPORTED_CONTENT_TYPE); @@ -503,16 +633,11 @@ STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { cch = sk_CMS_CertificateChoices_value(*pcerts, i); if (cch->type == 0) { - if (!certs) { - certs = sk_X509_new_null(); - if (!certs) - return NULL; - } - if (!sk_X509_push(certs, cch->d.certificate)) { + if (!X509_add_cert_new(&certs, cch->d.certificate, + X509_ADD_FLAG_UP_REF)) { sk_X509_pop_free(certs, X509_free); return NULL; } - X509_up_ref(cch->d.certificate); } } return certs; diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index 68c885622b..3dfeb72689 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -29,6 +29,7 @@ typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; typedef struct CMS_DigestedData_st CMS_DigestedData; typedef struct CMS_EncryptedData_st CMS_EncryptedData; typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; +typedef struct CMS_AuthEnvelopedData_st CMS_AuthEnvelopedData; typedef struct CMS_CompressedData_st CMS_CompressedData; typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; @@ -43,6 +44,12 @@ typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; +typedef struct CMS_CTX_st CMS_CTX; + +struct CMS_CTX_st { + OSSL_LIB_CTX *libctx; + char *propq; +}; struct CMS_ContentInfo_st { ASN1_OBJECT *contentType; @@ -52,12 +59,14 @@ struct CMS_ContentInfo_st { CMS_EnvelopedData *envelopedData; CMS_DigestedData *digestedData; CMS_EncryptedData *encryptedData; + CMS_AuthEnvelopedData *authEnvelopedData; CMS_AuthenticatedData *authenticatedData; CMS_CompressedData *compressedData; ASN1_TYPE *other; /* Other types ... */ void *otherData; } d; + CMS_CTX ctx; }; DEFINE_STACK_OF(CMS_CertificateChoices) @@ -92,6 +101,7 @@ struct CMS_SignerInfo_st { /* Digest and public key context for alternative parameters */ EVP_MD_CTX *mctx; EVP_PKEY_CTX *pctx; + const CMS_CTX *cms_ctx; }; struct CMS_SignerIdentifier_st { @@ -119,10 +129,12 @@ struct CMS_EncryptedContentInfo_st { ASN1_OBJECT *contentType; X509_ALGOR *contentEncryptionAlgorithm; ASN1_OCTET_STRING *encryptedContent; - /* Content encryption algorithm and key */ + /* Content encryption algorithm, key and tag */ const EVP_CIPHER *cipher; unsigned char *key; size_t keylen; + unsigned char *tag; + size_t taglen; /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ int debug; /* Set to 1 if we have no cert and need extra safety measures for MMA */ @@ -152,6 +164,7 @@ struct CMS_KeyTransRecipientInfo_st { EVP_PKEY *pkey; /* Public key context for this operation */ EVP_PKEY_CTX *pctx; + const CMS_CTX *cms_ctx; }; struct CMS_KeyAgreeRecipientInfo_st { @@ -164,6 +177,7 @@ struct CMS_KeyAgreeRecipientInfo_st { EVP_PKEY_CTX *pctx; /* Cipher context for CEK wrapping */ EVP_CIPHER_CTX *ctx; + const CMS_CTX *cms_ctx; }; struct CMS_OriginatorIdentifierOrKey_st { @@ -209,6 +223,7 @@ struct CMS_KEKRecipientInfo_st { /* Extra info: symmetric key to use */ unsigned char *key; size_t keylen; + const CMS_CTX *cms_ctx; }; struct CMS_KEKIdentifier_st { @@ -225,6 +240,7 @@ struct CMS_PasswordRecipientInfo_st { /* Extra info: password to use */ unsigned char *pass; size_t passlen; + const CMS_CTX *cms_ctx; }; struct CMS_OtherRecipientInfo_st { @@ -257,6 +273,16 @@ struct CMS_AuthenticatedData_st { STACK_OF(X509_ATTRIBUTE) *unauthAttrs; }; +struct CMS_AuthEnvelopedData_st { + int32_t version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncryptedContentInfo *authEncryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *authAttrs; + ASN1_OCTET_STRING *mac; + STACK_OF(X509_ATTRIBUTE) *unauthAttrs; +}; + struct CMS_CompressedData_st { int32_t version; X509_ALGOR *compressionAlgorithm; @@ -363,27 +389,36 @@ DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) # define CMS_OIK_PUBKEY 2 BIO *cms_content_bio(CMS_ContentInfo *cms); +const CMS_CTX *cms_get0_cmsctx(const CMS_ContentInfo *cms); +OSSL_LIB_CTX *cms_ctx_get0_libctx(const CMS_CTX *ctx); +const char *cms_ctx_get0_propq(const CMS_CTX *ctx); +void cms_resolve_libctx(CMS_ContentInfo *ci); -CMS_ContentInfo *cms_Data_create(void); +CMS_ContentInfo *cms_Data_create(OSSL_LIB_CTX *ctx, const char *propq); -CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md, + OSSL_LIB_CTX *libctx, + const char *propq); BIO *cms_DigestedData_init_bio(const CMS_ContentInfo *cms); -int cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, int verify); +int cms_DigestedData_do_final(const CMS_ContentInfo *cms, + BIO *chain, int verify); BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, - int type); + int type, const CMS_CTX *ctx); int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno); int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); -CMS_ContentInfo *cms_CompressedData_create(int comp_nid); +CMS_ContentInfo *cms_CompressedData_create(int comp_nid, OSSL_LIB_CTX *libctx, + const char *propq); BIO *cms_CompressedData_init_bio(const CMS_ContentInfo *cms); -BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm, + const CMS_CTX *ctx); int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, X509_ALGOR *mdalg); @@ -392,11 +427,13 @@ int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert); int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, + const CMS_CTX *ctx); BIO *cms_EncryptedData_init_bio(const CMS_ContentInfo *cms); int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen); + const unsigned char *key, size_t keylen, + const CMS_CTX *ctx); int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); @@ -404,30 +441,49 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); int cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain); +BIO *cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms); +int cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio); CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); +CMS_AuthEnvelopedData *cms_get0_auth_enveloped(CMS_ContentInfo *cms); +CMS_EncryptedContentInfo* cms_get0_env_enc_content(const CMS_ContentInfo *cms); + +/* RecipientInfo routines */ int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); int cms_pkey_get_ri_type(EVP_PKEY *pk); int cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type); + +void cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms); + /* KARI routines */ int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, EVP_PKEY *recipPubKey, X509 *originator, - EVP_PKEY *originatorPrivKey, unsigned int flags); + EVP_PKEY *originatorPrivKey, unsigned int flags, + const CMS_CTX *ctx); int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri); /* PWRI routines */ -int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de); +int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, int en_de); /* SignerInfo routines */ int CMS_si_check_attributes(const CMS_SignerInfo *si); +void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms); + /* ESS routines */ int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain); +int cms_dh_envelope(CMS_RecipientInfo *ri, int decrypt); +int cms_ecdh_envelope(CMS_RecipientInfo *ri, int decrypt); +int cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt); +int cms_ecdsa_dsa_sign(CMS_SignerInfo *si, int verify); +int cms_rsa_sign(CMS_SignerInfo *si, int verify); + DECLARE_ASN1_ITEM(CMS_CertificateChoices) DECLARE_ASN1_ITEM(CMS_DigestedData) DECLARE_ASN1_ITEM(CMS_EncryptedData) DECLARE_ASN1_ITEM(CMS_EnvelopedData) +DECLARE_ASN1_ITEM(CMS_AuthEnvelopedData) DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo) DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c index 4726165234..0393608fdb 100644 --- a/crypto/cms/cms_pwri.c +++ b/crypto/cms/cms_pwri.c @@ -18,8 +18,6 @@ #include "cms_local.h" #include "crypto/asn1.h" -DEFINE_STACK_OF(CMS_RecipientInfo) - int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, unsigned char *pass, ossl_ssize_t passlen) { @@ -44,16 +42,21 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ossl_ssize_t passlen, const EVP_CIPHER *kekciph) { + STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; + CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; EVP_CIPHER_CTX *ctx = NULL; X509_ALGOR *encalg = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; int ivlen; + const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms); - env = cms_get0_enveloped(cms); - if (!env) + ec = cms_get0_env_enc_content(cms); + if (ec == NULL) + return NULL; + ris = CMS_get0_RecipientInfos(cms); + if (ris == NULL) return NULL; if (wrap_nid <= 0) @@ -64,7 +67,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, /* Get from enveloped data */ if (kekciph == NULL) - kekciph = env->encryptedContentInfo->cipher; + kekciph = ec->cipher; if (kekciph == NULL) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); @@ -91,7 +94,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(cms_ctx->libctx, iv, ivlen) <= 0) goto err; if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) { CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); @@ -125,6 +128,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, ri->type = CMS_RECIPINFO_PASS; pwri = ri->d.pwri; + pwri->cms_ctx = cms_ctx; /* Since this is overwritten, free up empty structure already there */ X509_ALGOR_free(pwri->keyEncryptionAlgorithm); pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); @@ -154,7 +158,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, CMS_RecipientInfo_set0_password(ri, pass, passlen); pwri->version = 0; - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + if (!sk_CMS_RecipientInfo_push(ris, ri)) goto merr; return ri; @@ -232,7 +236,7 @@ static int kek_unwrap_key(unsigned char *out, size_t *outlen, static int kek_wrap_key(unsigned char *out, size_t *outlen, const unsigned char *in, size_t inlen, - EVP_CIPHER_CTX *ctx) + EVP_CIPHER_CTX *ctx, const CMS_CTX *cms_ctx) { size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); size_t olen; @@ -260,7 +264,8 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, memcpy(out + 4, in, inlen); /* Add random padding to end */ if (olen > inlen + 4 - && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) + && RAND_bytes_ex(cms_ctx->libctx, out + 4 + inlen, + olen - 4 - inlen) <= 0) return 0; /* Encrypt twice */ if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen) @@ -275,19 +280,21 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen, /* Encrypt/Decrypt content key in PWRI recipient info */ -int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de) +int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, int en_de) { CMS_EncryptedContentInfo *ec; CMS_PasswordRecipientInfo *pwri; int r = 0; X509_ALGOR *algtmp, *kekalg = NULL; EVP_CIPHER_CTX *kekctx = NULL; - const EVP_CIPHER *kekcipher; + const char *name; + EVP_CIPHER *kekcipher; unsigned char *key = NULL; size_t keylen; + const CMS_CTX *cms_ctx = cms_get0_cmsctx(cms); - ec = cms->d.envelopedData->encryptedContentInfo; + ec = cms_get0_env_enc_content(cms); pwri = ri->d.pwri; @@ -312,17 +319,18 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * return 0; } - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + name = OBJ_nid2sn(OBJ_obj2nid(kekalg->algorithm)); + kekcipher = EVP_CIPHER_fetch(cms_ctx->libctx, name, cms_ctx->propq); - if (!kekcipher) { + if (kekcipher == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); - return 0; + goto err; } kekctx = EVP_CIPHER_CTX_new(); if (kekctx == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de)) @@ -349,7 +357,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * if (en_de) { - if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx)) + if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; key = OPENSSL_malloc(keylen); @@ -357,7 +365,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * if (key == NULL) goto err; - if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx)) + if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; pwri->encryptedKey->data = key; pwri->encryptedKey->length = keylen; @@ -384,7 +392,7 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * r = 1; err: - + EVP_CIPHER_free(kekcipher); EVP_CIPHER_CTX_free(kekctx); if (!r) diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c new file mode 100644 index 0000000000..88201d7b44 --- /dev/null +++ b/crypto/cms/cms_rsa.c @@ -0,0 +1,253 @@ +/* + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "crypto/asn1.h" +#include "crypto/rsa.h" +#include "cms_local.h" + +static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) +{ + RSA_OAEP_PARAMS *oaep; + + oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), + alg->parameter); + + if (oaep == NULL) + return NULL; + + if (oaep->maskGenFunc != NULL) { + oaep->maskHash = x509_algor_mgf1_decode(oaep->maskGenFunc); + if (oaep->maskHash == NULL) { + RSA_OAEP_PARAMS_free(oaep); + return NULL; + } + } + return oaep; +} + +static int rsa_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pkctx; + X509_ALGOR *cmsalg; + int nid; + int rv = -1; + unsigned char *label = NULL; + int labellen = 0; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_OAEP_PARAMS *oaep; + + pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (pkctx == NULL) + return 0; + if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) + return -1; + nid = OBJ_obj2nid(cmsalg->algorithm); + if (nid == NID_rsaEncryption) + return 1; + if (nid != NID_rsaesOaep) { + CMSerr(0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE); + return -1; + } + /* Decode OAEP parameters */ + oaep = rsa_oaep_decode(cmsalg); + + if (oaep == NULL) { + CMSerr(0, CMS_R_INVALID_OAEP_PARAMETERS); + goto err; + } + + mgf1md = x509_algor_get_md(oaep->maskHash); + if (mgf1md == NULL) + goto err; + md = x509_algor_get_md(oaep->hashFunc); + if (md == NULL) + goto err; + + if (oaep->pSourceFunc != NULL) { + X509_ALGOR *plab = oaep->pSourceFunc; + + if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { + CMSerr(0, CMS_R_UNSUPPORTED_LABEL_SOURCE); + goto err; + } + if (plab->parameter->type != V_ASN1_OCTET_STRING) { + CMSerr(0, CMS_R_INVALID_LABEL); + goto err; + } + + label = plab->parameter->value.octet_string->data; + /* Stop label being freed when OAEP parameters are freed */ + plab->parameter->value.octet_string->data = NULL; + labellen = plab->parameter->value.octet_string->length; + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + if (label != NULL + && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + goto err; + /* Carry on */ + rv = 1; + + err: + RSA_OAEP_PARAMS_free(oaep); + return rv; +} + +static int rsa_cms_encrypt(CMS_RecipientInfo *ri) +{ + const EVP_MD *md, *mgf1md; + RSA_OAEP_PARAMS *oaep = NULL; + ASN1_STRING *os = NULL; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; + unsigned char *label; + + if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) + return 0; + if (pkctx != NULL) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* Not supported */ + if (pad_mode != RSA_PKCS1_OAEP_PADDING) + return 0; + if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) + goto err; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); + if (labellen < 0) + goto err; + oaep = RSA_OAEP_PARAMS_new(); + if (oaep == NULL) + goto err; + if (!x509_algor_new_from_md(&oaep->hashFunc, md)) + goto err; + if (!x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) + goto err; + if (labellen > 0) { + ASN1_OCTET_STRING *los; + + oaep->pSourceFunc = X509_ALGOR_new(); + if (oaep->pSourceFunc == NULL) + goto err; + los = ASN1_OCTET_STRING_new(); + if (los == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(los, label, labellen)) { + ASN1_OCTET_STRING_free(los); + goto err; + } + X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), + V_ASN1_OCTET_STRING, los); + } + /* create string with pss parameter encoding. */ + if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) + goto err; + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); + os = NULL; + rv = 1; + err: + RSA_OAEP_PARAMS_free(oaep); + ASN1_STRING_free(os); + return rv; +} + +int cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt) +{ + assert(decrypt == 0 || decrypt == 1); + + if (decrypt == 1) + return rsa_cms_decrypt(ri); + + if (decrypt == 0) + return rsa_cms_encrypt(ri); + + CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} + +static int rsa_cms_sign(CMS_SignerInfo *si) +{ + int pad_mode = RSA_PKCS1_PADDING; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + ASN1_STRING *os = NULL; + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + if (pkctx != NULL) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* We don't support it */ + if (pad_mode != RSA_PKCS1_PSS_PADDING) + return 0; + os = ossl_rsa_ctx_to_pss_string(pkctx); + if (os == NULL) + return 0; + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); + return 1; +} + +static int rsa_cms_verify(CMS_SignerInfo *si) +{ + int nid, nid2; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkctx); + + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + nid = OBJ_obj2nid(alg->algorithm); + if (nid == EVP_PKEY_RSA_PSS) + return ossl_rsa_pss_to_ctx(NULL, pkctx, alg, NULL); + /* Only PSS allowed for PSS keys */ + if (EVP_PKEY_is_a(pkey, "RSA-PSS")) { + RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if (nid == NID_rsaEncryption) + return 1; + /* Workaround for some implementation that use a signature OID */ + if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { + if (nid2 == NID_rsaEncryption) + return 1; + } + return 0; +} + +int cms_rsa_sign(CMS_SignerInfo *si, int verify) +{ + assert(verify == 0 || verify == 1); + + if (verify == 1) + return rsa_cms_verify(si); + + if (verify == 0) + return rsa_cms_sign(si); + + CMSerr(0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; +} diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index 54a836028f..377fac5917 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -20,12 +20,7 @@ #include "crypto/evp.h" #include "crypto/cms.h" #include "crypto/ess.h" - -DEFINE_STACK_OF(CMS_RevocationInfoChoice) -DEFINE_STACK_OF(CMS_SignerInfo) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_ALGOR) -DEFINE_STACK_OF(X509_ATTRIBUTE) +#include "crypto/x509.h" /* for X509_add_cert_new() */ /* CMS SignedData Utilities */ @@ -67,6 +62,7 @@ int CMS_SignedData_init(CMS_ContentInfo *cms) return 0; } + /* Check structures and fixup version numbers (if necessary) */ static void cms_sd_set_version(CMS_SignedData *sd) @@ -146,9 +142,11 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *sitmp; int i; + sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { ASN1_OCTET_STRING *messageDigest; + sitmp = sk_CMS_SignerInfo_value(sinfos, i); if (sitmp == si) continue; @@ -178,7 +176,8 @@ static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) return 0; } -int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type, + const CMS_CTX *ctx) { switch (type) { case CMS_SIGNERINFO_ISSUER_SERIAL: @@ -233,6 +232,16 @@ static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) { EVP_PKEY *pkey = si->pkey; int i; + +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) + if (EVP_PKEY_is_a(pkey, "DSA") || EVP_PKEY_is_a(pkey, "EC")) + return cms_ecdsa_dsa_sign(si, cmd); + else +#endif + if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS")) + return cms_rsa_sign(si, cmd); + + /* Something else? We'll give engines etc a chance to handle this */ if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) return 1; i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); @@ -255,6 +264,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, CMS_SignerInfo *si = NULL; X509_ALGOR *alg; int i, type; + const CMS_CTX *ctx = cms_get0_cmsctx(cms); + if (!X509_check_private_key(signer, pk)) { CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); @@ -272,6 +283,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, X509_up_ref(signer); EVP_PKEY_up_ref(pk); + si->cms_ctx = ctx; si->pkey = pk; si->signer = signer; si->mctx = EVP_MD_CTX_new(); @@ -292,7 +304,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, si->version = 1; } - if (!cms_set1_SignerIdentifier(si->sid, signer, type)) + if (!cms_set1_SignerIdentifier(si->sid, signer, type, ctx)) goto err; if (md == NULL) { @@ -311,6 +323,11 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, goto err; } + if (md == NULL) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); + goto err; + } + X509_ALGOR_set_md(si->digestAlgorithm, md); /* See if digest is present in digestAlgorithms */ @@ -395,15 +412,18 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (flags & CMS_KEY_PARAM) { if (flags & CMS_NOATTR) { - si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); + si->pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, si->pkey, + ctx->propq); if (si->pctx == NULL) goto err; if (EVP_PKEY_sign_init(si->pctx) <= 0) goto err; if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) goto err; - } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0) + } else if (EVP_DigestSignInit_ex(si->mctx, &si->pctx, EVP_MD_name(md), + ctx->libctx, ctx->propq, pk) <= 0) { goto err; + } } if (!sd->signerInfos) @@ -421,16 +441,31 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, } +void cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms) +{ + int i; + CMS_SignerInfo *si; + STACK_OF(CMS_SignerInfo) *sinfos = CMS_get0_SignerInfos(cms); + const CMS_CTX *ctx = cms_get0_cmsctx(cms); + + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (si != NULL) + si->cms_ctx = ctx; + } +} + static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) { ASN1_TIME *tt; int r = 0; - if (t) + + if (t != NULL) tt = t; else tt = X509_gmtime_adj(NULL, 0); - if (!tt) + if (tt == NULL) goto merr; if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, @@ -438,10 +473,8 @@ static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) goto merr; r = 1; - merr: - - if (!t) + if (t == NULL) ASN1_TIME_free(tt); if (!r) @@ -463,11 +496,9 @@ EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) { - CMS_SignedData *sd; - sd = cms_get0_signed(cms); - if (!sd) - return NULL; - return sd->signerInfos; + CMS_SignedData *sd = cms_get0_signed(cms); + + return sd != NULL ? sd->signerInfos : NULL; } STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) @@ -476,16 +507,13 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *si; int i; + sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); - if (si->signer) { - if (!signers) { - signers = sk_X509_new_null(); - if (!signers) - return NULL; - } - if (!sk_X509_push(signers, si->signer)) { + if (si->signer != NULL) { + if (!X509_add_cert_new(&signers, si->signer, + X509_ADD_FLAG_DEFAULT)) { sk_X509_free(signers); return NULL; } @@ -496,7 +524,7 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) { - if (signer) { + if (signer != NULL) { X509_up_ref(signer); EVP_PKEY_free(si->pkey); si->pkey = X509_get_pubkey(signer); @@ -527,13 +555,14 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, X509 *x; int i, j; int ret = 0; + sd = cms_get0_signed(cms); - if (!sd) + if (sd == NULL) return -1; certs = sd->certificates; for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { si = sk_CMS_SignerInfo_value(sd->signerInfos, i); - if (si->signer) + if (si->signer != NULL) continue; for (j = 0; j < sk_X509_num(scerts); j++) { @@ -545,7 +574,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, } } - if (si->signer || (flags & CMS_NOINTERN)) + if (si->signer != NULL || (flags & CMS_NOINTERN)) continue; for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { @@ -567,13 +596,13 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, X509_ALGOR **pdig, X509_ALGOR **psig) { - if (pk) + if (pk != NULL) *pk = si->pkey; - if (signer) + if (signer != NULL) *signer = si->signer; - if (pdig) + if (pdig != NULL) *pdig = si->digestAlgorithm; - if (psig) + if (psig != NULL) *psig = si->signatureAlgorithm; } @@ -588,13 +617,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, EVP_MD_CTX *mctx = EVP_MD_CTX_new(); int r = 0; EVP_PKEY_CTX *pctx = NULL; + const CMS_CTX *ctx = cms_get0_cmsctx(cms); if (mctx == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); return 0; } - if (!si->pkey) { + if (si->pkey == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); goto err; } @@ -612,6 +642,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, if (CMS_signed_get_attr_count(si) >= 0) { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; + if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) goto err; if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, @@ -628,6 +659,7 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, size_t siglen; unsigned char md[EVP_MAX_MD_SIZE]; unsigned int mdlen; + pctx = si->pctx; if (!EVP_DigestFinal_ex(mctx, md, &mdlen)) goto err; @@ -645,12 +677,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, } else { unsigned char *sig; unsigned int siglen; + sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); if (sig == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); goto err; } - if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) { + if (!EVP_SignFinal_ex(mctx, sig, &siglen, si->pkey, ctx->libctx, + ctx->propq)) { CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); OPENSSL_free(sig); goto err; @@ -672,6 +706,7 @@ int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) STACK_OF(CMS_SignerInfo) *sinfos; CMS_SignerInfo *si; int i; + sinfos = CMS_get0_SignerInfos(cms); for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); @@ -689,10 +724,10 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) unsigned char *abuf = NULL; int alen; size_t siglen; - const EVP_MD *md = NULL; + const CMS_CTX *ctx = si->cms_ctx; + const char *md_name = OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm->algorithm)); - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) + if (md_name == NULL) return 0; if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { @@ -707,7 +742,8 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si) pctx = si->pctx; else { EVP_MD_CTX_reset(mctx); - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestSignInit_ex(mctx, &pctx, md_name, ctx->libctx, ctx->propq, + si->pkey) <= 0) goto err; si->pctx = pctx; } @@ -780,9 +816,12 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) EVP_MD_CTX *mctx = NULL; unsigned char *abuf = NULL; int alen, r = -1; - const EVP_MD *md = NULL; + const char *name; + const EVP_MD *md; + EVP_MD *fetched_md = NULL; + const CMS_CTX *ctx = si->cms_ctx; - if (!si->pkey) { + if (si->pkey == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); return -1; } @@ -790,15 +829,29 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) if (!CMS_si_check_attributes(si)) return -1; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) + name = OBJ_nid2sn(OBJ_obj2nid(si->digestAlgorithm->algorithm)); + + (void)ERR_set_mark(); + fetched_md = EVP_MD_fetch(ctx->libctx, name, ctx->propq); + + if (fetched_md != NULL) + md = fetched_md; + else + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) { + (void)ERR_clear_last_mark(); + CMSerr(0, CMS_R_UNKNOWN_DIGEST_ALGORITHM); return -1; + } + (void)ERR_pop_to_mark(); + if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, ERR_R_MALLOC_FAILURE); - return -1; + goto err; } mctx = si->mctx; - if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_name(md), ctx->libctx, + NULL, si->pkey) <= 0) goto err; if (!cms_sd_asn1_ctrl(si, 1)) @@ -806,7 +859,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, ASN1_ITEM_rptr(CMS_Attributes_Verify)); - if (!abuf) + if (abuf == NULL || alen < 0) goto err; r = EVP_DigestVerifyUpdate(mctx, abuf, alen); OPENSSL_free(abuf); @@ -819,6 +872,7 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) if (r <= 0) CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); err: + EVP_MD_free(fetched_md); EVP_MD_CTX_reset(mctx); return r; } @@ -830,19 +884,21 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) int i; CMS_SignedData *sd; BIO *chain = NULL; + sd = cms_get0_signed(cms); - if (!sd) + if (sd == NULL) return NULL; if (cms->d.signedData->encapContentInfo->partial) cms_sd_set_version(sd); for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { X509_ALGOR *digestAlgorithm; BIO *mdbio; + digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); - mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); - if (!mdbio) + mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm, cms_get0_cmsctx(cms)); + if (mdbio == NULL) goto err; - if (chain) + if (chain != NULL) BIO_push(chain, mdbio); else chain = mdbio; @@ -871,7 +927,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) os = CMS_signed_get0_data_by_OBJ(si, OBJ_nid2obj(NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING); - if (!os) { + if (os == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); goto err; @@ -889,7 +945,7 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) /* If messageDigest found compare it */ - if (os) { + if (os != NULL) { if (mlen != (unsigned int)os->length) { CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); @@ -904,7 +960,9 @@ int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) r = 1; } else { const EVP_MD *md = EVP_MD_CTX_md(mctx); - pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); + const CMS_CTX *ctx = si->cms_ctx; + + pkctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, si->pkey, ctx->propq); if (pkctx == NULL) goto err; if (EVP_PKEY_verify_init(pkctx) <= 0) @@ -934,6 +992,7 @@ int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) { unsigned char *smder = NULL; int smderlen, r; + smderlen = i2d_X509_ALGORS(algs, &smder); if (smderlen <= 0) return 0; @@ -948,6 +1007,7 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, { X509_ALGOR *alg; ASN1_INTEGER *key = NULL; + if (keysize > 0) { key = ASN1_INTEGER_new(); if (key == NULL || !ASN1_INTEGER_set(key, keysize)) { diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index a83edce0f7..f8ae342551 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -16,15 +16,10 @@ #include "cms_local.h" #include "crypto/asn1.h" -DEFINE_STACK_OF(CMS_SignerInfo) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(CMS_RecipientEncryptedKey) -DEFINE_STACK_OF(CMS_RecipientInfo) - static BIO *cms_get_text_bio(BIO *out, unsigned int flags) { BIO *rbio; + if (out == NULL) rbio = BIO_new(BIO_s_null()); else if (flags & CMS_TEXT) { @@ -61,7 +56,7 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) break; } - if (tmpout && (BIO_write(tmpout, buf, i) != i)) + if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i)) goto err; } @@ -73,7 +68,6 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) } r = 1; - err: if (tmpout != out) BIO_free(tmpout); @@ -96,62 +90,72 @@ static void do_free_upto(BIO *f, BIO *upto) { if (upto != NULL) { BIO *tbio; + do { tbio = BIO_pop(f); BIO_free(f); f = tbio; } while (f != NULL && f != upto); - } else + } else { BIO_free_all(f); + } } int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); return 0; } cont = CMS_dataInit(cms, NULL); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); BIO_free_all(cont); return r; } -CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) +CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq) { - CMS_ContentInfo *cms; - cms = cms_Data_create(); - if (!cms) + CMS_ContentInfo *cms = cms_Data_create(libctx, propq); + + if (cms == NULL) return NULL; if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) return cms; CMS_ContentInfo_free(cms); - return NULL; } +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) +{ + return CMS_data_create_ex(in, flags, NULL, NULL); +} + int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags) { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; + r = cms_copy_content(out, cont, flags); if (r) r = cms_DigestedData_do_final(cms, cont, 1); @@ -159,14 +163,16 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, return r; } -CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, - unsigned int flags) +CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, + unsigned int flags, OSSL_LIB_CTX *ctx, + const char *propq) { CMS_ContentInfo *cms; - if (!md) + + if (md == NULL) md = EVP_sha1(); - cms = cms_DigestedData_create(md); - if (!cms) + cms = cms_DigestedData_create(md, ctx, propq); + if (cms == NULL) return NULL; if (!(flags & CMS_DETACHED)) @@ -179,41 +185,51 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, return NULL; } +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags) +{ + return CMS_digest_create_ex(in, md, flags, NULL, NULL); +} + int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, size_t keylen, BIO *dcont, BIO *out, unsigned int flags) { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, CMS_R_TYPE_NOT_ENCRYPTED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); do_free_upto(cont, dcont); return r; } -CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, - const unsigned char *key, - size_t keylen, unsigned int flags) +CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags, + OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; - if (!cipher) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); + + if (cipher == NULL) { + CMSerr(0, CMS_R_NO_CIPHER); return NULL; } - cms = CMS_ContentInfo_new(); + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL) return NULL; if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) @@ -230,16 +246,26 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, return NULL; } +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags) +{ + return CMS_EncryptedData_encrypt_ex(in, cipher, key, keylen, flags, NULL, + NULL); +} + static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, STACK_OF(X509) *certs, STACK_OF(X509_CRL) *crls, - STACK_OF(X509) **chain) + STACK_OF(X509) **chain, + const CMS_CTX *cms_ctx) { - X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + X509_STORE_CTX *ctx; X509 *signer; int i, j, r = 0; + ctx = X509_STORE_CTX_new_ex(cms_ctx->libctx, cms_ctx->propq); if (ctx == NULL) { CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE); goto err; @@ -250,7 +276,7 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, goto err; } X509_STORE_CTX_set_default(ctx, "smime_sign"); - if (crls) + if (crls != NULL) X509_STORE_CTX_set0_crls(ctx, crls); i = X509_verify_cert(ctx); @@ -285,11 +311,13 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, int i, scount = 0, ret = 0; BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; int cadesVerify = (flags & CMS_CADES) != 0; + const CMS_CTX *ctx = cms_get0_cmsctx(cms); - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; - if (dcont && !(flags & CMS_BINARY)) { + if (dcont != NULL && !(flags & CMS_BINARY)) { const ASN1_OBJECT *coid = CMS_get0_eContentType(cms); + if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF) flags |= CMS_ASCIICRLF; } @@ -337,7 +365,8 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, si = sk_CMS_SignerInfo_value(sinfos, i); if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls, - si_chains ? &si_chains[i] : NULL)) + si_chains ? &si_chains[i] : NULL, + ctx)) goto err; } } @@ -367,17 +396,19 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, * reading from a read write memory BIO when signatures are calculated. */ - if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { + if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { char *ptr; long len; + len = BIO_get_mem_data(dcont, &ptr); - tmpin = BIO_new_mem_buf(ptr, len); + tmpin = (len == 0) ? dcont : BIO_new_mem_buf(ptr, len); if (tmpin == NULL) { CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); goto err2; } - } else + } else { tmpin = dcont; + } /* * If not binary mode and detached generate digests by *writing* through * the BIO. That makes it possible to canonicalise the input. @@ -388,12 +419,12 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, * included content doesn't override detached content. */ tmpout = cms_get_text_bio(out, flags); - if (!tmpout) { + if (tmpout == NULL) { CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } cmsbio = CMS_dataInit(cms, tmpout); - if (!cmsbio) + if (cmsbio == NULL) goto err; /* * Don't use SMIME_TEXT for verify: it adds headers and we want to @@ -409,7 +440,7 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, } } else { cmsbio = CMS_dataInit(cms, tmpin); - if (!cmsbio) + if (cmsbio == NULL) goto err; if (!cms_copy_content(out, cmsbio, flags)) @@ -427,7 +458,6 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, } ret = 1; - err: if (!(flags & SMIME_BINARY) && dcont) { do_free_upto(cmsbio, tmpout); @@ -460,6 +490,7 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, X509_STORE *store, unsigned int flags) { int r; + flags &= ~(CMS_DETACHED | CMS_TEXT); r = CMS_verify(rcms, certs, store, NULL, NULL, flags); if (r <= 0) @@ -467,14 +498,15 @@ int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, return cms_Receipt_verify(rcms, ocms); } -CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, BIO *data, - unsigned int flags) +CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags, OSSL_LIB_CTX *libctx, + const char *propq) { CMS_ContentInfo *cms; int i; - cms = CMS_ContentInfo_new(); + cms = CMS_ContentInfo_new_ex(libctx, propq); if (cms == NULL || !CMS_SignedData_init(cms)) goto merr; if (flags & CMS_ASCIICRLF @@ -482,13 +514,14 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) goto err; - if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { - CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); + if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { + CMSerr(0, CMS_R_ADD_SIGNER_ERROR); goto err; } for (i = 0; i < sk_X509_num(certs); i++) { X509 *x = sk_X509_value(certs, i); + if (!CMS_add1_cert(cms, x)) goto merr; } @@ -503,13 +536,19 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, goto err; merr: - CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); + CMSerr(0, ERR_R_MALLOC_FAILURE); err: CMS_ContentInfo_free(cms); return NULL; } +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, unsigned int flags) +{ + return CMS_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL); +} + CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, unsigned int flags) @@ -519,6 +558,7 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, ASN1_OCTET_STRING **pos, *os; BIO *rct_cont = NULL; int r = 0; + const CMS_CTX *ctx = si->cms_ctx; flags &= ~(CMS_STREAM | CMS_TEXT); /* Not really detached but avoids content being allocated */ @@ -530,8 +570,8 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, /* Initialize signed data */ - cms = CMS_sign(NULL, NULL, certs, NULL, flags); - if (!cms) + cms = CMS_sign_ex(NULL, NULL, certs, NULL, flags, ctx->libctx, ctx->propq); + if (cms == NULL) goto err; /* Set inner content type to signed receipt */ @@ -545,13 +585,12 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, } os = cms_encode_Receipt(si); - - if (!os) + if (os == NULL) goto err; /* Set content to digest */ rct_cont = BIO_new_mem_buf(os->data, os->length); - if (!rct_cont) + if (rct_cont == NULL) goto err; /* Add msgSigDigest attribute */ @@ -578,19 +617,24 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, } -CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, - const EVP_CIPHER *cipher, unsigned int flags) +CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data, + const EVP_CIPHER *cipher, unsigned int flags, + OSSL_LIB_CTX *libctx, const char *propq) { CMS_ContentInfo *cms; int i; X509 *recip; - cms = CMS_EnvelopedData_create(cipher); - if (!cms) + + + cms = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) + ? CMS_AuthEnvelopedData_create_ex(cipher, libctx, propq) + : CMS_EnvelopedData_create_ex(cipher, libctx, propq); + if (cms == NULL) goto merr; for (i = 0; i < sk_X509_num(certs); i++) { recip = sk_X509_value(certs, i); if (!CMS_add1_recipient_cert(cms, recip, flags)) { - CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); + CMSerr(0, CMS_R_RECIPIENT_ERROR); goto err; } } @@ -605,13 +649,20 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, goto err; merr: - CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); + CMSerr(0, ERR_R_MALLOC_FAILURE); err: CMS_ContentInfo_free(cms); return NULL; } -static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, + const EVP_CIPHER *cipher, unsigned int flags) +{ + return CMS_encrypt_ex(certs, data, cipher, flags, NULL, NULL); +} + +static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, EVP_PKEY *pk, X509 *cert, X509 *peer) { int i; @@ -621,6 +672,7 @@ static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, CMS_RecipientInfo * reks = CMS_RecipientInfo_kari_get0_reks(ri); for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { int rv; + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) continue; @@ -639,15 +691,17 @@ int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL); } -int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer) +int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, + X509 *cert, X509 *peer) { STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; int i, r, cms_pkey_ri_type; int debug = 0, match_ri = 0; + ris = CMS_get0_RecipientInfos(cms); - if (ris) - debug = cms->d.envelopedData->encryptedContentInfo->debug; + if (ris != NULL) + debug = cms_get0_env_enc_content(cms)->debug; cms_pkey_ri_type = cms_pkey_get_ri_type(pk); if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) { @@ -675,12 +729,12 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cer * If we have a cert try matching RecipientInfo otherwise try them * all. */ - else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { + else if (cert == NULL|| !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { EVP_PKEY_up_ref(pk); CMS_RecipientInfo_set0_pkey(ri, pk); r = CMS_RecipientInfo_decrypt(cms, ri); CMS_RecipientInfo_set0_pkey(ri, NULL); - if (cert) { + if (cert != NULL) { /* * If not debugging clear any error and return success to * avoid leaking of information useful to MMA @@ -704,7 +758,10 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cer } } /* If no cert, key transport and not debugging always return success */ - if (cert == NULL && cms_pkey_ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { + if (cert == NULL + && cms_pkey_ri_type == CMS_RECIPINFO_TRANS + && match_ri + && !debug) { ERR_clear_error(); return 1; } @@ -721,6 +778,7 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms, STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; int i, r; + ris = CMS_get0_RecipientInfos(cms); for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { ri = sk_CMS_RecipientInfo_value(ris, i); @@ -731,13 +789,13 @@ int CMS_decrypt_set1_key(CMS_ContentInfo *cms, * If we have an id try matching RecipientInfo otherwise try them * all. */ - if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { + if (id == NULL || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { CMS_RecipientInfo_set0_key(ri, key, keylen); r = CMS_RecipientInfo_decrypt(cms, ri); CMS_RecipientInfo_set0_key(ri, NULL, 0); if (r > 0) return 1; - if (id) { + if (id != NULL) { CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR); return 0; } @@ -756,6 +814,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms, STACK_OF(CMS_RecipientInfo) *ris; CMS_RecipientInfo *ri; int i, r; + ris = CMS_get0_RecipientInfos(cms); for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { ri = sk_CMS_RecipientInfo_value(ris, i); @@ -779,20 +838,23 @@ int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, int r; BIO *cont; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { + int nid = OBJ_obj2nid(CMS_get0_type(cms)); + + if (nid != NID_pkcs7_enveloped + && nid != NID_id_smime_ct_authEnvelopedData) { CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; if (flags & CMS_DEBUG_DECRYPT) - cms->d.envelopedData->encryptedContentInfo->debug = 1; + cms_get0_env_enc_content(cms)->debug = 1; else - cms->d.envelopedData->encryptedContentInfo->debug = 0; - if (!cert) - cms->d.envelopedData->encryptedContentInfo->havenocert = 1; + cms_get0_env_enc_content(cms)->debug = 0; + if (cert == NULL) + cms_get0_env_enc_content(cms)->havenocert = 1; else - cms->d.envelopedData->encryptedContentInfo->havenocert = 0; + cms_get0_env_enc_content(cms)->havenocert = 0; if (pk == NULL && cert == NULL && dcont == NULL && out == NULL) return 1; if (pk != NULL && !CMS_decrypt_set1_pkey(cms, pk, cert)) @@ -815,7 +877,7 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) return 0; } - SMIME_crlf_copy(data, cmsbio, flags); + ret = SMIME_crlf_copy(data, cmsbio, flags); (void)BIO_flush(cmsbio); @@ -823,10 +885,7 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); goto err; } - - ret = 1; - - err: +err: do_free_upto(cmsbio, dcont); return ret; @@ -840,16 +899,17 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, { BIO *cont; int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA); return 0; } - if (!dcont && !check_content(cms)) + if (dcont == NULL && !check_content(cms)) return 0; cont = CMS_dataInit(cms, dcont); - if (!cont) + if (cont == NULL) return 0; r = cms_copy_content(out, cont, flags); do_free_upto(cont, dcont); @@ -859,10 +919,11 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) { CMS_ContentInfo *cms; + if (comp_nid <= 0) comp_nid = NID_zlib_compression; - cms = cms_CompressedData_create(comp_nid); - if (!cms) + cms = cms_CompressedData_create(comp_nid, NULL, NULL); + if (cms == NULL) return NULL; if (!(flags & CMS_DETACHED)) diff --git a/crypto/conf/conf_api.c b/crypto/conf/conf_api.c index b4edfb28ae..d64cc5031a 100644 --- a/crypto/conf/conf_api.c +++ b/crypto/conf/conf_api.c @@ -16,8 +16,6 @@ #include #include -DEFINE_STACK_OF(CONF_VALUE) - static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf); static void value_free_stack_doall(CONF_VALUE *a); diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index 1d34519d1a..63dfaef4d8 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -11,6 +11,9 @@ #include #include +#ifdef __TANDEM +# include /* strcasecmp */ +#endif #include "internal/cryptlib.h" #include "internal/o_dir.h" #include @@ -27,8 +30,6 @@ # endif #endif -DEFINE_STACK_OF(BIO) - #ifndef S_ISDIR # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) #endif @@ -442,11 +443,13 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) if (biosk == NULL) { if ((biosk = sk_BIO_new_null()) == NULL) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + BIO_free(next); goto err; } } if (!sk_BIO_push(biosk, in)) { CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + BIO_free(next); goto err; } /* continue with reading from the included BIO */ diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c index daf2320a19..9c3c2d6878 100644 --- a/crypto/conf/conf_err.c +++ b/crypto/conf/conf_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -36,6 +36,8 @@ static const ERR_STRING_DATA CONF_str_reasons[] = { {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_SUCH_FILE), "no such file"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_VALUE), "no value"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NUMBER_TOO_LARGE), "number too large"}, + {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION), + "openssl conf references missing section"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_DIRECTORY_INCLUDE), "recursive directory include"}, {ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_EMPTY), diff --git a/crypto/conf/conf_lib.c b/crypto/conf/conf_lib.c index a9d960b721..7a3ab72247 100644 --- a/crypto/conf/conf_lib.c +++ b/crypto/conf/conf_lib.c @@ -101,6 +101,7 @@ STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, return NULL; } else { CONF ctmp; + CONF_set_nconf(&ctmp, conf); return NCONF_get_section(&ctmp, section); } @@ -113,6 +114,7 @@ char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, return NCONF_get_string(NULL, group, name); } else { CONF ctmp; + CONF_set_nconf(&ctmp, conf); return NCONF_get_string(&ctmp, group, name); } @@ -129,6 +131,7 @@ long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, status = NCONF_get_number_e(NULL, group, name, &result); } else { CONF ctmp; + CONF_set_nconf(&ctmp, conf); status = NCONF_get_number_e(&ctmp, group, name, &result); } @@ -162,6 +165,7 @@ int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) { CONF ctmp; + CONF_set_nconf(&ctmp, conf); return NCONF_dump_bio(&ctmp, out); } @@ -174,7 +178,7 @@ int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) * the "CONF classic" functions, for consistency. */ -CONF *NCONF_new_with_libctx(OPENSSL_CTX *libctx, CONF_METHOD *meth) +CONF *NCONF_new_ex(OSSL_LIB_CTX *libctx, CONF_METHOD *meth) { CONF *ret; @@ -193,7 +197,7 @@ CONF *NCONF_new_with_libctx(OPENSSL_CTX *libctx, CONF_METHOD *meth) CONF *NCONF_new(CONF_METHOD *meth) { - return NCONF_new_with_libctx(NULL, meth); + return NCONF_new_ex(NULL, meth); } void NCONF_free(CONF *conf) @@ -329,6 +333,18 @@ int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, return 1; } +long _CONF_get_number(const CONF *conf, const char *section, + const char *name) +{ + int status; + long result = 0; + + ERR_set_mark(); + status = NCONF_get_number_e(conf, section, name, &result); + ERR_pop_to_mark(); + return status == 0 ? 0L : result; +} + #ifndef OPENSSL_NO_STDIO int NCONF_dump_fp(const CONF *conf, FILE *out) { diff --git a/crypto/conf/conf_mall.c b/crypto/conf/conf_mall.c index 123e2abaad..5d24a36cd9 100644 --- a/crypto/conf/conf_mall.c +++ b/crypto/conf/conf_mall.c @@ -18,6 +18,7 @@ #include #include #include "internal/provider.h" +#include "crypto/rand.h" #include "conf_local.h" /* Load all OpenSSL builtin modules */ @@ -33,4 +34,5 @@ void OPENSSL_load_builtin_modules(void) EVP_add_alg_module(); conf_add_ssl_module(); ossl_provider_add_conf_module(); + ossl_random_add_conf_module(); } diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index 64473417e9..bd945766b8 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -15,13 +15,13 @@ #include #include #include "internal/conf.h" +#include "openssl/conf_api.h" #include "internal/dso.h" #include "internal/thread_once.h" #include #include #include -DEFINE_STACK_OF(CONF_VALUE) DEFINE_STACK_OF(CONF_MODULE) DEFINE_STACK_OF(CONF_IMODULE) @@ -79,6 +79,11 @@ static int module_init(CONF_MODULE *pmod, const char *name, const char *value, static CONF_MODULE *module_load_dso(const CONF *cnf, const char *name, const char *value); +static int conf_diagnostics(const CONF *cnf) +{ + return _CONF_get_number(cnf, NULL, "config_diagnostics") != 0; +} + /* Main function: load modules from a CONF structure */ int CONF_modules_load(const CONF *cnf, const char *appname, @@ -87,12 +92,18 @@ int CONF_modules_load(const CONF *cnf, const char *appname, STACK_OF(CONF_VALUE) *values; CONF_VALUE *vl; char *vsection = NULL; - int ret, i; if (!cnf) return 1; + if (conf_diagnostics(cnf)) + flags &= ~(CONF_MFLAGS_IGNORE_ERRORS + | CONF_MFLAGS_IGNORE_RETURN_CODES + | CONF_MFLAGS_SILENT + | CONF_MFLAGS_IGNORE_MISSING_FILE); + + ERR_set_mark(); if (appname) vsection = NCONF_get_string(cnf, NULL, appname); @@ -100,39 +111,52 @@ int CONF_modules_load(const CONF *cnf, const char *appname, vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); if (!vsection) { - ERR_clear_error(); + ERR_pop_to_mark(); return 1; } OSSL_TRACE1(CONF, "Configuration in section %s\n", vsection); values = NCONF_get_section(cnf, vsection); - if (!values) + if (values == NULL) { + if (!(flags & CONF_MFLAGS_SILENT)) { + ERR_clear_last_mark(); + CONFerr(0, CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION); + ERR_add_error_data(2, "openssl_conf=", vsection); + } else { + ERR_pop_to_mark(); + } return 0; + } + ERR_pop_to_mark(); for (i = 0; i < sk_CONF_VALUE_num(values); i++) { vl = sk_CONF_VALUE_value(values, i); + ERR_set_mark(); ret = module_run(cnf, vl->name, vl->value, flags); OSSL_TRACE3(CONF, "Running module %s (%s) returned %d\n", vl->name, vl->value, ret); if (ret <= 0) - if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) + if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) { + ERR_clear_last_mark(); return ret; + } + ERR_pop_to_mark(); } return 1; } -int CONF_modules_load_file_with_libctx(OPENSSL_CTX *libctx, - const char *filename, - const char *appname, unsigned long flags) +int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename, + const char *appname, unsigned long flags) { char *file = NULL; CONF *conf = NULL; - int ret = 0; + int ret = 0, diagnostics = 0; - conf = NCONF_new_with_libctx(libctx, NULL); + ERR_set_mark(); + conf = NCONF_new_ex(libctx, NULL); if (conf == NULL) goto err; @@ -147,29 +171,33 @@ int CONF_modules_load_file_with_libctx(OPENSSL_CTX *libctx, if (NCONF_load(conf, file, NULL) <= 0) { if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) { - ERR_clear_error(); ret = 1; } goto err; } ret = CONF_modules_load(conf, appname, flags); + diagnostics = conf_diagnostics(conf); err: if (filename == NULL) OPENSSL_free(file); NCONF_free(conf); - if (flags & CONF_MFLAGS_IGNORE_RETURN_CODES) - return 1; + if ((flags & CONF_MFLAGS_IGNORE_RETURN_CODES) != 0 && !diagnostics) + ret = 1; + if (ret) + ERR_pop_to_mark(); + else + ERR_clear_last_mark(); return ret; } int CONF_modules_load_file(const char *filename, const char *appname, unsigned long flags) { - return CONF_modules_load_file_with_libctx(NULL, filename, appname, flags); + return CONF_modules_load_file_ex(NULL, filename, appname, flags); } DEFINE_RUN_ONCE_STATIC(do_load_builtin_modules) @@ -234,9 +262,8 @@ static CONF_MODULE *module_load_dso(const CONF *cnf, CONF_MODULE *md; /* Look for alternative path in module section */ - path = NCONF_get_string(cnf, value, "path"); + path = _CONF_get_string(cnf, value, "path"); if (path == NULL) { - ERR_clear_error(); path = name; } dso = DSO_load(NULL, path, NULL, 0); diff --git a/crypto/conf/conf_ssl.c b/crypto/conf/conf_ssl.c index eefd279a10..5b949be616 100644 --- a/crypto/conf/conf_ssl.c +++ b/crypto/conf/conf_ssl.c @@ -14,8 +14,6 @@ #include "internal/sslconf.h" #include "conf_local.h" -DEFINE_STACK_OF(CONF_VALUE) - /* * SSL library configuration module placeholder. We load it here but defer * all decisions about its contents to libssl. diff --git a/crypto/context.c b/crypto/context.c index de289fcb68..4dbfb723e1 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -12,34 +12,34 @@ #include "internal/thread_once.h" #include "internal/property.h" -struct openssl_ctx_onfree_list_st { - openssl_ctx_onfree_fn *fn; - struct openssl_ctx_onfree_list_st *next; +struct ossl_lib_ctx_onfree_list_st { + ossl_lib_ctx_onfree_fn *fn; + struct ossl_lib_ctx_onfree_list_st *next; }; -struct openssl_ctx_st { +struct ossl_lib_ctx_st { CRYPTO_RWLOCK *lock; CRYPTO_EX_DATA data; /* - * For most data in the OPENSSL_CTX we just use ex_data to store it. But + * For most data in the OSSL_LIB_CTX we just use ex_data to store it. But * that doesn't work for ex_data itself - so we store that directly. */ OSSL_EX_DATA_GLOBAL global; /* Map internal static indexes to dynamically created indexes */ - int dyn_indexes[OPENSSL_CTX_MAX_INDEXES]; + int dyn_indexes[OSSL_LIB_CTX_MAX_INDEXES]; /* Keep a separate lock for each index */ - CRYPTO_RWLOCK *index_locks[OPENSSL_CTX_MAX_INDEXES]; + CRYPTO_RWLOCK *index_locks[OSSL_LIB_CTX_MAX_INDEXES]; CRYPTO_RWLOCK *oncelock; - int run_once_done[OPENSSL_CTX_MAX_RUN_ONCE]; - int run_once_ret[OPENSSL_CTX_MAX_RUN_ONCE]; - struct openssl_ctx_onfree_list_st *onfreelist; + int run_once_done[OSSL_LIB_CTX_MAX_RUN_ONCE]; + int run_once_ret[OSSL_LIB_CTX_MAX_RUN_ONCE]; + struct ossl_lib_ctx_onfree_list_st *onfreelist; }; -static int context_init(OPENSSL_CTX *ctx) +static int context_init(OSSL_LIB_CTX *ctx) { size_t i; int exdata_done = 0; @@ -52,19 +52,19 @@ static int context_init(OPENSSL_CTX *ctx) if (ctx->oncelock == NULL) goto err; - for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++) { + for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) { ctx->index_locks[i] = CRYPTO_THREAD_lock_new(); ctx->dyn_indexes[i] = -1; if (ctx->index_locks[i] == NULL) goto err; } - /* OPENSSL_CTX is built on top of ex_data so we initialise that directly */ + /* OSSL_LIB_CTX is built on top of ex_data so we initialise that directly */ if (!do_ex_data_init(ctx)) goto err; exdata_done = 1; - if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, + if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, &ctx->data)) { crypto_cleanup_all_ex_data_int(ctx); goto err; @@ -84,9 +84,9 @@ static int context_init(OPENSSL_CTX *ctx) return 0; } -static int context_deinit(OPENSSL_CTX *ctx) +static int context_deinit(OSSL_LIB_CTX *ctx) { - struct openssl_ctx_onfree_list_st *tmp, *onfree; + struct ossl_lib_ctx_onfree_list_st *tmp, *onfree; int i; if (ctx == NULL) @@ -101,9 +101,9 @@ static int context_deinit(OPENSSL_CTX *ctx) onfree = onfree->next; OPENSSL_free(tmp); } - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, &ctx->data); crypto_cleanup_all_ex_data_int(ctx); - for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++) + for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) CRYPTO_THREAD_lock_free(ctx->index_locks[i]); CRYPTO_THREAD_lock_free(ctx->oncelock); @@ -114,7 +114,7 @@ static int context_deinit(OPENSSL_CTX *ctx) #ifndef FIPS_MODULE /* The default default context */ -static OPENSSL_CTX default_context_int; +static OSSL_LIB_CTX default_context_int; static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT; static CRYPTO_THREAD_LOCAL default_context_thread_local; @@ -125,12 +125,12 @@ DEFINE_RUN_ONCE_STATIC(default_context_do_init) && context_init(&default_context_int); } -void openssl_ctx_default_deinit(void) +void ossl_lib_ctx_default_deinit(void) { context_deinit(&default_context_int); } -static OPENSSL_CTX *get_thread_default_context(void) +static OSSL_LIB_CTX *get_thread_default_context(void) { if (!RUN_ONCE(&default_context_init, default_context_do_init)) return NULL; @@ -138,16 +138,16 @@ static OPENSSL_CTX *get_thread_default_context(void) return CRYPTO_THREAD_get_local(&default_context_thread_local); } -static OPENSSL_CTX *get_default_context(void) +static OSSL_LIB_CTX *get_default_context(void) { - OPENSSL_CTX *current_defctx = get_thread_default_context(); + OSSL_LIB_CTX *current_defctx = get_thread_default_context(); if (current_defctx == NULL) current_defctx = &default_context_int; return current_defctx; } -static int set_default_context(OPENSSL_CTX *defctx) +static int set_default_context(OSSL_LIB_CTX *defctx) { if (defctx == &default_context_int) defctx = NULL; @@ -156,37 +156,37 @@ static int set_default_context(OPENSSL_CTX *defctx) } #endif -OPENSSL_CTX *OPENSSL_CTX_new(void) +OSSL_LIB_CTX *OSSL_LIB_CTX_new(void) { - OPENSSL_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + OSSL_LIB_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL && !context_init(ctx)) { - OPENSSL_CTX_free(ctx); + OSSL_LIB_CTX_free(ctx); ctx = NULL; } return ctx; } #ifndef FIPS_MODULE -int OPENSSL_CTX_load_config(OPENSSL_CTX *ctx, const char *config_file) +int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file) { - return CONF_modules_load_file_with_libctx(ctx, config_file, NULL, 0) > 0; + return CONF_modules_load_file_ex(ctx, config_file, NULL, 0) > 0; } #endif -void OPENSSL_CTX_free(OPENSSL_CTX *ctx) +void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx) { - if (openssl_ctx_is_default(ctx)) + if (ossl_lib_ctx_is_default(ctx)) return; context_deinit(ctx); OPENSSL_free(ctx); } -OPENSSL_CTX *OPENSSL_CTX_set0_default(OPENSSL_CTX *libctx) +OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx) { #ifndef FIPS_MODULE - OPENSSL_CTX *current_defctx; + OSSL_LIB_CTX *current_defctx; if ((current_defctx = get_default_context()) != NULL && set_default_context(libctx)) @@ -196,7 +196,7 @@ OPENSSL_CTX *OPENSSL_CTX_set0_default(OPENSSL_CTX *libctx) return NULL; } -OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx) +OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx) { #ifndef FIPS_MODULE if (ctx == NULL) @@ -205,7 +205,7 @@ OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx) return ctx; } -int openssl_ctx_is_default(OPENSSL_CTX *ctx) +int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx) { #ifndef FIPS_MODULE if (ctx == NULL || ctx == get_default_context()) @@ -214,48 +214,48 @@ int openssl_ctx_is_default(OPENSSL_CTX *ctx) return 0; } -int openssl_ctx_is_global_default(OPENSSL_CTX *ctx) +int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx) { #ifndef FIPS_MODULE - if (openssl_ctx_get_concrete(ctx) == &default_context_int) + if (ossl_lib_ctx_get_concrete(ctx) == &default_context_int) return 1; #endif return 0; } -static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign, - CRYPTO_EX_DATA *ad, int index, - long argl_ign, void *argp) +static void ossl_lib_ctx_generic_new(void *parent_ign, void *ptr_ign, + CRYPTO_EX_DATA *ad, int index, + long argl_ign, void *argp) { - const OPENSSL_CTX_METHOD *meth = argp; - void *ptr = meth->new_func(crypto_ex_data_get_openssl_ctx(ad)); + const OSSL_LIB_CTX_METHOD *meth = argp; + void *ptr = meth->new_func(crypto_ex_data_get_ossl_lib_ctx(ad)); if (ptr != NULL) CRYPTO_set_ex_data(ad, index, ptr); } -static void openssl_ctx_generic_free(void *parent_ign, void *ptr, - CRYPTO_EX_DATA *ad, int index, - long argl_ign, void *argp) +static void ossl_lib_ctx_generic_free(void *parent_ign, void *ptr, + CRYPTO_EX_DATA *ad, int index, + long argl_ign, void *argp) { - const OPENSSL_CTX_METHOD *meth = argp; + const OSSL_LIB_CTX_METHOD *meth = argp; meth->free_func(ptr); } /* Non-static so we can use it in context_internal_test */ -static int openssl_ctx_init_index(OPENSSL_CTX *ctx, int static_index, - const OPENSSL_CTX_METHOD *meth) +static int ossl_lib_ctx_init_index(OSSL_LIB_CTX *ctx, int static_index, + const OSSL_LIB_CTX_METHOD *meth) { int idx; - ctx = openssl_ctx_get_concrete(ctx); + ctx = ossl_lib_ctx_get_concrete(ctx); if (ctx == NULL) return 0; - idx = crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, 0, + idx = crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, 0, (void *)meth, - openssl_ctx_generic_new, - NULL, openssl_ctx_generic_free); + ossl_lib_ctx_generic_new, + NULL, ossl_lib_ctx_generic_free); if (idx < 0) return 0; @@ -263,13 +263,13 @@ static int openssl_ctx_init_index(OPENSSL_CTX *ctx, int static_index, return 1; } -void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index, - const OPENSSL_CTX_METHOD *meth) +void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index, + const OSSL_LIB_CTX_METHOD *meth) { void *data = NULL; int dynidx; - ctx = openssl_ctx_get_concrete(ctx); + ctx = ossl_lib_ctx_get_concrete(ctx); if (ctx == NULL) return NULL; @@ -295,7 +295,7 @@ void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index, return data; } - if (!openssl_ctx_init_index(ctx, index, meth)) { + if (!ossl_lib_ctx_init_index(ctx, index, meth)) { CRYPTO_THREAD_unlock(ctx->lock); CRYPTO_THREAD_unlock(ctx->index_locks[index]); return NULL; @@ -304,7 +304,7 @@ void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index, CRYPTO_THREAD_unlock(ctx->lock); /* The alloc call ensures there's a value there */ - if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, + if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, &ctx->data, ctx->dyn_indexes[index])) data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]); @@ -313,20 +313,20 @@ void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index, return data; } -OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx) +OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx) { - ctx = openssl_ctx_get_concrete(ctx); + ctx = ossl_lib_ctx_get_concrete(ctx); if (ctx == NULL) return NULL; return &ctx->global; } -int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx, - openssl_ctx_run_once_fn run_once_fn) +int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, + ossl_lib_ctx_run_once_fn run_once_fn) { int done = 0, ret = 0; - ctx = openssl_ctx_get_concrete(ctx); + ctx = ossl_lib_ctx_get_concrete(ctx); if (ctx == NULL) return 0; @@ -354,9 +354,9 @@ int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx, return ret; } -int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn) +int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn) { - struct openssl_ctx_onfree_list_st *newonfree + struct ossl_lib_ctx_onfree_list_st *newonfree = OPENSSL_malloc(sizeof(*newonfree)); if (newonfree == NULL) diff --git a/crypto/core_algorithm.c b/crypto/core_algorithm.c index f4a20cb2d1..ddb9e5ae43 100644 --- a/crypto/core_algorithm.c +++ b/crypto/core_algorithm.c @@ -14,7 +14,7 @@ #include "internal/provider.h" struct algorithm_data_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; int operation_id; /* May be zero for finding them all */ int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result); void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, @@ -31,7 +31,7 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) int first_operation = 1; int last_operation = OSSL_OP__HIGHEST; int cur_operation; - int ok = 0; + int ok = 1; if (data->operation_id != 0) first_operation = last_operation = data->operation_id; @@ -77,15 +77,15 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) return 0; } - /* If post-condition fulfilled, set general success */ - if (ret) - ok = 1; + /* If post-condition not fulfilled, set general failure */ + if (!ret) + ok = 0; } return ok; } -void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, +void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, OSSL_PROVIDER *provider, int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result), diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index 89a44ddbe5..4fb432754b 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -16,7 +16,7 @@ #include "internal/provider.h" struct construct_data_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; OSSL_METHOD_STORE *store; int operation_id; int force_store; @@ -100,7 +100,7 @@ static void ossl_method_construct_this(OSSL_PROVIDER *provider, data->mcm->destruct(method, data->mcm_data); } -void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id, +void *ossl_method_construct(OSSL_LIB_CTX *libctx, int operation_id, int force_store, OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data) { diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c index b08fb84556..0cde909fc4 100644 --- a/crypto/core_namemap.c +++ b/crypto/core_namemap.c @@ -62,9 +62,9 @@ static void namenum_free(NAMENUM_ENTRY *n) OPENSSL_free(n); } -/* OPENSSL_CTX_METHOD functions for a namemap stored in a library context */ +/* OSSL_LIB_CTX_METHOD functions for a namemap stored in a library context */ -static void *stored_namemap_new(OPENSSL_CTX *libctx) +static void *stored_namemap_new(OSSL_LIB_CTX *libctx) { OSSL_NAMEMAP *namemap = ossl_namemap_new(); @@ -85,7 +85,7 @@ static void stored_namemap_free(void *vnamemap) } } -static const OPENSSL_CTX_METHOD stored_namemap_method = { +static const OSSL_LIB_CTX_METHOD stored_namemap_method = { stored_namemap_new, stored_namemap_free, }; @@ -390,11 +390,11 @@ static void get_legacy_md_names(const OBJ_NAME *on, void *arg) * ========================== */ -OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx) +OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx) { OSSL_NAMEMAP *namemap = - openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX, - &stored_namemap_method); + ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_NAMEMAP_INDEX, + &stored_namemap_method); #ifndef FIPS_MODULE if (namemap != NULL && ossl_namemap_empty(namemap)) { diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c index 0201f31e61..04b6cdb27f 100644 --- a/crypto/cpt_err.c +++ b/crypto/cpt_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -38,6 +38,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = { "provider already exists"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR), "provider section error"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_RANDOM_SECTION_ERROR), + "random section error"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_SECURE_MALLOC_FAILURE), "secure malloc failure"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long"}, @@ -46,6 +48,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = { "too many records"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_SMALL_BUFFER), "too small buffer"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION), + "unknown name in random section"}, {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ZERO_LENGTH_NUMBER), "zero length number"}, {0, NULL} diff --git a/crypto/crmf/crmf_err.c b/crypto/crmf/crmf_err.c index 159d5b2c91..61a1488838 100644 --- a/crypto/crmf/crmf_err.c +++ b/crypto/crmf/crmf_err.c @@ -30,6 +30,8 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = { "iterationcount below 100"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"}, + {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED), + "poposkinput not supported"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY), "popo inconsistent public key"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"}, @@ -45,8 +47,6 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = { "setting owf algor failure"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, - {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY), - "unsupported alg for popsigningkey"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, {ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO), diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 7530120ff3..9b80c526b5 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -36,9 +36,6 @@ #include #include -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(OSSL_CRMF_MSG) - /*- * atyp = Attribute Type * valt = Value Type @@ -353,57 +350,46 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, return 0; } -/* TODO: support cases 1+2 (besides case 3) defined in RFC 4211, section 4.1. */ -static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps, - OSSL_CRMF_CERTREQUEST *cr, - EVP_PKEY *pkey, int dgst) +static int create_popo_signature(OSSL_CRMF_POPOSIGNINGKEY *ps, + const OSSL_CRMF_CERTREQUEST *cr, + EVP_PKEY *pkey, const EVP_MD *digest, + OSSL_LIB_CTX *libctx, const char *propq) { - int ret = 0; - EVP_MD *fetched_md = NULL; - const EVP_MD *md = EVP_get_digestbynid(dgst); - if (ps == NULL || cr == NULL || pkey == NULL) { - CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_NULL_ARGUMENT); + CRMFerr(0, CRMF_R_NULL_ARGUMENT); return 0; } - - /* If we didn't find legacy MD, we try an implicit fetch */ - if (md == NULL) - md = fetched_md = EVP_MD_fetch(NULL, OBJ_nid2sn(dgst), NULL); - - if (md == NULL) { - CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, - CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY); + if (ps->poposkInput != NULL) { + /* TODO: support cases 1+2 defined in RFC 4211, section 4.1 */ + CRMFerr(0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED); return 0; } - ret = ASN1_item_sign(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST), - ps->algorithmIdentifier, NULL, ps->signature, - cr, pkey, md); - - EVP_MD_free(fetched_md); - return ret; + return ASN1_item_sign_ex(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST), + ps->algorithmIdentifier, NULL, ps->signature, cr, + NULL, pkey, digest, libctx, propq); } -int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey, - int dgst, int ppmtd) +int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm, + EVP_PKEY *pkey, const EVP_MD *digest, + OSSL_LIB_CTX *libctx, const char *propq) { OSSL_CRMF_POPO *pp = NULL; ASN1_INTEGER *tag = NULL; - if (crm == NULL || (ppmtd == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) { + if (crm == NULL || (meth == OSSL_CRMF_POPO_SIGNATURE && pkey == NULL)) { CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, CRMF_R_NULL_ARGUMENT); return 0; } - if (ppmtd == OSSL_CRMF_POPO_NONE) + if (meth == OSSL_CRMF_POPO_NONE) goto end; if ((pp = OSSL_CRMF_POPO_new()) == NULL) goto err; - pp->type = ppmtd; + pp->type = meth; - switch (ppmtd) { + switch (meth) { case OSSL_CRMF_POPO_RAVERIFIED: if ((pp->value.raVerified = ASN1_NULL_new()) == NULL) goto err; @@ -412,8 +398,11 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey, case OSSL_CRMF_POPO_SIGNATURE: { OSSL_CRMF_POPOSIGNINGKEY *ps = OSSL_CRMF_POPOSIGNINGKEY_new(); - if (ps == NULL - || !CRMF_poposigningkey_init(ps, crm->certReq, pkey, dgst)) { + + if (ps == NULL) + goto err; + if (!create_popo_signature(ps, crm->certReq, pkey, digest, + libctx, propq)) { OSSL_CRMF_POPOSIGNINGKEY_free(ps); goto err; } @@ -451,11 +440,14 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey, /* verifies the Proof-of-Possession of the request with the given rid in reqs */ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, - int rid, int acceptRAVerified) + int rid, int acceptRAVerified, + OSSL_LIB_CTX *libctx, const char *propq) { OSSL_CRMF_MSG *req = NULL; X509_PUBKEY *pubkey = NULL; OSSL_CRMF_POPOSIGNINGKEY *sig = NULL; + const ASN1_ITEM *it; + void *asn; if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) { CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, CRMF_R_NULL_ARGUMENT); @@ -499,21 +491,20 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, * TODO check the contents of the authInfo sub-field, * see RFC 4211 https://tools.ietf.org/html/rfc4211#section-4.1 */ - if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT), - sig->algorithmIdentifier, sig->signature, - sig->poposkInput, - X509_PUBKEY_get0(pubkey)) < 1) - return 0; + it = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT); + asn = sig->poposkInput; } else { if (req->certReq->certTemplate->subject == NULL) { CRMFerr(0, CRMF_R_POPO_MISSING_SUBJECT); return 0; } - if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST), - sig->algorithmIdentifier, sig->signature, - req->certReq, X509_PUBKEY_get0(pubkey)) < 1) - return 0; + it = ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST); + asn = req->certReq; } + if (ASN1_item_verify_ex(it, sig->algorithmIdentifier, sig->signature, + asn, NULL, X509_PUBKEY_get0(pubkey), libctx, + propq) < 1) + return 0; break; case OSSL_CRMF_POPO_KEYENC: /* @@ -594,8 +585,10 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, * returns a pointer to the decrypted certificate * returns NULL on error or if no certificate available */ -X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert, - EVP_PKEY *pkey) +X509 +*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert, + OSSL_LIB_CTX *libctx, const char *propq, + EVP_PKEY *pkey) { X509 *cert = NULL; /* decrypted certificate */ EVP_CIPHER_CTX *evp_ctx = NULL; /* context for symmetric encryption */ @@ -629,7 +622,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecer } cikeysize = EVP_CIPHER_key_length(cipher); /* first the symmetric key needs to be decrypted */ - pkctx = EVP_PKEY_CTX_new(pkey, NULL); + pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (pkctx != NULL && EVP_PKEY_decrypt_init(pkctx)) { ASN1_BIT_STRING *encKey = ecert->encSymmKey; size_t failure; @@ -685,10 +678,11 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecer outlen += n; /* convert decrypted certificate from DER to internal ASN.1 structure */ - if ((cert = d2i_X509(NULL, &p, outlen)) == NULL) { + if ((cert = X509_new_ex(libctx, propq)) == NULL) + goto end; + if (d2i_X509(&cert, &p, outlen) == NULL) CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, CRMF_R_ERROR_DECODING_CERTIFICATE); - } end: EVP_PKEY_CTX_free(pkctx); OPENSSL_free(outbuf); diff --git a/crypto/crmf/crmf_local.h b/crypto/crmf/crmf_local.h index b4d669875c..ee1ec7b07a 100644 --- a/crypto/crmf/crmf_local.h +++ b/crypto/crmf/crmf_local.h @@ -389,5 +389,4 @@ struct ossl_crmf_msg_st { /* 1 */ STACK_OF(OSSL_CRMF_ATTRIBUTETYPEANDVALUE) *regInfo; } /* OSSL_CRMF_MSG */; -/* DEFINE_STACK_OF(OSSL_CRMF_MSG) */ #endif diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c index f674eeeff7..9ad6ec149c 100644 --- a/crypto/crmf/crmf_pbm.c +++ b/crypto/crmf/crmf_pbm.c @@ -29,14 +29,15 @@ /*- * creates and initializes OSSL_CRMF_PBMPARAMETER (section 4.4) - * |slen| SHOULD be > 8 (16 is common) + * |slen| SHOULD be at least 8 (16 is common) * |owfnid| e.g., NID_sha256 - * |itercnt| MUST be > 100 (500 is common) + * |itercnt| MUST be >= 100 (e.g., 500) and <= OSSL_CRMF_PBM_MAX_ITERATION_COUNT * |macnid| e.g., NID_hmac_sha1 * returns pointer to OSSL_CRMF_PBMPARAMETER on success, NULL on error */ -OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid, - int itercnt, int macnid) +OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen, + int owfnid, size_t itercnt, + int macnid) { OSSL_CRMF_PBMPARAMETER *pbm = NULL; unsigned char *salt = NULL; @@ -51,7 +52,7 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid, */ if ((salt = OPENSSL_malloc(slen)) == NULL) goto err; - if (RAND_bytes(salt, (int)slen) <= 0) { + if (RAND_bytes_ex(libctx, salt, (int)slen) <= 0) { CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_FAILURE_OBTAINING_RANDOM); goto err; } @@ -82,6 +83,10 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid, CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_ITERATIONCOUNT_BELOW_100); goto err; } + if (itercnt > OSSL_CRMF_PBM_MAX_ITERATION_COUNT) { + CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_BAD_PBM_ITERATIONCOUNT); + goto err; + } if (!ASN1_INTEGER_set(pbm->iterationCount, itercnt)) { CRMFerr(CRMF_F_OSSL_CRMF_PBMP_NEW, CRMF_R_CRMFERROR); @@ -117,14 +122,16 @@ OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid, * |maclen| if not NULL, will set variable to the length of the mac on success * returns 1 on success, 0 on error */ -int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, +/* TODO try to combine with other MAC calculations in the libray */ +int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_CRMF_PBMPARAMETER *pbmp, const unsigned char *msg, size_t msglen, const unsigned char *sec, size_t seclen, unsigned char **out, size_t *outlen) { int mac_nid, hmac_md_nid = NID_undef; - const char *mdname = NULL; - const EVP_MD *m = NULL; + const char *mdname; + EVP_MD *owf = NULL; EVP_MD_CTX *ctx = NULL; unsigned char basekey[EVP_MAX_MD_SIZE]; unsigned int bklen = EVP_MAX_MD_SIZE; @@ -148,7 +155,8 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, * compute the key used in the MAC process. All implementations MUST * support SHA-1. */ - if ((m = EVP_get_digestbyobj(pbmp->owf->algorithm)) == NULL) { + mdname = OBJ_nid2sn(OBJ_obj2nid(pbmp->owf->algorithm)); + if ((owf = EVP_MD_fetch(libctx, mdname, propq)) == NULL) { CRMFerr(CRMF_F_OSSL_CRMF_PBM_NEW, CRMF_R_UNSUPPORTED_ALGORITHM); goto err; } @@ -157,7 +165,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, goto err; /* compute the basekey of the salted secret */ - if (!EVP_DigestInit_ex(ctx, m, NULL)) + if (!EVP_DigestInit_ex(ctx, owf, NULL)) goto err; /* first the secret */ if (!EVP_DigestUpdate(ctx, sec, seclen)) @@ -176,7 +184,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, /* the first iteration was already done above */ while (--iterations > 0) { - if (!EVP_DigestInit_ex(ctx, m, NULL)) + if (!EVP_DigestInit_ex(ctx, owf, NULL)) goto err; if (!EVP_DigestUpdate(ctx, basekey, bklen)) goto err; @@ -201,7 +209,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, (char *)mdname, 0); macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, basekey, bklen); - if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL + if ((mac = EVP_MAC_fetch(libctx, "HMAC", propq)) == NULL || (mctx = EVP_MAC_CTX_new(mac)) == NULL || !EVP_MAC_CTX_set_params(mctx, macparams) || !EVP_MAC_init(mctx) @@ -212,10 +220,10 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, ok = 1; err: - /* cleanup */ OPENSSL_cleanse(basekey, bklen); EVP_MAC_CTX_free(mctx); EVP_MAC_free(mac); + EVP_MD_free(owf); EVP_MD_CTX_free(ctx); if (ok == 1) { diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index bc29a3b583..7779ad05fe 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -471,3 +471,15 @@ size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max) return 0; } #endif + +#if defined(__TANDEM) && defined(OPENSSL_VPROC) +/* + * Define a VPROC function for HP NonStop build crypto library. + * This is used by platform version identification tools. + * Do not inline this procedure or make it static. + */ +# define OPENSSL_VPROC_STRING_(x) x##_CRYPTO +# define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x) +# define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC) +void OPENSSL_VPROC_FUNC(void) {} +#endif /* __TANDEM */ diff --git a/crypto/ct/ct_b64.c b/crypto/ct/ct_b64.c index ab4aaf82c1..5e80e4e44b 100644 --- a/crypto/ct/ct_b64.c +++ b/crypto/ct/ct_b64.c @@ -132,9 +132,9 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64, * 0 on decoding failure, or invalid parameter if any * -1 on internal (malloc) failure */ -int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64, - const char *name, OPENSSL_CTX *libctx, - const char *propq) +int CTLOG_new_from_base64_ex(CTLOG **ct_log, const char *pkey_base64, + const char *name, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char *pkey_der = NULL; int pkey_der_len; @@ -160,7 +160,7 @@ int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64, return 0; } - *ct_log = CTLOG_new_with_libctx(pkey, name, libctx, propq); + *ct_log = CTLOG_new_ex(pkey, name, libctx, propq); if (*ct_log == NULL) { EVP_PKEY_free(pkey); return 0; @@ -172,6 +172,5 @@ int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64, int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name) { - return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, name, NULL, - NULL); + return CTLOG_new_from_base64_ex(ct_log, pkey_base64, name, NULL, NULL); } diff --git a/crypto/ct/ct_local.h b/crypto/ct/ct_local.h index eef4c193de..a7573c97bb 100644 --- a/crypto/ct/ct_local.h +++ b/crypto/ct/ct_local.h @@ -101,7 +101,7 @@ struct sct_ctx_st { /* milliseconds since epoch (to check that the SCT isn't from the future) */ uint64_t epoch_time_in_ms; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; }; @@ -113,14 +113,14 @@ struct ct_policy_eval_ctx_st { /* milliseconds since epoch (to check that SCTs aren't from the future) */ uint64_t epoch_time_in_ms; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; }; /* * Creates a new context for verifying an SCT. */ -SCT_CTX *SCT_CTX_new(OPENSSL_CTX *ctx, const char *propq); +SCT_CTX *SCT_CTX_new(OSSL_LIB_CTX *ctx, const char *propq); /* * Deletes an SCT verification context. */ diff --git a/crypto/ct/ct_log.c b/crypto/ct/ct_log.c index 73eeee9d7d..11fc9d4367 100644 --- a/crypto/ct/ct_log.c +++ b/crypto/ct/ct_log.c @@ -18,13 +18,11 @@ #include "internal/cryptlib.h" -DEFINE_STACK_OF(CTLOG) - /* * Information about a CT log server. */ struct ctlog_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; char *name; uint8_t log_id[CT_V1_HASHLEN]; @@ -36,7 +34,7 @@ struct ctlog_st { * It takes ownership of any CTLOG instances added to it. */ struct ctlog_store_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; STACK_OF(CTLOG) *logs; }; @@ -102,7 +100,7 @@ static int ct_v1_log_id_from_pkey(CTLOG *log, EVP_PKEY *pkey) return ret; } -CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq) +CTLOG_STORE *CTLOG_STORE_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -134,7 +132,7 @@ CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq) CTLOG_STORE *CTLOG_STORE_new(void) { - return CTLOG_STORE_new_with_libctx(NULL, NULL); + return CTLOG_STORE_new_ex(NULL, NULL); } void CTLOG_STORE_free(CTLOG_STORE *store) @@ -163,8 +161,8 @@ static int ctlog_new_from_conf(CTLOG_STORE *store, CTLOG **ct_log, return 0; } - return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, description, - store->libctx, store->propq); + return CTLOG_new_from_base64_ex(ct_log, pkey_base64, description, + store->libctx, store->propq); } int CTLOG_STORE_load_default_file(CTLOG_STORE *store) @@ -266,8 +264,8 @@ int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file) * Takes ownership of the public key. * Copies the name. */ -CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name, - OPENSSL_CTX *libctx, const char *propq) +CTLOG *CTLOG_new_ex(EVP_PKEY *public_key, const char *name, OSSL_LIB_CTX *libctx, + const char *propq) { CTLOG *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -303,7 +301,7 @@ CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name, CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name) { - return CTLOG_new_with_libctx(public_key, name, NULL, NULL); + return CTLOG_new_ex(public_key, name, NULL, NULL); } /* Frees CT log and associated structures */ diff --git a/crypto/ct/ct_oct.c b/crypto/ct/ct_oct.c index 4aca0385d0..712fc563c4 100644 --- a/crypto/ct/ct_oct.c +++ b/crypto/ct/ct_oct.c @@ -21,8 +21,6 @@ #include "ct_local.h" -DEFINE_STACK_OF(SCT) - int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len) { size_t siglen; diff --git a/crypto/ct/ct_policy.c b/crypto/ct/ct_policy.c index e067fd8ea5..a33c618cf5 100644 --- a/crypto/ct/ct_policy.c +++ b/crypto/ct/ct_policy.c @@ -25,8 +25,8 @@ */ static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300; -CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx, - const char *propq) +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, + const char *propq) { CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX)); @@ -54,7 +54,7 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx, CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void) { - return CT_POLICY_EVAL_CTX_new_with_libctx(NULL, NULL); + return CT_POLICY_EVAL_CTX_new_ex(NULL, NULL); } void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx) diff --git a/crypto/ct/ct_prn.c b/crypto/ct/ct_prn.c index a89b4aa6e7..374235b7ec 100644 --- a/crypto/ct/ct_prn.c +++ b/crypto/ct/ct_prn.c @@ -16,8 +16,6 @@ #include "ct_local.h" -DEFINE_STACK_OF(SCT) - static void SCT_signature_algorithms_print(const SCT *sct, BIO *out) { int nid = SCT_get_signature_nid(sct); diff --git a/crypto/ct/ct_sct.c b/crypto/ct/ct_sct.c index f6c262c967..1b8e1dc61e 100644 --- a/crypto/ct/ct_sct.c +++ b/crypto/ct/ct_sct.c @@ -19,8 +19,6 @@ #include "ct_local.h" -DEFINE_STACK_OF(SCT) - SCT *SCT_new(void) { SCT *sct = OPENSSL_zalloc(sizeof(*sct)); diff --git a/crypto/ct/ct_sct_ctx.c b/crypto/ct/ct_sct_ctx.c index ad7b6e6f93..8e4dfd2377 100644 --- a/crypto/ct/ct_sct_ctx.c +++ b/crypto/ct/ct_sct_ctx.c @@ -20,7 +20,7 @@ #include "ct_local.h" -SCT_CTX *SCT_CTX_new(OPENSSL_CTX *libctx, const char *propq) +SCT_CTX *SCT_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) { SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx)); diff --git a/crypto/ct/ct_vfy.c b/crypto/ct/ct_vfy.c index f270e4378a..db0a3d83bd 100644 --- a/crypto/ct/ct_vfy.c +++ b/crypto/ct/ct_vfy.c @@ -122,8 +122,8 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) if (ctx == NULL) goto end; - if (!EVP_DigestVerifyInit_ex(ctx, NULL, "SHA2-256", sctx->propq, sctx->pkey, - sctx->libctx)) + if (!EVP_DigestVerifyInit_ex(ctx, NULL, "SHA2-256", sctx->libctx, + sctx->propq, sctx->pkey)) goto end; if (!sct_ctx_update(ctx, sctx, sct)) diff --git a/crypto/ct/ct_x509v3.c b/crypto/ct/ct_x509v3.c index 51dd779a3a..085402b046 100644 --- a/crypto/ct/ct_x509v3.c +++ b/crypto/ct/ct_x509v3.c @@ -13,8 +13,6 @@ #include "ct_local.h" -DEFINE_STACK_OF(SCT) - static char *i2s_poison(const X509V3_EXT_METHOD *method, void *val) { return OPENSSL_strdup("NULL"); diff --git a/crypto/der_writer.c b/crypto/der_writer.c index 8210327f06..c6fd4c4298 100644 --- a/crypto/der_writer.c +++ b/crypto/der_writer.c @@ -48,15 +48,16 @@ static int int_end_context(WPACKET *pkt, int tag) && (size1 == size2 || WPACKET_put_bytes_u8(pkt, tag)); } -int DER_w_precompiled(WPACKET *pkt, int tag, - const unsigned char *precompiled, size_t precompiled_n) +int ossl_DER_w_precompiled(WPACKET *pkt, int tag, + const unsigned char *precompiled, + size_t precompiled_n) { return int_start_context(pkt, tag) && WPACKET_memcpy(pkt, precompiled, precompiled_n) && int_end_context(pkt, tag); } -int DER_w_boolean(WPACKET *pkt, int tag, int b) +int ossl_DER_w_boolean(WPACKET *pkt, int tag, int b) { return int_start_context(pkt, tag) && WPACKET_start_sub_packet(pkt) @@ -66,8 +67,8 @@ int DER_w_boolean(WPACKET *pkt, int tag, int b) && int_end_context(pkt, tag); } -int DER_w_octet_string(WPACKET *pkt, int tag, - const unsigned char *data, size_t data_n) +int ossl_DER_w_octet_string(WPACKET *pkt, int tag, + const unsigned char *data, size_t data_n) { return int_start_context(pkt, tag) && WPACKET_start_sub_packet(pkt) @@ -77,7 +78,7 @@ int DER_w_octet_string(WPACKET *pkt, int tag, && int_end_context(pkt, tag); } -int DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value) +int ossl_DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value) { unsigned char tmp[4] = { 0, 0, 0, 0 }; unsigned char *pbuf = tmp + (sizeof(tmp) - 1); @@ -86,7 +87,7 @@ int DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value) *pbuf-- = (value & 0xFF); value >>= 8; } - return DER_w_octet_string(pkt, tag, tmp, sizeof(tmp)); + return ossl_DER_w_octet_string(pkt, tag, tmp, sizeof(tmp)); } static int int_der_w_integer(WPACKET *pkt, int tag, @@ -124,7 +125,7 @@ static int int_put_bytes_ulong(WPACKET *pkt, const void *v, } /* For integers, we only support unsigned values for now */ -int DER_w_ulong(WPACKET *pkt, int tag, unsigned long v) +int ossl_DER_w_ulong(WPACKET *pkt, int tag, unsigned long v) { return int_der_w_integer(pkt, tag, int_put_bytes_ulong, &v); } @@ -147,17 +148,17 @@ static int int_put_bytes_bn(WPACKET *pkt, const void *v, return 1; } -int DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v) +int ossl_DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v) { if (v == NULL || BN_is_negative(v)) return 0; if (BN_is_zero(v)) - return DER_w_ulong(pkt, tag, 0); + return ossl_DER_w_ulong(pkt, tag, 0); return int_der_w_integer(pkt, tag, int_put_bytes_bn, v); } -int DER_w_null(WPACKET *pkt, int tag) +int ossl_DER_w_null(WPACKET *pkt, int tag) { return int_start_context(pkt, tag) && WPACKET_start_sub_packet(pkt) @@ -167,13 +168,13 @@ int DER_w_null(WPACKET *pkt, int tag) } /* Constructed things need a start and an end */ -int DER_w_begin_sequence(WPACKET *pkt, int tag) +int ossl_DER_w_begin_sequence(WPACKET *pkt, int tag) { return int_start_context(pkt, tag) && WPACKET_start_sub_packet(pkt); } -int DER_w_end_sequence(WPACKET *pkt, int tag) +int ossl_DER_w_end_sequence(WPACKET *pkt, int tag) { /* * If someone set the flag WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH on this diff --git a/crypto/dh/build.info b/crypto/dh/build.info index 656e6ea828..887ef78b0b 100644 --- a/crypto/dh/build.info +++ b/crypto/dh/build.info @@ -1,10 +1,11 @@ LIBS=../../libcrypto -$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c dh_gen.c +$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c dh_gen.c \ + dh_kdf.c SOURCE[../../libcrypto]=$COMMON\ dh_asn1.c dh_err.c \ - dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c + dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_meth.c dh_ctrl.c IF[{- !$disabled{'deprecated-0.9.8'} -}] SOURCE[../../libcrypto]=dh_depr.c ENDIF diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index d5e5f72517..69b166362a 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -14,18 +14,17 @@ #include "internal/deprecated.h" #include -#include "internal/cryptlib.h" #include #include -#include "dh_local.h" #include -#include "crypto/asn1.h" -#include "crypto/dh.h" -#include "crypto/evp.h" -#include #include #include #include "internal/ffc.h" +#include "internal/cryptlib.h" +#include "crypto/asn1.h" +#include "crypto/dh.h" +#include "crypto/evp.h" +#include "dh_local.h" /* * i2d/d2i like DH parameter functions which use the appropriate routine for @@ -35,9 +34,19 @@ static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, long length) { - if (pkey->ameth == &dhx_asn1_meth) - return d2i_DHxparams(NULL, pp, length); - return d2i_DHparams(NULL, pp, length); + DH *dh = NULL; + int is_dhx = (pkey->ameth == &dhx_asn1_meth); + + if (is_dhx) + dh = d2i_DHxparams(NULL, pp, length); + else + dh = d2i_DHparams(NULL, pp, length); + + if (dh != NULL) { + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, is_dhx ? DH_FLAG_TYPE_DHX : DH_FLAG_TYPE_DH); + } + return dh; } static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp) @@ -101,7 +110,6 @@ static int dh_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) ASN1_INTEGER_free(public_key); DH_free(dh); return 0; - } static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) @@ -260,10 +268,8 @@ static int dh_param_decode(EVP_PKEY *pkey, { DH *dh; - if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) { - DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); + if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) return 0; - } dh->dirty_cnt++; EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); return 1; @@ -313,7 +319,7 @@ static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype) if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent)) goto err; - if (!ffc_params_print(bp, &x->params, indent)) + if (!ossl_ffc_params_print(bp, &x->params, indent)) goto err; if (x->length != 0) { @@ -347,15 +353,15 @@ static int dh_security_bits(const EVP_PKEY *pkey) static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - return ffc_params_cmp(&a->pkey.dh->params, &a->pkey.dh->params, - a->ameth != &dhx_asn1_meth); + return ossl_ffc_params_cmp(&a->pkey.dh->params, &a->pkey.dh->params, + a->ameth != &dhx_asn1_meth); } static int int_dh_param_copy(DH *to, const DH *from, int is_x942) { if (is_x942 == -1) is_x942 = (from->params.q != NULL); - if (!ffc_params_copy(&to->params, &from->params)) + if (!ossl_ffc_params_copy(&to->params, &from->params)) return 0; if (!is_x942) to->length = from->length; @@ -427,11 +433,6 @@ int DHparams_print(BIO *bp, const DH *x) return do_dh_print(bp, x, 4, 0); } -#ifndef OPENSSL_NO_CMS -static int dh_cms_decrypt(CMS_RecipientInfo *ri); -static int dh_cms_encrypt(CMS_RecipientInfo *ri); -#endif - static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { @@ -447,19 +448,6 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) static int dhx_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { -#ifndef OPENSSL_NO_CMS - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 1) - return dh_cms_decrypt(arg2); - else if (arg1 == 0) - return dh_cms_encrypt(arg2); - return -2; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_AGREE; - return 1; -#endif default: return -2; } @@ -491,7 +479,7 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey) } static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq) { DH *dh = from->pkey.dh; @@ -548,26 +536,39 @@ static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata, return rv; } -static int dh_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +static int dh_pkey_import_from_type(const OSSL_PARAM params[], void *vpctx, + int type) { EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - DH *dh = dh_new_with_libctx(pctx->libctx); + DH *dh = dh_new_ex(pctx->libctx); if (dh == NULL) { ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return 0; } + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, type == EVP_PKEY_DH ? DH_FLAG_TYPE_DH : DH_FLAG_TYPE_DHX); if (!dh_ffc_params_fromdata(dh, params) || !dh_key_fromdata(dh, params) - || !EVP_PKEY_assign_DH(pkey, dh)) { + || !EVP_PKEY_assign(pkey, type, dh)) { DH_free(dh); return 0; } return 1; } +static int dh_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DH); +} + +static int dhx_pkey_import_from(const OSSL_PARAM params[], void *vpctx) +{ + return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DHX); +} + const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { EVP_PKEY_DH, EVP_PKEY_DH, @@ -649,310 +650,9 @@ const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { 0, dh_pkey_public_check, - dh_pkey_param_check + dh_pkey_param_check, + 0, 0, 0, 0, + dh_pkey_dirty_cnt, + dh_pkey_export_to, + dhx_pkey_import_from, }; - -#ifndef OPENSSL_NO_CMS - -static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, - X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) -{ - const ASN1_OBJECT *aoid; - int atype; - const void *aval; - ASN1_INTEGER *public_key = NULL; - int rv = 0; - EVP_PKEY *pkpeer = NULL, *pk = NULL; - DH *dhpeer = NULL; - const unsigned char *p; - int plen; - - X509_ALGOR_get0(&aoid, &atype, &aval, alg); - if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) - goto err; - /* Only absent parameters allowed in RFC XXXX */ - if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) - goto err; - - pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (pk == NULL) - goto err; - if (pk->type != EVP_PKEY_DHX) - goto err; - /* Get parameters from parent key */ - dhpeer = DHparams_dup(pk->pkey.dh); - /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); - p = ASN1_STRING_get0_data(pubkey); - if (p == NULL || plen == 0) - goto err; - - if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) { - DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR); - goto err; - } - - /* We have parameters now set public key */ - if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) { - DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR); - goto err; - } - - pkpeer = EVP_PKEY_new(); - if (pkpeer == NULL) - goto err; - EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer); - dhpeer = NULL; - if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) - rv = 1; - err: - ASN1_INTEGER_free(public_key); - EVP_PKEY_free(pkpeer); - DH_free(dhpeer); - return rv; -} - -static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) -{ - int rv = 0; - - X509_ALGOR *alg, *kekalg = NULL; - ASN1_OCTET_STRING *ukm; - const unsigned char *p; - unsigned char *dukm = NULL; - size_t dukmlen = 0; - int keylen, plen; - const EVP_CIPHER *kekcipher; - EVP_CIPHER_CTX *kekctx; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) - goto err; - - /* - * For DH we only have one OID permissible. If ever any more get defined - * we will need something cleverer. - */ - if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { - DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR); - goto err; - } - - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) - goto err; - - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) - goto err; - - if (alg->parameter->type != V_ASN1_SEQUENCE) - goto err; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - if (!kekalg) - goto err; - kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); - if (!kekctx) - goto err; - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) - goto err; - if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) - goto err; - if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) - goto err; - - keylen = EVP_CIPHER_CTX_key_length(kekctx); - if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) - goto err; - /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ - if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, - OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) - <= 0) - goto err; - - if (ukm) { - dukmlen = ASN1_STRING_length(ukm); - dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); - if (!dukm) - goto err; - } - - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) - goto err; - dukm = NULL; - - rv = 1; - err: - X509_ALGOR_free(kekalg); - OPENSSL_free(dukm); - return rv; -} - -static int dh_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - - if (pctx == NULL) - return 0; - /* See if we need to set peer key */ - if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { - X509_ALGOR *alg; - ASN1_BIT_STRING *pubkey; - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, - NULL, NULL, NULL)) - return 0; - if (!alg || !pubkey) - return 0; - if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { - DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR); - return 0; - } - } - /* Set DH derivation parameters and initialise unwrap context */ - if (!dh_cms_set_shared_info(pctx, ri)) { - DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR); - return 0; - } - return 1; -} - -static int dh_cms_encrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - EVP_PKEY *pkey; - EVP_CIPHER_CTX *ctx; - int keylen; - X509_ALGOR *talg, *wrap_alg = NULL; - const ASN1_OBJECT *aoid; - ASN1_BIT_STRING *pubkey; - ASN1_STRING *wrap_str; - ASN1_OCTET_STRING *ukm; - unsigned char *penc = NULL, *dukm = NULL; - int penclen; - size_t dukmlen = 0; - int rv = 0; - int kdf_type, wrap_nid; - const EVP_MD *kdf_md; - - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (pctx == NULL) - return 0; - /* Get ephemeral key */ - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, - NULL, NULL, NULL)) - goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); - /* Is everything uninitialised? */ - if (aoid == OBJ_nid2obj(NID_undef)) { - ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); - - if (pubk == NULL) - goto err; - /* Set the key */ - - penclen = i2d_ASN1_INTEGER(pubk, &penc); - ASN1_INTEGER_free(pubk); - if (penclen <= 0) - goto err; - ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), - V_ASN1_UNDEF, NULL); - } - - /* See if custom parameters set */ - kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) - goto err; - - if (kdf_type == EVP_PKEY_DH_KDF_NONE) { - kdf_type = EVP_PKEY_DH_KDF_X9_42; - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) - goto err; - } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) - /* Unknown KDF */ - goto err; - if (kdf_md == NULL) { - /* Only SHA1 supported */ - kdf_md = EVP_sha1(); - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) - goto err; - } else if (EVP_MD_type(kdf_md) != NID_sha1) - /* Unsupported digest */ - goto err; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) - goto err; - - /* Get wrap NID */ - ctx = CMS_RecipientInfo_kari_get0_ctx(ri); - wrap_nid = EVP_CIPHER_CTX_type(ctx); - if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) - goto err; - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Package wrap algorithm in an AlgorithmIdentifier */ - - wrap_alg = X509_ALGOR_new(); - if (wrap_alg == NULL) - goto err; - wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); - wrap_alg->parameter = ASN1_TYPE_new(); - if (wrap_alg->parameter == NULL) - goto err; - if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) - goto err; - if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { - ASN1_TYPE_free(wrap_alg->parameter); - wrap_alg->parameter = NULL; - } - - if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - if (ukm) { - dukmlen = ASN1_STRING_length(ukm); - dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); - if (!dukm) - goto err; - } - - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) - goto err; - dukm = NULL; - - /* - * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter - * of another AlgorithmIdentifier. - */ - penc = NULL; - penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (penc == NULL || penclen == 0) - goto err; - wrap_str = ASN1_STRING_new(); - if (wrap_str == NULL) - goto err; - ASN1_STRING_set0(wrap_str, penc, penclen); - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), - V_ASN1_SEQUENCE, wrap_str); - - rv = 1; - - err: - OPENSSL_free(penc); - X509_ALGOR_free(wrap_alg); - OPENSSL_free(dukm); - return rv; -} - -#endif diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c index 5475d98bfa..cf5c735a6a 100644 --- a/crypto/dh/dh_asn1.c +++ b/crypto/dh/dh_asn1.c @@ -108,13 +108,14 @@ DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) params = &dh->params; DH_set0_pqg(dh, dhx->p, dhx->q, dhx->g); - ffc_params_set0_j(params, dhx->j); + ossl_ffc_params_set0_j(params, dhx->j); if (dhx->vparams != NULL) { /* The counter has a maximum value of 4 * numbits(p) - 1 */ size_t counter = (size_t)BN_get_word(dhx->vparams->counter); - ffc_params_set_validate_params(params, dhx->vparams->seed->data, - dhx->vparams->seed->length, counter); + ossl_ffc_params_set_validate_params(params, dhx->vparams->seed->data, + dhx->vparams->seed->length, + counter); ASN1_BIT_STRING_free(dhx->vparams->seed); BN_free(dhx->vparams->counter); OPENSSL_free(dhx->vparams); @@ -135,10 +136,10 @@ int i2d_DHxparams(const DH *dh, unsigned char **pp) const FFC_PARAMS *params = &dh->params; int counter; - ffc_params_get0_pqg(params, (const BIGNUM **)&dhx.p, - (const BIGNUM **)&dhx.q, (const BIGNUM **)&dhx.g); + ossl_ffc_params_get0_pqg(params, (const BIGNUM **)&dhx.p, + (const BIGNUM **)&dhx.q, (const BIGNUM **)&dhx.g); dhx.j = params->j; - ffc_params_get_validate_params(params, &seed.data, &seedlen, &counter); + ossl_ffc_params_get_validate_params(params, &seed.data, &seedlen, &counter); seed.length = (int)seedlen; if (counter != -1 && seed.data != NULL && seed.length > 0) { diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index a223121cd0..ce8c6f7185 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -62,8 +62,8 @@ int DH_check_params(const DH *dh, int *ret) * (2b) FFC domain params conform to FIPS-186-4 explicit domain param * validity tests. */ - return ffc_params_FIPS186_4_validate(dh->libctx, &dh->params, - FFC_PARAM_TYPE_DH, ret, NULL); + return ossl_ffc_params_FIPS186_4_validate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, ret, NULL); } #else int DH_check_params(const DH *dh, int *ret) @@ -235,7 +235,7 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) */ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) { - return ffc_validate_public_key(&dh->params, pub_key, ret); + return ossl_ffc_validate_public_key(&dh->params, pub_key, ret); } /* @@ -245,7 +245,7 @@ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) */ int dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret) { - return ffc_validate_public_key_partial(&dh->params, pub_key, ret); + return ossl_ffc_validate_public_key_partial(&dh->params, pub_key, ret); } int dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret) @@ -268,7 +268,7 @@ int dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret) if (BN_cmp(two_powN, dh->params.q) < 0) upper = two_powN; } - if (!ffc_validate_private_key(upper, priv_key, ret)) + if (!ossl_ffc_validate_private_key(upper, priv_key, ret)) goto err; ok = 1; diff --git a/crypto/dh/dh_ctrl.c b/crypto/dh/dh_ctrl.c new file mode 100644 index 0000000000..2aa69fd154 --- /dev/null +++ b/crypto/dh/dh_ctrl.c @@ -0,0 +1,569 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * DH low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include +#include "crypto/evp.h" +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/refcount.h" +#include "crypto/dh.h" +#include "dh_local.h" + +static int dh_paramgen_check(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + /* If key type not DH return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_DH + && ctx->pmeth->pkey_id != EVP_PKEY_DHX) + return -1; + return 1; +} + +static int dh_param_derive_check(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + /* If key type not DH return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_DH + && ctx->pmeth->pkey_id != EVP_PKEY_DHX) + return -1; + return 1; +} + +int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, + size_t seedlen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED, + (void *)seed, seedlen); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *name; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL); + + name = dh_gen_type_id2name(typ); + if (name == NULL) + return 0; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, + (char *) name, 0); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits = pbits; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, pbits, + NULL); + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits); + *p = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits) +{ + int ret; + OSSL_PARAM params[2], *p = params; + size_t bits2 = qbits; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, qbits, + NULL); + *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL); + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *name; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL); + name = ossl_ffc_named_group_from_uid(gen); + if (name == NULL) + return 0; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + (void *)name, 0); + *p = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen) +{ + return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen); +} + +int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *name; + + if ((ret = dh_paramgen_check(ctx)) <= 0) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.keymgmt.genctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, + EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_DH_NID, nid, NULL); + name = ossl_ffc_named_group_from_uid(nid); + if (name == NULL) + return 0; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, + (void *)name, 0); + *p = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf) +{ + int ret; + const char *kdf_type; + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL); + switch (kdf) { + case EVP_PKEY_DH_KDF_NONE: + kdf_type = ""; + break; + case EVP_PKEY_DH_KDF_X9_42: + kdf_type = OSSL_KDF_NAME_X942KDF; + break; + default: + return -2; + } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)kdf_type, 0); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + return ret; +} + +int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx) +{ + int ret; + char kdf_type[80]; /* 80 should be big enough */ + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, + kdf_type, sizeof(kdf_type)); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else if (ret != 1) { + return -1; + } + + if (kdf_type[0] == '\0') + return EVP_PKEY_DH_KDF_NONE; + else if (strcmp(kdf_type, OSSL_KDF_NAME_X942KDF) == 0) + return EVP_PKEY_DH_KDF_X9_42; + + return -1; +} + +int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *oid_name; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid)); + oid_name = OBJ_nid2sn(OBJ_obj2nid(oid)); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + (char *)oid_name, 0); + *p = OSSL_PARAM_construct_end(); + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + return ret; +} + +int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid) +{ + int ret, nid; + OSSL_PARAM params[2], *p = params; + char oid_name[80]; /* 80 should be big enough */ + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(oid)); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, + oid_name, sizeof(oid_name)); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else if (ret != 1) { + return -1; + } + nid = OBJ_sn2nid(oid_name); + if (nid == NID_undef) + nid = OBJ_ln2nid(oid_name); + *oid = (nid == NID_undef ? NULL : OBJ_nid2obj(nid)); + return *oid != NULL; +} + +int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + int ret; + OSSL_PARAM params[2], *p = params; + const char *md_name = NULL; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md)); + md_name = (md == NULL) ? "" : EVP_MD_name(md); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, + /* + * Cast away the const. This is read + * only so should be safe + */ + (char *)md_name, 0); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + return ret; +} + +int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd) +{ + int ret; + char name[80] = ""; /* 80 should be big enough */ + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd)); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, + name, sizeof(name)); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else if (ret != 1) { + return -1; + } + + /* May be NULL meaning "unknown" */ + *pmd = EVP_get_digestbyname(name); + + return 1; +} + +int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int inlen) +{ + int ret; + size_t len = inlen; + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_OUTLEN, inlen, NULL); + if (inlen <= 0) { + /* + * This would ideally be -1 or 0, but we have to retain compatibility + * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if + * in <= 0 + */ + return -2; + } + + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &len); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + return ret; +} + +int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen) +{ + int ret; + size_t len = UINT_MAX; + OSSL_PARAM params[2], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, + (void *)(plen)); + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &len); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else if (ret != 1) { + return -1; + } + + if (len > INT_MAX) + return -1; + + *plen = (int)len; + + return 1; +} + +int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len) +{ + int ret; + OSSL_PARAM params[2], *p = params; + + if (len <= 0) + return -1; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_DH_KDF_UKM, len, (void *)(ukm)); + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, + /* + * Cast away the const. This is read + * only so should be safe + */ + (void *)ukm, + (size_t)len); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + if (ret == 1) + OPENSSL_free(ukm); + return ret; +} + +int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm) +{ + int ret; + size_t ukmlen; + OSSL_PARAM params[3], *p = params; + + ret = dh_param_derive_check(ctx); + if (ret != 1) + return ret; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(pukm)); + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM, + (void **)pukm, 0); + *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN, + &ukmlen); + *p = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else if (ret != 1) { + return -1; + } + + if (ukmlen > INT_MAX) + return -1; + + return (int)ukmlen; +} diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index 52f3151bc8..8ed7120653 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -42,14 +42,14 @@ int dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits, #ifndef FIPS_MODULE if (type == DH_PARAMGEN_TYPE_FIPS_186_2) - ret = ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, - FFC_PARAM_TYPE_DH, - pbits, qbits, &res, cb); + ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, &res, cb); else #endif - ret = ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, - FFC_PARAM_TYPE_DH, - pbits, qbits, &res, cb); + ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH, + pbits, qbits, &res, cb); if (ret > 0) dh->dirty_cnt++; return ret; @@ -91,7 +91,7 @@ int dh_get_named_group_uid_from_size(int pbits) #ifdef FIPS_MODULE -static int dh_gen_named_group(OPENSSL_CTX *libctx, DH *ret, int prime_len) +static int dh_gen_named_group(OSSL_LIB_CTX *libctx, DH *ret, int prime_len) { DH *dh; int ok = 0; @@ -100,9 +100,9 @@ static int dh_gen_named_group(OPENSSL_CTX *libctx, DH *ret, int prime_len) if (nid == NID_undef) return 0; - dh = dh_new_by_nid_with_libctx(libctx, nid); + dh = dh_new_by_nid_ex(libctx, nid); if (dh != NULL - && ffc_params_copy(&ret->params, &dh->params)) { + && ossl_ffc_params_copy(&ret->params, &dh->params)) { ok = 1; ret->dirty_cnt++; } diff --git a/crypto/dh/dh_group_params.c b/crypto/dh/dh_group_params.c index e0daa6ebc4..d0b53a2f8b 100644 --- a/crypto/dh/dh_group_params.c +++ b/crypto/dh/dh_group_params.c @@ -78,7 +78,7 @@ static const DH_NAMED_GROUP dh_named_groups[] = { #endif }; -int ffc_named_group_to_uid(const char *name) +int ossl_ffc_named_group_to_uid(const char *name) { size_t i; @@ -89,7 +89,7 @@ int ffc_named_group_to_uid(const char *name) return NID_undef; } -const char *ffc_named_group_from_uid(int uid) +const char *ossl_ffc_named_group_from_uid(int uid) { size_t i; @@ -100,10 +100,10 @@ const char *ffc_named_group_from_uid(int uid) return NULL; } -static DH *dh_param_init(OPENSSL_CTX *libctx, int uid, const BIGNUM *p, +static DH *dh_param_init(OSSL_LIB_CTX *libctx, int uid, const BIGNUM *p, const BIGNUM *q, const BIGNUM *g) { - DH *dh = dh_new_with_libctx(libctx); + DH *dh = dh_new_ex(libctx); if (dh == NULL) return NULL; @@ -117,7 +117,7 @@ static DH *dh_param_init(OPENSSL_CTX *libctx, int uid, const BIGNUM *p, return dh; } -static DH *dh_new_by_group_name(OPENSSL_CTX *libctx, const char *name) +static DH *dh_new_by_group_name(OSSL_LIB_CTX *libctx, const char *name) { int i; @@ -136,19 +136,19 @@ static DH *dh_new_by_group_name(OPENSSL_CTX *libctx, const char *name) return NULL; } -DH *dh_new_by_nid_with_libctx(OPENSSL_CTX *libctx, int nid) +DH *dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid) { - const char *name = ffc_named_group_from_uid(nid); + const char *name = ossl_ffc_named_group_from_uid(nid); return dh_new_by_group_name(libctx, name); } DH *DH_new_by_nid(int nid) { - return dh_new_by_nid_with_libctx(NULL, nid); + return dh_new_by_nid_ex(NULL, nid); } -int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name) +int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name) { int i; BIGNUM *q = NULL; @@ -158,10 +158,10 @@ int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name) for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) { if (strcasecmp(dh_named_groups[i].name, group_name) == 0) { - ffc_params_set0_pqg(ffc, - (BIGNUM *)dh_named_groups[i].p, - (BIGNUM *)dh_named_groups[i].q, - (BIGNUM *)dh_named_groups[i].g); + ossl_ffc_params_set0_pqg(ffc, + (BIGNUM *)dh_named_groups[i].p, + (BIGNUM *)dh_named_groups[i].q, + (BIGNUM *)dh_named_groups[i].g); /* flush the cached nid, The DH layer is responsible for caching */ ffc->nid = NID_undef; return 1; diff --git a/crypto/dh/dh_kdf.c b/crypto/dh/dh_kdf.c index 1b8a320db1..9737d4d712 100644 --- a/crypto/dh/dh_kdf.c +++ b/crypto/dh/dh_kdf.c @@ -14,40 +14,34 @@ #include "internal/deprecated.h" #include "e_os.h" +#include "e_os.h" +#include +#include +#include +#include +#include +#include +#include +#include -#ifndef OPENSSL_NO_CMS -# include -# include -# include -# include -# include -# include -# include - -int DH_KDF_X9_42(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - ASN1_OBJECT *key_oid, - const unsigned char *ukm, size_t ukmlen, const EVP_MD *md) +/* Key derivation function from X9.63/SECG */ +int dh_KDF_X9_42_asn1(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const char *cek_alg, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md, + OSSL_LIB_CTX *libctx, const char *propq) { - int ret = 0, nid; + int ret = 0; EVP_KDF_CTX *kctx = NULL; EVP_KDF *kdf = NULL; - const char *oid_sn; OSSL_PARAM params[5], *p = params; const char *mdname = EVP_MD_name(md); - const OSSL_PROVIDER *prov = EVP_MD_provider(md); - OPENSSL_CTX *provctx = ossl_provider_library_context(prov); - nid = OBJ_obj2nid(key_oid); - if (nid == NID_undef) - return 0; - oid_sn = OBJ_nid2sn(nid); - if (oid_sn == NULL) - return 0; - - kdf = EVP_KDF_fetch(provctx, OSSL_KDF_NAME_X942KDF, NULL); - if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X942KDF, propq); + kctx = EVP_KDF_CTX_new(kdf); + if (kctx == NULL) goto err; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, @@ -56,13 +50,35 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_UKM, (unsigned char *)ukm, ukmlen); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, - (char *)oid_sn, 0); + (char *)cek_alg, 0); *p = OSSL_PARAM_construct_end(); ret = EVP_KDF_CTX_set_params(kctx, params) > 0 - && EVP_KDF_derive(kctx, out, outlen) > 0; + && EVP_KDF_derive(kctx, out, outlen) > 0; err: EVP_KDF_CTX_free(kctx); EVP_KDF_free(kdf); return ret; } -#endif /* OPENSSL_NO_CMS */ + +#if !defined(FIPS_MODULE) +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md) +{ + int nid; + const char *key_alg = NULL; + const OSSL_PROVIDER *prov = EVP_MD_provider(md); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + + nid = OBJ_obj2nid(key_oid); + if (nid == NID_undef) + return 0; + key_alg = OBJ_nid2sn(nid); + if (key_alg == NULL) + return 0; + + return dh_KDF_X9_42_asn1(out, outlen, Z, Zlen, key_alg, + ukm, ukmlen, md, libctx, NULL); +} +#endif /* !defined(FIPS_MODULE) */ diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 3b4da19cd2..8d9c72d65c 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -155,7 +155,7 @@ static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, static int dh_init(DH *dh) { dh->flags |= DH_FLAG_CACHE_MONT_P; - ffc_params_init(&dh->params); + ossl_ffc_params_init(&dh->params); dh->dirty_cnt++; return 1; } @@ -260,8 +260,8 @@ static int generate_key(DH *dh) || dh->length > BN_num_bits(dh->params.q)) goto err; /* dh->length = maximum bit length of generated private key */ - if (!ffc_generate_private_key(ctx, &dh->params, dh->length, - max_strength, priv_key)) + if (!ossl_ffc_generate_private_key(ctx, &dh->params, dh->length, + max_strength, priv_key)) goto err; } else { #ifdef FIPS_MODULE @@ -288,18 +288,18 @@ static int generate_key(DH *dh) #endif { /* Do a partial check for invalid p, q, g */ - if (!ffc_params_simple_validate(dh->libctx, &dh->params, - FFC_PARAM_TYPE_DH)) + if (!ossl_ffc_params_simple_validate(dh->libctx, &dh->params, + FFC_PARAM_TYPE_DH)) goto err; /* * For FFC FIPS 186-4 keygen * security strength s = 112, * Max Private key size N = len(q) */ - if (!ffc_generate_private_key(ctx, &dh->params, - BN_num_bits(dh->params.q), - MIN_STRENGTH, - priv_key)) + if (!ossl_ffc_generate_private_key(ctx, &dh->params, + BN_num_bits(dh->params.q), + MIN_STRENGTH, + priv_key)) goto err; } } diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 2a3921a137..94978a2cb2 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -24,7 +24,7 @@ #include "crypto/dh.h" #include "dh_local.h" -static DH *dh_new_intern(ENGINE *engine, OPENSSL_CTX *libctx); +static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); #ifndef FIPS_MODULE int DH_set_method(DH *dh, const DH_METHOD *meth) @@ -63,12 +63,12 @@ DH *DH_new_method(ENGINE *engine) } #endif /* !FIPS_MODULE */ -DH *dh_new_with_libctx(OPENSSL_CTX *libctx) +DH *dh_new_ex(OSSL_LIB_CTX *libctx) { return dh_new_intern(NULL, libctx); } -static DH *dh_new_intern(ENGINE *engine, OPENSSL_CTX *libctx) +static DH *dh_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DH *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -149,7 +149,7 @@ void DH_free(DH *r) CRYPTO_THREAD_lock_free(r->lock); - ffc_params_cleanup(&r->params); + ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); @@ -204,7 +204,7 @@ int DH_security_bits(const DH *dh) void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { - ffc_params_get0_pqg(&dh->params, p, q, g); + ossl_ffc_params_get0_pqg(&dh->params, p, q, g); } int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) @@ -217,7 +217,7 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) || (dh->params.g == NULL && g == NULL)) return 0; - ffc_params_set0_pqg(&dh->params, p, q, g); + ossl_ffc_params_set0_pqg(&dh->params, p, q, g); dh_cache_named_group(dh); if (q != NULL) dh->length = BN_num_bits(q); @@ -337,202 +337,10 @@ int dh_ffc_params_fromdata(DH *dh, const OSSL_PARAM params[]) if (ffc == NULL) return 0; - ret = ffc_params_fromdata(ffc, params); + ret = ossl_ffc_params_fromdata(ffc, params); if (ret) { dh_cache_named_group(dh); dh->dirty_cnt++; } return ret; } - -static int dh_paramgen_check(EVP_PKEY_CTX *ctx) -{ - if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - /* Uses the same return values as EVP_PKEY_CTX_ctrl */ - return -2; - } - /* If key type not DH return error */ - if (ctx->pmeth != NULL - && ctx->pmeth->pkey_id != EVP_PKEY_DH - && ctx->pmeth->pkey_id != EVP_PKEY_DHX) - return -1; - return 1; -} - -int EVP_PKEY_CTX_set_dh_paramgen_gindex(EVP_PKEY_CTX *ctx, int gindex) -{ - int ret; - OSSL_PARAM params[2], *p = params; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - - *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GINDEX, &gindex); - *p++ = OSSL_PARAM_construct_end(); - - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dh_paramgen_seed(EVP_PKEY_CTX *ctx, - const unsigned char *seed, - size_t seedlen) -{ - int ret; - OSSL_PARAM params[2], *p = params; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - - *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_FFC_SEED, - (void *)seed, seedlen); - *p++ = OSSL_PARAM_construct_end(); - - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dh_paramgen_type(EVP_PKEY_CTX *ctx, int typ) -{ - int ret; - OSSL_PARAM params[2], *p = params; - const char *name; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - -#if !defined(FIPS_MODULE) - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL); -#endif - - name = dh_gen_type_id2name(typ); - if (name == NULL) - return 0; - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, - (char *) name, 0); - *p++ = OSSL_PARAM_construct_end(); - - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dh_paramgen_prime_len(EVP_PKEY_CTX *ctx, int pbits) -{ - int ret; - OSSL_PARAM params[2], *p = params; - size_t bits = pbits; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - -#if !defined(FIPS_MODULE) - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, pbits, - NULL); -#endif - *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_PBITS, &bits); - *p++ = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dh_paramgen_subprime_len(EVP_PKEY_CTX *ctx, int qbits) -{ - int ret; - OSSL_PARAM params[2], *p = params; - size_t bits2 = qbits; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - -#if !defined(FIPS_MODULE) - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, qbits, - NULL); -#endif - *p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_FFC_QBITS, &bits2); - *p++ = OSSL_PARAM_construct_end(); - - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen) -{ - int ret; - OSSL_PARAM params[2], *p = params; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - -#if !defined(FIPS_MODULE) - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL); -#endif - - *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen); - *p++ = OSSL_PARAM_construct_end(); - - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen) -{ - int ret; - OSSL_PARAM params[2], *p = params; - const char *name; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - -#if !defined(FIPS_MODULE) - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DH_RFC5114, gen, NULL); -#endif - name = ffc_named_group_from_uid(gen); - if (name == NULL) - return 0; - - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, - (void *)name, 0); - *p++ = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, params); -} - -int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen) -{ - return EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen); -} - -int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) -{ - int ret; - OSSL_PARAM params[2], *p = params; - const char *name; - - if ((ret = dh_paramgen_check(ctx)) <= 0) - return ret; - -#if !defined(FIPS_MODULE) - /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, - EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_DH_NID, nid, NULL); -#endif - name = ffc_named_group_from_uid(nid); - if (name == NULL) - return 0; - - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, - (void *)name, 0); - *p++ = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, params); -} diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h index 51c3f974e1..1ff075e3dc 100644 --- a/crypto/dh/dh_local.h +++ b/crypto/dh/dh_local.h @@ -32,7 +32,7 @@ struct dh_st { CRYPTO_EX_DATA ex_data; ENGINE *engine; #endif - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; const DH_METHOD *meth; CRYPTO_RWLOCK *lock; diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c index 39b79ffb36..d0e1c55002 100644 --- a/crypto/dh/dh_pmeth.c +++ b/crypto/dh/dh_pmeth.c @@ -172,11 +172,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_DH_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; -#ifdef OPENSSL_NO_CMS - if (p1 != EVP_PKEY_DH_KDF_NONE) -#else if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) -#endif return -2; dctx->kdf_type = p1; return 1; @@ -278,7 +274,7 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, return -2; } -static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx, +static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx, BN_GENCB *pcb) { DH *ret; @@ -301,20 +297,22 @@ static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx, } if (dctx->md != NULL) - ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL); + ossl_ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL); # ifndef FIPS_MODULE if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2) - rv = ffc_params_FIPS186_2_generate(libctx, &ret->params, - FFC_PARAM_TYPE_DH, - prime_len, subprime_len, &res, pcb); + rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); else # endif /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */ if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) - rv = ffc_params_FIPS186_4_generate(libctx, &ret->params, - FFC_PARAM_TYPE_DH, - prime_len, subprime_len, &res, pcb); + rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); if (rv <= 0) { DH_free(ret); return NULL; @@ -445,7 +443,6 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, *keylen = ret; return 1; } -#ifndef OPENSSL_NO_CMS else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; @@ -475,7 +472,6 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, OPENSSL_clear_free(Z, Zlen); return ret; } -#endif return 0; } diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 651b463235..208c4ec19f 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include "internal/cryptlib.h" @@ -300,7 +299,7 @@ static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) if (to->pkey.dsa == NULL) return 0; } - if (!ffc_params_copy(&to->pkey.dsa->params, &from->pkey.dsa->params)) + if (!ossl_ffc_params_copy(&to->pkey.dsa->params, &from->pkey.dsa->params)) return 0; to->pkey.dsa->dirty_cnt++; @@ -309,7 +308,7 @@ static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - return ffc_params_cmp(&a->pkey.dsa->params, &b->pkey.dsa->params, 1); + return ossl_ffc_params_cmp(&a->pkey.dsa->params, &b->pkey.dsa->params, 1); } static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -363,7 +362,7 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) goto err; if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off)) goto err; - if (!ffc_params_print(bp, &x->params, off)) + if (!ossl_ffc_params_print(bp, &x->params, off)) goto err; ret = 1; err: @@ -481,27 +480,6 @@ static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_NONE; - return 1; -#endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: *(int *)arg2 = NID_sha256; @@ -520,7 +498,7 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) } static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq) { DSA *dsa = from->pkey.dsa; diff --git a/crypto/dsa/dsa_check.c b/crypto/dsa/dsa_check.c index 01cf0f6341..0d38340840 100644 --- a/crypto/dsa/dsa_check.c +++ b/crypto/dsa/dsa_check.c @@ -19,8 +19,8 @@ int dsa_check_params(const DSA *dsa, int *ret) * (2b) FFC domain params conform to FIPS-186-4 explicit domain param * validity tests. */ - return ffc_params_FIPS186_4_validate(dsa->libctx, &dsa->params, - FFC_PARAM_TYPE_DSA, ret, NULL); + return ossl_ffc_params_FIPS186_4_validate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, ret, NULL); } /* @@ -28,7 +28,7 @@ int dsa_check_params(const DSA *dsa, int *ret) */ int dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret) { - return ffc_validate_public_key(&dsa->params, pub_key, ret); + return ossl_ffc_validate_public_key(&dsa->params, pub_key, ret); } /* @@ -38,7 +38,7 @@ int dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret) */ int dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret) { - return ffc_validate_public_key_partial(&dsa->params, pub_key, ret); + return ossl_ffc_validate_public_key_partial(&dsa->params, pub_key, ret); } int dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret) @@ -46,7 +46,7 @@ int dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret) *ret = 0; return (dsa->params.q != NULL - && ffc_validate_private_key(dsa->params.q, priv_key, ret)); + && ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret)); } /* diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c index 94b3da8754..9d6d9a8d4a 100644 --- a/crypto/dsa/dsa_gen.c +++ b/crypto/dsa/dsa_gen.c @@ -30,14 +30,14 @@ int dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, #ifndef FIPS_MODULE if (type == DSA_PARAMGEN_TYPE_FIPS_186_2) - ret = ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params, - FFC_PARAM_TYPE_DSA, - pbits, qbits, &res, cb); + ret = ossl_ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, + pbits, qbits, &res, cb); else #endif - ret = ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params, - FFC_PARAM_TYPE_DSA, - pbits, qbits, &res, cb); + ret = ossl_ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA, + pbits, qbits, &res, cb); if (ret > 0) dsa->dirty_cnt++; return ret; @@ -53,7 +53,8 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits, return dsa->meth->dsa_paramgen(dsa, bits, seed_in, seed_len, counter_ret, h_ret, cb); if (seed_in != NULL - && !ffc_params_set_validate_params(&dsa->params, seed_in, seed_len, -1)) + && !ossl_ffc_params_set_validate_params(&dsa->params, seed_in, seed_len, + -1)) return 0; /* The old code used FIPS 186-2 DSA Parameter generation */ diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index b537ec0b3c..899663353f 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -18,6 +18,7 @@ #include "internal/cryptlib.h" #include #include +#include "prov/providercommon.h" #include "crypto/dsa.h" #include "dsa_local.h" @@ -75,8 +76,8 @@ static int dsa_keygen(DSA *dsa, int pairwise_test) } /* Do a partial check for invalid p, q, g */ - if (!ffc_params_simple_validate(dsa->libctx, &dsa->params, - FFC_PARAM_TYPE_DSA)) + if (!ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params, + FFC_PARAM_TYPE_DSA)) goto err; /* @@ -84,8 +85,9 @@ static int dsa_keygen(DSA *dsa, int pairwise_test) * security strength s = 112, * Max Private key size N = len(q) */ - if (!ffc_generate_private_key(ctx, &dsa->params, BN_num_bits(dsa->params.q), - MIN_STRENGTH, priv_key)) + if (!ossl_ffc_generate_private_key(ctx, &dsa->params, + BN_num_bits(dsa->params.q), + MIN_STRENGTH, priv_key)) goto err; if (dsa->pub_key == NULL) { @@ -113,6 +115,7 @@ static int dsa_keygen(DSA *dsa, int pairwise_test) OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg); ok = dsa_keygen_pairwise_test(dsa, cb, cbarg); if (!ok) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); BN_free(dsa->pub_key); BN_clear_free(dsa->priv_key); dsa->pub_key = NULL; diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index e71a8c8f8e..9df2818ecd 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -25,7 +25,7 @@ #include "crypto/dsa.h" #include "crypto/dh.h" /* required by DSA_dup_DH() */ -static DSA *dsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx); +static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); #ifndef FIPS_MODULE @@ -56,7 +56,7 @@ DH *DSA_dup_DH(const DSA *r) if (ret == NULL) goto err; - if (!ffc_params_copy(dh_get0_params(ret), &r->params)) + if (!ossl_ffc_params_copy(dh_get0_params(ret), &r->params)) goto err; if (r->pub_key != NULL) { @@ -132,7 +132,7 @@ const DSA_METHOD *DSA_get_method(DSA *d) return d->meth; } -static DSA *dsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx) +static DSA *dsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { DSA *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -194,7 +194,7 @@ DSA *DSA_new_method(ENGINE *engine) return dsa_new_intern(engine, NULL); } -DSA *dsa_new_with_ctx(OPENSSL_CTX *libctx) +DSA *dsa_new_with_ctx(OSSL_LIB_CTX *libctx) { return dsa_new_intern(NULL, libctx); } @@ -231,7 +231,7 @@ void DSA_free(DSA *r) CRYPTO_THREAD_lock_free(r->lock); - ffc_params_cleanup(&r->params); + ossl_ffc_params_cleanup(&r->params); BN_clear_free(r->pub_key); BN_clear_free(r->priv_key); OPENSSL_free(r); @@ -252,7 +252,7 @@ int DSA_up_ref(DSA *r) void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) { - ffc_params_get0_pqg(&d->params, p, q, g); + ossl_ffc_params_get0_pqg(&d->params, p, q, g); } int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) @@ -265,7 +265,7 @@ int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) || (d->params.g == NULL && g == NULL)) return 0; - ffc_params_set0_pqg(&d->params, p, q, g); + ossl_ffc_params_set0_pqg(&d->params, p, q, g); d->dirty_cnt++; return 1; @@ -356,7 +356,7 @@ int dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]) if (ffc == NULL) return 0; - ret = ffc_params_fromdata(ffc, params); + ret = ossl_ffc_params_fromdata(ffc, params); if (ret) dsa->dirty_cnt++; return ret; diff --git a/crypto/dsa/dsa_local.h b/crypto/dsa/dsa_local.h index 7b43ec6108..240e84f11e 100644 --- a/crypto/dsa/dsa_local.h +++ b/crypto/dsa/dsa_local.h @@ -32,7 +32,7 @@ struct dsa_st { /* functional reference if 'meth' is ENGINE-provided */ ENGINE *engine; CRYPTO_RWLOCK *lock; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; /* Provider data */ size_t dirty_cnt; /* If any key material changes, increment this */ diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index b52fa1c00b..547b0283fa 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -426,7 +426,7 @@ static int dsa_do_verify(const unsigned char *dgst, int dgst_len, static int dsa_init(DSA *dsa) { dsa->flags |= DSA_FLAG_CACHE_MONT_P; - ffc_params_init(&dsa->params); + ossl_ffc_params_init(&dsa->params); dsa->dirty_cnt++; return 1; } diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c index 7b364059e7..0f5a6157ae 100644 --- a/crypto/dsa/dsa_pmeth.c +++ b/crypto/dsa/dsa_pmeth.c @@ -218,10 +218,11 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return 0; } if (dctx->md != NULL) - ffc_set_digest(&dsa->params, EVP_MD_name(dctx->md), NULL); + ossl_ffc_set_digest(&dsa->params, EVP_MD_name(dctx->md), NULL); - ret = ffc_params_FIPS186_4_generate(NULL, &dsa->params, FFC_PARAM_TYPE_DSA, - dctx->nbits, dctx->qbits, &res, pcb); + ret = ossl_ffc_params_FIPS186_4_generate(NULL, &dsa->params, + FFC_PARAM_TYPE_DSA, dctx->nbits, + dctx->qbits, &res, pcb); BN_GENCB_free(pcb); if (ret > 0) EVP_PKEY_assign_DSA(pkey, dsa); diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c index 71a60bb39b..6a887d8190 100644 --- a/crypto/dsa/dsa_sign.c +++ b/crypto/dsa/dsa_sign.c @@ -65,7 +65,7 @@ DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) sig->r = BN_new(); if (sig->s == NULL) sig->s = BN_new(); - if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { + if (ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { if (psig == NULL || *psig == NULL) DSA_SIG_free(sig); return NULL; diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c index b8bbed87e8..b34984b919 100644 --- a/crypto/dso/dso_dlfcn.c +++ b/crypto/dso/dso_dlfcn.c @@ -19,8 +19,6 @@ #include "dso_local.h" #include "e_os.h" -DEFINE_STACK_OF(void) - #ifdef DSO_DLFCN # ifdef HAVE_DLFCN_H @@ -32,7 +30,7 @@ DEFINE_STACK_OF(void) # if defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ (defined(__osf__) && !defined(RTLD_NEXT)) || \ (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ - defined(__ANDROID__) + defined(__ANDROID__) || defined(__TANDEM) # undef HAVE_DLINFO # endif # endif diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c index 6c347b58d6..6e2b8d944d 100644 --- a/crypto/dso/dso_lib.c +++ b/crypto/dso/dso_lib.c @@ -10,8 +10,6 @@ #include "dso_local.h" #include "internal/refcount.h" -DEFINE_STACK_OF(void) - static DSO_METHOD *default_DSO_meth = NULL; static DSO *DSO_new_method(DSO_METHOD *meth) diff --git a/crypto/ec/asm/ecp_nistz256-armv4.S b/crypto/ec/asm/ecp_nistz256-armv4.S index 19405ab5b6..1b174db982 100644 --- a/crypto/ec/asm/ecp_nistz256-armv4.S +++ b/crypto/ec/asm/ecp_nistz256-armv4.S @@ -3851,9 +3851,9 @@ ecp_nistz256_point_add: ldr r14,[sp,#32*18+12] @ ~is_equal(S1,S2) mvn r10,r10 @ -1/0 -> 0/-1 mvn r12,r12 @ -1/0 -> 0/-1 - orr r11,r10 - orr r11,r12 - orrs r11,r14 @ set flags + orr r11,r11,r10 + orr r11,r11,r12 + orrs r11,r11,r14 @ set flags @ if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) bne .Ladd_proceed diff --git a/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/ec/asm/ecp_nistz256-armv4.pl index 32fd9087e0..0adad26cb1 100755 --- a/crypto/ec/asm/ecp_nistz256-armv4.pl +++ b/crypto/ec/asm/ecp_nistz256-armv4.pl @@ -1521,9 +1521,9 @@ ldr $t2,[sp,#32*18+12] @ ~is_equal(S1,S2) mvn $t0,$t0 @ -1/0 -> 0/-1 mvn $t1,$t1 @ -1/0 -> 0/-1 - orr $a0,$t0 - orr $a0,$t1 - orrs $a0,$t2 @ set flags + orr $a0,$a0,$t0 + orr $a0,$a0,$t1 + orrs $a0,$a0,$t2 @ set flags @ if(~is_equal(U1,U2) | in1infty | in2infty | ~is_equal(S1,S2)) bne .Ladd_proceed diff --git a/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/ec/asm/ecp_nistz256-x86_64.pl index fc8719cb62..430b14c86d 100755 --- a/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -74,7 +74,7 @@ $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $avx = ($ver>=3.0) + ($ver>=3.01); $addx = ($ver>=3.03); diff --git a/crypto/ec/asm/x25519-x86_64.pl b/crypto/ec/asm/x25519-x86_64.pl index a8b145e6a0..d2285269a3 100755 --- a/crypto/ec/asm/x25519-x86_64.pl +++ b/crypto/ec/asm/x25519-x86_64.pl @@ -92,7 +92,7 @@ $addx = ($1>=12); } -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { +if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)/) { my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 $addx = ($ver>=3.03); } diff --git a/crypto/ec/build.info b/crypto/ec/build.info index 8e4a6a9f4b..496a932e4c 100644 --- a/crypto/ec/build.info +++ b/crypto/ec/build.info @@ -50,14 +50,14 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \ ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \ curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \ curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \ - $ECASM ec_backend.c ecx_backend.c + $ECASM ec_backend.c ecx_backend.c ecdh_kdf.c IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}] $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c ENDIF SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \ - ec_err.c ecdh_kdf.c eck_prn.c ec_ctrl.c + ec_err.c eck_prn.c ec_ctrl.c SOURCE[../../providers/libfips.a]=$COMMON # Implementations are now spread across several libraries, so the defines diff --git a/crypto/ec/curve25519.c b/crypto/ec/curve25519.c index 19fdb8d74f..d939003043 100644 --- a/crypto/ec/curve25519.c +++ b/crypto/ec/curve25519.c @@ -5439,7 +5439,7 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[32], const uint8_t private_key[32], - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { uint8_t az[SHA512_DIGEST_LENGTH]; uint8_t nonce[SHA512_DIGEST_LENGTH]; @@ -5495,7 +5495,7 @@ static const char allzeroes[15]; int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[64], const uint8_t public_key[32], - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { int i; ge_p3 A; @@ -5577,15 +5577,15 @@ int ED25519_verify(const uint8_t *message, size_t message_len, return res; } -int ED25519_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[32], - const uint8_t private_key[32]) +int ED25519_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[32], + const uint8_t private_key[32], const char *propq) { uint8_t az[SHA512_DIGEST_LENGTH]; ge_p3 A; int r; EVP_MD *sha512 = NULL; - sha512 = EVP_MD_fetch(ctx, SN_sha512, NULL); + sha512 = EVP_MD_fetch(ctx, SN_sha512, propq); if (sha512 == NULL) return 0; r = EVP_Digest(private_key, 32, az, NULL, sha512, NULL); diff --git a/crypto/ec/curve448/curve448_local.h b/crypto/ec/curve448/curve448_local.h index 84dd157d94..c5ffa75f6b 100644 --- a/crypto/ec/curve448/curve448_local.h +++ b/crypto/ec/curve448/curve448_local.h @@ -10,12 +10,12 @@ # define OSSL_CRYPTO_EC_CURVE448_LOCAL_H # include "curve448utils.h" -int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], +int ED448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len); + const uint8_t *context, size_t context_len, const char *propq); -int ED448ph_verify(OPENSSL_CTX *ctx, const uint8_t hash[64], +int ED448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64], const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len); + const uint8_t *context, size_t context_len, const char *propq); #endif /* OSSL_CRYPTO_EC_CURVE448_LOCAL_H */ diff --git a/crypto/ec/curve448/ed448.h b/crypto/ec/curve448/ed448.h index 4f99fe6901..3a1a9b46d6 100644 --- a/crypto/ec/curve448/ed448.h +++ b/crypto/ec/curve448/ed448.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -38,9 +38,10 @@ * privkey (in): The private key. */ c448_error_t c448_ed448_derive_public_key( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t pubkey [EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey [EDDSA_448_PRIVATE_BYTES]); + const uint8_t privkey [EDDSA_448_PRIVATE_BYTES], + const char *propq); /* * EdDSA signing. @@ -60,13 +61,14 @@ c448_error_t c448_ed448_derive_public_key( * disambiguation. For Ed448 it is safe. */ c448_error_t c448_ed448_sign( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - size_t context_len); + size_t context_len, + const char *propq); /* * EdDSA signing with prehash. @@ -85,13 +87,14 @@ c448_error_t c448_ed448_sign( * disambiguation. For Ed448 it is safe. */ c448_error_t c448_ed448_sign_prehash( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - size_t context_len); + size_t context_len, + const char *propq); /* * EdDSA signature verification. @@ -111,14 +114,15 @@ c448_error_t c448_ed448_sign_prehash( * non-prehashed messages, at least without some very careful protocol-level * disambiguation. For Ed448 it is safe. */ -c448_error_t c448_ed448_verify(OPENSSL_CTX *ctx, +c448_error_t c448_ed448_verify(OSSL_LIB_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - uint8_t context_len); + uint8_t context_len, + const char *propq); /* * EdDSA signature verification. @@ -138,12 +142,13 @@ c448_error_t c448_ed448_verify(OPENSSL_CTX *ctx, * disambiguation. For Ed448 it is safe. */ c448_error_t c448_ed448_verify_prehash( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - uint8_t context_len); + uint8_t context_len, + const char *propq); /* * EdDSA point encoding. Used internally, exposed externally. @@ -194,8 +199,9 @@ c448_error_t curve448_point_decode_like_eddsa_and_mul_by_ratio( * ed (in): The EdDSA private key */ c448_error_t c448_ed448_convert_private_key_to_x448( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], - const uint8_t ed[EDDSA_448_PRIVATE_BYTES]); + const uint8_t ed[EDDSA_448_PRIVATE_BYTES], + const char *propq); #endif /* OSSL_CRYPTO_EC_CURVE448_ED448_H */ diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c index f4fbaf7539..d4c7f1562a 100644 --- a/crypto/ec/curve448/eddsa.c +++ b/crypto/ec/curve448/eddsa.c @@ -20,8 +20,9 @@ #define COFACTOR 4 -static c448_error_t oneshot_hash(OPENSSL_CTX *ctx, uint8_t *out, size_t outlen, - const uint8_t *in, size_t inlen) +static c448_error_t oneshot_hash(OSSL_LIB_CTX *ctx, uint8_t *out, size_t outlen, + const uint8_t *in, size_t inlen, + const char *propq) { EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); EVP_MD *shake256 = NULL; @@ -30,7 +31,7 @@ static c448_error_t oneshot_hash(OPENSSL_CTX *ctx, uint8_t *out, size_t outlen, if (hashctx == NULL) return C448_FAILURE; - shake256 = EVP_MD_fetch(ctx, "SHAKE256", NULL); + shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq); if (shake256 == NULL) goto err; @@ -53,11 +54,12 @@ static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]) secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80; } -static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, +static c448_error_t hash_init_with_dom(OSSL_LIB_CTX *ctx, EVP_MD_CTX *hashctx, uint8_t prehashed, uint8_t for_prehash, const uint8_t *context, - size_t context_len) + size_t context_len, + const char *propq) { #ifdef CHARSET_EBCDIC const char dom_s[] = {0x53, 0x69, 0x67, 0x45, @@ -75,7 +77,7 @@ static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, - (for_prehash == 0 ? 1 : 0)); dom[1] = (uint8_t)context_len; - shake256 = EVP_MD_fetch(ctx, "SHAKE256", NULL); + shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq); if (shake256 == NULL) return C448_FAILURE; @@ -93,20 +95,22 @@ static c448_error_t hash_init_with_dom(OPENSSL_CTX *ctx, EVP_MD_CTX *hashctx, /* In this file because it uses the hash */ c448_error_t c448_ed448_convert_private_key_to_x448( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t x[X448_PRIVATE_BYTES], - const uint8_t ed [EDDSA_448_PRIVATE_BYTES]) + const uint8_t ed [EDDSA_448_PRIVATE_BYTES], + const char *propq) { /* pass the private key through oneshot_hash function */ /* and keep the first X448_PRIVATE_BYTES bytes */ return oneshot_hash(ctx, x, X448_PRIVATE_BYTES, ed, - EDDSA_448_PRIVATE_BYTES); + EDDSA_448_PRIVATE_BYTES, propq); } c448_error_t c448_ed448_derive_public_key( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey[EDDSA_448_PRIVATE_BYTES]) + const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], + const char *propq) { /* only this much used for keygen */ uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]; @@ -116,7 +120,8 @@ c448_error_t c448_ed448_derive_public_key( if (!oneshot_hash(ctx, secret_scalar_ser, sizeof(secret_scalar_ser), privkey, - EDDSA_448_PRIVATE_BYTES)) + EDDSA_448_PRIVATE_BYTES, + propq)) return C448_FAILURE; clamp(secret_scalar_ser); @@ -148,13 +153,13 @@ c448_error_t c448_ed448_derive_public_key( } c448_error_t c448_ed448_sign( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { curve448_scalar_t secret_scalar; EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); @@ -175,7 +180,7 @@ c448_error_t c448_ed448_sign( uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2]; if (!oneshot_hash(ctx, expanded, sizeof(expanded), privkey, - EDDSA_448_PRIVATE_BYTES)) + EDDSA_448_PRIVATE_BYTES, propq)) goto err; clamp(expanded); curve448_scalar_decode_long(secret_scalar, expanded, @@ -183,7 +188,7 @@ c448_error_t c448_ed448_sign( /* Hash to create the nonce */ if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, - context_len) + context_len, propq) || !EVP_DigestUpdate(hashctx, expanded + EDDSA_448_PRIVATE_BYTES, EDDSA_448_PRIVATE_BYTES) @@ -224,7 +229,8 @@ c448_error_t c448_ed448_sign( uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES]; /* Compute the challenge */ - if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len) + if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len, + propq) || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point)) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) @@ -255,24 +261,24 @@ c448_error_t c448_ed448_sign( } c448_error_t c448_ed448_sign_prehash( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { return c448_ed448_sign(ctx, signature, privkey, pubkey, hash, 64, 1, - context, context_len); + context, context_len, propq); } c448_error_t c448_ed448_verify( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, - uint8_t context_len) + uint8_t context_len, const char *propq) { curve448_point_t pk_point, r_point; c448_error_t error; @@ -321,7 +327,7 @@ c448_error_t c448_ed448_verify( if (hashctx == NULL || !hash_init_with_dom(ctx, hashctx, prehashed, 0, context, - context_len) + context_len, propq) || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES) || !EVP_DigestUpdate(hashctx, message, message_len) @@ -350,54 +356,55 @@ c448_error_t c448_ed448_verify( } c448_error_t c448_ed448_verify_prehash( - OPENSSL_CTX *ctx, + OSSL_LIB_CTX *ctx, const uint8_t signature[EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], const uint8_t hash[64], const uint8_t *context, - uint8_t context_len) + uint8_t context_len, const char *propq) { return c448_ed448_verify(ctx, signature, pubkey, hash, 64, 1, context, - context_len); + context_len, propq); } -int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message, +int ED448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[57], const uint8_t private_key[57], const uint8_t *context, - size_t context_len) + size_t context_len, const char *propq) { return c448_ed448_sign(ctx, out_sig, private_key, public_key, message, - message_len, 0, context, context_len) + message_len, 0, context, context_len,propq) == C448_SUCCESS; } -int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len, +int ED448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len) + const uint8_t *context, size_t context_len, const char *propq) { return c448_ed448_verify(ctx, signature, public_key, message, message_len, - 0, context, (uint8_t)context_len) == C448_SUCCESS; + 0, context, (uint8_t)context_len, + propq) == C448_SUCCESS; } -int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], +int ED448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64], const uint8_t public_key[57], const uint8_t private_key[57], - const uint8_t *context, size_t context_len) + const uint8_t *context, size_t context_len, const char *propq) { return c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key, hash, - context, context_len) == C448_SUCCESS; + context, context_len, propq) == C448_SUCCESS; } -int ED448ph_verify(OPENSSL_CTX *ctx, const uint8_t hash[64], +int ED448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64], const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len) + const uint8_t *context, size_t context_len, const char *propq) { return c448_ed448_verify_prehash(ctx, signature, public_key, hash, context, - (uint8_t)context_len) == C448_SUCCESS; + (uint8_t)context_len, propq) == C448_SUCCESS; } -int ED448_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[57], - const uint8_t private_key[57]) +int ED448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57], + const uint8_t private_key[57], const char *propq) { - return c448_ed448_derive_public_key(ctx, out_public_key, private_key) + return c448_ed448_derive_public_key(ctx, out_public_key, private_key, propq) == C448_SUCCESS; } diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index 8a33b3232c..8857d3e388 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -18,23 +18,19 @@ #include #include #include -#include #include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/x509.h" #include #include "openssl/param_build.h" #include "ec_local.h" -#ifndef OPENSSL_NO_CMS -static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); -static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); -#endif - static int eckey_param2type(int *pptype, void **ppval, const EC_KEY *ec_key) { const EC_GROUP *group; int nid; + if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); return 0; @@ -105,12 +101,12 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) } static EC_KEY *eckey_type2param(int ptype, const void *pval, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { EC_KEY *eckey = NULL; EC_GROUP *group = NULL; - if ((eckey = EC_KEY_new_with_libctx(libctx, propq)) == NULL) { + if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) { ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); goto ecerr; } @@ -132,8 +128,7 @@ static EC_KEY *eckey_type2param(int ptype, const void *pval, * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID */ - group = EC_GROUP_new_by_curve_name_with_libctx(libctx, propq, - OBJ_obj2nid(poid)); + group = EC_GROUP_new_by_curve_name_ex(libctx, propq, OBJ_obj2nid(poid)); if (group == NULL) goto ecerr; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); @@ -160,17 +155,18 @@ static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; + OSSL_LIB_CTX *libctx = NULL; + const char *propq = NULL; - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + if (!X509_PUBKEY_get0_libctx(&libctx, &propq, pubkey) + || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); - eckey = eckey_type2param(ptype, pval, NULL, NULL); + eckey = eckey_type2param(ptype, pval, libctx, propq); - if (!eckey) { - ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); + if (!eckey) return 0; - } /* We have parameters now set public key */ if (!o2i_ECPublicKey(&eckey, &p, pklen)) { @@ -192,6 +188,7 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), *pb = EC_KEY_get0_public_key(b->pkey.ec); + if (group == NULL || pa == NULL || pb == NULL) return -2; r = EC_POINT_cmp(group, pa, pb, NULL); @@ -202,10 +199,8 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } -static int eckey_priv_decode_with_libctx(EVP_PKEY *pkey, - const PKCS8_PRIV_KEY_INFO *p8, - OPENSSL_CTX *libctx, - const char *propq) +static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, + OSSL_LIB_CTX *libctx, const char *propq) { const unsigned char *p = NULL; const void *pval; @@ -218,22 +213,19 @@ static int eckey_priv_decode_with_libctx(EVP_PKEY *pkey, X509_ALGOR_get0(NULL, &ptype, &pval, palg); eckey = eckey_type2param(ptype, pval, libctx, propq); - if (eckey == NULL) - goto ecliberr; + goto err; /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { ECerr(0, EC_R_DECODE_ERROR); - goto ecerr; + goto err; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; - ecliberr: - ECerr(0, ERR_R_EC_LIB); - ecerr: + err: EC_KEY_free(eckey); return 0; } @@ -299,6 +291,7 @@ static int ec_bits(const EVP_PKEY *pkey) static int ec_security_bits(const EVP_PKEY *pkey) { int ecbits = ec_bits(pkey); + if (ecbits >= 512) return 256; if (ecbits >= 384) @@ -343,6 +336,7 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), *group_b = EC_KEY_get0_group(b->pkey.ec); + if (group_a == NULL || group_b == NULL) return -2; if (EC_GROUP_cmp(group_a, group_b, NULL)) @@ -430,10 +424,8 @@ static int eckey_param_decode(EVP_PKEY *pkey, { EC_KEY *eckey; - if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) { - ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); + if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) return 0; - } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; } @@ -466,10 +458,8 @@ static int old_ec_priv_decode(EVP_PKEY *pkey, { EC_KEY *ec; - if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) { - ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); + if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) return 0; - } EVP_PKEY_assign_EC_KEY(pkey, ec); return 1; } @@ -486,6 +476,7 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) if (arg1 == 0) { int snid, hnid; X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); if (alg1 == NULL || alg1->algorithm == NULL) return -1; @@ -497,34 +488,6 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); } return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 1) - return ecdh_cms_decrypt(arg2); - else if (arg1 == 0) - return ecdh_cms_encrypt(arg2); - return -2; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_AGREE; - return 1; -#endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) { @@ -597,50 +560,14 @@ size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey) return pkey->pkey.ec->dirty_cnt; } -static ossl_inline -int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl) -{ - const EC_GROUP *ecg; - int curve_nid; - - if (eckey == NULL) - return 0; - - ecg = EC_KEY_get0_group(eckey); - if (ecg == NULL) - return 0; - - curve_nid = EC_GROUP_get_curve_name(ecg); - - if (curve_nid == NID_undef) { - /* explicit parameters */ - - /* - * TODO(3.0): should we support explicit parameters curves? - */ - return 0; - } else { - /* named curve */ - const char *curve_name = NULL; - - if ((curve_name = OBJ_nid2sn(curve_nid)) == NULL) - return 0; - - if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME, curve_name, 0)) - return 0; - } - - return 1; -} - static int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq) { const EC_KEY *eckey = NULL; const EC_GROUP *ecg = NULL; - unsigned char *pub_key_buf = NULL; + unsigned char *pub_key_buf = NULL, *gen_buf = NULL; size_t pub_key_buflen; OSSL_PARAM_BLD *tmpl; OSSL_PARAM *params = NULL; @@ -666,8 +593,17 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, if (tmpl == NULL) return 0; + /* + * EC_POINT_point2buf() can generate random numbers in some + * implementations so we need to ensure we use the correct libctx. + */ + bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) + goto err; + BN_CTX_start(bnctx); + /* export the domain parameters */ - if (!ecparams_to_params(eckey, tmpl)) + if (!ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf)) goto err; selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; @@ -675,14 +611,6 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, pub_point = EC_KEY_get0_public_key(eckey); if (pub_point != NULL) { - /* - * EC_POINT_point2buf() can generate random numbers in some - * implementations so we need to ensure we use the correct libctx. - */ - bnctx = BN_CTX_new_ex(libctx); - if (bnctx == NULL) - goto err; - /* convert pub_point to a octet string according to the SECG standard */ if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point, POINT_CONVERSION_COMPRESSED, @@ -769,6 +697,8 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata, OSSL_PARAM_BLD_free(tmpl); OSSL_PARAM_BLD_free_params(params); OPENSSL_free(pub_key_buf); + OPENSSL_free(gen_buf); + BN_CTX_end(bnctx); BN_CTX_free(bnctx); return rv; } @@ -777,14 +707,14 @@ static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx) { EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - EC_KEY *ec = EC_KEY_new_with_libctx(pctx->libctx, pctx->propquery); + EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery); if (ec == NULL) { ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return 0; } - if (!ec_key_domparams_fromdata(ec, params) + if (!ec_group_fromdata(ec, params) || !ec_key_otherparams_fromdata(ec, params) || !ec_key_fromdata(ec, params, 1) || !EVP_PKEY_assign_EC_KEY(pkey, ec)) { @@ -841,7 +771,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { ec_pkey_dirty_cnt, ec_pkey_export_to, ec_pkey_import_from, - eckey_priv_decode_with_libctx + eckey_priv_decode_ex }; #if !defined(OPENSSL_NO_SM2) @@ -864,320 +794,3 @@ int ECParameters_print(BIO *bp, const EC_KEY *x) { return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM); } - -#ifndef OPENSSL_NO_CMS - -static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, - X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) -{ - const ASN1_OBJECT *aoid; - int atype; - const void *aval; - int rv = 0; - EVP_PKEY *pkpeer = NULL; - EC_KEY *ecpeer = NULL; - const unsigned char *p; - int plen; - X509_ALGOR_get0(&aoid, &atype, &aval, alg); - if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) - goto err; - /* If absent parameters get group from main key */ - if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { - const EC_GROUP *grp; - EVP_PKEY *pk; - pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (pk == NULL) - goto err; - grp = EC_KEY_get0_group(pk->pkey.ec); - ecpeer = EC_KEY_new(); - if (ecpeer == NULL) - goto err; - if (!EC_KEY_set_group(ecpeer, grp)) - goto err; - } else { - ecpeer = eckey_type2param(atype, aval, pctx->libctx, pctx->propquery); - if (!ecpeer) - goto err; - } - /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); - p = ASN1_STRING_get0_data(pubkey); - if (p == NULL || plen == 0) - goto err; - if (!o2i_ECPublicKey(&ecpeer, &p, plen)) - goto err; - pkpeer = EVP_PKEY_new(); - if (pkpeer == NULL) - goto err; - EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); - if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) - rv = 1; - err: - EC_KEY_free(ecpeer); - EVP_PKEY_free(pkpeer); - return rv; -} - -/* Set KDF parameters based on KDF NID */ -static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) -{ - int kdf_nid, kdfmd_nid, cofactor; - const EVP_MD *kdf_md; - if (eckdf_nid == NID_undef) - return 0; - - /* Lookup KDF type, cofactor mode and digest */ - if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) - return 0; - - if (kdf_nid == NID_dh_std_kdf) - cofactor = 0; - else if (kdf_nid == NID_dh_cofactor_kdf) - cofactor = 1; - else - return 0; - - if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) - return 0; - - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_63) <= 0) - return 0; - - kdf_md = EVP_get_digestbynid(kdfmd_nid); - if (!kdf_md) - return 0; - - if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) - return 0; - return 1; -} - -static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) -{ - int rv = 0; - - X509_ALGOR *alg, *kekalg = NULL; - ASN1_OCTET_STRING *ukm; - const unsigned char *p; - unsigned char *der = NULL; - int plen, keylen; - const EVP_CIPHER *kekcipher; - EVP_CIPHER_CTX *kekctx; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) - return 0; - - if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { - ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR); - return 0; - } - - if (alg->parameter->type != V_ASN1_SEQUENCE) - return 0; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - if (!kekalg) - goto err; - kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); - if (!kekctx) - goto err; - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) - goto err; - if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) - goto err; - if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) - goto err; - - keylen = EVP_CIPHER_CTX_key_length(kekctx); - if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); - - if (!plen) - goto err; - - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) - goto err; - der = NULL; - - rv = 1; - err: - X509_ALGOR_free(kekalg); - OPENSSL_free(der); - return rv; -} - -static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* See if we need to set peer key */ - if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { - X509_ALGOR *alg; - ASN1_BIT_STRING *pubkey; - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, - NULL, NULL, NULL)) - return 0; - if (!alg || !pubkey) - return 0; - if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { - ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR); - return 0; - } - } - /* Set ECDH derivation parameters and initialise unwrap context */ - if (!ecdh_cms_set_shared_info(pctx, ri)) { - ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR); - return 0; - } - return 1; -} - -static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - EVP_PKEY *pkey; - EVP_CIPHER_CTX *ctx; - int keylen; - X509_ALGOR *talg, *wrap_alg = NULL; - const ASN1_OBJECT *aoid; - ASN1_BIT_STRING *pubkey; - ASN1_STRING *wrap_str; - ASN1_OCTET_STRING *ukm; - unsigned char *penc = NULL; - int penclen; - int rv = 0; - int ecdh_nid, kdf_type, kdf_nid, wrap_nid; - const EVP_MD *kdf_md; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* Get ephemeral key */ - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, - NULL, NULL, NULL)) - goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); - /* Is everything uninitialised? */ - if (aoid == OBJ_nid2obj(NID_undef)) { - - EC_KEY *eckey = pkey->pkey.ec; - /* Set the key */ - unsigned char *p; - - penclen = i2o_ECPublicKey(eckey, NULL); - if (penclen <= 0) - goto err; - penc = OPENSSL_malloc(penclen); - if (penc == NULL) - goto err; - p = penc; - penclen = i2o_ECPublicKey(eckey, &p); - if (penclen <= 0) - goto err; - ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), - V_ASN1_UNDEF, NULL); - } - - /* See if custom parameters set */ - kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) - goto err; - ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); - if (ecdh_nid < 0) - goto err; - else if (ecdh_nid == 0) - ecdh_nid = NID_dh_std_kdf; - else if (ecdh_nid == 1) - ecdh_nid = NID_dh_cofactor_kdf; - - if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { - kdf_type = EVP_PKEY_ECDH_KDF_X9_63; - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) - goto err; - } else - /* Unknown KDF */ - goto err; - if (kdf_md == NULL) { - /* Fixme later for better MD */ - kdf_md = EVP_sha1(); - if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) - goto err; - } - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) - goto err; - - /* Lookup NID for KDF+cofactor+digest */ - - if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) - goto err; - /* Get wrap NID */ - ctx = CMS_RecipientInfo_kari_get0_ctx(ri); - wrap_nid = EVP_CIPHER_CTX_type(ctx); - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Package wrap algorithm in an AlgorithmIdentifier */ - - wrap_alg = X509_ALGOR_new(); - if (wrap_alg == NULL) - goto err; - wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); - wrap_alg->parameter = ASN1_TYPE_new(); - if (wrap_alg->parameter == NULL) - goto err; - if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) - goto err; - if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { - ASN1_TYPE_free(wrap_alg->parameter); - wrap_alg->parameter = NULL; - } - - if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); - - if (!penclen) - goto err; - - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) - goto err; - penc = NULL; - - /* - * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter - * of another AlgorithmIdentifier. - */ - penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (!penc || !penclen) - goto err; - wrap_str = ASN1_STRING_new(); - if (wrap_str == NULL) - goto err; - ASN1_STRING_set0(wrap_str, penc, penclen); - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); - - rv = 1; - - err: - OPENSSL_free(penc); - X509_ALGOR_free(wrap_alg); - return rv; -} - -#endif diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 654a12ad60..e95cffd42c 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -23,75 +23,6 @@ #ifndef FIPS_MODULE -int EC_GROUP_get_basis_type(const EC_GROUP *group) -{ - int i; - - if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field) - /* everything else is currently not supported */ - return 0; - - /* Find the last non-zero element of group->poly[] */ - for (i = 0; - i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; - i++) - continue; - - if (i == 4) - return NID_X9_62_ppBasis; - else if (i == 2) - return NID_X9_62_tpBasis; - else - /* everything else is currently not supported */ - return 0; -} - -#ifndef OPENSSL_NO_EC2M -int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) -{ - if (group == NULL) - return 0; - - if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field - || !((group->poly[0] != 0) && (group->poly[1] != 0) - && (group->poly[2] == 0))) { - ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - if (k) - *k = group->poly[1]; - - return 1; -} - -int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, - unsigned int *k2, unsigned int *k3) -{ - if (group == NULL) - return 0; - - if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field - || !((group->poly[0] != 0) && (group->poly[1] != 0) - && (group->poly[2] != 0) && (group->poly[3] != 0) - && (group->poly[4] == 0))) { - ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - if (k1) - *k1 = group->poly[3]; - if (k2) - *k2 = group->poly[2]; - if (k3) - *k3 = group->poly[1]; - - return 1; -} -#endif - /* some structures needed for the asn1 encoding */ typedef struct x9_62_pentanomial_st { int32_t k1; @@ -143,6 +74,12 @@ struct ec_parameters_st { ASN1_INTEGER *cofactor; } /* ECPARAMETERS */ ; +typedef enum { + ECPKPARAMETERS_TYPE_NAMED = 0, + ECPKPARAMETERS_TYPE_EXPLICIT, + ECPKPARAMETERS_TYPE_IMPLICIT +} ecpk_parameters_type_t; + struct ecpk_parameters_st { int type; union { @@ -444,7 +381,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) } ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group, - ECPARAMETERS *params) + ECPARAMETERS *params) { size_t len = 0; ECPARAMETERS *ret = NULL; @@ -541,9 +478,10 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, return NULL; } } else { - if (ret->type == 0) + if (ret->type == ECPKPARAMETERS_TYPE_NAMED) ASN1_OBJECT_free(ret->value.named_curve); - else if (ret->type == 1 && ret->value.parameters) + else if (ret->type == ECPKPARAMETERS_TYPE_EXPLICIT + && ret->value.parameters != NULL) ECPARAMETERS_free(ret->value.parameters); } @@ -560,7 +498,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, EC_R_MISSING_OID); ok = 0; } else { - ret->type = 0; + ret->type = ECPKPARAMETERS_TYPE_NAMED; ret->value.named_curve = asn1obj; } } else @@ -568,7 +506,7 @@ ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group, ok = 0; } else { /* use the ECPARAMETERS structure */ - ret->type = 1; + ret->type = ECPKPARAMETERS_TYPE_EXPLICIT; if ((ret->value.parameters = EC_GROUP_get_ecparameters(group, NULL)) == NULL) ok = 0; @@ -910,7 +848,8 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) return NULL; } - if (params->type == 0) { /* the curve is given by an OID */ + if (params->type == ECPKPARAMETERS_TYPE_NAMED) { + /* the curve is given by an OID */ tmp = OBJ_obj2nid(params->value.named_curve); if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, @@ -918,15 +857,16 @@ EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) return NULL; } EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); - } else if (params->type == 1) { /* the parameters are given by a - * ECPARAMETERS structure */ + } else if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) { + /* the parameters are given by an ECPARAMETERS structure */ ret = EC_GROUP_new_from_ecparameters(params->value.parameters); if (!ret) { ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB); return NULL; } EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_EXPLICIT_CURVE); - } else if (params->type == 2) { /* implicitlyCA */ + } else if (params->type == ECPKPARAMETERS_TYPE_IMPLICIT) { + /* implicit parameters inherited from CA - unsupported */ return NULL; } else { ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR); @@ -945,17 +885,18 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) const unsigned char *p = *in; if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { - ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); ECPKPARAMETERS_free(params); return NULL; } if ((group = EC_GROUP_new_from_ecpkparameters(params)) == NULL) { - ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); ECPKPARAMETERS_free(params); return NULL; } + if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT) + group->decoded_from_explicit_params = 1; + if (a) { EC_GROUP_free(*a); *a = group; @@ -991,10 +932,8 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) EC_PRIVATEKEY *priv_key = NULL; const unsigned char *p = *in; - if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) return NULL; - } if (a == NULL || *a == NULL) { if ((ret = EC_KEY_new()) == NULL) { @@ -1007,6 +946,9 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) if (priv_key->parameters) { EC_GROUP_free(ret->group); ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters); + if (ret->group != NULL + && priv_key->parameters->type == ECPKPARAMETERS_TYPE_EXPLICIT) + ret->group->decoded_from_explicit_params = 1; } if (ret->group == NULL) { @@ -1164,7 +1106,6 @@ EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) ret = *a; if (!d2i_ECPKParameters(&ret->group, in, len)) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); if (a == NULL || *a != ret) EC_KEY_free(ret); else @@ -1277,7 +1218,7 @@ ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **psig, const unsigned char **ppin, long len) sig->r = BN_new(); if (sig->s == NULL) sig->s = BN_new(); - if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { + if (ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { if (psig == NULL || *psig == NULL) ECDSA_SIG_free(sig); return NULL; diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index 2277c2c724..f4a6d976aa 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -10,15 +10,179 @@ #include #include #include +#include #include "crypto/bn.h" #include "crypto/ec.h" +#include "ec_local.h" +#include "e_os.h" +#include "internal/param_build_set.h" + +/* Mapping between a flag and a name */ +static const OSSL_ITEM encoding_nameid_map[] = { + { OPENSSL_EC_EXPLICIT_CURVE, OSSL_PKEY_EC_ENCODING_EXPLICIT }, + { OPENSSL_EC_NAMED_CURVE, OSSL_PKEY_EC_ENCODING_GROUP }, +}; + +int ec_encoding_name2id(const char *name) +{ + size_t i, sz; + + /* Return the default value if there is no name */ + if (name == NULL) + return OPENSSL_EC_NAMED_CURVE; + + for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) { + if (strcasecmp(name, encoding_nameid_map[i].ptr) == 0) + return encoding_nameid_map[i].id; + } + return -1; +} + +static char *ec_param_encoding_id2name(int id) +{ + size_t i, sz; + + for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) { + if (id == (int)encoding_nameid_map[i].id) + return encoding_nameid_map[i].ptr; + } + return NULL; +} + +int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *bnctx, unsigned char **genbuf) +{ + int ret = 0, curve_nid, encoding_flag; + const char *field_type, *encoding_name; + const BIGNUM *cofactor, *order; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + point_conversion_form_t genform; + const EC_POINT *genpt; + unsigned char *seed = NULL; + size_t genbuf_len, seed_len; + + if (group == NULL) { + ECerr(0,EC_R_PASSED_NULL_PARAMETER); + return 0; + } + + encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE; + encoding_name = ec_param_encoding_id2name(encoding_flag); + if (encoding_name == NULL + || !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_EC_ENCODING, + encoding_name)) { + ECerr(0, EC_R_INVALID_ENCODING); + return 0; + } + + curve_nid = EC_GROUP_get_curve_name(group); + if (curve_nid == NID_undef) { + /* explicit curve */ + int fid = EC_GROUP_get_field_type(group); + + if (fid == NID_X9_62_prime_field) { + field_type = SN_X9_62_prime_field; + } else if (fid == NID_X9_62_characteristic_two_field) { + field_type = SN_X9_62_characteristic_two_field; + } else { + ECerr(0, EC_R_INVALID_FIELD); + return 0; + } + + p = BN_CTX_get(bnctx); + a = BN_CTX_get(bnctx); + b = BN_CTX_get(bnctx); + if (b == NULL) { + ECerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_GROUP_get_curve(group, p, a, b, bnctx)) { + ECerr(0, EC_R_INVALID_CURVE); + goto err; + } + + order = EC_GROUP_get0_order(group); + if (order == NULL) { + ECerr(0, EC_R_INVALID_GROUP_ORDER); + goto err; + } + genpt = EC_GROUP_get0_generator(group); + if (genpt == NULL) { + ECerr(0, EC_R_INVALID_GENERATOR); + goto err; + } + genform = EC_GROUP_get_point_conversion_form(group); + genbuf_len = EC_POINT_point2buf(group, genpt, genform, genbuf, bnctx); + if (genbuf_len == 0) { + ECerr(0, EC_R_INVALID_GENERATOR); + goto err; + } + + if (!ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_EC_FIELD_TYPE, + field_type) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b) + || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER, + order) + || !ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_EC_GENERATOR, + *genbuf, genbuf_len)) { + ECerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } + + cofactor = EC_GROUP_get0_cofactor(group); + if (cofactor != NULL + && !ossl_param_build_set_bn(tmpl, params, + OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) { + ECerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } + + seed = EC_GROUP_get0_seed(group); + seed_len = EC_GROUP_get_seed_len(group); + if (seed != NULL + && seed_len > 0 + && !ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_EC_SEED, + seed, seed_len)) { + ECerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } +#ifdef OPENSSL_NO_EC2M + if (fid == NID_X9_62_characteristic_two_field) { + ECerr(0, EC_R_GF2M_NOT_SUPPORTED); + goto err; + } +#endif + } else { + /* named curve */ + const char *curve_name = ec_curve_nid2name(curve_nid); + + if (curve_name == NULL + || !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_GROUP_NAME, + curve_name)) { + ECerr(0, EC_R_INVALID_CURVE); + goto err; + } + } + ret = 1; +err: + return ret; +} /* * The intention with the "backend" source file is to offer backend support * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider * implementations alike. */ - int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode) { const EC_GROUP *ecg = EC_KEY_get0_group(ec); @@ -163,52 +327,27 @@ int ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private) return ok; } -int ec_key_domparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +int ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) { - const OSSL_PARAM *param_ec_name; - EC_GROUP *ecg = NULL; - char *curve_name = NULL; int ok = 0; + EC_GROUP *group = NULL; if (ec == NULL) return 0; - param_ec_name = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); - if (param_ec_name == NULL) { - /* explicit parameters */ - - /* - * TODO(3.0): should we support explicit parameters curves? - */ - return 0; - } else { - /* named curve */ - int curve_nid; - - if (!OSSL_PARAM_get_utf8_string(param_ec_name, &curve_name, 0) - || curve_name == NULL - || (curve_nid = ec_curve_name2nid(curve_name)) == NID_undef) - goto err; - - if ((ecg = EC_GROUP_new_by_curve_name_with_libctx(ec_key_get_libctx(ec), - ec_key_get0_propq(ec), - curve_nid)) == NULL) - goto err; - } + group = EC_GROUP_new_from_params(params, ec_key_get_libctx(ec), + ec_key_get0_propq(ec)); - if (!EC_KEY_set_group(ec, ecg)) + if (!EC_KEY_set_group(ec, group)) goto err; /* * TODO(3.0): if the group has changed, should we invalidate the private and * public key? */ - ok = 1; - - err: - OPENSSL_free(curve_name); - EC_GROUP_free(ecg); +err: + EC_GROUP_free(group); return ok; } @@ -227,5 +366,6 @@ int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) || !ec_set_ecdh_cofactor_mode(ec, mode)) return 0; } + return 1; } diff --git a/crypto/ec/ec_ctrl.c b/crypto/ec/ec_ctrl.c index b47d7b606c..1465af2bec 100644 --- a/crypto/ec/ec_ctrl.c +++ b/crypto/ec/ec_ctrl.c @@ -443,4 +443,44 @@ int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) return EVP_PKEY_CTX_set_group_name(ctx, OBJ_nid2sn(nid)); } + +int evp_pkey_ctx_set_ec_param_enc_prov(EVP_PKEY_CTX *ctx, int param_enc) +{ + const char *enc = NULL; + OSSL_PARAM params[2], *p = params; + int ret = -2; /* Assume unsupported */ + + if (ctx == NULL + || !EVP_PKEY_CTX_IS_GEN_OP(ctx) + || ctx->op.keymgmt.genctx == NULL) + goto end; + + switch (param_enc) { + case OPENSSL_EC_EXPLICIT_CURVE: + enc = OSSL_PKEY_EC_ENCODING_EXPLICIT; + break; + case OPENSSL_EC_NAMED_CURVE: + enc = OSSL_PKEY_EC_ENCODING_GROUP; + break; + default: + goto end; + } + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, + (char *)enc, 0); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + end: + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc) +{ + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_EC_PARAM_ENC, param_enc, NULL); +} #endif diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index bf02c261f7..687860ea92 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -18,6 +18,7 @@ #include "ec_local.h" #include #include +#include #include #include "internal/nelem.h" #include "e_os.h" /* strcasecmp required by windows */ @@ -3179,7 +3180,7 @@ int ec_curve_name2nid(const char *name) return NID_undef; } -static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, +static EC_GROUP *ec_group_new_from_data(OSSL_LIB_CTX *libctx, const char *propq, const ec_list_element curve) { @@ -3196,8 +3197,8 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, /* If no curve data curve method must handle everything */ if (curve.data == NULL) - return ec_group_new_with_libctx(libctx, propq, - curve.meth != NULL ? curve.meth() : NULL); + return ec_group_new_ex(libctx, propq, + curve.meth != NULL ? curve.meth() : NULL); if ((ctx = BN_CTX_new_ex(libctx)) == NULL) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); @@ -3219,7 +3220,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, if (curve.meth != 0) { meth = curve.meth(); - if (((group = ec_group_new_with_libctx(libctx, propq, meth)) == NULL) || + if (((group = ec_group_new_ex(libctx, propq, meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; @@ -3289,8 +3290,8 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, return group; } -EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, - const char *propq, int nid) +EC_GROUP *EC_GROUP_new_by_curve_name_ex(OSSL_LIB_CTX *libctx, const char *propq, + int nid) { EC_GROUP *ret = NULL; const ec_list_element *curve; @@ -3298,6 +3299,9 @@ EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, if ((curve = ec_curve_nid2curve(nid)) == NULL || (ret = ec_group_new_from_data(libctx, propq, *curve)) == NULL) { ECerr(0, EC_R_UNKNOWN_GROUP); +#ifndef FIPS_MODULE + ERR_add_error_data(2, "name=", OBJ_nid2sn(nid)); +#endif return NULL; } @@ -3307,7 +3311,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, #ifndef FIPS_MODULE EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { - return EC_GROUP_new_by_curve_name_with_libctx(NULL, NULL, nid); + return EC_GROUP_new_by_curve_name_ex(NULL, NULL, nid); } #endif diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c index e5e6f10ce4..c841ad741d 100644 --- a/crypto/ec/ec_cvt.c +++ b/crypto/ec/ec_cvt.c @@ -54,7 +54,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, meth = EC_GFp_mont_method(); #endif - ret = ec_group_new_with_libctx(bn_get_lib_ctx(ctx), NULL, meth); + ret = ec_group_new_ex(bn_get_libctx(ctx), NULL, meth); if (ret == NULL) return NULL; @@ -75,7 +75,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, meth = EC_GF2m_simple_method(); - ret = ec_group_new_with_libctx(bn_get_lib_ctx(ctx), NULL, meth); + ret = ec_group_new_ex(bn_get_libctx(ctx), NULL, meth); if (ret == NULL) return NULL; diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index afb2696285..35cf7d158f 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -27,8 +27,6 @@ static const ERR_STRING_DATA EC_str_reasons[] = { "curve does not support ecdsa"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING), "curve does not support signing"}, - {ERR_PACK(ERR_LIB_EC, 0, EC_R_D2I_ECPKPARAMETERS_FAILURE), - "d2i ecpkparameters failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_DECODE_ERROR), "decode error"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, @@ -44,7 +42,10 @@ static const ERR_STRING_DATA EC_str_reasons[] = { "i2d ecpkparameters failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_A), "invalid a"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_B), "invalid b"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COFACTOR), "invalid cofactor"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSION_BIT), @@ -55,14 +56,19 @@ static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ENCODING), "invalid encoding"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FIELD), "invalid field"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FORM), "invalid form"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GENERATOR), "invalid generator"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GROUP_ORDER), "invalid group order"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_KEY), "invalid key"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_NAMED_GROUP_CONVERSION), + "invalid named group conversion"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_P), "invalid p"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PEER_KEY), "invalid peer key"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, + {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_SEED), "invalid seed"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, @@ -85,8 +91,6 @@ static const ERR_STRING_DATA EC_str_reasons[] = { {ERR_PACK(ERR_LIB_EC, 0, EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_PEER_KEY_ERROR), "peer key error"}, - {ERR_PACK(ERR_LIB_EC, 0, EC_R_PKPARAMETERS2GROUP_FAILURE), - "pkparameters2group failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, {ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_AT_INFINITY), "point at infinity"}, diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 84ce095693..63001203ae 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -21,6 +21,7 @@ #include #include #include +#include "prov/providercommon.h" #include "crypto/bn.h" static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, @@ -33,18 +34,18 @@ EC_KEY *EC_KEY_new(void) } #endif -EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq) +EC_KEY *EC_KEY_new_ex(OSSL_LIB_CTX *ctx, const char *propq) { return ec_key_new_method_int(ctx, propq, NULL); } -EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, - const char *propq, int nid) +EC_KEY *EC_KEY_new_by_curve_name_ex(OSSL_LIB_CTX *ctx, const char *propq, + int nid) { - EC_KEY *ret = EC_KEY_new_with_libctx(ctx, propq); + EC_KEY *ret = EC_KEY_new_ex(ctx, propq); if (ret == NULL) return NULL; - ret->group = EC_GROUP_new_by_curve_name_with_libctx(ctx, propq, nid); + ret->group = EC_GROUP_new_by_curve_name_ex(ctx, propq, nid); if (ret->group == NULL) { EC_KEY_free(ret); return NULL; @@ -60,7 +61,7 @@ EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, #ifndef FIPS_MODULE EC_KEY *EC_KEY_new_by_curve_name(int nid) { - return EC_KEY_new_by_curve_name_with_libctx(NULL, NULL, nid); + return EC_KEY_new_by_curve_name_ex(NULL, NULL, nid); } #endif @@ -121,8 +122,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) if (src->group != NULL) { /* clear the old group */ EC_GROUP_free(dest->group); - dest->group = ec_group_new_with_libctx(src->libctx, src->propq, - src->group->meth); + dest->group = ec_group_new_ex(src->libctx, src->propq, src->group->meth); if (dest->group == NULL) return NULL; if (!EC_GROUP_copy(dest->group, src->group)) @@ -255,14 +255,16 @@ int ossl_ec_key_gen(EC_KEY *eckey) * fails then the keypair is not generated, * Returns 1 if the keypair was generated or 0 otherwise. */ -int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test) +static int ec_generate_key(EC_KEY *eckey, int pairwise_test) { int ok = 0; BIGNUM *priv_key = NULL; - const BIGNUM *order = NULL; + const BIGNUM *tmp = NULL; + BIGNUM *order = NULL; EC_POINT *pub_key = NULL; const EC_GROUP *group = eckey->group; BN_CTX *ctx = BN_CTX_secure_new_ex(eckey->libctx); + int sm2 = EC_KEY_get_flags(eckey) & EC_FLAG_SM2_RANGE ? 1 : 0; if (ctx == NULL) goto err; @@ -280,8 +282,8 @@ int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test) * stated in the security policy. */ - order = EC_GROUP_get0_order(group); - if (order == NULL) + tmp = EC_GROUP_get0_order(group); + if (tmp == NULL) goto err; /* @@ -292,6 +294,18 @@ int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test) * 1 + rand[0..n-2] would effect the way that tests feed dummy entropy into * rand so the simpler backward compatible method has been used here. */ + + /* range of SM2 private key is [1, n-1) */ + if (sm2) { + order = BN_new(); + if (order == NULL || !BN_sub(order, tmp, BN_value_one())) + goto err; + } else { + order = BN_dup(tmp); + if (order == NULL) + goto err; + } + do if (!BN_priv_rand_range_ex(priv_key, order, ctx)) goto err; @@ -324,12 +338,13 @@ int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test) OSSL_CALLBACK *cb = NULL; void *cbarg = NULL; - OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg); + OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg); ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg); } err: /* Step (9): If there is an error return an invalid keypair. */ if (!ok) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); BN_clear(eckey->priv_key); if (eckey->pub_key != NULL) EC_POINT_set_to_infinity(group, eckey->pub_key); @@ -338,12 +353,13 @@ int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test) EC_POINT_free(pub_key); BN_clear_free(priv_key); BN_CTX_free(ctx); + BN_free(order); return ok; } int ec_key_simple_generate_key(EC_KEY *eckey) { - return ec_generate_key(NULL, eckey, 0); + return ec_generate_key(eckey, 0); } int ec_key_simple_generate_public_key(EC_KEY *eckey) @@ -635,7 +651,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, } -OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *key) +OSSL_LIB_CTX *ec_key_get_libctx(const EC_KEY *key) { return key->libctx; } @@ -820,6 +836,13 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags) key->dirty_cnt++; } +int EC_KEY_decoded_from_explicit_params(const EC_KEY *key) +{ + if (key == NULL || key->group == NULL) + return -1; + return key->group->decoded_from_explicit_params; +} + size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, unsigned char **pbuf, BN_CTX *ctx) { diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c index 3fec8a4d81..d01b96f654 100644 --- a/crypto/ec/ec_kmeth.c +++ b/crypto/ec/ec_kmeth.c @@ -76,7 +76,7 @@ int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth) return 1; } -EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq, +EC_KEY *ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, ENGINE *engine) { EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index a0c007a13e..d1d403e175 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -15,16 +15,19 @@ #include "internal/deprecated.h" #include - +#include +#include #include #include - +#include "crypto/ec.h" +#include "internal/nelem.h" #include "ec_local.h" +#include "e_os.h" /* strcasecmp */ /* functions for EC_GROUP objects */ -EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, - const EC_METHOD *meth) +EC_GROUP *ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EC_METHOD *meth) { EC_GROUP *ret; @@ -78,7 +81,7 @@ EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, # ifndef FIPS_MODULE EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) { - return ec_group_new_with_libctx(NULL, NULL, meth); + return ec_group_new_ex(NULL, NULL, meth); } # endif #endif @@ -240,6 +243,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) dest->asn1_flag = src->asn1_flag; dest->asn1_form = src->asn1_form; + dest->decoded_from_explicit_params = src->decoded_from_explicit_params; if (src->seed) { OPENSSL_free(dest->seed); @@ -267,7 +271,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) if (a == NULL) return NULL; - if ((t = ec_group_new_with_libctx(a->libctx, a->propq, a->meth)) == NULL) + if ((t = ec_group_new_ex(a->libctx, a->propq, a->meth)) == NULL) return NULL; if (!EC_GROUP_copy(t, a)) goto err; @@ -1317,3 +1321,404 @@ int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx) return group->meth->blind_coordinates(group, p, ctx); } + +int EC_GROUP_get_basis_type(const EC_GROUP *group) +{ + int i; + + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field) + /* everything else is currently not supported */ + return 0; + + /* Find the last non-zero element of group->poly[] */ + for (i = 0; + i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; + i++) + continue; + + if (i == 4) + return NID_X9_62_ppBasis; + else if (i == 2) + return NID_X9_62_tpBasis; + else + /* everything else is currently not supported */ + return 0; +} + +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) +{ + if (group == NULL) + return 0; + + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] == 0))) { + ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k) + *k = group->poly[1]; + + return 1; +} + +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, + unsigned int *k2, unsigned int *k3) +{ + if (group == NULL) + return 0; + + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] != 0) && (group->poly[3] != 0) + && (group->poly[4] == 0))) { + ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k1) + *k1 = group->poly[3]; + if (k2) + *k2 = group->poly[2]; + if (k3) + *k3 = group->poly[1]; + + return 1; +} +#endif + +/* + * Check if the explicit parameters group matches any built-in curves. + * + * We create a copy of the group just built, so that we can remove optional + * fields for the lookup: we do this to avoid the possibility that one of + * the optional parameters is used to force the library into using a less + * performant and less secure EC_METHOD instead of the specialized one. + * In any case, `seed` is not really used in any computation, while a + * cofactor different from the one in the built-in table is just + * mathematically wrong anyway and should not be used. + */ +static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group, + OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *ctx) +{ + EC_GROUP *ret_group = NULL, *dup = NULL; + int curve_name_nid; + + const EC_POINT *point = EC_GROUP_get0_generator(group); + const BIGNUM *order = EC_GROUP_get0_order(group); + int no_seed = (EC_GROUP_get0_seed(group) == NULL); + + if ((dup = EC_GROUP_dup(group)) == NULL + || EC_GROUP_set_seed(dup, NULL, 0) != 1 + || !EC_GROUP_set_generator(dup, point, order, NULL)) + goto err; + if ((curve_name_nid = ec_curve_nid_from_params(dup, ctx)) != NID_undef) { + /* + * The input explicit parameters successfully matched one of the + * built-in curves: often for built-in curves we have specialized + * methods with better performance and hardening. + * + * In this case we replace the `EC_GROUP` created through explicit + * parameters with one created from a named group. + */ + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + /* + * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for + * the same curve, we prefer the SECP nid when matching explicit + * parameters as that is associated with a specialized EC_METHOD. + */ + if (curve_name_nid == NID_wap_wsg_idm_ecid_wtls12) + curve_name_nid = NID_secp224r1; +#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */ + + ret_group = EC_GROUP_new_by_curve_name_ex(libctx, propq, curve_name_nid); + if (ret_group == NULL) + goto err; + + /* + * Set the flag so that EC_GROUPs created from explicit parameters are + * serialized using explicit parameters by default. + */ + EC_GROUP_set_asn1_flag(ret_group, OPENSSL_EC_EXPLICIT_CURVE); + + /* + * If the input params do not contain the optional seed field we make + * sure it is not added to the returned group. + * + * The seed field is not really used inside libcrypto anyway, and + * adding it to parsed explicit parameter keys would alter their DER + * encoding output (because of the extra field) which could impact + * applications fingerprinting keys by their DER encoding. + */ + if (no_seed) { + if (EC_GROUP_set_seed(ret_group, NULL, 0) != 1) + goto err; + } + } else { + ret_group = (EC_GROUP *)group; + } + EC_GROUP_free(dup); + return ret_group; +err: + EC_GROUP_free(dup); + EC_GROUP_free(ret_group); + return NULL; +} + +static int ec_encoding_param2id(const OSSL_PARAM *p, int *id) +{ + const char *name = NULL; + int status = 0; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + name = p->data; + status = (name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + status = OSSL_PARAM_get_utf8_ptr(p, &name); + break; + } + if (status) { + int i = ec_encoding_name2id(name); + + if (i >= 0) { + *id = i; + return 1; + } + } + return 0; +} + +static EC_GROUP *group_new_from_name(const OSSL_PARAM *p, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int ok = 0, nid; + const char *curve_name = NULL; + + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + /* The OSSL_PARAM functions have no support for this */ + curve_name = p->data; + ok = (curve_name != NULL); + break; + case OSSL_PARAM_UTF8_PTR: + ok = OSSL_PARAM_get_utf8_ptr(p, &curve_name); + break; + } + + if (ok) { + nid = ec_curve_name2nid(curve_name); + if (nid == NID_undef) { + ECerr(0, EC_R_INVALID_CURVE); + return NULL; + } else { + return EC_GROUP_new_by_curve_name_ex(libctx, propq, nid); + } + } + return NULL; +} + +EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx, const char *propq) +{ + const OSSL_PARAM *ptmp, *pa, *pb; + int ok = 0; + EC_GROUP *group = NULL, *named_group = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL; + EC_POINT *point = NULL; + int field_bits = 0; + int is_prime_field = 1; + BN_CTX *bnctx = NULL; + const unsigned char *buf = NULL; + int encoding_flag = -1; + + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); + if (ptmp != NULL && !ec_encoding_param2id(ptmp, &encoding_flag)) { + ECerr(0, EC_R_INVALID_ENCODING); + return 0; + } + + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); + if (ptmp != NULL) { + group = group_new_from_name(ptmp, libctx, propq); + if (group != NULL) + EC_GROUP_set_asn1_flag(group, encoding_flag); + return group; + } + bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) { + ECerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(bnctx); + + p = BN_CTX_get(bnctx); + a = BN_CTX_get(bnctx); + b = BN_CTX_get(bnctx); + order = BN_CTX_get(bnctx); + if (order == NULL) { + ECerr(0, ERR_R_MALLOC_FAILURE); + goto err; + } + + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); + if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_UTF8_STRING) { + ECerr(0, EC_R_INVALID_FIELD); + goto err; + } + if (strcasecmp(ptmp->data, SN_X9_62_prime_field) == 0) { + is_prime_field = 1; + } else if (strcasecmp(ptmp->data, SN_X9_62_characteristic_two_field) == 0) { + is_prime_field = 0; + } else { + /* Invalid field */ + ECerr(0, EC_R_UNSUPPORTED_FIELD); + goto err; + } + + pa = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); + if (!OSSL_PARAM_get_BN(pa, &a)) { + ECerr(0, EC_R_INVALID_A); + goto err; + } + pb = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); + if (!OSSL_PARAM_get_BN(pb, &b)) { + ECerr(0, EC_R_INVALID_B); + goto err; + } + + /* extract the prime number or irreducible polynomial */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); + if (!OSSL_PARAM_get_BN(ptmp, &p)) { + ECerr(0, EC_R_INVALID_P); + goto err; + } + + if (is_prime_field) { + if (BN_is_negative(p) || BN_is_zero(p)) { + ECerr(0, EC_R_INVALID_P); + goto err; + } + field_bits = BN_num_bits(p); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerr(0, EC_R_FIELD_TOO_LARGE); + goto err; + } + + /* create the EC_GROUP structure */ + group = EC_GROUP_new_curve_GFp(p, a, b, bnctx); + } else { +#ifdef OPENSSL_NO_EC2M + ECerr(0, EC_R_GF2M_NOT_SUPPORTED); + goto err; +#else + /* create the EC_GROUP structure */ + group = EC_GROUP_new_curve_GF2m(p, a, b, NULL); + if (group != NULL) { + field_bits = EC_GROUP_get_degree(group); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerr(0, EC_R_FIELD_TOO_LARGE); + goto err; + } + } +#endif /* OPENSSL_NO_EC2M */ + } + + if (group == NULL) { + ECerr(0, ERR_R_EC_LIB); + goto err; + } + + /* Optional seed */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + if (ptmp != NULL) { + if (ptmp->data_type != OSSL_PARAM_OCTET_STRING) { + ECerr(0, EC_R_INVALID_SEED); + goto err; + } + if (!EC_GROUP_set_seed(group, ptmp->data, ptmp->data_size)) + goto err; + } + + /* generator base point */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); + if (ptmp == NULL + || ptmp->data_type != OSSL_PARAM_OCTET_STRING) { + ECerr(0, EC_R_INVALID_GENERATOR); + goto err; + } + buf = (const unsigned char *)(ptmp->data); + if ((point = EC_POINT_new(group)) == NULL) + goto err; + EC_GROUP_set_point_conversion_form(group, + (point_conversion_form_t)buf[0] & ~0x01); + if (!EC_POINT_oct2point(group, point, buf, ptmp->data_size, bnctx)) { + ECerr(0, EC_R_INVALID_GENERATOR); + goto err; + } + + /* order */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); + if (!OSSL_PARAM_get_BN(ptmp, &order) + || (BN_is_negative(order) || BN_is_zero(order)) + || (BN_num_bits(order) > (int)field_bits + 1)) { /* Hasse bound */ + ECerr(0, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + /* Optional cofactor */ + ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); + if (ptmp != NULL) { + cofactor = BN_CTX_get(bnctx); + if (cofactor == NULL || !OSSL_PARAM_get_BN(ptmp, &cofactor)) { + ECerr(0, EC_R_INVALID_COFACTOR); + goto err; + } + } + + /* set the generator, order and cofactor (if present) */ + if (!EC_GROUP_set_generator(group, point, order, cofactor)) { + ECerr(0, EC_R_INVALID_GENERATOR); + goto err; + } + + named_group = ec_group_explicit_to_named(group, libctx, propq, bnctx); + if (named_group == NULL) { + ECerr(0, EC_R_INVALID_NAMED_GROUP_CONVERSION); + goto err; + } + if (named_group == group) { + /* + * If we did not find a named group then the encoding should be explicit + * if it was specified + */ + if (encoding_flag == OPENSSL_EC_NAMED_CURVE) { + ECerr(0, EC_R_INVALID_ENCODING); + goto err; + } + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE); + } else { + EC_GROUP_free(group); + group = named_group; + } + ok = 1; + err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + EC_POINT_free(point); + BN_CTX_end(bnctx); + BN_CTX_free(bnctx); + + return group; +} diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h index aa040b54d1..004cfbd8d4 100644 --- a/crypto/ec/ec_local.h +++ b/crypto/ec/ec_local.h @@ -213,6 +213,8 @@ struct ec_group_st { BIGNUM *order, *cofactor; int curve_name; /* optional NID for named curve */ int asn1_flag; /* flag to control the asn1 encoding */ + int decoded_from_explicit_params; /* set if decoded from explicit + * curve parameters encoding */ point_conversion_form_t asn1_form; unsigned char *seed; /* optional seed for parameters (appears in * ASN1) */ @@ -273,7 +275,7 @@ struct ec_group_st { EC_PRE_COMP *ec; } pre_comp; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; }; @@ -297,7 +299,7 @@ struct ec_key_st { CRYPTO_EX_DATA ex_data; #endif CRYPTO_RWLOCK *lock; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; /* Provider data */ @@ -599,8 +601,8 @@ int ec_group_simple_order_bits(const EC_GROUP *group); * \param meth EC_METHOD to use * \return newly created EC_GROUP object or NULL in case of an error. */ -EC_GROUP *ec_group_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, - const EC_METHOD *meth); +EC_GROUP *ec_group_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EC_METHOD *meth); #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized @@ -655,7 +657,7 @@ struct ec_key_method_st { #define EC_KEY_METHOD_DYNAMIC 1 -EC_KEY *ec_key_new_method_int(OPENSSL_CTX *libctx, const char *propq, +EC_KEY *ec_key_new_method_int(OSSL_LIB_CTX *libctx, const char *propq, ENGINE *engine); int ossl_ec_key_gen(EC_KEY *eckey); diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c index 7eeeedc0e9..0758d9be4a 100644 --- a/crypto/ec/ec_pmeth.c +++ b/crypto/ec/ec_pmeth.c @@ -216,7 +216,8 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, goto err; /* Do KDF stuff */ if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, - dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) + dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md, + ctx->libctx, ctx->propquery)) goto err; rv = 1; diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c index fb501c6ada..df0858a032 100644 --- a/crypto/ec/ecdh_kdf.c +++ b/crypto/ec/ecdh_kdf.c @@ -24,13 +24,14 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, - const EVP_MD *md) + const EVP_MD *md, + OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; EVP_KDF_CTX *kctx = NULL; OSSL_PARAM params[4], *p = params; const char *mdname = EVP_MD_name(md); - EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL); + EVP_KDF *kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_X963KDF, propq); if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) { *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -59,6 +60,6 @@ int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, const unsigned char *sinfo, size_t sinfolen, const EVP_MD *md) { - return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md); + return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md, NULL, NULL); } #endif diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index 042f9ca8da..d1e652ae4f 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -27,7 +27,8 @@ int ecx_public_from_private(ECX_KEY *key) X25519_public_from_private(key->pubkey, key->privkey); break; case ECX_KEY_TYPE_ED25519: - if (!ED25519_public_from_private(key->libctx, key->pubkey, key->privkey)) { + if (!ED25519_public_from_private(key->libctx, key->pubkey, key->privkey, + key->propq)) { ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY); return 0; } @@ -36,7 +37,8 @@ int ecx_public_from_private(ECX_KEY *key) X448_public_from_private(key->pubkey, key->privkey); break; case ECX_KEY_TYPE_ED448: - if (!ED448_public_from_private(key->libctx, key->pubkey, key->privkey)) { + if (!ED448_public_from_private(key->libctx, key->pubkey, key->privkey, + key->propq)) { ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY); return 0; } diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c index 46abd57a74..1d2891928e 100644 --- a/crypto/ec/ecx_key.c +++ b/crypto/ec/ecx_key.c @@ -10,7 +10,8 @@ #include #include "crypto/ecx.h" -ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey) +ECX_KEY *ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, + const char *propq) { ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -36,14 +37,21 @@ ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey) ret->type = type; ret->references = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { + if (propq != NULL) { + ret->propq = OPENSSL_strdup(propq); ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return NULL; + if (ret->propq == NULL) + goto err; } + ret->lock = CRYPTO_THREAD_lock_new(); + if (ret->lock == NULL) + goto err; return ret; +err: + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return NULL; } void ecx_key_free(ECX_KEY *key) @@ -59,6 +67,7 @@ void ecx_key_free(ECX_KEY *key) return; REF_ASSERT_ISNT(i < 0); + OPENSSL_free(key->propq); OPENSSL_secure_clear_free(key->privkey, key->keylen); CRYPTO_THREAD_lock_free(key->lock); OPENSSL_free(key); diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 8b63e6918d..5405164783 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -36,7 +36,7 @@ typedef enum { /* Setup EVP_PKEY using public, private or generation */ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, const unsigned char *p, int plen, ecx_key_op_t op, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { ECX_KEY *key = NULL; unsigned char *privkey, *pubkey; @@ -59,7 +59,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, } } - key = ecx_key_new(libctx, KEYNID2TYPE(id), 1); + key = ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq); if (key == NULL) { ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE); return 0; @@ -75,7 +75,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, goto err; } if (op == KEY_OP_KEYGEN) { - if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) + if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id)) <= 0) goto err; if (id == EVP_PKEY_X25519) { privkey[0] &= 248; @@ -149,9 +149,8 @@ static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0; } -static int ecx_priv_decode_with_libctx(EVP_PKEY *pkey, - const PKCS8_PRIV_KEY_INFO *p8, - OPENSSL_CTX *libctx, const char *propq) +static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, + OSSL_LIB_CTX *libctx, const char *propq) { const unsigned char *p; int plen; @@ -397,7 +396,7 @@ static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey) } static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq) { const ECX_KEY *key = from->pkey.ecx; @@ -439,7 +438,8 @@ static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx, { EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - ECX_KEY *ecx = ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0); + ECX_KEY *ecx = ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0, + pctx->propquery); if (ecx == NULL) { ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); @@ -504,7 +504,7 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { ecx_pkey_export_to, x25519_import_from, - ecx_priv_decode_with_libctx + ecx_priv_decode_ex }; static int x448_import_from(const OSSL_PARAM params[], void *vpctx) @@ -557,7 +557,7 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = { ecx_pkey_export_to, x448_import_from, - ecx_priv_decode_with_libctx + ecx_priv_decode_ex }; static int ecd_size25519(const EVP_PKEY *pkey) @@ -570,9 +570,9 @@ static int ecd_size448(const EVP_PKEY *pkey) return ED448_SIGSIZE; } -static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *sigalg, ASN1_BIT_STRING *str, - EVP_PKEY *pkey) +static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *str, EVP_PKEY *pkey) { const ASN1_OBJECT *obj; int ptype; @@ -592,7 +592,8 @@ static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; } -static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, +static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *str) { @@ -612,7 +613,8 @@ static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg, return 1; } -static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, +static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *str) { @@ -681,7 +683,7 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { ecx_pkey_export_to, ed25519_import_from, - ecx_priv_decode_with_libctx + ecx_priv_decode_ex }; static int ed448_import_from(const OSSL_PARAM params[], void *vpctx) @@ -733,7 +735,7 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = { ecx_pkey_export_to, ed448_import_from, - ecx_priv_decode_with_libctx + ecx_priv_decode_ex }; static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) @@ -860,12 +862,8 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig, return 0; } - /* - * TODO(3.0): We use NULL for the library context for now. Will need to - * change later. - */ - if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey, - NULL, 0) == 0) + if (ED448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, edkey->privkey, + NULL, 0, edkey->propq) == 0) return 0; *siglen = ED448_SIGSIZE; return 1; @@ -880,7 +878,8 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig, if (siglen != ED25519_SIGSIZE) return 0; - return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL); + return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, + edkey->libctx, edkey->propq); } static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, @@ -892,11 +891,8 @@ static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig, if (siglen != ED448_SIGSIZE) return 0; - /* - * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to - * change. - */ - return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0); + return ED448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, NULL, 0, + edkey->propq); } static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) @@ -947,7 +943,8 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -963,7 +960,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN) <= 0) goto err; privkey[0] &= 248; @@ -989,7 +986,8 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -1005,7 +1003,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN) <= 0) goto err; privkey[0] &= 252; @@ -1034,7 +1032,8 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, }; unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; unsigned int sz; @@ -1051,7 +1050,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN) <= 0) goto err; if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL)) @@ -1091,7 +1090,8 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 }; unsigned char x_dst[57], buff[114]; - ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1); + ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1, + ctx->propquery); unsigned char *privkey = NULL, *pubkey; EVP_MD_CTX *hashctx = NULL; @@ -1108,7 +1108,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) goto err; } - if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0) + if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN) <= 0) goto err; hashctx = EVP_MD_CTX_new(); diff --git a/crypto/encode_decode/build.info b/crypto/encode_decode/build.info new file mode 100644 index 0000000000..e2cd846673 --- /dev/null +++ b/crypto/encode_decode/build.info @@ -0,0 +1,5 @@ +SOURCE[../../libcrypto]=encoder_meth.c encoder_lib.c encoder_pkey.c +SOURCE[../../libcrypto]=decoder_meth.c decoder_lib.c decoder_pkey.c + +SOURCE[../../libcrypto]=encoder_err.c +SOURCE[../../libcrypto]=decoder_err.c diff --git a/crypto/serializer/deserializer_err.c b/crypto/encode_decode/decoder_err.c similarity index 55% rename from crypto/serializer/deserializer_err.c rename to crypto/encode_decode/decoder_err.c index 2cc245996f..984f7abeb9 100644 --- a/crypto/serializer/deserializer_err.c +++ b/crypto/encode_decode/decoder_err.c @@ -9,23 +9,23 @@ */ #include -#include +#include #ifndef OPENSSL_NO_ERR -static const ERR_STRING_DATA OSSL_DESERIALIZER_str_reasons[] = { - {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, OSSL_DESERIALIZER_R_MISSING_GET_PARAMS), - "missing get params"}, +static const ERR_STRING_DATA OSSL_DECODER_str_reasons[] = { + {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_MISSING_GET_PARAMS), + "missing get params"}, {0, NULL} }; #endif -int ERR_load_OSSL_DESERIALIZER_strings(void) +int ERR_load_OSSL_DECODER_strings(void) { #ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OSSL_DESERIALIZER_str_reasons[0].error) == NULL) - ERR_load_strings_const(OSSL_DESERIALIZER_str_reasons); + if (ERR_reason_error_string(OSSL_DECODER_str_reasons[0].error) == NULL) + ERR_load_strings_const(OSSL_DECODER_str_reasons); #endif return 1; } diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c new file mode 100644 index 0000000000..20350a8cd6 --- /dev/null +++ b/crypto/encode_decode/decoder_lib.c @@ -0,0 +1,587 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal/passphrase.h" +#include "crypto/decoder.h" +#include "encoder_local.h" +#include "e_os.h" + +struct decoder_process_data_st { + OSSL_DECODER_CTX *ctx; + + /* Current BIO */ + BIO *bio; + + /* Index of the current decoder instance to be processed */ + size_t current_decoder_inst_index; +}; + +static int decoder_process(const OSSL_PARAM params[], void *arg); + +int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in) +{ + struct decoder_process_data_st data; + int ok = 0; + + memset(&data, 0, sizeof(data)); + data.ctx = ctx; + data.bio = in; + + /* Enable passphrase caching */ + (void)ossl_pw_enable_passphrase_caching(&ctx->pwdata); + + ok = decoder_process(NULL, &data); + + /* Clear any internally cached passphrase */ + (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata); + + return ok; +} + +#ifndef OPENSSL_NO_STDIO +static BIO *bio_from_file(FILE *fp) +{ + BIO *b; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + return b; +} + +int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *fp) +{ + BIO *b = bio_from_file(fp); + int ret = 0; + + if (b != NULL) + ret = OSSL_DECODER_from_bio(ctx, b); + + BIO_free(b); + return ret; +} +#endif + +int OSSL_DECODER_from_data(OSSL_DECODER_CTX *ctx, const unsigned char **pdata, + size_t *pdata_len) +{ + BIO *membio; + int ret = 0; + + if (pdata == NULL || *pdata == NULL || pdata_len == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + membio = BIO_new_mem_buf(*pdata, (int)*pdata_len); + if (OSSL_DECODER_from_bio(ctx, membio)) { + *pdata_len = (size_t)BIO_get_mem_data(membio, pdata); + ret = 1; + } + BIO_free(membio); + + return ret; +} + +int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, + const char *input_type) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * NULL is a valid starting input type, and means that the caller leaves + * it to code to discover what the starting input type is. + */ + ctx->start_input_type = input_type; + return 1; +} + +OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, + void *decoderctx) +{ + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + OSSL_PARAM params[2]; + + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (decoder->get_params == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, + OSSL_DECODER_R_MISSING_GET_PARAMS); + return 0; + } + + if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!OSSL_DECODER_up_ref(decoder)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Cache the input type for this encoder */ + params[0] = + OSSL_PARAM_construct_utf8_ptr(OSSL_DECODER_PARAM_INPUT_TYPE, + (char **)&decoder_inst->input_type, 0); + params[1] = OSSL_PARAM_construct_end(); + + if (!decoder->get_params(params) + || !OSSL_PARAM_modified(¶ms[0])) + goto err; + + decoder_inst->decoder = decoder; + decoder_inst->decoderctx = decoderctx; + return decoder_inst; + err: + ossl_decoder_instance_free(decoder_inst); + return NULL; +} + +void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst != NULL) { + if (decoder_inst->decoder != NULL) + decoder_inst->decoder->freectx(decoder_inst->decoderctx); + decoder_inst->decoderctx = NULL; + OSSL_DECODER_free(decoder_inst->decoder); + decoder_inst->decoder = NULL; + OPENSSL_free(decoder_inst); + } +} + +int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_INSTANCE *di) +{ + if (ctx->decoder_insts == NULL + && (ctx->decoder_insts = + sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + return (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, di) > 0); +} + +int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) +{ + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + const OSSL_PROVIDER *prov = NULL; + void *decoderctx = NULL; + void *provctx = NULL; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + prov = OSSL_DECODER_provider(decoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if ((decoderctx = decoder->newctx(provctx)) == NULL + || (decoder_inst = + ossl_decoder_instance_new(decoder, decoderctx)) == NULL) + goto err; + /* Avoid double free of decoderctx on further errors */ + decoderctx = NULL; + + if (!ossl_decoder_ctx_add_decoder_inst(ctx, decoder_inst)) + goto err; + + return 1; + err: + ossl_decoder_instance_free(decoder_inst); + if (decoderctx != NULL) + decoder->freectx(decoderctx); + return 0; +} + +int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + /* + * This function goes through existing decoder methods in + * |ctx->decoder_insts|, and tries to fetch new decoders that produce + * what the existing ones want as input, and push those newly fetched + * decoders on top of the same stack. + * Then it does the same again, but looping over the newly fetched + * decoders, until there are no more encoders to be fetched, or + * when we have done this 10 times. + * + * we do this with sliding windows on the stack by keeping track of indexes + * and of the end. + * + * +----------------+ + * | DER to RSA | <--- w_prev_start + * +----------------+ + * | DER to DSA | + * +----------------+ + * | DER to DH | + * +----------------+ + * | PEM to DER | <--- w_prev_end, w_new_start + * +----------------+ + * <--- w_new_end + */ + size_t w_prev_start, w_prev_end; /* "previous" decoders */ + size_t w_new_start, w_new_end; /* "new" decoders */ + size_t count = 0; /* Calculates how many were added in each iteration */ + size_t depth = 0; /* Counts the number of iterations */ + + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* + * If there is no stack of OSSL_DECODER_INSTANCE, we have nothing + * more to add. That's fine. + */ + if (ctx->decoder_insts == NULL) + return 1; + + w_prev_start = 0; + w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); + do { + size_t i; + + w_new_start = w_new_end = w_prev_end; + + for (i = w_prev_start; i < w_prev_end; i++) { + OSSL_DECODER_INSTANCE *decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + const char *input_type = + OSSL_DECODER_INSTANCE_get_input_type(decoder_inst); + OSSL_DECODER *decoder = NULL; + + /* + * If the caller has specified what the initial input should be, + * and the decoder implementation we're looking at has that + * input type, there's no point adding on more implementations + * on top of this one, so we don't. + */ + if (ctx->start_input_type != NULL + && strcasecmp(ctx->start_input_type, input_type) == 0) + continue; + + ERR_set_mark(); + decoder = OSSL_DECODER_fetch(libctx, input_type, propq); + ERR_pop_to_mark(); + + if (decoder != NULL) { + size_t j; + + /* + * Check that we don't already have this decoder in our + * stack We only need to check among the newly added ones. + */ + for (j = w_new_start; j < w_new_end; j++) { + OSSL_DECODER_INSTANCE *check_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, j); + + if (decoder == check_inst->decoder) { + /* We found it, so drop the new fetch */ + OSSL_DECODER_free(decoder); + decoder = NULL; + break; + } + } + } + + if (decoder == NULL) + continue; + + /* + * Apart from keeping w_new_end up to date, We don't care about + * errors here. If it doesn't collect, then it doesn't... + */ + if (OSSL_DECODER_CTX_add_decoder(ctx, decoder)) /* ref++ */ + w_new_end++; + OSSL_DECODER_free(decoder); /* ref-- */ + } + /* How many were added in this iteration */ + count = w_new_end - w_new_start; + + /* Slide the "previous decoder" windows */ + w_prev_start = w_new_start; + w_prev_end = w_new_end; + + depth++; + } while (count != 0 && depth <= 10); + + return 1; +} + +int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL || ctx->decoder_insts == NULL) + return 0; + return sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); +} + +int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CONSTRUCT *construct) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct = construct; + return 1; +} + +int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx, + void *construct_data) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct_data = construct_data; + return 1; +} + +int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CLEANUP *cleanup) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->cleanup = cleanup; + return 1; +} + +OSSL_DECODER_CONSTRUCT * +OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->construct; +} + +void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->construct_data; +} + +OSSL_DECODER_CLEANUP * +OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx) +{ + if (ctx == NULL) + return NULL; + return ctx->cleanup; +} + +int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, + void *reference, size_t reference_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + OSSL_DECODER *decoder = NULL; + void *decoderctx = NULL; + + if (!(ossl_assert(decoder_inst != NULL) + && ossl_assert(reference != NULL) + && ossl_assert(export_cb != NULL) + && ossl_assert(export_cbarg != NULL))) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + return decoder->export_object(decoderctx, reference, reference_sz, + export_cb, export_cbarg); +} + +OSSL_DECODER * +OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->decoder; +} + +void * +OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->decoderctx; +} + +const char * +OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst) +{ + if (decoder_inst == NULL) + return NULL; + return decoder_inst->input_type; +} + +static int decoder_process(const OSSL_PARAM params[], void *arg) +{ + struct decoder_process_data_st *data = arg; + OSSL_DECODER_CTX *ctx = data->ctx; + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + OSSL_DECODER *decoder = NULL; + BIO *bio = data->bio; + long loc; + size_t i; + int err, ok = 0; + /* For recursions */ + struct decoder_process_data_st new_data; + const char *object_type = NULL; + + memset(&new_data, 0, sizeof(new_data)); + new_data.ctx = data->ctx; + + if (params == NULL) { + /* First iteration, where we prepare for what is to come */ + + data->current_decoder_inst_index = + OSSL_DECODER_CTX_get_num_decoders(ctx); + + bio = data->bio; + } else { + const OSSL_PARAM *p; + + decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, + data->current_decoder_inst_index); + decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + + if (ctx->construct != NULL + && ctx->construct(decoder_inst, params, ctx->construct_data)) { + ok = 1; + goto end; + } + + /* The constructor didn't return success */ + + /* + * so we try to use the object we got and feed it to any next + * decoder that will take it. Object references are not + * allowed for this. + * If this data isn't present, decoding has failed. + */ + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA); + if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) + goto end; + new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size); + if (new_data.bio == NULL) + goto end; + bio = new_data.bio; + + /* Get the object type if there is one */ + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &object_type)) + goto end; + } + + /* + * If we have no more decoders to look through at this point, + * we failed + */ + if (data->current_decoder_inst_index == 0) + goto end; + + if ((loc = BIO_tell(bio)) < 0) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_BIO_LIB); + goto end; + } + + for (i = data->current_decoder_inst_index; i-- > 0;) { + OSSL_DECODER_INSTANCE *new_decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + OSSL_DECODER *new_decoder = + OSSL_DECODER_INSTANCE_get_decoder(new_decoder_inst); + void *new_decoderctx = + OSSL_DECODER_INSTANCE_get_decoder_ctx(new_decoder_inst); + const char *new_input_type = + OSSL_DECODER_INSTANCE_get_input_type(new_decoder_inst); + + /* + * If |decoder| is NULL, it means we've just started, and the caller + * may have specified what it expects the initial input to be. If + * that's the case, we do this extra check. + */ + if (decoder == NULL && ctx->start_input_type != NULL + && strcasecmp(ctx->start_input_type, new_input_type) != 0) + continue; + + /* + * If we have a previous decoder, we check that the input type + * of the next to be used matches the type of this previous one. + * input_type is a cache of the parameter "input-type" value for + * that decoder. + */ + if (decoder != NULL && !OSSL_DECODER_is_a(decoder, new_input_type)) + continue; + + /* + * If the previous decoder gave us an object type, we check to see + * if that matches the decoder we're currently considering. + */ + if (object_type != NULL && !OSSL_DECODER_is_a(new_decoder, object_type)) + continue; + + /* + * Checking the return value of BIO_reset() or BIO_seek() is unsafe. + * Furthermore, BIO_reset() is unsafe to use if the source BIO happens + * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero + * no matter where we are in the underlying buffer we're reading from. + * + * So, we simply do a BIO_seek(), and use BIO_tell() that we're back + * at the same position. This is a best effort attempt, but BIO_seek() + * and BIO_tell() should come as a pair... + */ + (void)BIO_seek(bio, loc); + if (BIO_tell(bio) != loc) + goto end; + + /* Recurse */ + new_data.current_decoder_inst_index = i; + ok = new_decoder->decode(new_decoderctx, (OSSL_CORE_BIO *)bio, + decoder_process, &new_data, + ossl_pw_passphrase_callback_dec, + &new_data.ctx->pwdata); + if (ok) + break; + err = ERR_peek_last_error(); + if ((ERR_GET_LIB(err) == ERR_LIB_EVP + && ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM) +#ifndef OPENSSL_NO_EC + || (ERR_GET_LIB(err) == ERR_LIB_EC + && ERR_GET_REASON(err) == EC_R_UNKNOWN_GROUP) +#endif + || (ERR_GET_LIB(err) == ERR_LIB_X509 + && ERR_GET_REASON(err) == X509_R_UNSUPPORTED_ALGORITHM)) + break; /* fatal error; preserve it on the error queue and stop */ + } + + end: + BIO_free(new_data.bio); + return ok; +} diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c new file mode 100644 index 0000000000..f27bb4c1e4 --- /dev/null +++ b/crypto/encode_decode/decoder_meth.c @@ -0,0 +1,534 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "crypto/decoder.h" +#include "encoder_local.h" + +/* + * Decoder can have multiple names, separated with colons in a name string + */ +#define NAME_SEPARATOR ':' + +/* Simple method structure constructor and destructor */ +static OSSL_DECODER *ossl_decoder_new(void) +{ + OSSL_DECODER *decoder = NULL; + + if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL + || (decoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { + OSSL_DECODER_free(decoder); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + decoder->base.refcnt = 1; + + return decoder; +} + +int OSSL_DECODER_up_ref(OSSL_DECODER *decoder) +{ + int ref = 0; + + CRYPTO_UP_REF(&decoder->base.refcnt, &ref, decoder->base.lock); + return 1; +} + +void OSSL_DECODER_free(OSSL_DECODER *decoder) +{ + int ref = 0; + + if (decoder == NULL) + return; + + CRYPTO_DOWN_REF(&decoder->base.refcnt, &ref, decoder->base.lock); + if (ref > 0) + return; + ossl_provider_free(decoder->base.prov); + CRYPTO_THREAD_lock_free(decoder->base.lock); + OPENSSL_free(decoder); +} + +/* Permanent decoder method store, constructor and destructor */ +static void decoder_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *decoder_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD decoder_store_method = { + decoder_store_new, + decoder_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct decoder_data_st { + OSSL_LIB_CTX *libctx; + OSSL_METHOD_CONSTRUCT_METHOD *mcm; + int id; /* For get_decoder_from_store() */ + const char *names; /* For get_decoder_from_store() */ + const char *propquery; /* For get_decoder_from_store() */ +}; + +/* + * Generic routines to fetch / create DECODER methods with + * ossl_method_construct() + */ + +/* Temporary decoder method store, constructor and destructor */ +static void *alloc_tmp_decoder_store(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + +static void dealloc_tmp_decoder_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent decoder store */ +static OSSL_METHOD_STORE *get_decoder_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_STORE_INDEX, + &decoder_store_method); +} + +/* Get decoder methods from a store, or put one in */ +static void *get_decoder_from_store(OSSL_LIB_CTX *libctx, void *store, + void *data) +{ + struct decoder_data_st *methdata = data; + void *method = NULL; + int id; + + if ((id = methdata->id) == 0) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + id = ossl_namemap_name2num(namemap, methdata->names); + } + + if (store == NULL + && (store = get_decoder_store(libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) + return NULL; + return method; +} + +static int put_decoder_in_store(OSSL_LIB_CTX *libctx, void *store, + void *method, const OSSL_PROVIDER *prov, + int operation_id, const char *names, + const char *propdef, void *unused) +{ + OSSL_NAMEMAP *namemap; + int id; + + if ((namemap = ossl_namemap_stored(libctx)) == NULL + || (id = ossl_namemap_name2num(namemap, names)) == 0) + return 0; + + if (store == NULL && (store = get_decoder_store(libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + (int (*)(void *))OSSL_DECODER_up_ref, + (void (*)(void *))OSSL_DECODER_free); +} + +/* Create and populate a decoder method */ +void *ossl_decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_DECODER *decoder = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + + if ((decoder = ossl_decoder_new()) == NULL) + return NULL; + decoder->base.id = id; + decoder->base.propdef = algodef->property_definition; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_DECODER_NEWCTX: + if (decoder->newctx == NULL) + decoder->newctx = OSSL_FUNC_decoder_newctx(fns); + break; + case OSSL_FUNC_DECODER_FREECTX: + if (decoder->freectx == NULL) + decoder->freectx = OSSL_FUNC_decoder_freectx(fns); + break; + case OSSL_FUNC_DECODER_GET_PARAMS: + if (decoder->get_params == NULL) + decoder->get_params = + OSSL_FUNC_decoder_get_params(fns); + break; + case OSSL_FUNC_DECODER_GETTABLE_PARAMS: + if (decoder->gettable_params == NULL) + decoder->gettable_params = + OSSL_FUNC_decoder_gettable_params(fns); + break; + case OSSL_FUNC_DECODER_SET_CTX_PARAMS: + if (decoder->set_ctx_params == NULL) + decoder->set_ctx_params = + OSSL_FUNC_decoder_set_ctx_params(fns); + break; + case OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS: + if (decoder->settable_ctx_params == NULL) + decoder->settable_ctx_params = + OSSL_FUNC_decoder_settable_ctx_params(fns); + break; + case OSSL_FUNC_DECODER_DECODE: + if (decoder->decode == NULL) + decoder->decode = OSSL_FUNC_decoder_decode(fns); + break; + case OSSL_FUNC_DECODER_EXPORT_OBJECT: + if (decoder->export_object == NULL) + decoder->export_object = OSSL_FUNC_decoder_export_object(fns); + break; + } + } + /* + * Try to check that the method is sensible. + * If you have a constructor, you must have a destructor and vice versa. + * You must have at least one of the encoding driver functions. + */ + if (!((decoder->newctx == NULL && decoder->freectx == NULL) + || (decoder->newctx != NULL && decoder->freectx != NULL)) + || decoder->decode == NULL) { + OSSL_DECODER_free(decoder); + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + OSSL_DECODER_free(decoder); + return NULL; + } + + decoder->base.prov = prov; + return decoder; +} + + +/* + * The core fetching functionality passes the names of the implementation. + * This function is responsible to getting an identity number for them, + * then call ossl_decoder_from_dispatch() with that identity number. + */ +static void *construct_decoder(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *unused) +{ + /* + * This function is only called if get_decoder_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the name already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = ossl_decoder_from_dispatch(id, algodef, prov); + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_decoder(void *method, void *data) +{ + OSSL_DECODER_free(method); +} + +static int up_ref_decoder(void *method) +{ + return OSSL_DECODER_up_ref(method); +} + +static void free_decoder(void *method) +{ + OSSL_DECODER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by name */ +static OSSL_DECODER *inner_ossl_decoder_fetch(OSSL_LIB_CTX *libctx, int id, + const char *name, + const char *properties) +{ + OSSL_METHOD_STORE *store = get_decoder_store(libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + void *method = NULL; + + if (store == NULL || namemap == NULL) + return NULL; + + /* + * If we have been passed neither a name_id or a name, we have an + * internal programming error. + */ + if (!ossl_assert(id != 0 || name != NULL)) + return NULL; + + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + + if (id == 0 + || !ossl_method_store_cache_get(store, id, properties, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + alloc_tmp_decoder_store, + dealloc_tmp_decoder_store, + get_decoder_from_store, + put_decoder_in_store, + construct_decoder, + destruct_decoder + }; + struct decoder_data_st mcmdata; + + mcmdata.libctx = libctx; + mcmdata.mcm = &mcm; + mcmdata.id = id; + mcmdata.names = name; + mcmdata.propquery = properties; + if ((method = ossl_method_construct(libctx, OSSL_OP_DECODER, + 0 /* !force_cache */, + &mcm, &mcmdata)) != NULL) { + /* + * If construction did create a method for us, we know that + * there is a correct name_id and meth_id, since those have + * already been calculated in get_decoder_from_store() and + * put_decoder_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + ossl_method_store_cache_set(store, id, properties, method, + up_ref_decoder, free_decoder); + } + } + + return method; +} + +OSSL_DECODER *OSSL_DECODER_fetch(OSSL_LIB_CTX *libctx, const char *name, + const char *properties) +{ + return inner_ossl_decoder_fetch(libctx, 0, name, properties); +} + +OSSL_DECODER *ossl_decoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id, + const char *properties) +{ + return inner_ossl_decoder_fetch(libctx, id, NULL, properties); +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.prov; +} + +const char *OSSL_DECODER_properties(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.propdef; +} + +int OSSL_DECODER_number(const OSSL_DECODER *decoder) +{ + if (!ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return decoder->base.id; +} + +int OSSL_DECODER_is_a(const OSSL_DECODER *decoder, const char *name) +{ + if (decoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == decoder->base.id; + } + return 0; +} + +struct decoder_do_all_data_st { + void (*user_fn)(void *method, void *arg); + void *user_arg; +}; + +static void decoder_do_one(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algodef, + int no_store, void *vdata) +{ + struct decoder_do_all_data_st *data = vdata; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = ossl_decoder_from_dispatch(id, algodef, provider); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + OSSL_DECODER_free(method); + } +} + +void OSSL_DECODER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(OSSL_DECODER *decoder, void *arg), + void *arg) +{ + struct decoder_do_all_data_st data; + + data.user_fn = (void (*)(void *, void *))fn; + data.user_arg = arg; + ossl_algorithm_do_all(libctx, OSSL_OP_DECODER, NULL, + NULL, decoder_do_one, NULL, + &data); +} + +void OSSL_DECODER_names_do_all(const OSSL_DECODER *decoder, + void (*fn)(const char *name, void *data), + void *data) +{ + if (decoder == NULL) + return; + + if (decoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(decoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + ossl_namemap_doall_names(namemap, decoder->base.id, fn, data); + } +} + +const OSSL_PARAM * +OSSL_DECODER_gettable_params(OSSL_DECODER *decoder) +{ + if (decoder != NULL && decoder->gettable_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_DECODER_provider(decoder)); + + return decoder->gettable_params(provctx); + } + return NULL; +} + +int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[]) +{ + if (decoder != NULL && decoder->get_params != NULL) + return decoder->get_params(params); + return 0; +} + +const OSSL_PARAM * +OSSL_DECODER_settable_ctx_params(OSSL_DECODER *decoder) +{ + if (decoder != NULL && decoder->settable_ctx_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_DECODER_provider(decoder)); + + return decoder->settable_ctx_params(provctx); + } + return NULL; +} + +/* + * Decoder context support + */ + +/* + * |encoder| value NULL is valid, and signifies that there is no decoder. + * This is useful to provide fallback mechanisms. + * Functions that want to verify if there is a decoder can do so with + * OSSL_DECODER_CTX_get_decoder() + */ +OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void) +{ + OSSL_DECODER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + + return ctx; +} + +int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx, + const OSSL_PARAM params[]) +{ + size_t i; + size_t l; + + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->decoder_insts == NULL) + return 1; + + l = OSSL_DECODER_CTX_get_num_decoders(ctx); + for (i = 0; i < l; i++) { + OSSL_DECODER_INSTANCE *decoder_inst = + sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i); + OSSL_DECODER *decoder = + OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + OSSL_DECODER *decoderctx = + OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + + if (decoderctx == NULL || decoder->set_ctx_params == NULL) + continue; + if (!decoder->set_ctx_params(decoderctx, params)) + return 0; + } + return 1; +} + +void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx) +{ + if (ctx != NULL) { + if (ctx->cleanup != NULL) + ctx->cleanup(ctx->construct_data); + sk_OSSL_DECODER_INSTANCE_pop_free(ctx->decoder_insts, + ossl_decoder_instance_free); + ossl_pw_clear_passphrase_data(&ctx->pwdata); + OPENSSL_free(ctx); + } +} diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c new file mode 100644 index 0000000000..e9c0141804 --- /dev/null +++ b/crypto/encode_decode/decoder_pkey.c @@ -0,0 +1,345 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include "crypto/evp.h" +#include "crypto/decoder.h" +#include "encoder_local.h" + +int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, + const unsigned char *kstr, + size_t klen) +{ + return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); +} + +int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data) +{ + return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); +} + +int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx, + pem_password_cb *cb, void *cbarg) +{ + return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); +} + +int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg) +{ + return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); +} + +/* + * Support for OSSL_DECODER_CTX_new_by_EVP_PKEY: + * The construct data, and collecting keymgmt information for it + */ + +DEFINE_STACK_OF(EVP_KEYMGMT) + +struct decoder_EVP_PKEY_data_st { + char *object_type; /* recorded object data type, may be NULL */ + void **object; /* Where the result should end up */ + STACK_OF(EVP_KEYMGMT) *keymgmts; /* The EVP_KEYMGMTs we handle */ +}; + +static int decoder_construct_EVP_PKEY(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, + void *construct_data) +{ + struct decoder_EVP_PKEY_data_st *data = construct_data; + OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); + void *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); + size_t i, end_i; + /* + * |object_ref| points to a provider reference to an object, its exact + * contents entirely opaque to us, but may be passed to any provider + * function that expects this (such as OSSL_FUNC_keymgmt_load(). + * + * This pointer is considered volatile, i.e. whatever it points at + * is assumed to be freed as soon as this function returns. + */ + void *object_ref = NULL; + size_t object_ref_sz = 0; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p != NULL) { + char *object_type = NULL; + + if (!OSSL_PARAM_get_utf8_string(p, &object_type, 0)) + return 0; + OPENSSL_free(data->object_type); + data->object_type = object_type; + } + + /* + * For stuff that should end up in an EVP_PKEY, we only accept an object + * reference for the moment. This enforces that the key data itself + * remains with the provider. + */ + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE); + if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) + return 0; + object_ref = p->data; + object_ref_sz = p->data_size; + + /* We may have reached one of the goals, let's find out! */ + end_i = sk_EVP_KEYMGMT_num(data->keymgmts); + for (i = 0; end_i; i++) { + EVP_KEYMGMT *keymgmt = sk_EVP_KEYMGMT_value(data->keymgmts, i); + + /* + * There are two ways to find a matching KEYMGMT: + * + * 1. If the object data type (recorded in |data->object_type|) + * is defined, by checking it using EVP_KEYMGMT_is_a(). + * 2. If the object data type is NOT defined, by comparing the + * EVP_KEYMGMT and OSSL_DECODER method numbers. Since + * EVP_KEYMGMT and OSSL_DECODE operate with the same + * namemap, we know that the method numbers must match. + * + * This allows individual decoders to specify variants of keys, + * such as a DER to RSA decoder finding a RSA-PSS key, without + * having to decode the exact same DER blob into the exact same + * internal structure twice. This is, of course, entirely at the + * discretion of the decoder implementations. + */ + if (data->object_type != NULL + ? EVP_KEYMGMT_is_a(keymgmt, data->object_type) + : EVP_KEYMGMT_number(keymgmt) == OSSL_DECODER_number(decoder)) { + EVP_PKEY *pkey = NULL; + void *keydata = NULL; + const OSSL_PROVIDER *keymgmt_prov = + EVP_KEYMGMT_provider(keymgmt); + const OSSL_PROVIDER *decoder_prov = + OSSL_DECODER_provider(decoder); + + /* + * If the EVP_KEYMGMT and the OSSL_DECODER are from the + * same provider, we assume that the KEYMGMT has a key loading + * function that can handle the provider reference we hold. + * + * Otherwise, we export from the decoder and import the + * result in the keymgmt. + */ + if (keymgmt_prov == decoder_prov) { + keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz); + } else { + struct evp_keymgmt_util_try_import_data_st import_data; + + import_data.keymgmt = keymgmt; + import_data.keydata = NULL; + import_data.selection = OSSL_KEYMGMT_SELECT_ALL; + + /* + * No need to check for errors here, the value of + * |import_data.keydata| is as much an indicator. + */ + (void)decoder->export_object(decoderctx, + object_ref, object_ref_sz, + &evp_keymgmt_util_try_import, + &import_data); + keydata = import_data.keydata; + import_data.keydata = NULL; + } + + if (keydata != NULL + && (pkey = + evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL) + evp_keymgmt_freedata(keymgmt, keydata); + + *data->object = pkey; + + break; + } + } + /* + * We successfully looked through, |*ctx->object| determines if we + * actually found something. + */ + return (*data->object != NULL); +} + +static void decoder_clean_EVP_PKEY_construct_arg(void *construct_data) +{ + struct decoder_EVP_PKEY_data_st *data = construct_data; + + if (data != NULL) { + sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free); + OPENSSL_free(data->object_type); + OPENSSL_free(data); + } +} + +struct collected_data_st { + struct decoder_EVP_PKEY_data_st *process_data; + const char *keytype; + STACK_OF(OPENSSL_CSTRING) *names; + OSSL_DECODER_CTX *ctx; + + unsigned int error_occured:1; +}; + +static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) +{ + struct collected_data_st *data = arg; + + if (data->keytype != NULL && !EVP_KEYMGMT_is_a(keymgmt, data->keytype)) + return; + if (data->error_occured) + return; + + data->error_occured = 1; /* Assume the worst */ + + if (!EVP_KEYMGMT_up_ref(keymgmt) /* ref++ */) + return; + if (sk_EVP_KEYMGMT_push(data->process_data->keymgmts, keymgmt) <= 0) { + EVP_KEYMGMT_free(keymgmt); /* ref-- */ + return; + } + + data->error_occured = 0; /* All is good now */ +} + +static void collect_name(const char *name, void *arg) +{ + struct collected_data_st *data = arg; + + if (data->error_occured) + return; + + data->error_occured = 1; /* Assume the worst */ + + if (sk_OPENSSL_CSTRING_push(data->names, name) <= 0) + return; + + data->error_occured = 0; /* All is good now */ +} + +static void collect_decoder(OSSL_DECODER *decoder, void *arg) +{ + struct collected_data_st *data = arg; + size_t i, end_i; + + if (data->error_occured) + return; + + data->error_occured = 1; /* Assume the worst */ + if (data->names == NULL) + return; + + end_i = sk_OPENSSL_CSTRING_num(data->names); + for (i = 0; i < end_i; i++) { + const char *name = sk_OPENSSL_CSTRING_value(data->names, i); + + if (!OSSL_DECODER_is_a(decoder, name)) + continue; + (void)OSSL_DECODER_CTX_add_decoder(data->ctx, decoder); + } + + data->error_occured = 0; /* All is good now */ +} + +int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, + EVP_PKEY **pkey, const char *keytype, + OSSL_LIB_CTX *libctx, + const char *propquery) +{ + struct collected_data_st *data = NULL; + size_t i, end_i; + int ok = 0; + + if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL + || (data->process_data = + OPENSSL_zalloc(sizeof(*data->process_data))) == NULL + || (data->process_data->keymgmts = sk_EVP_KEYMGMT_new_null()) == NULL + || (data->names = sk_OPENSSL_CSTRING_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + goto err; + } + data->process_data->object = (void **)pkey; + data->ctx = ctx; + data->keytype = keytype; + + /* First, find all keymgmts to form goals */ + EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, data); + + if (data->error_occured) + goto err; + + /* Then, we collect all the keymgmt names */ + end_i = sk_EVP_KEYMGMT_num(data->process_data->keymgmts); + for (i = 0; i < end_i; i++) { + EVP_KEYMGMT *keymgmt = + sk_EVP_KEYMGMT_value(data->process_data->keymgmts, i); + + EVP_KEYMGMT_names_do_all(keymgmt, collect_name, data); + + if (data->error_occured) + goto err; + } + + /* + * Finally, find all decoders that have any keymgmt of the collected + * keymgmt names + */ + OSSL_DECODER_do_all_provided(libctx, collect_decoder, data); + + if (data->error_occured) + goto err; + + if (OSSL_DECODER_CTX_get_num_decoders(ctx) != 0) { + if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_EVP_PKEY) + || !OSSL_DECODER_CTX_set_construct_data(ctx, data->process_data) + || !OSSL_DECODER_CTX_set_cleanup(ctx, + decoder_clean_EVP_PKEY_construct_arg)) + goto err; + + data->process_data = NULL; /* Avoid it being freed */ + } + + ok = 1; + err: + if (data != NULL) { + decoder_clean_EVP_PKEY_construct_arg(data->process_data); + sk_OPENSSL_CSTRING_free(data->names); + OPENSSL_free(data); + } + return ok; +} + +OSSL_DECODER_CTX * +OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, + const char *input_type, const char *keytype, + OSSL_LIB_CTX *libctx, const char *propquery) +{ + OSSL_DECODER_CTX *ctx = NULL; + + if ((ctx = OSSL_DECODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) + && ossl_decoder_ctx_setup_for_EVP_PKEY(ctx, pkey, keytype, + libctx, propquery) + && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)) + return ctx; + + OSSL_DECODER_CTX_free(ctx); + return NULL; +} diff --git a/crypto/encode_decode/encoder_err.c b/crypto/encode_decode/encoder_err.c new file mode 100644 index 0000000000..2c95a2a20e --- /dev/null +++ b/crypto/encode_decode/encoder_err.c @@ -0,0 +1,35 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#ifndef OPENSSL_NO_ERR + +static const ERR_STRING_DATA OSSL_ENCODER_str_reasons[] = { + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_ENCODER_NOT_FOUND), + "encoder not found"}, + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY), + "incorrect property query"}, + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_MISSING_GET_PARAMS), + "missing get params"}, + {0, NULL} +}; + +#endif + +int ERR_load_OSSL_ENCODER_strings(void) +{ +#ifndef OPENSSL_NO_ERR + if (ERR_reason_error_string(OSSL_ENCODER_str_reasons[0].error) == NULL) + ERR_load_strings_const(OSSL_ENCODER_str_reasons); +#endif + return 1; +} diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c new file mode 100644 index 0000000000..593483313c --- /dev/null +++ b/crypto/encode_decode/encoder_lib.c @@ -0,0 +1,431 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" /* strcasecmp on Windows */ +#include +#include +#include +#include +#include +#include +#include "encoder_local.h" + +static int encoder_process(OSSL_ENCODER_CTX *ctx, BIO *out); + +int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out) +{ + return encoder_process(ctx, out); +} + +#ifndef OPENSSL_NO_STDIO +static BIO *bio_from_file(FILE *fp) +{ + BIO *b; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_BUF_LIB); + return NULL; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + return b; +} + +int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp) +{ + BIO *b = bio_from_file(fp); + int ret = 0; + + if (b != NULL) + ret = OSSL_ENCODER_to_bio(ctx, b); + + BIO_free(b); + return ret; +} +#endif + +int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata, + size_t *pdata_len) +{ + BIO *out = BIO_new(BIO_s_mem()); + BUF_MEM *buf = NULL; + int ret = 0; + + if (pdata_len == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (OSSL_ENCODER_to_bio(ctx, out) + && BIO_get_mem_ptr(out, &buf) > 0) { + ret = 1; /* Hope for the best. A too small buffer will clear this */ + + if (pdata != NULL && *pdata != NULL) { + if (*pdata_len < buf->length) + /* + * It's tempting to do |*pdata_len = (size_t)buf->length| + * However, it's believed to be confusing more than helpful, + * so we don't. + */ + ret = 0; + else + *pdata_len -= buf->length; + } else { + /* The buffer with the right size is already allocated for us */ + *pdata_len = (size_t)buf->length; + } + + if (ret) { + if (pdata != NULL) { + if (*pdata != NULL) { + memcpy(*pdata, buf->data, buf->length); + *pdata += buf->length; + } else { + /* In this case, we steal the data from BIO_s_mem() */ + *pdata = (unsigned char *)buf->data; + buf->data = NULL; + } + } + } + } + BIO_free(out); + return ret; +} + +int OSSL_ENCODER_CTX_set_output_type(OSSL_ENCODER_CTX *ctx, + const char *output_type) +{ + if (!ossl_assert(ctx != NULL) || !ossl_assert(output_type != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + ctx->output_type = output_type; + return 1; +} + +int OSSL_ENCODER_CTX_set_selection(OSSL_ENCODER_CTX *ctx, int selection) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ossl_assert(selection != 0)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + ctx->selection = selection; + return 1; +} + +static OSSL_ENCODER_INSTANCE *ossl_encoder_instance_new(OSSL_ENCODER *encoder, + void *encoderctx) +{ + OSSL_ENCODER_INSTANCE *encoder_inst = NULL; + OSSL_PARAM params[3]; + + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (encoder->get_params == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, + OSSL_ENCODER_R_MISSING_GET_PARAMS); + return 0; + } + + if ((encoder_inst = OPENSSL_zalloc(sizeof(*encoder_inst))) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* + * Cache the input and output types for this encoder. The output type + * is mandatory. + */ + params[0] = + OSSL_PARAM_construct_utf8_ptr(OSSL_ENCODER_PARAM_OUTPUT_TYPE, + (char **)&encoder_inst->output_type, 0); + params[1] = + OSSL_PARAM_construct_utf8_ptr(OSSL_ENCODER_PARAM_INPUT_TYPE, + (char **)&encoder_inst->input_type, 0); + params[2] = OSSL_PARAM_construct_end(); + + if (!encoder->get_params(params) + || !OSSL_PARAM_modified(¶ms[1])) + goto err; + + if (!OSSL_ENCODER_up_ref(encoder)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); + goto err; + } + + encoder_inst->encoder = encoder; + encoder_inst->encoderctx = encoderctx; + return encoder_inst; + err: + ossl_encoder_instance_free(encoder_inst); + return NULL; +} + +void ossl_encoder_instance_free(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst != NULL) { + if (encoder_inst->encoder != NULL) + encoder_inst->encoder->freectx(encoder_inst->encoderctx); + encoder_inst->encoderctx = NULL; + OSSL_ENCODER_free(encoder_inst->encoder); + encoder_inst->encoder = NULL; + OPENSSL_free(encoder_inst); + } +} + +static int ossl_encoder_ctx_add_encoder_inst(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_INSTANCE *ei) +{ + if (ctx->encoder_insts == NULL + && (ctx->encoder_insts = + sk_OSSL_ENCODER_INSTANCE_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + return (sk_OSSL_ENCODER_INSTANCE_push(ctx->encoder_insts, ei) > 0); +} + +int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder) +{ + OSSL_ENCODER_INSTANCE *encoder_inst = NULL; + const OSSL_PROVIDER *prov = NULL; + void *encoderctx = NULL; + void *provctx = NULL; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + prov = OSSL_ENCODER_provider(encoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if ((encoderctx = encoder->newctx(provctx)) == NULL + || (encoder_inst = + ossl_encoder_instance_new(encoder, encoderctx)) == NULL) + goto err; + /* Avoid double free of encoderctx on further errors */ + encoderctx = NULL; + + if (!ossl_encoder_ctx_add_encoder_inst(ctx, encoder_inst)) + goto err; + + return 1; + err: + ossl_encoder_instance_free(encoder_inst); + if (encoderctx != NULL) + encoder->freectx(encoderctx); + return 0; +} + +int OSSL_ENCODER_CTX_add_extra(OSSL_ENCODER_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return 1; +} + +int OSSL_ENCODER_CTX_get_num_encoders(OSSL_ENCODER_CTX *ctx) +{ + if (ctx == NULL || ctx->encoder_insts == NULL) + return 0; + return sk_OSSL_ENCODER_INSTANCE_num(ctx->encoder_insts); +} + +int OSSL_ENCODER_CTX_set_construct(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_CONSTRUCT *construct) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct = construct; + return 1; +} + +int OSSL_ENCODER_CTX_set_construct_data(OSSL_ENCODER_CTX *ctx, + void *construct_data) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->construct_data = construct_data; + return 1; +} + +int OSSL_ENCODER_CTX_set_cleanup(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_CLEANUP *cleanup) +{ + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx->cleanup = cleanup; + return 1; +} + +OSSL_ENCODER * +OSSL_ENCODER_INSTANCE_get_encoder(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->encoder; +} + +void * +OSSL_ENCODER_INSTANCE_get_encoder_ctx(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->encoderctx; +} + +const char * +OSSL_ENCODER_INSTANCE_get_input_type(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->input_type; +} + +const char * +OSSL_ENCODER_INSTANCE_get_output_type(OSSL_ENCODER_INSTANCE *encoder_inst) +{ + if (encoder_inst == NULL) + return NULL; + return encoder_inst->output_type; +} + +static int encoder_process(OSSL_ENCODER_CTX *ctx, BIO *out) +{ + size_t i, end; + void *latest_output = NULL; + size_t latest_output_length = 0; + const char *latest_output_type = NULL; + const char *last_input_type = NULL; + int ok = 0; + + end = OSSL_ENCODER_CTX_get_num_encoders(ctx); + for (i = 0; i < end; i++) { + OSSL_ENCODER_INSTANCE *encoder_inst = + sk_OSSL_ENCODER_INSTANCE_value(ctx->encoder_insts, i); + OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst); + const char *current_input_type = + OSSL_ENCODER_INSTANCE_get_input_type(encoder_inst); + const char *current_output_type = + OSSL_ENCODER_INSTANCE_get_output_type(encoder_inst); + BIO *current_out; + BIO *allocated_out = NULL; + const void *current_data = NULL; + OSSL_PARAM abstract[3]; + OSSL_PARAM *abstract_p; + const OSSL_PARAM *current_abstract = NULL; + + if (latest_output_type == NULL) { + /* + * This is the first iteration, so we prepare the object to be + * encoded + */ + + current_data = ctx->construct(encoder_inst, ctx->construct_data); + + /* Assume that the constructor recorded an error */ + if (current_data == NULL) + goto loop_end; + } else { + /* + * Check that the latest output type matches the currently + * considered encoder + */ + if (!OSSL_ENCODER_is_a(encoder, latest_output_type)) + continue; + + /* + * If there is a latest output type, there should be a latest output + */ + if (!ossl_assert(latest_output != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INTERNAL_ERROR); + goto loop_end; + } + + /* + * Create an object abstraction from the latest output, which was + * stolen from the previous round. + */ + abstract_p = abstract; + if (last_input_type != NULL) + *abstract_p++ = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + (char *)last_input_type, 0); + *abstract_p++ = + OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, + latest_output, + latest_output_length); + *abstract_p = OSSL_PARAM_construct_end(); + current_abstract = abstract; + } + + /* + * If the desired output type matches the output type of the currently + * considered encoder, we're setting up final output. Otherwise, set + * up an intermediary memory output. + */ + if (strcasecmp(ctx->output_type, current_output_type) == 0) + current_out = out; + else if ((current_out = allocated_out = BIO_new(BIO_s_mem())) == NULL) + goto loop_end; /* Assume BIO_new() recorded an error */ + + ok = encoder->encode(encoderctx, (OSSL_CORE_BIO *)current_out, + current_data, current_abstract, ctx->selection, + ossl_pw_passphrase_callback_enc, &ctx->pwdata); + + if (current_input_type != NULL) + last_input_type = current_input_type; + + if (!ok) + goto loop_end; + + OPENSSL_free(latest_output); + + /* + * Steal the output from the BIO_s_mem, if we did allocate one. + * That'll be the data for an object abstraction in the next round. + */ + if (allocated_out != NULL) { + BUF_MEM *buf; + + BIO_get_mem_ptr(allocated_out, &buf); + latest_output = buf->data; + latest_output_length = buf->length; + memset(buf, 0, sizeof(*buf)); + BIO_free(allocated_out); + } + + loop_end: + if (current_data != NULL) + ctx->cleanup(ctx->construct_data); + + if (ok) + break; + } + + OPENSSL_free(latest_output); + return ok; +} diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h new file mode 100644 index 0000000000..a57d0cd16c --- /dev/null +++ b/crypto/encode_decode/encoder_local.h @@ -0,0 +1,126 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/passphrase.h" +#include "internal/refcount.h" + +struct ossl_endecode_base_st { + OSSL_PROVIDER *prov; + int id; + const char *propdef; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; +}; + +struct ossl_encoder_st { + struct ossl_endecode_base_st base; + OSSL_FUNC_encoder_newctx_fn *newctx; + OSSL_FUNC_encoder_freectx_fn *freectx; + OSSL_FUNC_encoder_get_params_fn *get_params; + OSSL_FUNC_encoder_gettable_params_fn *gettable_params; + OSSL_FUNC_encoder_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_encoder_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_encoder_encode_fn *encode; + OSSL_FUNC_encoder_import_object_fn *import_object; + OSSL_FUNC_encoder_free_object_fn *free_object; +}; + +struct ossl_decoder_st { + struct ossl_endecode_base_st base; + OSSL_FUNC_decoder_newctx_fn *newctx; + OSSL_FUNC_decoder_freectx_fn *freectx; + OSSL_FUNC_decoder_get_params_fn *get_params; + OSSL_FUNC_decoder_gettable_params_fn *gettable_params; + OSSL_FUNC_decoder_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_decoder_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_decoder_decode_fn *decode; + OSSL_FUNC_decoder_export_object_fn *export_object; +}; + +struct ossl_encoder_instance_st { + OSSL_ENCODER *encoder; /* Never NULL */ + void *encoderctx; /* Never NULL */ + const char *input_type; /* May be NULL */ + const char *output_type; /* Never NULL */ +}; + +DEFINE_STACK_OF(OSSL_ENCODER_INSTANCE) + +void ossl_encoder_instance_free(OSSL_ENCODER_INSTANCE *encoder_inst); + +struct ossl_encoder_ctx_st { + /* + * The desired output type. The encoder implementation have a gettable + * "output-type" parameter that this will match against. + */ + const char *output_type; + /* + * Select what parts of an object will be encoded. This selection is + * bit encoded, and the bits correspond to selection bits available with + * the provider side operation. For example, when encoding an EVP_PKEY, + * the OSSL_KEYMGMT_SELECT_ macros are used for this. + */ + int selection; + + /* + * Decoders that are components of any current decoding path. + */ + STACK_OF(OSSL_ENCODER_INSTANCE) *encoder_insts; + + /* + * The constructor and destructor of an object to pass to the first + * encoder in a chain. + */ + OSSL_ENCODER_CONSTRUCT *construct; + OSSL_ENCODER_CLEANUP *cleanup; + void *construct_data; + + /* For any function that needs a passphrase reader */ + struct ossl_passphrase_data_st pwdata; +}; + +struct ossl_decoder_instance_st { + OSSL_DECODER *decoder; /* Never NULL */ + void *decoderctx; /* Never NULL */ + const char *input_type; /* Never NULL */ +}; + +DEFINE_STACK_OF(OSSL_DECODER_INSTANCE) + +struct ossl_decoder_ctx_st { + /* + * The caller may know the input type of the data they pass. If not, + * this will remain NULL and the decoding functionality will start + * with trying to decode with any desencoder in |decoder_insts|, + * regardless of their respective input type. + */ + const char *start_input_type; + + /* + * Decoders that are components of any current decoding path. + */ + STACK_OF(OSSL_DECODER_INSTANCE) *decoder_insts; + + /* + * The constructors of a decoding, and its caller argument. + */ + OSSL_DECODER_CONSTRUCT *construct; + OSSL_DECODER_CLEANUP *cleanup; + void *construct_data; + + /* For any function that needs a passphrase reader */ + struct ossl_passphrase_data_st pwdata; +}; diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c new file mode 100644 index 0000000000..bee54bf63a --- /dev/null +++ b/crypto/encode_decode/encoder_meth.c @@ -0,0 +1,541 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "crypto/encoder.h" +#include "encoder_local.h" + +/* + * Encoder can have multiple names, separated with colons in a name string + */ +#define NAME_SEPARATOR ':' + +/* Simple method structure constructor and destructor */ +static OSSL_ENCODER *ossl_encoder_new(void) +{ + OSSL_ENCODER *encoder = NULL; + + if ((encoder = OPENSSL_zalloc(sizeof(*encoder))) == NULL + || (encoder->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { + OSSL_ENCODER_free(encoder); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + + encoder->base.refcnt = 1; + + return encoder; +} + +int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder) +{ + int ref = 0; + + CRYPTO_UP_REF(&encoder->base.refcnt, &ref, encoder->base.lock); + return 1; +} + +void OSSL_ENCODER_free(OSSL_ENCODER *encoder) +{ + int ref = 0; + + if (encoder == NULL) + return; + + CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref, encoder->base.lock); + if (ref > 0) + return; + ossl_provider_free(encoder->base.prov); + CRYPTO_THREAD_lock_free(encoder->base.lock); + OPENSSL_free(encoder); +} + +/* Permanent encoder method store, constructor and destructor */ +static void encoder_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *encoder_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD encoder_store_method = { + encoder_store_new, + encoder_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct encoder_data_st { + OSSL_LIB_CTX *libctx; + OSSL_METHOD_CONSTRUCT_METHOD *mcm; + int id; /* For get_encoder_from_store() */ + const char *names; /* For get_encoder_from_store() */ + const char *propquery; /* For get_encoder_from_store() */ +}; + +/* + * Generic routines to fetch / create ENCODER methods with + * ossl_method_construct() + */ + +/* Temporary encoder method store, constructor and destructor */ +static void *alloc_tmp_encoder_store(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + +static void dealloc_tmp_encoder_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent encoder store */ +static OSSL_METHOD_STORE *get_encoder_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_ENCODER_STORE_INDEX, + &encoder_store_method); +} + +/* Get encoder methods from a store, or put one in */ +static void *get_encoder_from_store(OSSL_LIB_CTX *libctx, void *store, + void *data) +{ + struct encoder_data_st *methdata = data; + void *method = NULL; + int id; + + if ((id = methdata->id) == 0) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + id = ossl_namemap_name2num(namemap, methdata->names); + } + + if (store == NULL + && (store = get_encoder_store(libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) + return NULL; + return method; +} + +static int put_encoder_in_store(OSSL_LIB_CTX *libctx, void *store, + void *method, const OSSL_PROVIDER *prov, + int operation_id, const char *names, + const char *propdef, void *unused) +{ + OSSL_NAMEMAP *namemap; + int id; + + if ((namemap = ossl_namemap_stored(libctx)) == NULL + || (id = ossl_namemap_name2num(namemap, names)) == 0) + return 0; + + if (store == NULL && (store = get_encoder_store(libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + (int (*)(void *))OSSL_ENCODER_up_ref, + (void (*)(void *))OSSL_ENCODER_free); +} + +/* Create and populate a encoder method */ +static void *encoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_ENCODER *encoder = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + + if ((encoder = ossl_encoder_new()) == NULL) + return NULL; + encoder->base.id = id; + encoder->base.propdef = algodef->property_definition; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_ENCODER_NEWCTX: + if (encoder->newctx == NULL) + encoder->newctx = + OSSL_FUNC_encoder_newctx(fns); + break; + case OSSL_FUNC_ENCODER_FREECTX: + if (encoder->freectx == NULL) + encoder->freectx = + OSSL_FUNC_encoder_freectx(fns); + break; + case OSSL_FUNC_ENCODER_GET_PARAMS: + if (encoder->get_params == NULL) + encoder->get_params = + OSSL_FUNC_encoder_get_params(fns); + break; + case OSSL_FUNC_ENCODER_GETTABLE_PARAMS: + if (encoder->gettable_params == NULL) + encoder->gettable_params = + OSSL_FUNC_encoder_gettable_params(fns); + break; + case OSSL_FUNC_ENCODER_SET_CTX_PARAMS: + if (encoder->set_ctx_params == NULL) + encoder->set_ctx_params = + OSSL_FUNC_encoder_set_ctx_params(fns); + break; + case OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS: + if (encoder->settable_ctx_params == NULL) + encoder->settable_ctx_params = + OSSL_FUNC_encoder_settable_ctx_params(fns); + break; + case OSSL_FUNC_ENCODER_ENCODE: + if (encoder->encode == NULL) + encoder->encode = OSSL_FUNC_encoder_encode(fns); + break; + case OSSL_FUNC_ENCODER_IMPORT_OBJECT: + if (encoder->import_object == NULL) + encoder->import_object = + OSSL_FUNC_encoder_import_object(fns); + break; + case OSSL_FUNC_ENCODER_FREE_OBJECT: + if (encoder->free_object == NULL) + encoder->free_object = + OSSL_FUNC_encoder_free_object(fns); + break; + } + } + /* + * Try to check that the method is sensible. + * If you have a constructor, you must have a destructor and vice versa. + * You must have the encoding driver functions. + */ + if (!((encoder->newctx == NULL && encoder->freectx == NULL) + || (encoder->newctx != NULL && encoder->freectx != NULL) + || (encoder->import_object != NULL && encoder->free_object != NULL) + || (encoder->import_object == NULL && encoder->free_object == NULL)) + || encoder->encode == NULL + || encoder->gettable_params == NULL + || encoder->get_params == NULL) { + OSSL_ENCODER_free(encoder); + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS); + return NULL; + } + + if (prov != NULL && !ossl_provider_up_ref(prov)) { + OSSL_ENCODER_free(encoder); + return NULL; + } + + encoder->base.prov = prov; + return encoder; +} + + +/* + * The core fetching functionality passes the names of the implementation. + * This function is responsible to getting an identity number for them, + * then call encoder_from_dispatch() with that identity number. + */ +static void *construct_encoder(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *unused) +{ + /* + * This function is only called if get_encoder_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the name already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = encoder_from_dispatch(id, algodef, prov); + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_encoder(void *method, void *data) +{ + OSSL_ENCODER_free(method); +} + +static int up_ref_encoder(void *method) +{ + return OSSL_ENCODER_up_ref(method); +} + +static void free_encoder(void *method) +{ + OSSL_ENCODER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by name */ +static OSSL_ENCODER *inner_ossl_encoder_fetch(OSSL_LIB_CTX *libctx, + int id, const char *name, + const char *properties) +{ + OSSL_METHOD_STORE *store = get_encoder_store(libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + void *method = NULL; + + if (store == NULL || namemap == NULL) + return NULL; + + /* + * If we have been passed neither a name_id or a name, we have an + * internal programming error. + */ + if (!ossl_assert(id != 0 || name != NULL)) + return NULL; + + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + + if (id == 0 + || !ossl_method_store_cache_get(store, id, properties, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + alloc_tmp_encoder_store, + dealloc_tmp_encoder_store, + get_encoder_from_store, + put_encoder_in_store, + construct_encoder, + destruct_encoder + }; + struct encoder_data_st mcmdata; + + mcmdata.libctx = libctx; + mcmdata.mcm = &mcm; + mcmdata.id = id; + mcmdata.names = name; + mcmdata.propquery = properties; + if ((method = ossl_method_construct(libctx, OSSL_OP_ENCODER, + 0 /* !force_cache */, + &mcm, &mcmdata)) != NULL) { + /* + * If construction did create a method for us, we know that + * there is a correct name_id and meth_id, since those have + * already been calculated in get_encoder_from_store() and + * put_encoder_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, name); + ossl_method_store_cache_set(store, id, properties, method, + up_ref_encoder, free_encoder); + } + } + + return method; +} + +OSSL_ENCODER *OSSL_ENCODER_fetch(OSSL_LIB_CTX *libctx, const char *name, + const char *properties) +{ + return inner_ossl_encoder_fetch(libctx, 0, name, properties); +} + +OSSL_ENCODER *ossl_encoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id, + const char *properties) +{ + return inner_ossl_encoder_fetch(libctx, id, NULL, properties); +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.prov; +} + +const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.propdef; +} + +int OSSL_ENCODER_number(const OSSL_ENCODER *encoder) +{ + if (!ossl_assert(encoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return encoder->base.id; +} + +int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name) +{ + if (encoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(encoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == encoder->base.id; + } + return 0; +} + +struct encoder_do_all_data_st { + void (*user_fn)(void *method, void *arg); + void *user_arg; +}; + +static void encoder_do_one(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algodef, + int no_store, void *vdata) +{ + struct encoder_do_all_data_st *data = vdata; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *names = algodef->algorithm_names; + int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method = NULL; + + if (id != 0) + method = + encoder_from_dispatch(id, algodef, provider); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + OSSL_ENCODER_free(method); + } +} + +void OSSL_ENCODER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(OSSL_ENCODER *encoder, void *arg), + void *arg) +{ + struct encoder_do_all_data_st data; + + data.user_fn = (void (*)(void *, void *))fn; + data.user_arg = arg; + + /* + * No pre- or post-condition for this call, as this only creates methods + * temporarly and then promptly destroys them. + */ + ossl_algorithm_do_all(libctx, OSSL_OP_ENCODER, NULL, NULL, + encoder_do_one, NULL, &data); +} + +void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder, + void (*fn)(const char *name, void *data), + void *data) +{ + if (encoder == NULL) + return; + + if (encoder->base.prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(encoder->base.prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + ossl_namemap_doall_names(namemap, encoder->base.id, fn, data); + } +} + +const OSSL_PARAM * +OSSL_ENCODER_gettable_params(OSSL_ENCODER *encoder) +{ + if (encoder != NULL && encoder->gettable_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_ENCODER_provider(encoder)); + + return encoder->gettable_params(provctx); + } + return NULL; +} + +int OSSL_ENCODER_get_params(OSSL_ENCODER *encoder, OSSL_PARAM params[]) +{ + if (encoder != NULL && encoder->get_params != NULL) + return encoder->get_params(params); + return 0; +} + +const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder) +{ + if (encoder != NULL && encoder->settable_ctx_params != NULL) { + void *provctx = ossl_provider_ctx(OSSL_ENCODER_provider(encoder)); + + return encoder->settable_ctx_params(provctx); + } + return NULL; +} + +/* + * Encoder context support + */ + +OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(void) +{ + OSSL_ENCODER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + + return ctx; +} + +int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx, + const OSSL_PARAM params[]) +{ + size_t i; + size_t l; + + if (!ossl_assert(ctx != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx->encoder_insts == NULL) + return 1; + + l = OSSL_ENCODER_CTX_get_num_encoders(ctx); + for (i = 0; i < l; i++) { + OSSL_ENCODER_INSTANCE *encoder_inst = + sk_OSSL_ENCODER_INSTANCE_value(ctx->encoder_insts, i); + OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst); + + if (encoderctx == NULL || encoder->set_ctx_params == NULL) + continue; + if (!encoder->set_ctx_params(encoderctx, params)) + return 0; + } + return 1; +} + +void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx) +{ + if (ctx != NULL) { + sk_OSSL_ENCODER_INSTANCE_pop_free(ctx->encoder_insts, + ossl_encoder_instance_free); + OPENSSL_free(ctx->construct_data); + ossl_pw_clear_passphrase_data(&ctx->pwdata); + OPENSSL_free(ctx); + } +} diff --git a/crypto/encode_decode/encoder_pkey.c b/crypto/encode_decode/encoder_pkey.c new file mode 100644 index 0000000000..b6f4cf777a --- /dev/null +++ b/crypto/encode_decode/encoder_pkey.c @@ -0,0 +1,358 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" /* strcasecmp on Windows */ +#include +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/property.h" +#include "crypto/evp.h" +#include "encoder_local.h" + +DEFINE_STACK_OF(OSSL_ENCODER) + +int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx, + const char *cipher_name, + const char *propquery) +{ + OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_CIPHER, + (void *)cipher_name, 0); + params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, + (void *)propquery, 0); + + return OSSL_ENCODER_CTX_set_params(ctx, params); +} + +int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx, + const unsigned char *kstr, + size_t klen) +{ + return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); +} + +int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data) +{ + return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); +} + +int OSSL_ENCODER_CTX_set_pem_password_cb(OSSL_ENCODER_CTX *ctx, + pem_password_cb *cb, void *cbarg) +{ + return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); +} + +int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg) +{ + return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); +} + +/* + * Support for OSSL_ENCODER_CTX_new_by_TYPE: + * finding a suitable encoder + */ + +struct collected_encoder_st { + const char *output_type; + STACK_OF(OSSL_ENCODER) *encoders; + int error_occured; +}; + +static void collect_encoder(OSSL_ENCODER *encoder, void *arg) +{ + struct collected_encoder_st *data = arg; + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + const char *output_type = NULL; + + if (data->error_occured) + return; + + /* + * Ask for the output type. If the encoder doesn't answer to that, + * we refuse it. + */ + params[0] = + OSSL_PARAM_construct_utf8_ptr(OSSL_ENCODER_PARAM_OUTPUT_TYPE, + (char **)&output_type, 0); + if (!encoder->get_params(params) + || !OSSL_PARAM_modified(¶ms[0]) + || output_type == NULL + || strcasecmp(output_type, data->output_type) != 0) + return; + + data->error_occured = 1; /* Assume the worst */ + + if (!OSSL_ENCODER_up_ref(encoder) /* ref++ */) + return; + if (sk_OSSL_ENCODER_push(data->encoders, encoder) <= 0) { + OSSL_ENCODER_free(encoder); /* ref-- */ + return; + } + + data->error_occured = 0; /* All is good now */ +} + +struct collected_names_st { + STACK_OF(OPENSSL_CSTRING) *names; + unsigned int error_occured:1; +}; + +static void collect_name(const char *name, void *arg) +{ + struct collected_names_st *data = arg; + + if (data->error_occured) + return; + + data->error_occured = 1; /* Assume the worst */ + + if (sk_OPENSSL_CSTRING_push(data->names, name) <= 0) + return; + + data->error_occured = 0; /* All is good now */ +} + +/* + * Support for OSSL_ENCODER_to_bio: + * writing callback for the OSSL_PARAM (the implementation doesn't have + * intimate knowledge of the provider side object) + */ + +struct construct_data_st { + const EVP_PKEY *pk; + int selection; + + OSSL_ENCODER_INSTANCE *encoder_inst; + const void *obj; + void *constructed_obj; +}; + +static int encoder_import_cb(const OSSL_PARAM params[], void *arg) +{ + struct construct_data_st *construct_data = arg; + OSSL_ENCODER_INSTANCE *encoder_inst = construct_data->encoder_inst; + OSSL_ENCODER *encoder = OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + void *encoderctx = OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst); + + construct_data->constructed_obj = + encoder->import_object(encoderctx, construct_data->selection, params); + + return (construct_data->constructed_obj != NULL); +} + +static const void * +encoder_construct_EVP_PKEY(OSSL_ENCODER_INSTANCE *encoder_inst, void *arg) +{ + struct construct_data_st *data = arg; + + if (data->obj == NULL) { + OSSL_ENCODER *encoder = + OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst); + const EVP_PKEY *pk = data->pk; + const OSSL_PROVIDER *k_prov = EVP_KEYMGMT_provider(pk->keymgmt); + const OSSL_PROVIDER *e_prov = OSSL_ENCODER_provider(encoder); + + if (k_prov != e_prov) { + data->encoder_inst = encoder_inst; + + if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, data->selection, + &encoder_import_cb, data)) + return NULL; + data->obj = data->constructed_obj; + } else { + data->obj = pk->keydata; + } + } + + return data->obj; +} + +static void encoder_destruct_EVP_PKEY(void *arg) +{ + struct construct_data_st *data = arg; + + if (data->encoder_inst != NULL) { + OSSL_ENCODER *encoder = + OSSL_ENCODER_INSTANCE_get_encoder(data->encoder_inst); + + encoder->free_object(data->constructed_obj); + } + data->constructed_obj = NULL; +} + +/* + * OSSL_ENCODER_CTX_new_by_EVP_PKEY() returns a ctx with no encoder if + * it couldn't find a suitable encoder. This allows a caller to detect if + * a suitable encoder was found, with OSSL_ENCODER_CTX_get_num_encoder(), + * and to use fallback methods if the result is NULL. + */ +static int ossl_encoder_ctx_setup_for_EVP_PKEY(OSSL_ENCODER_CTX *ctx, + const EVP_PKEY *pkey, + int selection, + OSSL_LIB_CTX *libctx, + const char *propquery) +{ + struct construct_data_st *data = NULL; + int ok = 0; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(pkey != NULL)) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (pkey->keymgmt != NULL) { + OSSL_ENCODER *found = NULL; + const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(pkey->keymgmt); + struct collected_encoder_st encoder_data; + struct collected_names_st keymgmt_data; + int i; + + if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Select the encoder in two steps. First, collect all encoders + * that have the correct output type, as well as all keymgmt names. + */ + encoder_data.output_type = ctx->output_type; + encoder_data.encoders = sk_OSSL_ENCODER_new_null(); + encoder_data.error_occured = 0; + keymgmt_data.names = sk_OPENSSL_CSTRING_new_null(); + keymgmt_data.error_occured = 0; + if (encoder_data.encoders == NULL || keymgmt_data.names == NULL) { + sk_OSSL_ENCODER_free(encoder_data.encoders); + sk_OPENSSL_CSTRING_free(keymgmt_data.names); + return 0; + } + OSSL_ENCODER_do_all_provided(libctx, collect_encoder, &encoder_data); + EVP_KEYMGMT_names_do_all(pkey->keymgmt, collect_name, &keymgmt_data); + + /*- + * Now we look for the most desirable encoder for our |pkey|. + * + * Encoders offer two functions: + * + * - one ('encode') that encodes a given provider-native object that + * it knows intimately, so it must be from the same provider. + * - one ('import_object') that imports the parameters of an object + * of the same type from a different provider, which is used to + * create a temporary object that 'encode' can handle. + * + * It is, of course, more desirable to be able to use 'encode' + * directly without having to go through an export/import maneuver, + * but the latter allows us to have generic encoders. + * + * Of course, if |libctx| is different from |pkey|'s library context, + * we're going to have to do an export/import maneuvre no matter what. + */ + for (i = 0; i < sk_OSSL_ENCODER_num(encoder_data.encoders); i++) { + OSSL_ENCODER *encoder = + sk_OSSL_ENCODER_value(encoder_data.encoders, i); + int j; + + /* Check that any of the |keymgmt| names match */ + for (j = 0; j < sk_OPENSSL_CSTRING_num(keymgmt_data.names); j++) { + const char *name = + sk_OPENSSL_CSTRING_value(keymgmt_data.names, j); + + if (OSSL_ENCODER_is_a(encoder, name)) + break; + } + + if (j == sk_OPENSSL_CSTRING_num(keymgmt_data.names)) + continue; + + /* We found one! Process it */ + if (OSSL_ENCODER_provider(encoder) == desired_prov) { + /* + * We found one in the same provider as the keymgmt. Choose + * it and stop looking. + */ + found = encoder; + break; + } + if (found == NULL && encoder->import_object != NULL) { + /* + * We found one that's good enough. Choose it for now, but + * keep looking. + */ + found = encoder; + } + } + + if (found != NULL) { + (void)OSSL_ENCODER_CTX_add_encoder(ctx, found); + } else { + if (encoder_data.error_occured) + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + else + ERR_raise(ERR_LIB_OSSL_ENCODER, + OSSL_ENCODER_R_ENCODER_NOT_FOUND); + } + + sk_OPENSSL_CSTRING_free(keymgmt_data.names); + sk_OSSL_ENCODER_pop_free(encoder_data.encoders, OSSL_ENCODER_free); + } + + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) { + if (!OSSL_ENCODER_CTX_set_construct(ctx, encoder_construct_EVP_PKEY) + || !OSSL_ENCODER_CTX_set_construct_data(ctx, data) + || !OSSL_ENCODER_CTX_set_cleanup(ctx, encoder_destruct_EVP_PKEY)) + goto err; + + data->pk = pkey; + data->selection = selection; + + data = NULL; /* Avoid it being freed */ + } + + ok = 1; + err: + if (data != NULL) { + OSSL_ENCODER_CTX_set_construct_data(ctx, NULL); + OPENSSL_free(data); + } + return ok; +} + +OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, + const char *output_type, + int selection, + OSSL_LIB_CTX *libctx, + const char *propquery) +{ + OSSL_ENCODER_CTX *ctx = NULL; + + if ((ctx = OSSL_ENCODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (OSSL_ENCODER_CTX_set_output_type(ctx, output_type) + && OSSL_ENCODER_CTX_set_selection(ctx, selection) + && ossl_encoder_ctx_setup_for_EVP_PKEY(ctx, pkey, selection, + libctx, propquery) + && OSSL_ENCODER_CTX_add_extra(ctx, libctx, propquery)) + return ctx; + + OSSL_ENCODER_CTX_free(ctx); + return NULL; +} diff --git a/crypto/engine/eng_cnf.c b/crypto/engine/eng_cnf.c index dcc30b6c62..0fb576c847 100644 --- a/crypto/engine/eng_cnf.c +++ b/crypto/engine/eng_cnf.c @@ -14,8 +14,6 @@ #include #include -DEFINE_STACK_OF(CONF_VALUE) - /* ENGINE config module */ static const char *skip_dot(const char *name) diff --git a/crypto/engine/eng_dyn.c b/crypto/engine/eng_dyn.c index 73d7b14ae6..01935578c2 100644 --- a/crypto/engine/eng_dyn.c +++ b/crypto/engine/eng_dyn.c @@ -20,8 +20,6 @@ * prototypes. */ -DEFINE_STACK_OF_STRING() - /* Our ENGINE handlers */ static int dynamic_init(ENGINE *e); static int dynamic_finish(ENGINE *e); diff --git a/crypto/err/err.c b/crypto/err/err.c index e2d70d7a58..2c8240f0ba 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -75,8 +75,8 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"}, {ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"}, {ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"}, - {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"}, - {ERR_PACK(ERR_LIB_OSSL_DESERIALIZER, 0, 0), "DESERIALIZER routines"}, + {ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, 0), "ENCODER routines"}, + {ERR_PACK(ERR_LIB_OSSL_DECODER, 0, 0), "DECODER routines"}, {ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"}, {0, NULL}, }; @@ -225,7 +225,7 @@ static void err_patch(int lib, ERR_STRING_DATA *str) } /* - * Hash in |str| error strings. Assumes the URN_ONCE was done. + * Hash in |str| error strings. Assumes the RUN_ONCE was done. */ static int err_load_strings(const ERR_STRING_DATA *str) { diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index f1bed12795..589ff1094c 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -40,16 +40,16 @@ L OSSL_STORE include/openssl/store.h crypto/store/store_err.c L ESS include/openssl/ess.h crypto/ess/ess_err.c L PROP include/internal/property.h crypto/property/property_err.c L PROV providers/common/include/prov/providercommon.h providers/common/provider_err.c -L OSSL_SERIALIZER include/openssl/serializer.h crypto/serializer/serializer_err.c -L OSSL_DESERIALIZER include/openssl/deserializer.h crypto/serializer/deserializer_err.c +L OSSL_ENCODER include/openssl/encoder.h crypto/encode_decode/encoder_err.c +L OSSL_DECODER include/openssl/decoder.h crypto/encode_decode/decoder_err.c L HTTP include/openssl/http.h crypto/http/http_err.c # additional header files to be scanned for function names L NONE include/openssl/x509_vfy.h NONE -L NONE crypto/ec/ec_local.h NONE -L NONE crypto/cms/cms_local.h NONE -L NONE crypto/ct/ct_local.h NONE -L NONE ssl/ssl_local.h NONE +L NONE crypto/ec/ec_local.h NONE +L NONE crypto/cms/cms_local.h NONE +L NONE crypto/ct/ct_local.h NONE +L NONE ssl/ssl_local.h NONE # SSL/TLS alerts R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 53becb8ed4..7bb83593a6 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -40,7 +40,6 @@ ASN1_F_ASN1_ITEM_FLAGS_I2D:118:asn1_item_flags_i2d ASN1_F_ASN1_ITEM_I2D_BIO:192:ASN1_item_i2d_bio ASN1_F_ASN1_ITEM_I2D_FP:193:ASN1_item_i2d_fp ASN1_F_ASN1_ITEM_PACK:198:ASN1_item_pack -ASN1_F_ASN1_ITEM_SIGN:195:ASN1_item_sign ASN1_F_ASN1_ITEM_SIGN_CTX:220:ASN1_item_sign_ctx ASN1_F_ASN1_ITEM_UNPACK:199:ASN1_item_unpack ASN1_F_ASN1_ITEM_VERIFY:197:ASN1_item_verify @@ -64,6 +63,7 @@ ASN1_F_ASN1_TEMPLATE_NOEXP_D2I:131:asn1_template_noexp_d2i ASN1_F_ASN1_TIME_ADJ:217:ASN1_TIME_adj ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING:134:ASN1_TYPE_get_int_octetstring ASN1_F_ASN1_TYPE_GET_OCTETSTRING:135:ASN1_TYPE_get_octetstring +ASN1_F_ASN1_TYPE_GET_OCTETSTRING_INT:146: ASN1_F_ASN1_UTCTIME_ADJ:218:ASN1_UTCTIME_adj ASN1_F_ASN1_VERIFY:137:ASN1_verify ASN1_F_B64_READ_ASN1:209:b64_read_asn1 @@ -1058,6 +1058,7 @@ PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF:112:PKCS12_SAFEBAG_create0_p8inf PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8:113:PKCS12_SAFEBAG_create0_pkcs8 PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT:133:\ PKCS12_SAFEBAG_create_pkcs8_encrypt +PKCS12_F_PKCS12_SAFEBAG_CREATE_SECRET:134: PKCS12_F_PKCS12_SETUP_MAC:122:PKCS12_setup_mac PKCS12_F_PKCS12_SET_MAC:123:PKCS12_set_mac PKCS12_F_PKCS12_UNPACK_AUTHSAFES:130:PKCS12_unpack_authsafes @@ -1135,17 +1136,10 @@ RAND_F_GET_ENTROPY:106:get_entropy RAND_F_RAND_BYTES:100:RAND_bytes RAND_F_RAND_BYTES_EX:126:rand_bytes_ex RAND_F_RAND_DRBG_ENABLE_LOCKING:119:rand_drbg_enable_locking -RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate RAND_F_RAND_DRBG_GET_ENTROPY:120:rand_drbg_get_entropy RAND_F_RAND_DRBG_GET_NONCE:123:rand_drbg_get_nonce RAND_F_RAND_DRBG_INIT_METHOD:130: -RAND_F_RAND_DRBG_INSTANTIATE:108:RAND_DRBG_instantiate -RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new -RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed RAND_F_RAND_DRBG_RESTART:102:rand_drbg_restart -RAND_F_RAND_DRBG_SET:104:RAND_DRBG_set -RAND_F_RAND_DRBG_SET_DEFAULTS:121:RAND_DRBG_set_defaults -RAND_F_RAND_DRBG_UNINSTANTIATE:118:RAND_DRBG_uninstantiate RAND_F_RAND_LOAD_FILE:111:RAND_load_file RAND_F_RAND_POOL_ACQUIRE_ENTROPY:122:rand_pool_acquire_entropy RAND_F_RAND_POOL_ADD:103:rand_pool_add @@ -1174,7 +1168,6 @@ RSA_F_RSA_CHECK_KEY:123:RSA_check_key RSA_F_RSA_CHECK_KEY_EX:160:RSA_check_key_ex RSA_F_RSA_CMS_DECRYPT:159:rsa_cms_decrypt RSA_F_RSA_CMS_VERIFY:158:rsa_cms_verify -RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES:168:rsa_fips186_4_gen_prob_primes RSA_F_RSA_ITEM_VERIFY:148:rsa_item_verify RSA_F_RSA_METH_DUP:161:RSA_meth_dup RSA_F_RSA_METH_NEW:162:RSA_meth_new @@ -1218,10 +1211,6 @@ RSA_F_RSA_PUB_DECODE:139:rsa_pub_decode RSA_F_RSA_SETUP_BLINDING:136:RSA_setup_blinding RSA_F_RSA_SIGN:117:RSA_sign RSA_F_RSA_SIGN_ASN1_OCTET_STRING:118:RSA_sign_ASN1_OCTET_STRING -RSA_F_RSA_SP800_56B_CHECK_KEYPAIR:169:rsa_sp800_56b_check_keypair -RSA_F_RSA_SP800_56B_CHECK_PUBLIC:170:rsa_sp800_56b_check_public -RSA_F_RSA_SP800_56B_PAIRWISE_TEST:171:rsa_sp800_56b_pairwise_test -RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH:172:rsa_sp800_56b_validate_strength RSA_F_RSA_VERIFY:119:RSA_verify RSA_F_RSA_VERIFY_ASN1_OCTET_STRING:120:RSA_verify_ASN1_OCTET_STRING RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1:126:RSA_verify_PKCS1_PSS_mgf1 @@ -1237,6 +1226,8 @@ SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest SM2_F_SM2_DECRYPT:102:sm2_decrypt SM2_F_SM2_ENCRYPT:103:sm2_encrypt +SM2_F_SM2_INTERNAL_SIGN:116: +SM2_F_SM2_INTERNAL_VERIFY:117: SM2_F_SM2_PLAINTEXT_SIZE:104:sm2_plaintext_size SM2_F_SM2_SIGN:105:sm2_sign SM2_F_SM2_SIG_GEN:106:sm2_sig_gen @@ -1410,11 +1401,13 @@ SSL_F_SSL_CTX_USE_SERVERINFO_EX:543:SSL_CTX_use_serverinfo_ex SSL_F_SSL_CTX_USE_SERVERINFO_FILE:337:SSL_CTX_use_serverinfo_file SSL_F_SSL_DANE_DUP:403:ssl_dane_dup SSL_F_SSL_DANE_ENABLE:395:SSL_dane_enable +SSL_F_SSL_DECAPSULATE:643: SSL_F_SSL_DERIVE:590:ssl_derive SSL_F_SSL_DO_CONFIG:391:ssl_do_config SSL_F_SSL_DO_HANDSHAKE:180:SSL_do_handshake SSL_F_SSL_DUP_CA_LIST:408:SSL_dup_CA_list SSL_F_SSL_ENABLE_CT:402:SSL_enable_ct +SSL_F_SSL_ENCAPSULATE:644: SSL_F_SSL_GENERATE_PKEY_GROUP:559:ssl_generate_pkey_group SSL_F_SSL_GENERATE_SESSION_ID:547:ssl_generate_session_id SSL_F_SSL_GET_NEW_SESSION:181:ssl_get_new_session @@ -2003,6 +1996,7 @@ ASN1_R_TYPE_NOT_CONSTRUCTED:156:type not constructed ASN1_R_TYPE_NOT_PRIMITIVE:195:type not primitive ASN1_R_UNEXPECTED_EOC:159:unexpected eoc ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH:215:universalstring is wrong length +ASN1_R_UNKNOWN_DIGEST:229:unknown digest ASN1_R_UNKNOWN_FORMAT:160:unknown format ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:161:unknown message digest algorithm ASN1_R_UNKNOWN_OBJECT_TYPE:162:unknown object type @@ -2093,7 +2087,6 @@ CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match CMP_R_CHECKAFTER_OUT_OF_RANGE:181:checkafter out of range -CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE:166:checking pbm no secret available CMP_R_ENCOUNTERED_KEYUPDATEWARNING:176:encountered keyupdatewarning CMP_R_ENCOUNTERED_WAITING:162:encountered waiting CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection @@ -2115,6 +2108,7 @@ CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature +CMP_R_FAILED_BUILDING_OWN_CHAIN:164:failed building own chain CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range @@ -2124,6 +2118,7 @@ CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION:130:\ missing key input for creating protection CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE:142:missing key usage digitalsignature CMP_R_MISSING_P10CSR:121:missing p10csr +CMP_R_MISSING_PBM_SECRET:166:missing pbm secret CMP_R_MISSING_PRIVATE_KEY:131:missing private key CMP_R_MISSING_PROTECTION:143:missing protection CMP_R_MISSING_REFERENCE_CERT:168:missing reference cert @@ -2171,6 +2166,8 @@ CMS_R_ATTRIBUTE_ERROR:161:attribute error CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present CMS_R_CERTIFICATE_HAS_NO_KEYID:160:certificate has no keyid CMS_R_CERTIFICATE_VERIFY_ERROR:100:certificate verify error +CMS_R_CIPHER_AEAD_SET_TAG_ERROR:184:cipher aead set tag error +CMS_R_CIPHER_GET_TAG:185:cipher get tag CMS_R_CIPHER_INITIALISATION_ERROR:101:cipher initialisation error CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR:102:\ cipher parameter initialisation error @@ -2185,6 +2182,7 @@ CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA:108:content type not signed data CMS_R_CONTENT_VERIFY_ERROR:109:content verify error CMS_R_CTRL_ERROR:110:ctrl error CMS_R_CTRL_FAILURE:111:ctrl failure +CMS_R_DECODE_ERROR:187:decode error CMS_R_DECRYPT_ERROR:112:decrypt error CMS_R_ERROR_GETTING_PUBLIC_KEY:113:error getting public key CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\ @@ -2196,6 +2194,9 @@ CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter CMS_R_INVALID_KEY_LENGTH:118:invalid key length +CMS_R_INVALID_LABEL:190:invalid label +CMS_R_INVALID_OAEP_PARAMETERS:191:invalid oaep parameters +CMS_R_KDF_PARAMETER_ERROR:186:kdf parameter error CMS_R_MD_BIO_INIT_ERROR:119:md bio init error CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH:120:\ messagedigest attribute wrong length @@ -2227,10 +2228,12 @@ CMS_R_NO_PRIVATE_KEY:133:no private key CMS_R_NO_PUBLIC_KEY:134:no public key CMS_R_NO_RECEIPT_REQUEST:168:no receipt request CMS_R_NO_SIGNERS:135:no signers +CMS_R_PEER_KEY_ERROR:188:peer key error CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE:136:\ private key does not match certificate CMS_R_RECEIPT_DECODE_ERROR:169:receipt decode error CMS_R_RECIPIENT_ERROR:137:recipient error +CMS_R_SHARED_INFO_ERROR:189:shared info error CMS_R_SIGNER_CERTIFICATE_NOT_FOUND:138:signer certificate not found CMS_R_SIGNFINAL_ERROR:139:signfinal error CMS_R_SMIME_TEXT_ERROR:140:smime text error @@ -2246,9 +2249,11 @@ CMS_R_UNKNOWN_DIGEST_ALGORITHM:149:unknown digest algorithm CMS_R_UNKNOWN_ID:150:unknown id CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM:151:unsupported compression algorithm CMS_R_UNSUPPORTED_CONTENT_TYPE:152:unsupported content type +CMS_R_UNSUPPORTED_ENCRYPTION_TYPE:192:unsupported encryption type CMS_R_UNSUPPORTED_KEK_ALGORITHM:153:unsupported kek algorithm CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM:179:\ unsupported key encryption algorithm +CMS_R_UNSUPPORTED_LABEL_SOURCE:193:unsupported label source CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE:155:unsupported recipientinfo type CMS_R_UNSUPPORTED_RECIPIENT_TYPE:154:unsupported recipient type CMS_R_UNSUPPORTED_TYPE:156:unsupported type @@ -2275,6 +2280,8 @@ CONF_R_NO_SECTION:107:no section CONF_R_NO_SUCH_FILE:114:no such file CONF_R_NO_VALUE:108:no value CONF_R_NUMBER_TOO_LARGE:121:number too large +CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION:124:\ + openssl conf references missing section CONF_R_RECURSIVE_DIRECTORY_INCLUDE:111:recursive directory include CONF_R_SSL_COMMAND_SECTION_EMPTY:117:ssl command section empty CONF_R_SSL_COMMAND_SECTION_NOT_FOUND:118:ssl command section not found @@ -2294,6 +2301,7 @@ CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100 CRMF_R_MALFORMED_IV:101:malformed iv CRMF_R_NULL_ARGUMENT:109:null argument +CRMF_R_POPOSKINPUT_NOT_SUPPORTED:113:poposkinput not supported CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key CRMF_R_POPO_MISSING:121:popo missing CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key @@ -2302,7 +2310,6 @@ CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm -CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY:113:unsupported alg for popsigningkey CRMF_R_UNSUPPORTED_CIPHER:114:unsupported cipher CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\ unsupported method for creating popo @@ -2319,11 +2326,13 @@ CRYPTO_R_INVALID_OSSL_PARAM_TYPE:110:invalid ossl param type CRYPTO_R_ODD_NUMBER_OF_DIGITS:103:odd number of digits CRYPTO_R_PROVIDER_ALREADY_EXISTS:104:provider already exists CRYPTO_R_PROVIDER_SECTION_ERROR:105:provider section error +CRYPTO_R_RANDOM_SECTION_ERROR:119:random section error CRYPTO_R_SECURE_MALLOC_FAILURE:111:secure malloc failure CRYPTO_R_STRING_TOO_LONG:112:string too long CRYPTO_R_TOO_MANY_BYTES:113:too many bytes CRYPTO_R_TOO_MANY_RECORDS:114:too many records CRYPTO_R_TOO_SMALL_BUFFER:116:too small buffer +CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION:120:unknown name in random section CRYPTO_R_ZERO_LENGTH_NUMBER:115:zero length number CT_R_BASE64_DECODE_ERROR:108:base64 decode error CT_R_INVALID_LOG_ID_LENGTH:100:invalid log id length @@ -2409,7 +2418,6 @@ EC_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range EC_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA:170:curve does not support ecdsa EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing -EC_R_D2I_ECPKPARAMETERS_FAILURE:117:d2i ecpkparameters failure EC_R_DECODE_ERROR:142:decode error EC_R_DISCRIMINANT_IS_ZERO:118:discriminant is zero EC_R_EC_GROUP_NEW_BY_NAME_FAILURE:119:ec group new by name failure @@ -2419,7 +2427,10 @@ EC_R_GF2M_NOT_SUPPORTED:147:gf2m not supported EC_R_GROUP2PKPARAMETERS_FAILURE:120:group2pkparameters failure EC_R_I2D_ECPKPARAMETERS_FAILURE:121:i2d ecpkparameters failure EC_R_INCOMPATIBLE_OBJECTS:101:incompatible objects +EC_R_INVALID_A:168:invalid a EC_R_INVALID_ARGUMENT:112:invalid argument +EC_R_INVALID_B:169:invalid b +EC_R_INVALID_COFACTOR:171:invalid cofactor EC_R_INVALID_COMPRESSED_POINT:110:invalid compressed point EC_R_INVALID_COMPRESSION_BIT:109:invalid compression bit EC_R_INVALID_CURVE:141:invalid curve @@ -2428,12 +2439,16 @@ EC_R_INVALID_DIGEST_TYPE:138:invalid digest type EC_R_INVALID_ENCODING:102:invalid encoding EC_R_INVALID_FIELD:103:invalid field EC_R_INVALID_FORM:104:invalid form +EC_R_INVALID_GENERATOR:173:invalid generator EC_R_INVALID_GROUP_ORDER:122:invalid group order EC_R_INVALID_KEY:116:invalid key +EC_R_INVALID_NAMED_GROUP_CONVERSION:174:invalid named group conversion EC_R_INVALID_OUTPUT_LENGTH:161:invalid output length +EC_R_INVALID_P:172:invalid p EC_R_INVALID_PEER_KEY:133:invalid peer key EC_R_INVALID_PENTANOMIAL_BASIS:132:invalid pentanomial basis EC_R_INVALID_PRIVATE_KEY:123:invalid private key +EC_R_INVALID_SEED:175:invalid seed EC_R_INVALID_TRINOMIAL_BASIS:137:invalid trinomial basis EC_R_KDF_PARAMETER_ERROR:148:kdf parameter error EC_R_KEYS_NOT_SET:140:keys not set @@ -2452,7 +2467,6 @@ EC_R_NO_PRIVATE_VALUE:154:no private value EC_R_OPERATION_NOT_SUPPORTED:152:operation not supported EC_R_PASSED_NULL_PARAMETER:134:passed null parameter EC_R_PEER_KEY_ERROR:149:peer key error -EC_R_PKPARAMETERS2GROUP_FAILURE:127:pkparameters2group failure EC_R_POINT_ARITHMETIC_FAILURE:155:point arithmetic failure EC_R_POINT_AT_INFINITY:106:point at infinity EC_R_POINT_COORDINATES_BLIND_FAILURE:163:point coordinates blind failure @@ -2553,11 +2567,14 @@ EVP_R_INVALID_FIPS_MODE:168:invalid fips mode EVP_R_INVALID_IV_LENGTH:194:invalid iv length EVP_R_INVALID_KEY:163:invalid key EVP_R_INVALID_KEY_LENGTH:130:invalid key length +EVP_R_INVALID_LENGTH:221:invalid length EVP_R_INVALID_NULL_ALGORITHM:218:invalid null algorithm EVP_R_INVALID_OPERATION:148:invalid operation EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions EVP_R_INVALID_SALT_LENGTH:186:invalid salt length -EVP_R_KEYGEN_FAILURE:120:keygen failure +EVP_R_INVALID_SECRET_LENGTH:223:invalid secret length +EVP_R_INVALID_SEED_LENGTH:220:invalid seed length +EVP_R_INVALID_VALUE:222:invalid value EVP_R_KEYMGMT_EXPORT_FAILURE:205:keymgmt export failure EVP_R_KEY_SETUP_FAILED:180:key setup failed EVP_R_LOCKING_NOT_SUPPORTED:213:locking not supported @@ -2623,6 +2640,9 @@ HTTP_R_ERROR_PARSING_URL:101:error parsing url HTTP_R_ERROR_RECEIVING:103:error receiving HTTP_R_ERROR_SENDING:102:error sending HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length +HTTP_R_INVALID_PORT_NUMBER:123:invalid port number +HTTP_R_INVALID_URL_PATH:125:invalid url path +HTTP_R_INVALID_URL_PREFIX:124:invalid url prefix HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding HTTP_R_MISSING_CONTENT_TYPE:121:missing content type @@ -2671,6 +2691,8 @@ OBJ_R_UNKNOWN_NID:101:unknown nid OBJ_R_UNKNOWN_OBJECT_NAME:103:unknown object name OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error OCSP_R_DIGEST_ERR:102:digest err +OCSP_R_DIGEST_NAME_ERR:106:digest name err +OCSP_R_DIGEST_SIZE_ERR:107:digest size err OCSP_R_ERROR_IN_NEXTUPDATE_FIELD:122:error in nextupdate field OCSP_R_ERROR_IN_THISUPDATE_FIELD:123:error in thisupdate field OCSP_R_MISSING_OCSPSIGNING_USAGE:103:missing ocspsigning usage @@ -2694,9 +2716,10 @@ OCSP_R_STATUS_TOO_OLD:127:status too old OCSP_R_UNKNOWN_MESSAGE_DIGEST:119:unknown message digest OCSP_R_UNKNOWN_NID:120:unknown nid OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type -OSSL_DESERIALIZER_R_MISSING_GET_PARAMS:100:missing get params -OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query -OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND:101:serializer not found +OSSL_DECODER_R_MISSING_GET_PARAMS:100:missing get params +OSSL_ENCODER_R_ENCODER_NOT_FOUND:101:encoder not found +OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY:100:incorrect property query +OSSL_ENCODER_R_MISSING_GET_PARAMS:102:missing get params OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac @@ -2708,8 +2731,9 @@ OSSL_STORE_R_LOADER_INCOMPLETE:116:loader incomplete OSSL_STORE_R_LOADING_STARTED:117:loading started OSSL_STORE_R_NOT_A_CERTIFICATE:100:not a certificate OSSL_STORE_R_NOT_A_CRL:101:not a crl -OSSL_STORE_R_NOT_A_KEY:102:not a key OSSL_STORE_R_NOT_A_NAME:103:not a name +OSSL_STORE_R_NOT_A_PRIVATE_KEY:102:not a private key +OSSL_STORE_R_NOT_A_PUBLIC_KEY:122:not a public key OSSL_STORE_R_NOT_PARAMETERS:104:not parameters OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR:114:passphrase callback error OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE:108:path must be absolute @@ -2752,6 +2776,7 @@ PEM_R_UNEXPECTED_DEK_IV:130:unexpected dek iv PEM_R_UNSUPPORTED_CIPHER:113:unsupported cipher PEM_R_UNSUPPORTED_ENCRYPTION:114:unsupported encryption PEM_R_UNSUPPORTED_KEY_COMPONENTS:126:unsupported key components +PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE:110:unsupported public key type PKCS12_R_CANT_PACK_STRUCTURE:100:cant pack structure PKCS12_R_CONTENT_TYPE_NOT_DATA:121:content type not data PKCS12_R_DECODE_ERROR:101:decode error @@ -2760,6 +2785,7 @@ PKCS12_R_ENCRYPT_ERROR:103:encrypt error PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE:120:error setting encrypted data type PKCS12_R_INVALID_NULL_ARGUMENT:104:invalid null argument PKCS12_R_INVALID_NULL_PKCS12_POINTER:105:invalid null pkcs12 pointer +PKCS12_R_INVALID_TYPE:112:invalid type PKCS12_R_IV_GEN_ERROR:106:iv gen error PKCS12_R_KEY_GEN_ERROR:107:key gen error PKCS12_R_MAC_ABSENT:108:mac absent @@ -2768,9 +2794,7 @@ PKCS12_R_MAC_SETUP_ERROR:110:mac setup error PKCS12_R_MAC_STRING_SET_ERROR:111:mac string set error PKCS12_R_MAC_VERIFY_FAILURE:113:mac verify failure PKCS12_R_PARSE_ERROR:114:parse error -PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR:115:pkcs12 algor cipherinit error PKCS12_R_PKCS12_CIPHERFINAL_ERROR:116:pkcs12 cipherfinal error -PKCS12_R_PKCS12_PBE_CRYPT_ERROR:117:pkcs12 pbe crypt error PKCS12_R_UNKNOWN_DIGEST_ALGORITHM:118:unknown digest algorithm PKCS12_R_UNSUPPORTED_PKCS12_MODE:119:unsupported pkcs12 mode PKCS7_R_CERTIFICATE_VERIFY_ERROR:117:certificate verify error @@ -2852,6 +2876,9 @@ PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter PROV_R_FAILED_TO_SIGN:175:failed to sign +PROV_R_FIPS_MODULE_CONDITIONAL_ERROR:227:fips module conditional error +PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE:224:fips module entering error state +PROV_R_FIPS_MODULE_IN_ERROR_STATE:225:fips module in error state PROV_R_GENERATE_ERROR:191:generate error PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ illegal or unsupported padding mode @@ -2866,6 +2893,7 @@ PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length PROV_R_INVALID_DATA:115:invalid data PROV_R_INVALID_DIGEST:122:invalid digest PROV_R_INVALID_DIGEST_LENGTH:166:invalid digest length +PROV_R_INVALID_DIGEST_SIZE:218:invalid digest size PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count PROV_R_INVALID_IVLEN:116:invalid ivlen PROV_R_INVALID_IV_LENGTH:109:invalid iv length @@ -2905,7 +2933,10 @@ PROV_R_MISSING_SESSION_ID:133:missing session id PROV_R_MISSING_TYPE:134:missing type PROV_R_MISSING_XCGHASH:135:missing xcghash PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure +PROV_R_NOT_A_PRIVATE_KEY:221:not a private key +PROV_R_NOT_A_PUBLIC_KEY:220:not a public key PROV_R_NOT_INSTANTIATED:193:not instantiated +PROV_R_NOT_PARAMETERS:226:not parameters PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set @@ -2915,12 +2946,15 @@ PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\ PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small PROV_R_PARENT_LOCKING_NOT_ENABLED:182:parent locking not enabled PROV_R_PARENT_STRENGTH_TOO_WEAK:194:parent strength too weak +PROV_R_PATH_MUST_BE_ABSOLUTE:219:path must be absolute PROV_R_PERSONALISATION_STRING_TOO_LONG:195:personalisation string too long PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small PROV_R_READ_KEY:159:read key PROV_R_REQUEST_TOO_LARGE_FOR_DRBG:196:request too large for drbg PROV_R_REQUIRE_CTR_MODE_CIPHER:206:require ctr mode cipher PROV_R_RESEED_ERROR:197:reseed error +PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:222:\ + search only supported for directories PROV_R_SELF_TEST_KAT_FAILURE:215:self test kat failure PROV_R_SELF_TEST_POST_FAILURE:216:self test post failure PROV_R_TAG_NOTSET:119:tag notset @@ -2942,6 +2976,7 @@ PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg PROV_R_UNSUPPORTED_KEY_SIZE:153:unsupported key size PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS:152:unsupported number of rounds +PROV_R_URI_AUTHORITY_UNSUPPORTED:223:uri authority unsupported PROV_R_VALUE_ERROR:138:value error PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size @@ -2987,6 +3022,8 @@ RAND_R_RESEED_ERROR:118:reseed error RAND_R_SELFTEST_FAILURE:119:selftest failure RAND_R_TOO_LITTLE_NONCE_REQUESTED:135:too little nonce requested RAND_R_TOO_MUCH_NONCE_REQUESTED:136:too much nonce requested +RAND_R_UNABLE_TO_CREATE_DRBG:143:unable to create drbg +RAND_R_UNABLE_TO_FETCH_DRBG:144:unable to fetch drbg RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:141:\ unable to get parent reseed prop counter RAND_R_UNABLE_TO_GET_PARENT_STRENGTH:138:unable to get parent strength @@ -3274,6 +3311,7 @@ SSL_R_NO_SHARED_CIPHER:193:no shared cipher SSL_R_NO_SHARED_GROUPS:410:no shared groups SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS:376:no shared signature algorithms SSL_R_NO_SRTP_PROFILES:359:no srtp profiles +SSL_R_NO_SUITABLE_DIGEST_ALGORITHM:297:no suitable digest algorithm SSL_R_NO_SUITABLE_KEY_SHARE:101:no suitable key share SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM:118:no suitable signature algorithm SSL_R_NO_VALID_SCTS:216:no valid scts @@ -3451,6 +3489,7 @@ X509V3_R_BN_TO_ASN1_INTEGER_ERROR:101:bn to asn1 integer error X509V3_R_DIRNAME_ERROR:149:dirname error X509V3_R_DISTPOINT_ALREADY_SET:160:distpoint already set X509V3_R_DUPLICATE_ZONE_ID:133:duplicate zone id +X509V3_R_EMPTY_KEY_USAGE:169:empty key usage X509V3_R_ERROR_CONVERTING_ZONE:131:error converting zone X509V3_R_ERROR_CREATING_EXTENSION:144:error creating extension X509V3_R_ERROR_IN_EXTENSION:128:error in extension @@ -3465,13 +3504,14 @@ X509V3_R_INCORRECT_POLICY_SYNTAX_TAG:152:incorrect policy syntax tag X509V3_R_INVALID_ASNUMBER:162:invalid asnumber X509V3_R_INVALID_ASRANGE:163:invalid asrange X509V3_R_INVALID_BOOLEAN_STRING:104:invalid boolean string +X509V3_R_INVALID_CERTIFICATE:158:invalid certificate +X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name X509V3_R_INVALID_EXTENSION_STRING:105:invalid extension string X509V3_R_INVALID_INHERITANCE:165:invalid inheritance X509V3_R_INVALID_IPADDRESS:166:invalid ipaddress X509V3_R_INVALID_MULTIPLE_RDNS:161:invalid multiple rdns X509V3_R_INVALID_NAME:106:invalid name X509V3_R_INVALID_NULL_ARGUMENT:107:invalid null argument -X509V3_R_INVALID_EMPTY_NAME:108:invalid empty name X509V3_R_INVALID_NULL_VALUE:109:invalid null value X509V3_R_INVALID_NUMBER:140:invalid number X509V3_R_INVALID_NUMBERS:141:invalid numbers @@ -3486,6 +3526,7 @@ X509V3_R_INVALID_SYNTAX:143:invalid syntax X509V3_R_ISSUER_DECODE_ERROR:126:issuer decode error X509V3_R_MISSING_VALUE:124:missing value X509V3_R_NEED_ORGANIZATION_AND_NUMBERS:142:need organization and numbers +X509V3_R_NEGATIVE_PATHLEN:168:negative pathlen X509V3_R_NO_CONFIG_DATABASE:136:no config database X509V3_R_NO_ISSUER_CERTIFICATE:121:no issuer certificate X509V3_R_NO_ISSUER_DETAILS:127:no issuer details @@ -3521,9 +3562,12 @@ X509_R_CERTIFICATE_VERIFICATION_FAILED:139:certificate verification failed X509_R_CERT_ALREADY_IN_HASH_TABLE:101:cert already in hash table X509_R_CRL_ALREADY_DELTA:127:crl already delta X509_R_CRL_VERIFY_FAILURE:131:crl verify failure +X509_R_ERROR_GETTING_MD_BY_NID:141:error getting md by nid +X509_R_ERROR_USING_SIGINF_SET:142:error using siginf set X509_R_IDP_MISMATCH:128:idp mismatch X509_R_INVALID_ATTRIBUTES:138:invalid attributes X509_R_INVALID_DIRECTORY:113:invalid directory +X509_R_INVALID_DISTPOINT:143:invalid distpoint X509_R_INVALID_FIELD_NAME:119:invalid field name X509_R_INVALID_TRUST:123:invalid trust X509_R_ISSUER_MISMATCH:129:issuer mismatch @@ -3547,6 +3591,7 @@ X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY:108:unable to get certs public key X509_R_UNKNOWN_KEY_TYPE:117:unknown key type X509_R_UNKNOWN_NID:109:unknown nid X509_R_UNKNOWN_PURPOSE_ID:121:unknown purpose id +X509_R_UNKNOWN_SIGID_ALGS:144:unknown sigid algs X509_R_UNKNOWN_TRUST_ID:120:unknown trust id X509_R_UNSUPPORTED_ALGORITHM:111:unsupported algorithm X509_R_WRONG_LOOKUP_TYPE:112:wrong lookup type diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c index ad0d6f332c..325acddb95 100644 --- a/crypto/ess/ess_lib.c +++ b/crypto/ess/ess_lib.c @@ -14,11 +14,6 @@ #include "crypto/ess.h" #include "crypto/x509.h" -DEFINE_STACK_OF(ESS_CERT_ID) -DEFINE_STACK_OF(ESS_CERT_ID_V2) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(X509) - static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, X509 *cert, int issuer_needed); diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/asymcipher.c similarity index 94% rename from crypto/evp/pmeth_fn.c rename to crypto/evp/asymcipher.c index 2ecad8b77c..0c767179e6 100644 --- a/crypto/evp/pmeth_fn.c +++ b/crypto/evp/asymcipher.c @@ -38,7 +38,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation) */ ERR_set_mark(); - if (ctx->engine != NULL || ctx->keytype == NULL) + if (evp_pkey_ctx_is_legacy(ctx)) goto legacy; /* @@ -405,7 +405,7 @@ OSSL_PROVIDER *EVP_ASYM_CIPHER_provider(const EVP_ASYM_CIPHER *cipher) return cipher->prov; } -EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) { return evp_generic_fetch(ctx, OSSL_OP_ASYM_CIPHER, algorithm, properties, @@ -424,7 +424,7 @@ int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher) return cipher->name_id; } -void EVP_ASYM_CIPHER_do_all_provided(OPENSSL_CTX *libctx, +void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_ASYM_CIPHER *cipher, void *arg), void *arg) @@ -444,3 +444,24 @@ void EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher, evp_names_do_all(cipher->prov, cipher->name_id, fn, data); } +const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *cip) +{ + void *provctx; + + if (cip == NULL || cip->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_provider(cip)); + return cip->gettable_ctx_params(provctx); +} + +const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *cip) +{ + void *provctx; + + if (cip == NULL || cip->settable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_ASYM_CIPHER_provider(cip)); + return cip->settable_ctx_params(provctx); +} diff --git a/crypto/evp/build.info b/crypto/evp/build.info index ccd8357453..7f1459a15c 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -2,7 +2,7 @@ LIBS=../../libcrypto $COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \ mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \ - pmeth_check.c evp_rand.c + pmeth_check.c evp_rand.c asymcipher.c kem.c SOURCE[../../libcrypto]=$COMMON\ encode.c evp_key.c evp_cnf.c \ @@ -13,10 +13,8 @@ SOURCE[../../libcrypto]=$COMMON\ bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \ c_allc.c c_alld.c bio_ok.c \ evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \ - pkey_kdf.c pmeth_fn.c\ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c \ - pkey_mac.c \ legacy_sha.c IF[{- !$disabled{'deprecated-3.0'} -}] diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 3d25b75be7..281749558d 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -21,22 +22,9 @@ #include "internal/provider.h" #include "evp_local.h" -/* This call frees resources associated with the context */ -int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) -{ - if (ctx == NULL) - return 1; - -#ifndef FIPS_MODULE - /* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */ - /* - * pctx should be freed by the user of EVP_MD_CTX - * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set - */ - if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) - EVP_PKEY_CTX_free(ctx->pctx); -#endif +void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force) +{ EVP_MD_free(ctx->fetched_digest); ctx->fetched_digest = NULL; ctx->reqdigest = NULL; @@ -58,21 +46,71 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) ctx->digest->cleanup(ctx); if (ctx->digest && ctx->digest->ctx_size && ctx->md_data - && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { + && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE) || force)) OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); - } + if (force) + ctx->digest = NULL; #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) ENGINE_finish(ctx->engine); + ctx->engine = NULL; #endif +} - /* TODO(3.0): End of legacy code */ +/* This call frees resources associated with the context */ +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +{ + if (ctx == NULL) + return 1; +#ifndef FIPS_MODULE + /* TODO(3.0): Temporarily no support for EVP_DigestSign* in FIPS module */ + /* + * pctx should be freed by the user of EVP_MD_CTX + * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set + */ + if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { + EVP_PKEY_CTX_free(ctx->pctx); + ctx->pctx = NULL; + } +#endif + + evp_md_ctx_clear_digest(ctx, 0); OPENSSL_cleanse(ctx, sizeof(*ctx)); return 1; } +#ifndef FIPS_MODULE +EVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_MD_CTX *ctx; + EVP_PKEY_CTX *pctx = NULL; + + if ((ctx = EVP_MD_CTX_new()) == NULL + || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq)) == NULL) { + ASN1err(0, ERR_R_MALLOC_FAILURE); + goto err; + } + +# ifndef OPENSSL_NO_EC + if (id != NULL && EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) { + ASN1err(0, ERR_R_MALLOC_FAILURE); + goto err; + } +# endif + + EVP_MD_CTX_set_pkey_ctx(ctx, pctx); + return ctx; + + err: + EVP_PKEY_CTX_free(pctx); + EVP_MD_CTX_free(ctx); + return NULL; +} +#endif + EVP_MD_CTX *EVP_MD_CTX_new(void) { return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); @@ -101,6 +139,25 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) ENGINE *tmpimpl = NULL; #endif +#if !defined(FIPS_MODULE) + if (ctx->pctx != NULL + && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx) + && ctx->pctx->op.sig.sigprovctx != NULL) { + /* + * Prior to OpenSSL 3.0 calling EVP_DigestInit_ex() on an mdctx + * previously initialised with EVP_DigestSignInit() would retain + * information about the key, and re-initialise for another sign + * operation. So in that case we redirect to EVP_DigestSignInit() + */ + if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX) + return EVP_DigestSignInit(ctx, NULL, type, impl, NULL); + if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX) + return EVP_DigestVerifyInit(ctx, NULL, type, impl, NULL); + EVPerr(0, EVP_R_UPDATE_ERROR); + return 0; + } +#endif + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); if (ctx->provctx != NULL) { @@ -174,10 +231,8 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) #else EVP_MD *provmd = EVP_MD_fetch(NULL, OBJ_nid2sn(type->type), ""); - if (provmd == NULL) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + if (provmd == NULL) return 0; - } type = provmd; EVP_MD_free(ctx->fetched_digest); ctx->fetched_digest = provmd; @@ -295,8 +350,9 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) * Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and * EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate(). * Some code calls EVP_DigestUpdate() directly even when initialised - * with EVP_DigestSignInit_ex() or EVP_DigestVerifyInit_ex(), so we - * detect that and redirect to the correct EVP_Digest*Update() function + * with EVP_DigestSignInit_ex() or + * EVP_DigestVerifyInit_ex(), so we detect that and redirect to + * the correct EVP_Digest*Update() function */ if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX) return EVP_DigestSignUpdate(ctx, data, count); @@ -334,11 +390,18 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) /* The caller can assume that this removes any secret data from the context */ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *isize) { - int ret; + int ret, sz; size_t size = 0; - size_t mdsize = EVP_MD_size(ctx->digest); + size_t mdsize = 0; - if (ctx->digest == NULL || ctx->digest->prov == NULL) + if (ctx->digest == NULL) + return 0; + + sz = EVP_MD_size(ctx->digest); + if (sz < 0) + return 0; + mdsize = sz; + if (ctx->digest->prov == NULL) goto legacy; if (ctx->digest->dfinal == NULL) { @@ -447,10 +510,12 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) if (in->fetched_digest != NULL) EVP_MD_up_ref(in->fetched_digest); - out->provctx = in->digest->dupctx(in->provctx); - if (out->provctx == NULL) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX); - return 0; + if (in->provctx != NULL) { + out->provctx = in->digest->dupctx(in->provctx); + if (out->provctx == NULL) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_NOT_ABLE_TO_COPY_CTX); + return 0; + } } /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */ @@ -557,7 +622,8 @@ int EVP_MD_get_params(const EVP_MD *digest, OSSL_PARAM params[]) const OSSL_PARAM *EVP_MD_gettable_params(const EVP_MD *digest) { if (digest != NULL && digest->gettable_params != NULL) - return digest->gettable_params(); + return digest->gettable_params( + ossl_provider_ctx(EVP_MD_provider(digest))); return NULL; } @@ -565,9 +631,7 @@ int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]) { EVP_PKEY_CTX *pctx = ctx->pctx; - if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL) - return ctx->digest->set_ctx_params(ctx->provctx, params); - + /* If we have a pctx then we should try that first */ if (pctx != NULL && (pctx->operation == EVP_PKEY_OP_VERIFYCTX || pctx->operation == EVP_PKEY_OP_SIGNCTX) @@ -575,13 +639,17 @@ int EVP_MD_CTX_set_params(EVP_MD_CTX *ctx, const OSSL_PARAM params[]) && pctx->op.sig.signature->set_ctx_md_params != NULL) return pctx->op.sig.signature->set_ctx_md_params(pctx->op.sig.sigprovctx, params); + + if (ctx->digest != NULL && ctx->digest->set_ctx_params != NULL) + return ctx->digest->set_ctx_params(ctx->provctx, params); + return 0; } const OSSL_PARAM *EVP_MD_settable_ctx_params(const EVP_MD *md) { if (md != NULL && md->settable_ctx_params != NULL) - return md->settable_ctx_params(); + return md->settable_ctx_params(ossl_provider_ctx(EVP_MD_provider(md))); return NULL; } @@ -589,11 +657,10 @@ const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx) { EVP_PKEY_CTX *pctx; - if (ctx != NULL - && ctx->digest != NULL - && ctx->digest->settable_ctx_params != NULL) - return ctx->digest->settable_ctx_params(); + if (ctx == NULL) + return NULL; + /* If we have a pctx then we should try that first */ pctx = ctx->pctx; if (pctx != NULL && (pctx->operation == EVP_PKEY_OP_VERIFYCTX @@ -603,6 +670,10 @@ const OSSL_PARAM *EVP_MD_CTX_settable_params(EVP_MD_CTX *ctx) return pctx->op.sig.signature->settable_ctx_md_params( pctx->op.sig.sigprovctx); + if (ctx->digest != NULL && ctx->digest->settable_ctx_params != NULL) + return ctx->digest->settable_ctx_params( + ossl_provider_ctx(EVP_MD_provider(ctx->digest))); + return NULL; } @@ -610,9 +681,7 @@ int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]) { EVP_PKEY_CTX *pctx = ctx->pctx; - if (ctx->digest != NULL && ctx->digest->get_params != NULL) - return ctx->digest->get_ctx_params(ctx->provctx, params); - + /* If we have a pctx then we should try that first */ if (pctx != NULL && (pctx->operation == EVP_PKEY_OP_VERIFYCTX || pctx->operation == EVP_PKEY_OP_SIGNCTX) @@ -621,13 +690,16 @@ int EVP_MD_CTX_get_params(EVP_MD_CTX *ctx, OSSL_PARAM params[]) return pctx->op.sig.signature->get_ctx_md_params(pctx->op.sig.sigprovctx, params); + if (ctx->digest != NULL && ctx->digest->get_params != NULL) + return ctx->digest->get_ctx_params(ctx->provctx, params); + return 0; } const OSSL_PARAM *EVP_MD_gettable_ctx_params(const EVP_MD *md) { if (md != NULL && md->gettable_ctx_params != NULL) - return md->gettable_ctx_params(); + return md->gettable_ctx_params(ossl_provider_ctx(EVP_MD_provider(md))); return NULL; } @@ -635,11 +707,10 @@ const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx) { EVP_PKEY_CTX *pctx; - if (ctx != NULL - && ctx->digest != NULL - && ctx->digest->gettable_ctx_params != NULL) - return ctx->digest->gettable_ctx_params(); + if (ctx == NULL) + return NULL; + /* If we have a pctx then we should try that first */ pctx = ctx->pctx; if (pctx != NULL && (pctx->operation == EVP_PKEY_OP_VERIFYCTX @@ -649,6 +720,11 @@ const OSSL_PARAM *EVP_MD_CTX_gettable_params(EVP_MD_CTX *ctx) return pctx->op.sig.signature->gettable_ctx_md_params( pctx->op.sig.sigprovctx); + if (ctx->digest != NULL + && ctx->digest->gettable_ctx_params != NULL) + return ctx->digest->gettable_ctx_params( + ossl_provider_ctx(EVP_MD_provider(ctx->digest))); + return NULL; } @@ -878,7 +954,7 @@ static void evp_md_free(void *md) EVP_MD_free(md); } -EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) { EVP_MD *md = @@ -911,7 +987,7 @@ void EVP_MD_free(EVP_MD *md) OPENSSL_free(md); } -void EVP_MD_do_all_provided(OPENSSL_CTX *libctx, +void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_MD *mac, void *arg), void *arg) { diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c index c037090695..08abd5fb09 100644 --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -179,8 +179,7 @@ static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { aesni_cbc_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - EVP_CIPHER_CTX_encrypting(ctx)); + ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); return 1; } @@ -300,7 +299,7 @@ static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (iv) { xctx->xts.key2 = &xctx->ks2; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); + memcpy(ctx->iv, iv, 16); } return 1; @@ -326,7 +325,7 @@ static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -651,7 +650,7 @@ static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (iv) { xctx->xts.key2 = &xctx->ks2; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); + memcpy(ctx->iv, iv, 16); } return 1; @@ -676,7 +675,7 @@ static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -986,7 +985,7 @@ static int s390x_aes_ofb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *ivec, int enc) { S390X_AES_OFB_CTX *cctx = EVP_C_DATA(S390X_AES_OFB_CTX, ctx); - const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx); + const unsigned char *iv = ctx->oiv; const int keylen = EVP_CIPHER_CTX_key_length(ctx); const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); @@ -1041,7 +1040,7 @@ static int s390x_aes_cfb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *ivec, int enc) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); - const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx); + const unsigned char *iv = ctx->oiv; const int keylen = EVP_CIPHER_CTX_key_length(ctx); const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); @@ -1107,7 +1106,7 @@ static int s390x_aes_cfb8_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *ivec, int enc) { S390X_AES_CFB_CTX *cctx = EVP_C_DATA(S390X_AES_CFB_CTX, ctx); - const unsigned char *iv = EVP_CIPHER_CTX_original_iv(ctx); + const unsigned char *iv = ctx->oiv; const int keylen = EVP_CIPHER_CTX_key_length(ctx); const int ivlen = EVP_CIPHER_CTX_iv_length(ctx); @@ -1333,17 +1332,16 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, c); S390X_AES_GCM_CTX *gctx_out; EVP_CIPHER_CTX *out; - unsigned char *buf, *iv; + unsigned char *buf; int ivlen, enc, len; switch (type) { case EVP_CTRL_INIT: ivlen = EVP_CIPHER_iv_length(c->cipher); - iv = EVP_CIPHER_CTX_iv_noconst(c); gctx->key_set = 0; gctx->iv_set = 0; gctx->ivlen = ivlen; - gctx->iv = iv; + gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; @@ -1358,12 +1356,11 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; if (arg != 12) { - iv = EVP_CIPHER_CTX_iv_noconst(c); len = S390X_gcm_ivpadlen(arg); /* Allocate memory for iv if needed. */ if (gctx->ivlen == 12 || len > S390X_gcm_ivpadlen(gctx->ivlen)) { - if (gctx->iv != iv) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); if ((gctx->iv = OPENSSL_malloc(len)) == NULL) { @@ -1479,10 +1476,9 @@ static int s390x_aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) case EVP_CTRL_COPY: out = ptr; gctx_out = EVP_C_DATA(S390X_AES_GCM_CTX, out); - iv = EVP_CIPHER_CTX_iv_noconst(c); - if (gctx->iv == iv) { - gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out); + if (gctx->iv == c->iv) { + gctx_out->iv = out->iv; } else { len = S390X_gcm_ivpadlen(gctx->ivlen); @@ -1657,13 +1653,11 @@ static int s390x_aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_gcm_cleanup(EVP_CIPHER_CTX *c) { S390X_AES_GCM_CTX *gctx = EVP_C_DATA(S390X_AES_GCM_CTX, c); - const unsigned char *iv; if (gctx == NULL) return 0; - iv = EVP_CIPHER_CTX_iv(c); - if (iv != gctx->iv) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); OPENSSL_cleanse(gctx, sizeof(*gctx)); @@ -1862,7 +1856,7 @@ static int s390x_aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); - unsigned char *ivec = EVP_CIPHER_CTX_iv_noconst(ctx); + unsigned char *ivec = ctx->iv; unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx); const int enc = EVP_CIPHER_CTX_encrypting(ctx); @@ -1916,7 +1910,6 @@ static int s390x_aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *iv, int enc) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); - unsigned char *ivec; int keylen; if (iv == NULL && key == NULL) @@ -1938,8 +1931,7 @@ static int s390x_aes_ccm_init_key(EVP_CIPHER_CTX *ctx, } if (iv != NULL) { - ivec = EVP_CIPHER_CTX_iv_noconst(ctx); - memcpy(ivec, iv, 15 - cctx->aes.ccm.l); + memcpy(ctx->iv, iv, 15 - cctx->aes.ccm.l); cctx->aes.ccm.iv_set = 1; } @@ -1959,7 +1951,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, ctx); const int enc = EVP_CIPHER_CTX_encrypting(ctx); int rv; - unsigned char *buf, *ivec; + unsigned char *buf; if (!cctx->aes.ccm.key_set) return -1; @@ -1981,8 +1973,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (out == NULL) { /* Update(): Pass message length. */ if (in == NULL) { - ivec = EVP_CIPHER_CTX_iv_noconst(ctx); - s390x_aes_ccm_setiv(cctx, ivec, len); + s390x_aes_ccm_setiv(cctx, ctx->iv, len); cctx->aes.ccm.len_set = 1; return len; @@ -2007,8 +1998,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, * In case message length was not previously set explicitly via * Update(), set it now. */ - ivec = EVP_CIPHER_CTX_iv_noconst(ctx); - s390x_aes_ccm_setiv(cctx, ivec, len); + s390x_aes_ccm_setiv(cctx, ctx->iv, len); cctx->aes.ccm.len_set = 1; } @@ -2047,7 +2037,7 @@ static int s390x_aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { S390X_AES_CCM_CTX *cctx = EVP_C_DATA(S390X_AES_CCM_CTX, c); - unsigned char *buf, *iv; + unsigned char *buf; int enc, len; switch (type) { @@ -2101,8 +2091,7 @@ static int s390x_aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; /* Copy to first part of the iv. */ - iv = EVP_CIPHER_CTX_iv_noconst(c); - memcpy(iv, ptr, arg); + memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: @@ -2404,15 +2393,14 @@ static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx); if (dat->stream.cbc) - (*dat->stream.cbc) (in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); else if (EVP_CIPHER_CTX_encrypting(ctx)) - CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, + dat->block); else CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + ctx->iv, dat->block); return 1; } @@ -2440,7 +2428,7 @@ static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block); + ctx->iv, &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -2452,7 +2440,7 @@ static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; @@ -2465,7 +2453,7 @@ static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; @@ -2479,7 +2467,7 @@ static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) { int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; @@ -2488,7 +2476,7 @@ static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, while (len >= MAXBITCHUNK) { int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); len -= MAXBITCHUNK; @@ -2498,7 +2486,7 @@ static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (len) { int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -2514,12 +2502,12 @@ static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (dat->stream.ctr) CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->stream.ctr); else CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); @@ -2536,7 +2524,7 @@ static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) if (gctx == NULL) return 0; OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); - if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c)) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); return 1; } @@ -2588,14 +2576,6 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) memcpy(ptr, c->buf, arg); return 1; - case EVP_CTRL_GET_IV: - if (gctx->iv_gen != 1 && gctx->iv_gen_rand != 1) - return 0; - if (gctx->ivlen != arg) - return 0; - memcpy(ptr, gctx->iv, arg); - return 1; - case EVP_CTRL_GCM_SET_IV_FIXED: /* Special case: -1 length restores whole IV */ if (arg == -1) { @@ -3213,7 +3193,7 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, if (iv) { xctx->xts.key2 = &xctx->ks2; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16); + memcpy(ctx->iv, iv, 16); } return 1; @@ -3245,9 +3225,8 @@ static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (xctx->stream) (*xctx->stream) (in, out, len, xctx->xts.key1, xctx->xts.key2, - EVP_CIPHER_CTX_iv_noconst(ctx)); - else if (CRYPTO_xts128_encrypt(&xctx->xts, EVP_CIPHER_CTX_iv_noconst(ctx), - in, out, len, + ctx->iv); + else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, EVP_CIPHER_CTX_encrypting(ctx))) return 0; return 1; @@ -3311,7 +3290,7 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (arg != EVP_CCM_TLS_FIXED_IV_LEN) return 0; /* Just copy to first part of IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg); + memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: @@ -3402,7 +3381,7 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } while (0); if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -3421,11 +3400,11 @@ static int aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in, + memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L, + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; /* Use saved AAD */ @@ -3477,7 +3456,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!out) { if (!in) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; @@ -3496,8 +3475,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, /* If not set length yet do it */ if (!cctx->len_set) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), - 15 - cctx->L, len)) + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; } @@ -3564,8 +3542,8 @@ static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, wctx->iv = NULL; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx)); - wctx->iv = EVP_CIPHER_CTX_iv_noconst(ctx); + memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + wctx->iv = ctx->iv; } return 1; } @@ -3729,7 +3707,7 @@ static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) octx->key_set = 0; octx->iv_set = 0; octx->ivlen = EVP_CIPHER_iv_length(c->cipher); - octx->iv = EVP_CIPHER_CTX_iv_noconst(c); + octx->iv = c->iv; octx->taglen = 16; octx->data_buf_len = 0; octx->aad_buf_len = 0; diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c index aa3b9d354e..f787d014d2 100644 --- a/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -26,6 +26,7 @@ #include "crypto/modes.h" #include "crypto/evp.h" #include "internal/constant_time.h" +#include "evp_local.h" typedef struct { AES_KEY ks; @@ -438,8 +439,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { SHA1_Update(&key->md, in + iv, sha_off); - aesni_cbc_sha1_enc(in, out, blocks, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + aesni_cbc_sha1_enc(in, out, blocks, &key->ks, ctx->iv, &key->md, in + iv + sha_off); blocks *= SHA_CBLOCK; aes_off += blocks; @@ -471,10 +471,10 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, out[plen] = l; /* encrypt HMAC|padding at once */ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } else { aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } } else { union { @@ -504,7 +504,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, return 0; /* omit explicit iv */ - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), in, AES_BLOCK_SIZE); + memcpy(ctx->iv, in, AES_BLOCK_SIZE); in += AES_BLOCK_SIZE; out += AES_BLOCK_SIZE; @@ -525,7 +525,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, # endif /* decrypt HMAC|padding at once */ aesni_cbc_encrypt(in, out, len, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), 0); + ctx->iv, 0); /* figure out payload length */ pad = out[len - 1]; @@ -761,7 +761,7 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, # endif /* decrypt HMAC|padding at once */ aesni_cbc_encrypt(in, out, len, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), 0); + ctx->iv, 0); SHA1_Update(&key->md, out, len); } diff --git a/crypto/evp/e_aes_cbc_hmac_sha256.c b/crypto/evp/e_aes_cbc_hmac_sha256.c index 72508c9851..6227002395 100644 --- a/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -26,6 +26,7 @@ #include "crypto/modes.h" #include "internal/constant_time.h" #include "crypto/evp.h" +#include "evp_local.h" typedef struct { AES_KEY ks; @@ -468,8 +469,7 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, SHA256_Update(&key->md, in + iv, sha_off); (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), - &key->md, in + iv + sha_off); + ctx->iv, &key->md, in + iv + sha_off); blocks *= SHA256_CBLOCK; aes_off += blocks; sha_off += blocks; @@ -500,10 +500,10 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, out[plen] = l; /* encrypt HMAC|padding at once */ aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } else { aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, - &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1); + &key->ks, ctx->iv, 1); } } else { union { @@ -516,7 +516,7 @@ static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, /* decrypt HMAC|padding at once */ aesni_cbc_encrypt(in, out, len, &key->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), 0); + ctx->iv, 0); if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ size_t inp_len, mask, j, i; diff --git a/crypto/evp/e_aria.c b/crypto/evp/e_aria.c index 9720fcb7e5..9f3a909122 100644 --- a/crypto/evp/e_aria.c +++ b/crypto/evp/e_aria.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -13,7 +13,6 @@ # include # include # include -# include # include "crypto/aria.h" # include "crypto/evp.h" # include "crypto/modes.h" @@ -174,8 +173,7 @@ static int aria_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, unsigned int num = EVP_CIPHER_CTX_num(ctx); EVP_ARIA_KEY *dat = EVP_C_DATA(EVP_ARIA_KEY,ctx); - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, (block128_f) aria_encrypt); EVP_CIPHER_CTX_set_num(ctx, num); @@ -253,7 +251,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx->key_set = 0; gctx->iv_set = 0; gctx->ivlen = EVP_CIPHER_iv_length(c->cipher); - gctx->iv = EVP_CIPHER_CTX_iv_noconst(c); + gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; @@ -268,7 +266,7 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; /* Allocate memory for IV if needed */ if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { - if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c)) + if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) { EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE); @@ -372,8 +370,8 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; gctx_out->gcm.key = &gctx_out->ks; } - if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c)) - gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out); + if (gctx->iv == c->iv) + gctx_out->iv = out->iv; else { if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) { EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE); @@ -494,7 +492,7 @@ static int aria_gcm_cleanup(EVP_CIPHER_CTX *ctx) { EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx); - if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(ctx)) + if (gctx->iv != ctx->iv) OPENSSL_free(gctx->iv); return 1; @@ -522,7 +520,7 @@ static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, cctx->key_set = 1; } if (iv) { - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + memcpy(ctx->iv, iv, 15 - cctx->L); cctx->iv_set = 1; } return 1; @@ -578,7 +576,7 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (arg != EVP_CCM_TLS_FIXED_IV_LEN) return 0; /* Just copy to first part of IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg); + memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: @@ -642,11 +640,11 @@ static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in, + memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L, + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; /* Use saved AAD */ @@ -697,8 +695,7 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (!out) { if (!in) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), - 15 - cctx->L, len)) + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; return len; @@ -716,8 +713,7 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, /* If not set length yet do it */ if (!cctx->len_set) { - if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), - 15 - cctx->L, len)) + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; cctx->len_set = 1; } diff --git a/crypto/evp/e_bf.c b/crypto/evp/e_bf.c index c9ca56dc70..9e240d1124 100644 --- a/crypto/evp/e_bf.c +++ b/crypto/evp/e_bf.c @@ -20,6 +20,7 @@ # include "crypto/evp.h" # include # include +# include "evp_local.h" static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); diff --git a/crypto/evp/e_camellia.c b/crypto/evp/e_camellia.c index e9a29930fc..79ac163e3a 100644 --- a/crypto/evp/e_camellia.c +++ b/crypto/evp/e_camellia.c @@ -23,6 +23,7 @@ #include "crypto/evp.h" #include "crypto/modes.h" #include "crypto/cmll_platform.h" +#include "evp_local.h" static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -219,15 +220,12 @@ static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); if (dat->stream.cbc) - (*dat->stream.cbc) (in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); else if (EVP_CIPHER_CTX_encrypting(ctx)) - CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); else - CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), dat->block); + CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block); return 1; } @@ -254,8 +252,7 @@ static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block); + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -266,8 +263,8 @@ static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, ctx->iv, &num, + EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -278,8 +275,8 @@ static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, ctx->iv, &num, + EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -291,8 +288,8 @@ static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) { int num = EVP_CIPHER_CTX_num(ctx); - CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, ctx->iv, &num, + EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); return 1; } @@ -300,7 +297,7 @@ static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, while (len >= MAXBITCHUNK) { int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); len -= MAXBITCHUNK; out += MAXBITCHUNK; @@ -309,7 +306,7 @@ static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (len) { int num = EVP_CIPHER_CTX_num(ctx); CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); + ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -323,13 +320,11 @@ static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx); if (dat->stream.ctr) - CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->stream.ctr); else - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, dat->block); EVP_CIPHER_CTX_set_num(ctx, num); diff --git a/crypto/evp/e_cast.c b/crypto/evp/e_cast.c index 9ee06d060b..8325a5f8d2 100644 --- a/crypto/evp/e_cast.c +++ b/crypto/evp/e_cast.c @@ -21,6 +21,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); diff --git a/crypto/evp/e_des.c b/crypto/evp/e_des.c index 9d8af99d92..d3b2206bb7 100644 --- a/crypto/evp/e_des.c +++ b/crypto/evp/e_des.c @@ -21,6 +21,7 @@ # include "crypto/evp.h" # include # include +# include "evp_local.h" typedef struct { union { @@ -75,7 +76,7 @@ static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num); + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; @@ -85,7 +86,7 @@ static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); DES_ofb64_encrypt(in, out, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num); + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); } return 1; @@ -97,14 +98,13 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx); if (dat->stream.cbc != NULL) { - (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, - EVP_CIPHER_CTX_iv_noconst(ctx)); + (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv); return 1; } while (inl >= EVP_MAXCHUNK) { DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; @@ -113,7 +113,7 @@ static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_ncbc_encrypt(in, out, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); return 1; } @@ -125,7 +125,7 @@ static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num, + (DES_cblock *)ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; @@ -136,7 +136,7 @@ static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); DES_cfb64_encrypt(in, out, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num, + (DES_cblock *)ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -160,7 +160,7 @@ static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, for (n = 0; n < chunk * 8; ++n) { c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; DES_cfb_encrypt(c, d, 1, 1, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | @@ -182,7 +182,7 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, while (inl >= EVP_MAXCHUNK) { DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; @@ -191,7 +191,7 @@ static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_cfb_encrypt(in, out, 8, (long)inl, EVP_CIPHER_CTX_get_cipher_data(ctx), - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); return 1; } diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c index 3f7802ef1f..be4030895a 100644 --- a/crypto/evp/e_des3.c +++ b/crypto/evp/e_des3.c @@ -87,7 +87,7 @@ static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; @@ -99,7 +99,7 @@ static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, DES_ede3_ofb64_encrypt(in, out, (long)inl, &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &num); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -113,14 +113,14 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (dat->stream.cbc != NULL) { (*dat->stream.cbc) (in, out, inl, dat->ks.ks, - EVP_CIPHER_CTX_iv_noconst(ctx)); + ctx->iv); return 1; } while (inl >= EVP_MAXCHUNK) { DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &dat->ks1, &dat->ks2, &dat->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; @@ -129,7 +129,7 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_ede3_cbc_encrypt(in, out, (long)inl, &dat->ks1, &dat->ks2, &dat->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); return 1; } @@ -141,8 +141,7 @@ static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + &data(ctx)->ks3, (DES_cblock *)ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); inl -= EVP_MAXCHUNK; @@ -153,8 +152,7 @@ static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, int num = EVP_CIPHER_CTX_num(ctx); DES_ede3_cfb64_encrypt(in, out, (long)inl, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + &data(ctx)->ks3, (DES_cblock *)ctx->iv, &num, EVP_CIPHER_CTX_encrypting(ctx)); EVP_CIPHER_CTX_set_num(ctx, num); } @@ -177,8 +175,7 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; DES_ede3_cfb_encrypt(c, d, 1, 1, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + &data(ctx)->ks3, (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | ((d[0] & 0x80) >> (unsigned int)(n % 8)); @@ -193,8 +190,7 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, while (inl >= EVP_MAXCHUNK) { DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + &data(ctx)->ks3, (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); inl -= EVP_MAXCHUNK; in += EVP_MAXCHUNK; @@ -203,8 +199,7 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, if (inl) DES_ede3_cfb_encrypt(in, out, 8, (long)inl, &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + &data(ctx)->ks3, (DES_cblock *)ctx->iv, EVP_CIPHER_CTX_encrypting(ctx)); return 1; } @@ -330,7 +325,7 @@ static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, return -1; if (out == NULL) return inl - 16; - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8); + memcpy(ctx->iv, wrap_iv, 8); /* Decrypt first block which will end up as icv */ des_ede_cbc_cipher(ctx, icv, in, 8); /* Decrypt central blocks */ @@ -348,7 +343,7 @@ static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, /* Reverse order of everything */ BUF_reverse(icv, NULL, 8); BUF_reverse(out, NULL, inl - 16); - BUF_reverse(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 8); + BUF_reverse(ctx->iv, iv, 8); /* Decrypt again using new IV */ des_ede_cbc_cipher(ctx, out, out, inl - 16); des_ede_cbc_cipher(ctx, icv, icv, 8); @@ -360,7 +355,7 @@ static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, OPENSSL_cleanse(icv, 8); OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); OPENSSL_cleanse(iv, 8); - OPENSSL_cleanse(EVP_CIPHER_CTX_iv_noconst(ctx), 8); + OPENSSL_cleanse(ctx->iv, 8); if (rv == -1) OPENSSL_cleanse(out, inl - 16); @@ -380,13 +375,13 @@ static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out, memcpy(out + inl + 8, sha1tmp, 8); OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); /* Generate random IV */ - if (RAND_bytes(EVP_CIPHER_CTX_iv_noconst(ctx), 8) <= 0) + if (RAND_bytes(ctx->iv, 8) <= 0) return -1; - memcpy(out, EVP_CIPHER_CTX_iv_noconst(ctx), 8); + memcpy(out, ctx->iv, 8); /* Encrypt everything after IV in place */ des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8); BUF_reverse(out, NULL, inl + 16); - memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8); + memcpy(ctx->iv, wrap_iv, 8); des_ede_cbc_cipher(ctx, out, out, inl + 16); return inl + 16; } diff --git a/crypto/evp/e_idea.c b/crypto/evp/e_idea.c index 43665887da..a4778a2c05 100644 --- a/crypto/evp/e_idea.c +++ b/crypto/evp/e_idea.c @@ -22,6 +22,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" /* Can't use IMPLEMENT_BLOCK_CIPHER because IDEA_ecb_encrypt is different */ diff --git a/crypto/evp/e_rc2.c b/crypto/evp/e_rc2.c index 88d8e524cc..a8fb18e72d 100644 --- a/crypto/evp/e_rc2.c +++ b/crypto/evp/e_rc2.c @@ -22,6 +22,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -159,9 +160,7 @@ static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) if (type != NULL) { num = rc2_meth_to_magic(c); j = EVP_CIPHER_CTX_iv_length(c); - i = ASN1_TYPE_set_int_octetstring(type, num, - (unsigned char *)EVP_CIPHER_CTX_original_iv(c), - j); + i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); } return i; } diff --git a/crypto/evp/e_seed.c b/crypto/evp/e_seed.c index 3f223ce936..98c7385f61 100644 --- a/crypto/evp/e_seed.c +++ b/crypto/evp/e_seed.c @@ -20,6 +20,7 @@ #include #include #include "crypto/evp.h" +#include "evp_local.h" static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c index 4653c10a14..5a164eff75 100644 --- a/crypto/evp/e_sm4.c +++ b/crypto/evp/e_sm4.c @@ -1,5 +1,5 @@ /* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * @@ -15,6 +15,7 @@ # include # include "crypto/sm4.h" # include "crypto/evp.h" +# include "evp_local.h" typedef struct { SM4_KEY ks; @@ -74,8 +75,7 @@ static int sm4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, unsigned int num = EVP_CIPHER_CTX_num(ctx); EVP_SM4_KEY *dat = EVP_C_DATA(EVP_SM4_KEY, ctx); - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - EVP_CIPHER_CTX_iv_noconst(ctx), + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, EVP_CIPHER_CTX_buf_noconst(ctx), &num, (block128_f)SM4_encrypt); EVP_CIPHER_CTX_set_num(ctx, num); diff --git a/crypto/evp/e_xcbc_d.c b/crypto/evp/e_xcbc_d.c index f2b540e7cf..20756211b0 100644 --- a/crypto/evp/e_xcbc_d.c +++ b/crypto/evp/e_xcbc_d.c @@ -22,6 +22,7 @@ # include # include "crypto/evp.h" # include +# include "evp_local.h" static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); @@ -72,7 +73,7 @@ static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, { while (inl >= EVP_MAXCHUNK) { DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &data(ctx)->inw, &data(ctx)->outw, EVP_CIPHER_CTX_encrypting(ctx)); inl -= EVP_MAXCHUNK; @@ -81,7 +82,7 @@ static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, } if (inl) DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks, - (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), + (DES_cblock *)ctx->iv, &data(ctx)->inw, &data(ctx)->outw, EVP_CIPHER_CTX_encrypting(ctx)); return 1; diff --git a/crypto/evp/evp_cnf.c b/crypto/evp/evp_cnf.c index 27815553bd..b6f33795a1 100644 --- a/crypto/evp/evp_cnf.c +++ b/crypto/evp/evp_cnf.c @@ -14,8 +14,7 @@ #include #include #include - -DEFINE_STACK_OF(CONF_VALUE) +#include "crypto/evp.h" /* Algorithm configuration module. */ @@ -52,7 +51,7 @@ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) return 0; } } else if (strcmp(oval->name, "default_properties") == 0) { - if (!EVP_set_default_properties(cnf->libctx, oval->value)) { + if (!evp_set_default_properties_int(cnf->libctx, oval->value, 0)) { EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_SET_DEFAULT_PROPERTY_FAILURE); return 0; } diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index b8cb5daad0..929c95eed8 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -175,10 +174,8 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, : OBJ_nid2sn(cipher->nid), ""); - if (provciph == NULL) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + if (provciph == NULL) return 0; - } cipher = provciph; EVP_CIPHER_free(ctx->fetched_cipher); ctx->fetched_cipher = provciph; @@ -972,11 +969,6 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS: /* Used by DASYNC */ default: goto end; - case EVP_CTRL_GET_IV: - set_params = 0; - params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV, - ptr, sz); - break; case EVP_CTRL_AEAD_SET_IVLEN: if (arg < 0) return 0; @@ -1160,24 +1152,41 @@ int EVP_CIPHER_CTX_get_params(EVP_CIPHER_CTX *ctx, OSSL_PARAM params[]) const OSSL_PARAM *EVP_CIPHER_gettable_params(const EVP_CIPHER *cipher) { if (cipher != NULL && cipher->gettable_params != NULL) - return cipher->gettable_params(); + return cipher->gettable_params( + ossl_provider_ctx(EVP_CIPHER_provider(cipher))); return NULL; } const OSSL_PARAM *EVP_CIPHER_settable_ctx_params(const EVP_CIPHER *cipher) { if (cipher != NULL && cipher->settable_ctx_params != NULL) - return cipher->settable_ctx_params(); + return cipher->settable_ctx_params( + ossl_provider_ctx(EVP_CIPHER_provider(cipher))); return NULL; } const OSSL_PARAM *EVP_CIPHER_gettable_ctx_params(const EVP_CIPHER *cipher) { if (cipher != NULL && cipher->gettable_ctx_params != NULL) - return cipher->gettable_ctx_params(); + return cipher->gettable_ctx_params( + ossl_provider_ctx(EVP_CIPHER_provider(cipher))); return NULL; } +#ifndef FIPS_MODULE +static OSSL_LIB_CTX *EVP_CIPHER_CTX_get_libctx(EVP_CIPHER_CTX *ctx) +{ + const EVP_CIPHER *cipher = ctx->cipher; + const OSSL_PROVIDER *prov; + + if (cipher == NULL) + return NULL; + + prov = EVP_CIPHER_provider(cipher); + return ossl_provider_libctx(prov); +} +#endif + int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) { if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) @@ -1188,9 +1197,10 @@ int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) #else { int kl; + OSSL_LIB_CTX *libctx = EVP_CIPHER_CTX_get_libctx(ctx); kl = EVP_CIPHER_CTX_key_length(ctx); - if (kl <= 0 || RAND_priv_bytes(key, kl) <= 0) + if (kl <= 0 || RAND_priv_bytes_ex(libctx, key, kl) <= 0) return 0; return 1; } @@ -1446,7 +1456,7 @@ static void evp_cipher_free(void *cipher) EVP_CIPHER_free(cipher); } -EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) { EVP_CIPHER *cipher = @@ -1484,7 +1494,7 @@ void EVP_CIPHER_free(EVP_CIPHER *cipher) OPENSSL_free(cipher); } -void EVP_CIPHER_do_all_provided(OPENSSL_CTX *libctx, +void EVP_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_CIPHER *mac, void *arg), void *arg) { diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index d13cd05faa..52a224a517 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -90,6 +90,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_LENGTH), "invalid length"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_NULL_ALGORITHM), "invalid null algorithm"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation"}, @@ -97,7 +98,11 @@ static const ERR_STRING_DATA EVP_str_reasons[] = { "invalid provider functions"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH), "invalid salt length"}, - {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SECRET_LENGTH), + "invalid secret length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SEED_LENGTH), + "invalid seed length"}, + {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_VALUE), "invalid value"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE), "keymgmt export failure"}, {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"}, diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 5cb59d98fc..e8d1336aa3 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -17,6 +17,7 @@ #include "internal/core.h" #include "internal/provider.h" #include "internal/namemap.h" +#include "internal/property.h" #include "crypto/evp.h" /* evp_local.h needs it */ #include "evp_local.h" @@ -27,25 +28,28 @@ static void evp_method_store_free(void *vstore) ossl_method_store_free(vstore); } -static void *evp_method_store_new(OPENSSL_CTX *ctx) +static void *evp_method_store_new(OSSL_LIB_CTX *ctx) { return ossl_method_store_new(ctx); } -static const OPENSSL_CTX_METHOD evp_method_store_method = { +static const OSSL_LIB_CTX_METHOD evp_method_store_method = { evp_method_store_new, evp_method_store_free, }; /* Data to be passed through ossl_method_construct() */ struct evp_method_data_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; OSSL_METHOD_CONSTRUCT_METHOD *mcm; int operation_id; /* For get_evp_method_from_store() */ int name_id; /* For get_evp_method_from_store() */ const char *names; /* For get_evp_method_from_store() */ const char *propquery; /* For get_evp_method_from_store() */ + + unsigned int flag_construct_error_occured : 1; + void *(*method_from_dispatch)(int name_id, const OSSL_DISPATCH *, OSSL_PROVIDER *); int (*refcnt_up_method)(void *method); @@ -55,7 +59,7 @@ struct evp_method_data_st { /* * Generic routines to fetch / create EVP methods with ossl_method_construct() */ -static void *alloc_tmp_evp_method_store(OPENSSL_CTX *ctx) +static void *alloc_tmp_evp_method_store(OSSL_LIB_CTX *ctx) { return ossl_method_store_new(ctx); } @@ -66,10 +70,10 @@ static void *alloc_tmp_evp_method_store(OPENSSL_CTX *ctx) ossl_method_store_free(store); } -static OSSL_METHOD_STORE *get_evp_method_store(OPENSSL_CTX *libctx) +static OSSL_METHOD_STORE *get_evp_method_store(OSSL_LIB_CTX *libctx) { - return openssl_ctx_get_data(libctx, OPENSSL_CTX_EVP_METHOD_STORE_INDEX, - &evp_method_store_method); + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX, + &evp_method_store_method); } /* @@ -91,7 +95,7 @@ static uint32_t evp_method_id(int name_id, unsigned int operation_id) return ((name_id << 8) & 0xFFFFFF00) | (operation_id & 0x000000FF); } -static void *get_evp_method_from_store(OPENSSL_CTX *libctx, void *store, +static void *get_evp_method_from_store(OSSL_LIB_CTX *libctx, void *store, void *data) { struct evp_method_data_st *methdata = data; @@ -129,7 +133,7 @@ static void *get_evp_method_from_store(OPENSSL_CTX *libctx, void *store, return method; } -static int put_evp_method_in_store(OPENSSL_CTX *libctx, void *store, +static int put_evp_method_in_store(OSSL_LIB_CTX *libctx, void *store, void *method, const OSSL_PROVIDER *prov, int operation_id, const char *names, const char *propdef, void *data) @@ -181,15 +185,27 @@ static void *construct_evp_method(const OSSL_ALGORITHM *algodef, * number. */ struct evp_method_data_st *methdata = data; - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); const char *names = algodef->algorithm_names; int name_id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); + void *method; if (name_id == 0) return NULL; - return methdata->method_from_dispatch(name_id, algodef->implementation, - prov); + + method = methdata->method_from_dispatch(name_id, algodef->implementation, + prov); + + /* + * Flag to indicate that there was actual construction errors. This + * helps inner_evp_generic_fetch() determine what error it should + * record on inaccessible algorithms. + */ + if (method == NULL) + methdata->flag_construct_error_occured = 1; + + return method; } static void destruct_evp_method(void *method, void *data) @@ -199,8 +215,21 @@ static void destruct_evp_method(void *method, void *data) methdata->destruct_method(method); } +static const char *libctx_descriptor(OSSL_LIB_CTX *libctx) +{ +#ifdef FIPS_MODULE + return "FIPS internal library context"; +#else + if (ossl_lib_ctx_is_global_default(libctx)) + return "Global default library context"; + if (ossl_lib_ctx_is_default(libctx)) + return "Thread-local default library context"; + return "Non-default library context"; +#endif +} + static void * -inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, +inner_evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id, int name_id, const char *name, const char *properties, void *(*new_method)(int name_id, @@ -213,23 +242,30 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); uint32_t meth_id = 0; void *method = NULL; + int unsupported = 0; - if (store == NULL || namemap == NULL) + if (store == NULL || namemap == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT); return NULL; + } /* * If there's ever an operation_id == 0 passed, we have an internal * programming error. */ - if (!ossl_assert(operation_id > 0)) + if (!ossl_assert(operation_id > 0)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); return NULL; + } /* * If we have been passed neither a name_id or a name, we have an * internal programming error. */ - if (!ossl_assert(name_id != 0 || name != NULL)) + if (!ossl_assert(name_id != 0 || name != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); return NULL; + } /* If we haven't received a name id yet, try to get one for the name */ if (name_id == 0) @@ -241,9 +277,19 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, * evp_method_id returns 0 if we have too many operations (more than * about 2^8) or too many names (more than about 2^24). In that case, * we can't create any new method. + * For all intents and purposes, this is an internal error. */ - if (name_id != 0 && (meth_id = evp_method_id(name_id, operation_id)) == 0) + if (name_id != 0 && (meth_id = evp_method_id(name_id, operation_id)) == 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); return NULL; + } + + /* + * If we haven't found the name yet, chances are that the algorithm to + * be fetched is unsupported. + */ + if (name_id == 0) + unsupported = 1; if (meth_id == 0 || !ossl_method_store_cache_get(store, meth_id, properties, &method)) { @@ -266,6 +312,7 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, mcmdata.method_from_dispatch = new_method; mcmdata.refcnt_up_method = up_ref_method; mcmdata.destruct_method = free_method; + mcmdata.flag_construct_error_occured = 0; if ((method = ossl_method_construct(libctx, operation_id, 0 /* !force_cache */, &mcm, &mcmdata)) != NULL) { @@ -281,23 +328,31 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, ossl_method_store_cache_set(store, meth_id, properties, method, up_ref_method, free_method); } + + /* + * If we never were in the constructor, the algorithm to be fetched + * is unsupported. + */ + unsupported = !mcmdata.flag_construct_error_occured; } - return method; -} + if (method == NULL) { + int code = + unsupported ? EVP_R_UNSUPPORTED_ALGORITHM : EVP_R_FETCH_FAILED; -#ifndef FIPS_MODULE -static const char *libctx_descriptor(OPENSSL_CTX *libctx) -{ - if (openssl_ctx_is_global_default(libctx)) - return "Global default library context"; - if (openssl_ctx_is_default(libctx)) - return "Thread-local default library context"; - return "Non-default library context"; + if (name == NULL) + name = ossl_namemap_num2name(namemap, name_id, 0); + ERR_raise_data(ERR_LIB_EVP, code, + "%s, Algorithm (%s : %d), Properties (%s)", + libctx_descriptor(libctx), + name = NULL ? "" : name, name_id, + properties == NULL ? "" : properties); + } + + return method; } -#endif -void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, +void *evp_generic_fetch(OSSL_LIB_CTX *libctx, int operation_id, const char *name, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, @@ -305,24 +360,9 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, int (*up_ref_method)(void *), void (*free_method)(void *)) { - void *ret = inner_evp_generic_fetch(libctx, - operation_id, 0, name, properties, - new_method, up_ref_method, free_method); - - if (ret == NULL) { - int code = EVP_R_FETCH_FAILED; - -#ifdef FIPS_MODULE - ERR_raise(ERR_LIB_EVP, code); -#else - ERR_raise_data(ERR_LIB_EVP, code, - "%s, Algorithm (%s), Properties (%s)", - libctx_descriptor(libctx), - name = NULL ? "" : name, - properties == NULL ? "" : properties); -#endif - } - return ret; + return inner_evp_generic_fetch(libctx, + operation_id, 0, name, properties, + new_method, up_ref_method, free_method); } /* @@ -332,7 +372,7 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, * This is meant to be used when one method needs to fetch an associated * other method. */ -void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id, +void *evp_generic_fetch_by_number(OSSL_LIB_CTX *libctx, int operation_id, int name_id, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, @@ -340,52 +380,40 @@ void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id, int (*up_ref_method)(void *), void (*free_method)(void *)) { - void *ret = inner_evp_generic_fetch(libctx, - operation_id, name_id, NULL, - properties, new_method, up_ref_method, - free_method); + return inner_evp_generic_fetch(libctx, + operation_id, name_id, NULL, + properties, new_method, up_ref_method, + free_method); +} - if (ret == NULL) { - int code = EVP_R_FETCH_FAILED; +void evp_method_store_flush(OSSL_LIB_CTX *libctx) +{ + OSSL_METHOD_STORE *store = get_evp_method_store(libctx); -#ifdef FIPS_MODULE - ERR_raise(ERR_LIB_EVP, code); -#else - { - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - const char *name = (namemap == NULL) - ? NULL - : ossl_namemap_num2name(namemap, name_id, 0); - - ERR_raise_data(ERR_LIB_EVP, code, - "%s, Algorithm (%s), Properties (%s)", - libctx_descriptor(libctx), - name = NULL ? "" : name, - properties == NULL ? "" : properties); - } -#endif - } - return ret; + if (store != NULL) + ossl_method_store_flush_cache(store, 1); } -static int evp_set_default_properties(OPENSSL_CTX *libctx, - OSSL_PROPERTY_LIST *def_prop) +static int evp_set_parsed_default_properties(OSSL_LIB_CTX *libctx, + OSSL_PROPERTY_LIST *def_prop, + int loadconfig) { OSSL_METHOD_STORE *store = get_evp_method_store(libctx); - OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx); + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, loadconfig); if (plp != NULL) { ossl_property_free(*plp); *plp = def_prop; if (store != NULL) - ossl_method_store_flush_cache(store); + ossl_method_store_flush_cache(store, 0); return 1; } EVPerr(0, ERR_R_INTERNAL_ERROR); return 0; } -int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) +int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq, + int loadconfig) { OSSL_PROPERTY_LIST *pl = NULL; @@ -393,13 +421,17 @@ int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq) EVPerr(0, EVP_R_DEFAULT_QUERY_PARSE_ERROR); return 0; } - return evp_set_default_properties(libctx, pl); + return evp_set_parsed_default_properties(libctx, pl, loadconfig); } +int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq) +{ + return evp_set_default_properties_int(libctx, propq, 1); +} -static int evp_default_properties_merge(OPENSSL_CTX *libctx, const char *propq) +static int evp_default_properties_merge(OSSL_LIB_CTX *libctx, const char *propq) { - OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx); + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, 1); OSSL_PROPERTY_LIST *pl1, *pl2; if (propq == NULL) @@ -416,23 +448,23 @@ static int evp_default_properties_merge(OPENSSL_CTX *libctx, const char *propq) EVPerr(0, ERR_R_MALLOC_FAILURE); return 0; } - return evp_set_default_properties(libctx, pl2); + return evp_set_parsed_default_properties(libctx, pl2, 0); } -static int evp_default_property_is_enabled(OPENSSL_CTX *libctx, +static int evp_default_property_is_enabled(OSSL_LIB_CTX *libctx, const char *prop_name) { - OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx); + OSSL_PROPERTY_LIST **plp = ossl_ctx_global_properties(libctx, 1); return plp != NULL && ossl_property_is_enabled(libctx, prop_name, *plp); } -int EVP_default_properties_is_fips_enabled(OPENSSL_CTX *libctx) +int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX *libctx) { return evp_default_property_is_enabled(libctx, "fips"); } -int EVP_default_properties_enable_fips(OPENSSL_CTX *libctx, int enable) +int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable) { const char *query = (enable != 0) ? "fips=yes" : "-fips"; @@ -452,7 +484,7 @@ static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, int no_store, void *vdata) { struct do_all_data_st *data = vdata; - OPENSSL_CTX *libctx = ossl_provider_library_context(provider); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); int name_id = ossl_namemap_add_names(namemap, 0, algo->algorithm_names, NAME_SEPARATOR); @@ -467,7 +499,7 @@ static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, } } -void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, +void evp_generic_do_all(OSSL_LIB_CTX *libctx, int operation_id, void (*user_fn)(void *method, void *arg), void *user_arg, void *(*new_method)(int name_id, @@ -492,7 +524,7 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, const char *evp_first_name(const OSSL_PROVIDER *prov, int name_id) { - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); return ossl_namemap_num2name(namemap, name_id, 0); @@ -504,7 +536,7 @@ int evp_is_a(OSSL_PROVIDER *prov, int number, /* * For a |prov| that is NULL, the library context will be NULL */ - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); if (prov == NULL) @@ -516,7 +548,7 @@ void evp_names_do_all(OSSL_PROVIDER *prov, int number, void (*fn)(const char *name, void *data), void *data) { - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); ossl_namemap_doall_names(namemap, number, fn, data); diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 9f2165dc59..81151e4f01 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -22,11 +22,59 @@ #include #include #include "crypto/evp.h" +#include "crypto/asn1.h" #include "internal/provider.h" #include "evp_local.h" #if !defined(FIPS_MODULE) int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + return evp_cipher_param_to_asn1_ex(c, type, NULL); +} + +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + return evp_cipher_asn1_to_param_ex(c, type, NULL); +} + +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type) +{ + int i = 0; + unsigned int l; + + if (type != NULL) { + unsigned char iv[EVP_MAX_IV_LENGTH]; + + l = EVP_CIPHER_CTX_iv_length(ctx); + if (!ossl_assert(l <= sizeof(iv))) + return -1; + i = ASN1_TYPE_get_octetstring(type, iv, l); + if (i != (int)l) + return -1; + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1)) + return -1; + } + return i; +} + +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int j; + unsigned char *oiv = NULL; + + if (type != NULL) { + oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c); + j = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(j <= sizeof(c->iv)); + i = ASN1_TYPE_set_octetstring(type, oiv, j); + } + return i; +} + +int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { int ret = -1; /* Assume the worst */ const EVP_CIPHER *cipher = c->cipher; @@ -58,6 +106,9 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) break; case EVP_CIPH_GCM_MODE: + ret = evp_cipher_set_asn1_aead_params(c, type, asn1_params); + break; + case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: @@ -104,15 +155,16 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) err: if (ret == -2) - EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ASN1_R_UNSUPPORTED_CIPHER); + EVPerr(0, EVP_R_UNSUPPORTED_CIPHER); else if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, EVP_R_CIPHER_PARAMETER_ERROR); + EVPerr(0, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; } -int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { int ret = -1; /* Assume the worst */ const EVP_CIPHER *cipher = c->cipher; @@ -142,6 +194,9 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) break; case EVP_CIPH_GCM_MODE: + ret = evp_cipher_get_asn1_aead_params(c, type, asn1_params); + break; + case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: @@ -170,48 +225,43 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) } if (ret == -2) - EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_UNSUPPORTED_CIPHER); + EVPerr(0, EVP_R_UNSUPPORTED_CIPHER); else if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_CIPHER_PARAMETER_ERROR); + EVPerr(0, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; } -int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type) +int evp_cipher_get_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { int i = 0; - unsigned int l; + long tl; + unsigned char iv[EVP_MAX_IV_LENGTH]; - if (type != NULL) { - unsigned char iv[EVP_MAX_IV_LENGTH]; + if (type == NULL || asn1_params == NULL) + return 0; - l = EVP_CIPHER_CTX_iv_length(ctx); - if (!ossl_assert(l <= sizeof(iv))) - return -1; - i = ASN1_TYPE_get_octetstring(type, iv, l); - if (i != (int)l) - return -1; + i = asn1_type_get_octetstring_int(type, &tl, NULL, EVP_MAX_IV_LENGTH); + if (i <= 0) + return -1; + asn1_type_get_octetstring_int(type, &tl, iv, i); + + memcpy(asn1_params->iv, iv, i); + asn1_params->iv_len = i; - if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1)) - return -1; - } return i; } -int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_set_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { - int i = 0; - unsigned int j; - unsigned char *oiv = NULL; + if (type == NULL || asn1_params == NULL) + return 0; - if (type != NULL) { - oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c); - j = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(j <= sizeof(c->iv)); - i = ASN1_TYPE_set_octetstring(type, oiv, j); - } - return i; + return asn1_type_set_octetstring_int(type, asn1_params->tag_len, + asn1_params->iv, asn1_params->iv_len); } #endif /* !defined(FIPS_MODULE) */ @@ -436,6 +486,7 @@ int EVP_CIPHER_CTX_tag_length(const EVP_CIPHER_CTX *ctx) return ret == 1 ? (int)v : 0; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx) { int ok; @@ -460,7 +511,7 @@ const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; params[0] = - OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, (void **)&v, + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV_STATE, (void **)&v, sizeof(ctx->iv)); ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); @@ -474,12 +525,31 @@ unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; params[0] = - OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV, (void **)&v, + OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_IV_STATE, (void **)&v, sizeof(ctx->iv)); ok = evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); return ok != 0 ? v : NULL; } +#endif /* OPENSSL_NO_DEPRECATED_3_0_0 */ + +int EVP_CIPHER_CTX_get_iv_state(EVP_CIPHER_CTX *ctx, void *buf, size_t len) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV_STATE, buf, len); + return evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); +} + +int EVP_CIPHER_CTX_get_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len) +{ + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_IV, buf, len); + return evp_do_ciph_ctx_getparams(ctx->cipher, ctx->provctx, params); +} unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx) { @@ -619,14 +689,14 @@ const OSSL_PROVIDER *EVP_MD_provider(const EVP_MD *md) int EVP_MD_block_size(const EVP_MD *md) { int ok; - size_t v = md->block_size; + size_t v; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; if (md == NULL) { EVPerr(EVP_F_EVP_MD_BLOCK_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; } - + v = md->block_size; params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_BLOCK_SIZE, &v); ok = evp_do_md_getparams(md, params); @@ -646,14 +716,14 @@ int EVP_MD_pkey_type(const EVP_MD *md) int EVP_MD_size(const EVP_MD *md) { int ok; - size_t v = md->md_size; + size_t v; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; if (md == NULL) { EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); return -1; } - + v = md->md_size; params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &v); ok = evp_do_md_getparams(md, params); diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 99c53484a6..0112cdca02 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -69,34 +69,10 @@ struct evp_kdf_ctx_st { struct evp_rand_ctx_st { EVP_RAND *meth; /* Method structure */ void *data; /* Algorithm-specific data */ -} /* EVP_RAND_CTX */ ; - -struct evp_rand_st { - OSSL_PROVIDER *prov; - int name_id; - CRYPTO_REF_COUNT refcnt; + EVP_RAND_CTX *parent; /* Parent EVP_RAND or NULL if none */ + CRYPTO_REF_COUNT refcnt; /* Context reference count */ CRYPTO_RWLOCK *refcnt_lock; - - const OSSL_DISPATCH *dispatch; - OSSL_FUNC_rand_newctx_fn *newctx; - OSSL_FUNC_rand_freectx_fn *freectx; - OSSL_FUNC_rand_instantiate_fn *instantiate; - OSSL_FUNC_rand_uninstantiate_fn *uninstantiate; - OSSL_FUNC_rand_generate_fn *generate; - OSSL_FUNC_rand_reseed_fn *reseed; - OSSL_FUNC_rand_nonce_fn *nonce; - OSSL_FUNC_rand_enable_locking_fn *enable_locking; - OSSL_FUNC_rand_lock_fn *lock; - OSSL_FUNC_rand_unlock_fn *unlock; - OSSL_FUNC_rand_gettable_params_fn *gettable_params; - OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params; - OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params; - OSSL_FUNC_rand_get_params_fn *get_params; - OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params; - OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_rand_set_callbacks_fn *set_callbacks; - OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization; -} /* EVP_RAND */ ; +} /* EVP_RAND_CTX */ ; struct evp_keymgmt_st { int id; /* libcrypto internal */ @@ -208,6 +184,25 @@ struct evp_asym_cipher_st { OSSL_FUNC_asym_cipher_settable_ctx_params_fn *settable_ctx_params; } /* EVP_ASYM_CIPHER */; +struct evp_kem_st { + int name_id; + OSSL_PROVIDER *prov; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_kem_newctx_fn *newctx; + OSSL_FUNC_kem_encapsulate_init_fn *encapsulate_init; + OSSL_FUNC_kem_encapsulate_fn *encapsulate; + OSSL_FUNC_kem_decapsulate_init_fn *decapsulate_init; + OSSL_FUNC_kem_decapsulate_fn *decapsulate; + OSSL_FUNC_kem_freectx_fn *freectx; + OSSL_FUNC_kem_dupctx_fn *dupctx; + OSSL_FUNC_kem_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_kem_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_kem_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_kem_settable_ctx_params_fn *settable_ctx_params; +} /* EVP_KEM */; + int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, ASN1_TYPE *param, const EVP_CIPHER *c, const EVP_MD *md, @@ -237,21 +232,21 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len); #include #include -void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id, +void *evp_generic_fetch(OSSL_LIB_CTX *ctx, int operation_id, const char *name, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)); -void *evp_generic_fetch_by_number(OPENSSL_CTX *ctx, int operation_id, +void *evp_generic_fetch_by_number(OSSL_LIB_CTX *ctx, int operation_id, int name_id, const char *properties, void *(*new_method)(int name_id, const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov), int (*up_ref_method)(void *), void (*free_method)(void *)); -void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, +void evp_generic_do_all(OSSL_LIB_CTX *libctx, int operation_id, void (*user_fn)(void *method, void *arg), void *user_arg, void *(*new_method)(int name_id, @@ -260,13 +255,18 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, void (*free_method)(void *)); /* Internal fetchers for method types that are to be combined with others */ -EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, +EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OSSL_LIB_CTX *ctx, int name_id, const char *properties); /* Internal structure constructors for fetched methods */ EVP_MD *evp_md_new(void); EVP_CIPHER *evp_cipher_new(void); +int evp_cipher_get_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params); +int evp_cipher_set_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params); + /* Helper functions to avoid duplicating code */ /* diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c index a9f94bd5bc..b283b0a684 100644 --- a/crypto/evp/evp_pbe.c +++ b/crypto/evp/evp_pbe.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -114,6 +114,7 @@ int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, cipher = EVP_get_cipherbynid(cipher_nid); if (!cipher) { EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER); + ERR_add_error_data(1, OBJ_nid2sn(cipher_nid)); return 0; } } @@ -128,11 +129,7 @@ int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, } } - if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE); - return 0; - } - return 1; + return keygen(ctx, pass, passlen, param, cipher, md, en_de); } DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c index cfe0544ed6..9e7c978656 100644 --- a/crypto/evp/evp_pkey.c +++ b/crypto/evp/evp_pkey.c @@ -18,8 +18,8 @@ /* Extract a private key from a PKCS8 structure */ -EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx, - const char *propq) +EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, + const char *propq) { EVP_PKEY *pkey = NULL; const ASN1_OBJECT *algoid; @@ -40,11 +40,9 @@ EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx, goto error; } - if (pkey->ameth->priv_decode_with_libctx != NULL) { - if (!pkey->ameth->priv_decode_with_libctx(pkey, p8, libctx, propq)) { - EVPerr(0, EVP_R_PRIVATE_KEY_DECODE_ERROR); + if (pkey->ameth->priv_decode_ex != NULL) { + if (!pkey->ameth->priv_decode_ex(pkey, p8, libctx, propq)) goto error; - } } else if (pkey->ameth->priv_decode != NULL) { if (!pkey->ameth->priv_decode(pkey, p8)) { EVPerr(0, EVP_R_PRIVATE_KEY_DECODE_ERROR); @@ -64,7 +62,7 @@ EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx, EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) { - return evp_pkcs82pkey_int(p8, NULL, NULL); + return EVP_PKCS82PKEY_ex(p8, NULL, NULL); } /* Turn a private key into a PKCS8 structure */ @@ -77,6 +75,11 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey) return NULL; } + /* Force a key downgrade if that's possible */ + /* TODO(3.0) Is there a better way for provider-native keys? */ + if (EVP_PKEY_get0(pkey) == NULL) + return NULL; + if (pkey->ameth) { if (pkey->ameth->priv_encode) { if (!pkey->ameth->priv_encode(p8, pkey)) { @@ -158,3 +161,20 @@ int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, return 1; return 0; } + +const char *EVP_PKEY_get0_first_alg_name(const EVP_PKEY *key) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + const char *name = NULL; + + if (key->keymgmt != NULL) + return EVP_KEYMGMT_get0_first_name(key->keymgmt); + + /* Otherwise fallback to legacy */ + ameth = EVP_PKEY_get0_asn1(key); + if (ameth != NULL) + EVP_PKEY_asn1_get0_info(NULL, NULL, + NULL, NULL, &name, ameth); + + return name; +} diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index 9273fd9c19..44b648705c 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -25,6 +25,32 @@ #include "internal/provider.h" #include "evp_local.h" +struct evp_rand_st { + OSSL_PROVIDER *prov; + int name_id; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *refcnt_lock; + + const OSSL_DISPATCH *dispatch; + OSSL_FUNC_rand_newctx_fn *newctx; + OSSL_FUNC_rand_freectx_fn *freectx; + OSSL_FUNC_rand_instantiate_fn *instantiate; + OSSL_FUNC_rand_uninstantiate_fn *uninstantiate; + OSSL_FUNC_rand_generate_fn *generate; + OSSL_FUNC_rand_reseed_fn *reseed; + OSSL_FUNC_rand_nonce_fn *nonce; + OSSL_FUNC_rand_enable_locking_fn *enable_locking; + OSSL_FUNC_rand_lock_fn *lock; + OSSL_FUNC_rand_unlock_fn *unlock; + OSSL_FUNC_rand_gettable_params_fn *gettable_params; + OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params; + OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_rand_get_params_fn *get_params; + OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params; + OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params; + OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization; +} /* EVP_RAND */ ; + static int evp_rand_up_ref(void *vrand) { EVP_RAND *rand = (EVP_RAND *)vrand; @@ -144,11 +170,6 @@ static void *evp_rand_from_dispatch(int name_id, break; rand->nonce = OSSL_FUNC_rand_nonce(fns); break; - case OSSL_FUNC_RAND_SET_CALLBACKS: - if (rand->set_callbacks != NULL) - break; - rand->set_callbacks = OSSL_FUNC_rand_set_callbacks(fns); - break; case OSSL_FUNC_RAND_ENABLE_LOCKING: if (rand->enable_locking != NULL) break; @@ -242,7 +263,7 @@ static void *evp_rand_from_dispatch(int name_id, return rand; } -EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm, +EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties, @@ -287,6 +308,13 @@ int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]) return 1; } +static int evp_rand_ctx_up_ref(EVP_RAND_CTX *ctx) +{ + int ref = 0; + + return CRYPTO_UP_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); +} + EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) { EVP_RAND_CTX *ctx; @@ -299,13 +327,21 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) } ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { + if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(ctx); EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; } if (parent != NULL) { if (!EVP_RAND_enable_locking(parent)) { EVPerr(0, EVP_R_UNABLE_TO_ENABLE_PARENT_LOCKING); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + OPENSSL_free(ctx); + return NULL; + } + if (!evp_rand_ctx_up_ref(parent)) { + EVPerr(0, ERR_R_INTERNAL_ERROR); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); OPENSSL_free(ctx); return NULL; } @@ -317,20 +353,33 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) || !EVP_RAND_up_ref(rand)) { EVPerr(0, ERR_R_MALLOC_FAILURE); rand->freectx(ctx->data); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); OPENSSL_free(ctx); + EVP_RAND_CTX_free(parent); return NULL; } ctx->meth = rand; + ctx->parent = parent; + ctx->refcnt = 1; return ctx; } void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) { if (ctx != NULL) { - ctx->meth->freectx(ctx->data); - ctx->data = NULL; - EVP_RAND_free(ctx->meth); - OPENSSL_free(ctx); + int ref = 0; + + CRYPTO_DOWN_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); + if (ref <= 0) { + EVP_RAND_CTX *parent = ctx->parent; + + ctx->meth->freectx(ctx->data); + ctx->data = NULL; + EVP_RAND_free(ctx->meth); + CRYPTO_THREAD_lock_free(ctx->refcnt_lock); + OPENSSL_free(ctx); + EVP_RAND_CTX_free(parent); + } } } @@ -377,22 +426,28 @@ int EVP_RAND_set_ctx_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand) { - return rand->gettable_params == NULL ? NULL : rand->gettable_params(); + if (rand->gettable_params == NULL) + return NULL; + return rand->gettable_params(ossl_provider_ctx(EVP_RAND_provider(rand))); } const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand) { - return rand->gettable_ctx_params == NULL ? NULL - : rand->gettable_ctx_params(); + if (rand->gettable_ctx_params == NULL) + return NULL; + return rand->gettable_ctx_params( + ossl_provider_ctx(EVP_RAND_provider(rand))); } const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand) { - return rand->settable_ctx_params == NULL ? NULL - : rand->settable_ctx_params(); + if (rand->settable_ctx_params == NULL) + return NULL; + return rand->settable_ctx_params( + ossl_provider_ctx(EVP_RAND_provider(rand))); } -void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx, +void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_RAND *rand, void *arg), void *arg) { @@ -573,38 +628,6 @@ int EVP_RAND_state(EVP_RAND_CTX *ctx) return state; } -static int evp_rand_set_callbacks_locked(EVP_RAND_CTX *ctx, - OSSL_INOUT_CALLBACK *get_entropy, - OSSL_CALLBACK *cleanup_entropy, - OSSL_INOUT_CALLBACK *get_nonce, - OSSL_CALLBACK *cleanup_nonce, - void *arg) -{ - if (ctx->meth->set_callbacks == NULL) { - EVPerr(0, EVP_R_UNABLE_TO_SET_CALLBACKS); - return 0; - } - ctx->meth->set_callbacks(ctx->data, get_entropy, cleanup_entropy, - get_nonce, cleanup_nonce, arg); - return 1; -} - -int EVP_RAND_set_callbacks(EVP_RAND_CTX *ctx, - OSSL_INOUT_CALLBACK *get_entropy, - OSSL_CALLBACK *cleanup_entropy, - OSSL_INOUT_CALLBACK *get_nonce, - OSSL_CALLBACK *cleanup_nonce, void *arg) -{ - int res; - - if (!evp_rand_lock(ctx)) - return 0; - res = evp_rand_set_callbacks_locked(ctx, get_entropy, cleanup_entropy, - get_nonce, cleanup_nonce, arg); - evp_rand_unlock(ctx); - return res; -} - static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx) { if (ctx->meth->verify_zeroization != NULL) diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index 28e1f88db9..485ff28041 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -166,7 +166,7 @@ OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange) return exchange->prov; } -EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) { return evp_generic_fetch(ctx, OSSL_OP_KEYEXCH, algorithm, properties, @@ -197,16 +197,36 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) */ ERR_set_mark(); - if (ctx->keymgmt == NULL) + if (evp_pkey_ctx_is_legacy(ctx)) goto legacy; /* * Ensure that the key is provided, either natively, or as a cached export. - * If not, go legacy + * If not, goto legacy */ tmp_keymgmt = ctx->keymgmt; - provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, - &tmp_keymgmt, ctx->propquery); + if (ctx->pkey == NULL) { + /* + * Some algorithms (e.g. legacy KDFs) don't have a pkey - so we create + * a blank one. + */ + EVP_PKEY *pkey = EVP_PKEY_new(); + + if (pkey == NULL || !EVP_PKEY_set_type_by_keymgmt(pkey, tmp_keymgmt)) { + ERR_clear_last_mark(); + EVP_PKEY_free(pkey); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + provkey = pkey->keydata = evp_keymgmt_newdata(tmp_keymgmt); + if (provkey == NULL) + EVP_PKEY_free(pkey); + else + ctx->pkey = pkey; + } else { + provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + } if (provkey == NULL) goto legacy; if (!EVP_KEYMGMT_up_ref(tmp_keymgmt)) { @@ -437,7 +457,7 @@ int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name) return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name); } -void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx, +void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_KEYEXCH *keyexch, void *arg), void *arg) { @@ -454,3 +474,24 @@ void EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch, if (keyexch->prov != NULL) evp_names_do_all(keyexch->prov, keyexch->name_id, fn, data); } + +const OSSL_PARAM *EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH *keyexch) +{ + void *provctx; + + if (keyexch == NULL || keyexch->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_KEYEXCH_provider(keyexch)); + return keyexch->gettable_ctx_params(provctx); +} + +const OSSL_PARAM *EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH *keyexch) +{ + void *provctx; + + if (keyexch == NULL || keyexch->settable_ctx_params == NULL) + return NULL; + provctx = ossl_provider_ctx(EVP_KEYEXCH_provider(keyexch)); + return keyexch->settable_ctx_params(provctx); +} diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index d22bb39c82..9ccaec8cc1 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -88,6 +88,13 @@ int EVP_KDF_number(const EVP_KDF *kdf) return kdf->name_id; } +const char *EVP_KDF_name(const EVP_KDF *kdf) +{ + if (kdf->prov != NULL) + return evp_first_name(kdf->prov, kdf->name_id); + return NULL; +} + int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name) { return evp_is_a(kdf->prov, kdf->name_id, NULL, name); diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c index 9b5e01afa6..a89a8e9836 100644 --- a/crypto/evp/kdf_meth.c +++ b/crypto/evp/kdf_meth.c @@ -147,7 +147,7 @@ static void *evp_kdf_from_dispatch(int name_id, return kdf; } -EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, +EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_KDF, algorithm, properties, @@ -169,24 +169,24 @@ const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf) { if (kdf->gettable_params == NULL) return NULL; - return kdf->gettable_params(); + return kdf->gettable_params(ossl_provider_ctx(EVP_KDF_provider(kdf))); } const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf) { if (kdf->gettable_ctx_params == NULL) return NULL; - return kdf->gettable_ctx_params(); + return kdf->gettable_ctx_params(ossl_provider_ctx(EVP_KDF_provider(kdf))); } const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf) { if (kdf->settable_ctx_params == NULL) return NULL; - return kdf->settable_ctx_params(); + return kdf->settable_ctx_params(ossl_provider_ctx(EVP_KDF_provider(kdf))); } -void EVP_KDF_do_all_provided(OPENSSL_CTX *libctx, +void EVP_KDF_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_KDF *kdf, void *arg), void *arg) { diff --git a/crypto/evp/kem.c b/crypto/evp/kem.c new file mode 100644 index 0000000000..2e61d2061e --- /dev/null +++ b/crypto/evp/kem.c @@ -0,0 +1,380 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "crypto/evp.h" +#include "internal/provider.h" +#include "evp_local.h" + +static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation) +{ + int ret = 0; + EVP_KEM *kem = NULL; + EVP_KEYMGMT *tmp_keymgmt = NULL; + void *provkey = NULL; + const char *supported_kem = NULL; + + if (ctx == NULL || ctx->keytype == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + return 0; + } + + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = operation; + + /* + * Ensure that the key is provided, either natively, or as a cached export. + */ + tmp_keymgmt = ctx->keymgmt; + provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, + &tmp_keymgmt, ctx->propquery); + if (provkey == NULL + || !EVP_KEYMGMT_up_ref(tmp_keymgmt)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + EVP_KEYMGMT_free(ctx->keymgmt); + ctx->keymgmt = tmp_keymgmt; + + if (ctx->keymgmt->query_operation_name != NULL) + supported_kem = ctx->keymgmt->query_operation_name(OSSL_OP_KEM); + + /* + * If we didn't get a supported kem, assume there is one with the + * same name as the key type. + */ + if (supported_kem == NULL) + supported_kem = ctx->keytype; + + kem = EVP_KEM_fetch(ctx->libctx, supported_kem, ctx->propquery); + if (kem == NULL + || (EVP_KEYMGMT_provider(ctx->keymgmt) != EVP_KEM_provider(kem))) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + + ctx->op.encap.kem = kem; + ctx->op.encap.kemprovctx = kem->newctx(ossl_provider_ctx(kem->prov)); + if (ctx->op.encap.kemprovctx == NULL) { + /* The provider key can stay in the cache */ + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + switch (operation) { + case EVP_PKEY_OP_ENCAPSULATE: + if (kem->encapsulate_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = kem->encapsulate_init(ctx->op.encap.kemprovctx, provkey); + break; + case EVP_PKEY_OP_DECAPSULATE: + if (kem->decapsulate_init == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + ret = -2; + goto err; + } + ret = kem->decapsulate_init(ctx->op.encap.kemprovctx, provkey); + break; + default: + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + + if (ret > 0) + return 1; + err: + if (ret <= 0) { + evp_pkey_ctx_free_old_ops(ctx); + ctx->operation = EVP_PKEY_OP_UNDEFINED; + } + return ret; +} + +int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx) +{ + return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE); +} + +int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + unsigned char *secret, size_t *secretlen) +{ + if (ctx == NULL) + return 0; + + if (ctx->operation != EVP_PKEY_OP_ENCAPSULATE) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.encap.kemprovctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (out != NULL && secret == NULL) + return 0; + + return ctx->op.encap.kem->encapsulate(ctx->op.encap.kemprovctx, + out, outlen, secret, secretlen); +} + +int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx) +{ + return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE); +} + +int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, + unsigned char *secret, size_t *secretlen, + const unsigned char *in, size_t inlen) +{ + if (ctx == NULL + || (in == NULL || inlen == 0) + || (secret == NULL && secretlen == NULL)) + return 0; + + if (ctx->operation != EVP_PKEY_OP_DECAPSULATE) { + EVPerr(0, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ctx->op.encap.kemprovctx == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + return ctx->op.encap.kem->decapsulate(ctx->op.encap.kemprovctx, + secret, secretlen, in, inlen); +} + +static EVP_KEM *evp_kem_new(OSSL_PROVIDER *prov) +{ + EVP_KEM *kem = OPENSSL_zalloc(sizeof(EVP_KEM)); + + if (kem == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + kem->lock = CRYPTO_THREAD_lock_new(); + if (kem->lock == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + OPENSSL_free(kem); + return NULL; + } + kem->prov = prov; + ossl_provider_up_ref(prov); + kem->refcnt = 1; + + return kem; +} + +static void *evp_kem_from_dispatch(int name_id, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) +{ + EVP_KEM *kem = NULL; + int ctxfncnt = 0, encfncnt = 0, decfncnt = 0; + int gparamfncnt = 0, sparamfncnt = 0; + + if ((kem = evp_kem_new(prov)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + kem->name_id = name_id; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_KEM_NEWCTX: + if (kem->newctx != NULL) + break; + kem->newctx = OSSL_FUNC_kem_newctx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_KEM_ENCAPSULATE_INIT: + if (kem->encapsulate_init != NULL) + break; + kem->encapsulate_init = OSSL_FUNC_kem_encapsulate_init(fns); + encfncnt++; + break; + case OSSL_FUNC_KEM_ENCAPSULATE: + if (kem->encapsulate != NULL) + break; + kem->encapsulate = OSSL_FUNC_kem_encapsulate(fns); + encfncnt++; + break; + case OSSL_FUNC_KEM_DECAPSULATE_INIT: + if (kem->decapsulate_init != NULL) + break; + kem->decapsulate_init = OSSL_FUNC_kem_decapsulate_init(fns); + decfncnt++; + break; + case OSSL_FUNC_KEM_DECAPSULATE: + if (kem->decapsulate != NULL) + break; + kem->decapsulate = OSSL_FUNC_kem_decapsulate(fns); + decfncnt++; + break; + case OSSL_FUNC_KEM_FREECTX: + if (kem->freectx != NULL) + break; + kem->freectx = OSSL_FUNC_kem_freectx(fns); + ctxfncnt++; + break; + case OSSL_FUNC_KEM_DUPCTX: + if (kem->dupctx != NULL) + break; + kem->dupctx = OSSL_FUNC_kem_dupctx(fns); + break; + case OSSL_FUNC_KEM_GET_CTX_PARAMS: + if (kem->get_ctx_params != NULL) + break; + kem->get_ctx_params + = OSSL_FUNC_kem_get_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS: + if (kem->gettable_ctx_params != NULL) + break; + kem->gettable_ctx_params + = OSSL_FUNC_kem_gettable_ctx_params(fns); + gparamfncnt++; + break; + case OSSL_FUNC_KEM_SET_CTX_PARAMS: + if (kem->set_ctx_params != NULL) + break; + kem->set_ctx_params + = OSSL_FUNC_kem_set_ctx_params(fns); + sparamfncnt++; + break; + case OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS: + if (kem->settable_ctx_params != NULL) + break; + kem->settable_ctx_params + = OSSL_FUNC_kem_settable_ctx_params(fns); + sparamfncnt++; + break; + } + } + if (ctxfncnt != 2 + || (encfncnt != 0 && encfncnt != 2) + || (decfncnt != 0 && decfncnt != 2) + || (encfncnt != 2 && decfncnt != 2) + || (gparamfncnt != 0 && gparamfncnt != 2) + || (sparamfncnt != 0 && sparamfncnt != 2)) { + /* + * In order to be a consistent set of functions we must have at least + * a set of context functions (newctx and freectx) as well as a pair of + * "kem" functions: (encapsulate_init, encapsulate) or + * (decapsulate_init, decapsulate). set_ctx_params and settable_ctx_params are + * optional, but if one of them is present then the other one must also + * be present. The same applies to get_ctx_params and + * gettable_ctx_params. The dupctx function is optional. + */ + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); + goto err; + } + + return kem; + err: + EVP_KEM_free(kem); + return NULL; +} + +void EVP_KEM_free(EVP_KEM *kem) +{ + if (kem != NULL) { + int i; + + CRYPTO_DOWN_REF(&kem->refcnt, &i, kem->lock); + if (i > 0) + return; + ossl_provider_free(kem->prov); + CRYPTO_THREAD_lock_free(kem->lock); + OPENSSL_free(kem); + } +} + +int EVP_KEM_up_ref(EVP_KEM *kem) +{ + int ref = 0; + + CRYPTO_UP_REF(&kem->refcnt, &ref, kem->lock); + return 1; +} + +OSSL_PROVIDER *EVP_KEM_provider(const EVP_KEM *kem) +{ + return kem->prov; +} + +EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties) +{ + return evp_generic_fetch(ctx, OSSL_OP_KEM, algorithm, properties, + evp_kem_from_dispatch, + (int (*)(void *))EVP_KEM_up_ref, + (void (*)(void *))EVP_KEM_free); +} + +int EVP_KEM_is_a(const EVP_KEM *kem, const char *name) +{ + return evp_is_a(kem->prov, kem->name_id, NULL, name); +} + +int EVP_KEM_number(const EVP_KEM *kem) +{ + return kem->name_id; +} + +void EVP_KEM_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_KEM *kem, void *arg), + void *arg) +{ + evp_generic_do_all(libctx, OSSL_OP_KEM, (void (*)(void *, void *))fn, arg, + evp_kem_from_dispatch, + (void (*)(void *))EVP_KEM_free); +} + +void EVP_KEM_names_do_all(const EVP_KEM *kem, + void (*fn)(const char *name, void *data), + void *data) +{ + if (kem->prov != NULL) + evp_names_do_all(kem->prov, kem->name_id, fn, data); +} + +const OSSL_PARAM *EVP_KEM_gettable_ctx_params(const EVP_KEM *kem) +{ + void *provctx; + + if (kem == NULL || kem->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_KEM_provider(kem)); + return kem->gettable_ctx_params(provctx); +} + +const OSSL_PARAM *EVP_KEM_settable_ctx_params(const EVP_KEM *kem) +{ + void *provctx; + + if (kem == NULL || kem->settable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_KEM_provider(kem)); + return kem->settable_ctx_params(provctx); +} diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 5ef4115f47..763982e58f 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -77,6 +77,13 @@ EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata) return pkey; } +int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + return evp_keymgmt_export(pk->keymgmt, pk->keydata, selection, + export_cb, export_cbarg); +} + void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) { struct evp_keymgmt_util_try_import_data_st import_data; @@ -139,8 +146,8 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt) * The export function calls the callback (evp_keymgmt_util_try_import), * which does the import for us. If successful, we're done. */ - if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, OSSL_KEYMGMT_SELECT_ALL, - &evp_keymgmt_util_try_import, &import_data)) { + if (!evp_keymgmt_util_export(pk, OSSL_KEYMGMT_SELECT_ALL, + &evp_keymgmt_util_try_import, &import_data)) { /* If there was an error, bail out */ evp_keymgmt_freedata(keymgmt, import_data.keydata); return NULL; @@ -392,8 +399,9 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) import_data.keydata = to_keydata; import_data.selection = selection; - if (!evp_keymgmt_export(from->keymgmt, from->keydata, selection, - &evp_keymgmt_util_try_import, &import_data)) { + if (!evp_keymgmt_util_export(from, selection, + &evp_keymgmt_util_try_import, + &import_data)) { evp_keymgmt_freedata(to_keymgmt, alloc_keydata); return 0; } diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index 47067dd6c7..66cef52144 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -16,7 +16,6 @@ #include "crypto/evp.h" #include "evp_local.h" - static void *keymgmt_new(void) { EVP_KEYMGMT *keymgmt = NULL; @@ -198,7 +197,7 @@ static void *keymgmt_from_dispatch(int name_id, return keymgmt; } -EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, +EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OSSL_LIB_CTX *ctx, int name_id, const char *properties) { return evp_generic_fetch_by_number(ctx, @@ -208,7 +207,7 @@ EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, (void (*)(void *))EVP_KEYMGMT_free); } -EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) { return evp_generic_fetch(ctx, OSSL_OP_KEYMGMT, algorithm, properties, @@ -250,12 +249,17 @@ int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt) return keymgmt->name_id; } +const char *EVP_KEYMGMT_get0_first_name(const EVP_KEYMGMT *keymgmt) +{ + return evp_first_name(keymgmt->prov, keymgmt->name_id); +} + int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name) { return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name); } -void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx, +void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_KEYMGMT *keymgmt, void *arg), void *arg) { @@ -328,7 +332,7 @@ int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, return keymgmt->gen_set_params(genctx, params); } -const OSSL_PARAM *evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt) +const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt) { void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); @@ -367,11 +371,13 @@ int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, return keymgmt->get_params(keydata, params); } -const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt) +const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt) { + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + if (keymgmt->gettable_params == NULL) return NULL; - return keymgmt->gettable_params(); + return keymgmt->gettable_params(provctx); } int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata, @@ -382,11 +388,13 @@ int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata, return keymgmt->set_params(keydata, params); } -const OSSL_PARAM *evp_keymgmt_settable_params(const EVP_KEYMGMT *keymgmt) +const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt) { + void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt)); + if (keymgmt->settable_params == NULL) return NULL; - return keymgmt->settable_params(); + return keymgmt->settable_params(provctx); } int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keydata, int selection) diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 8d37f19d6c..c1bddcb946 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -38,8 +38,8 @@ static const char *canon_mdname(const char *mdname) static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, const char *mdname, - const char *props, ENGINE *e, EVP_PKEY *pkey, - OPENSSL_CTX *libctx, int ver) + OSSL_LIB_CTX *libctx, const char *props, + ENGINE *e, EVP_PKEY *pkey, int ver) { EVP_PKEY_CTX *locpctx = NULL; EVP_SIGNATURE *signature = NULL; @@ -80,7 +80,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, */ ERR_set_mark(); - if (locpctx->engine != NULL || locpctx->keytype == NULL) + if (evp_pkey_ctx_is_legacy(locpctx)) goto legacy; /* @@ -172,13 +172,18 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, locmdname, sizeof(locmdname)) > 0) { mdname = canon_mdname(locmdname); - } else { - EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); - return 0; } } if (mdname != NULL) { + /* + * We're about to get a new digest so clear anything associated with + * an old digest. + */ + evp_md_ctx_clear_digest(ctx, 1); + + /* legacy code support for engines */ + ERR_set_mark(); /* * This might be requested by a later call to EVP_MD_CTX_md(). * In that case the "explicit fetch" rules apply for that @@ -186,8 +191,19 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, * so the EVP_MD should not be used beyound the lifetime of the * EVP_MD_CTX. */ - ctx->reqdigest = ctx->fetched_digest = - EVP_MD_fetch(locpctx->libctx, mdname, props); + ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props); + if (ctx->fetched_digest != NULL) { + ctx->digest = ctx->reqdigest = ctx->fetched_digest; + } else { + /* legacy engine support : remove the mark when this is deleted */ + ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname); + if (ctx->digest == NULL) { + (void)ERR_clear_last_mark(); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + (void)ERR_pop_to_mark(); } } @@ -207,7 +223,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, mdname, provkey); } - return ret ? 1 : 0; + goto end; + err: evp_pkey_ctx_free_old_ops(locpctx); locpctx->operation = EVP_PKEY_OP_UNDEFINED; @@ -282,34 +299,41 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, if (ctx->pctx->pmeth->digest_custom != NULL) ctx->pctx->flag_call_digest_custom = 1; - return 1; + ret = 1; + + end: +#ifndef FIPS_MODULE + if (ret > 0) + ret = evp_pkey_ctx_use_cached_data(locpctx); +#endif + + return ret > 0 ? 1 : 0; } int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, EVP_PKEY *pkey, - OPENSSL_CTX *libctx) + const char *mdname, OSSL_LIB_CTX *libctx, + const char *props, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, libctx, - 0); + return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 0); } int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 0); + return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 0); } int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, - EVP_PKEY *pkey, OPENSSL_CTX *libctx) + const char *mdname, OSSL_LIB_CTX *libctx, + const char *props, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, libctx, 1); + return do_sigver_init(ctx, pctx, NULL, mdname, libctx, props, NULL, pkey, 1); } int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) { - return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 1); + return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1); } #endif /* FIPS_MDOE */ diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index a5c1b44666..d76ffedcb8 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -112,19 +112,19 @@ int EVP_MAC_init(EVP_MAC_CTX *ctx) int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen) { - if (datalen == 0) - return 1; return ctx->meth->update(ctx->data, data, datalen); } int EVP_MAC_final(EVP_MAC_CTX *ctx, unsigned char *out, size_t *outl, size_t outsize) { - size_t l = EVP_MAC_size(ctx); + size_t l; int res = 1; if (out != NULL) res = ctx->meth->final(ctx->data, out, &l, outsize); + else + l = EVP_MAC_size(ctx); if (outl != NULL) *outl = l; return res; @@ -162,6 +162,13 @@ int EVP_MAC_number(const EVP_MAC *mac) return mac->name_id; } +const char *EVP_MAC_name(const EVP_MAC *mac) +{ + if (mac->prov != NULL) + return evp_first_name(mac->prov, mac->name_id); + return NULL; +} + int EVP_MAC_is_a(const EVP_MAC *mac, const char *name) { return evp_is_a(mac->prov, mac->name_id, NULL, name); diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c index d96383a961..c2b7c5c613 100644 --- a/crypto/evp/mac_meth.c +++ b/crypto/evp/mac_meth.c @@ -149,7 +149,7 @@ static void *evp_mac_from_dispatch(int name_id, return mac; } -EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, +EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties) { return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties, @@ -176,24 +176,24 @@ const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac) { if (mac->gettable_params == NULL) return NULL; - return mac->gettable_params(); + return mac->gettable_params(ossl_provider_ctx(EVP_MAC_provider(mac))); } const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac) { if (mac->gettable_ctx_params == NULL) return NULL; - return mac->gettable_ctx_params(); + return mac->gettable_ctx_params(ossl_provider_ctx(EVP_MAC_provider(mac))); } const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac) { if (mac->settable_ctx_params == NULL) return NULL; - return mac->settable_ctx_params(); + return mac->settable_ctx_params(ossl_provider_ctx(EVP_MAC_provider(mac))); } -void EVP_MAC_do_all_provided(OPENSSL_CTX *libctx, +void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_MAC *mac, void *arg), void *arg) { diff --git a/crypto/evp/names.c b/crypto/evp/names.c index 5eb7a39ae0..cb59813857 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -72,7 +72,8 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) return evp_get_cipherbyname_ex(NULL, name); } -const EVP_CIPHER *evp_get_cipherbyname_ex(OPENSSL_CTX *libctx, const char *name) +const EVP_CIPHER *evp_get_cipherbyname_ex(OSSL_LIB_CTX *libctx, + const char *name) { const EVP_CIPHER *cp; OSSL_NAMEMAP *namemap; @@ -117,7 +118,7 @@ const EVP_MD *EVP_get_digestbyname(const char *name) return evp_get_digestbyname_ex(NULL, name); } -const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name) +const EVP_MD *evp_get_digestbyname_ex(OSSL_LIB_CTX *libctx, const char *name) { const EVP_MD *dp; OSSL_NAMEMAP *namemap; diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c index 4e9603757b..7e9a80e5c0 100644 --- a/crypto/evp/p5_crpt.c +++ b/crypto/evp/p5_crpt.c @@ -91,7 +91,7 @@ int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, goto err; mdsize = EVP_MD_size(md); if (mdsize < 0) - return 0; + goto err; for (i = 1; i < iter; i++) { if (!EVP_DigestInit_ex(ctx, md, NULL)) goto err; diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c index 6e89ffd999..830a97dde2 100644 --- a/crypto/evp/p5_crpt2.c +++ b/crypto/evp/p5_crpt2.c @@ -19,9 +19,10 @@ #include "crypto/evp.h" #include "evp_local.h" -int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - const EVP_MD *digest, int keylen, unsigned char *out) +int pkcs5_pbkdf2_hmac_ex(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out, + OSSL_LIB_CTX *libctx, const char *propq) { const char *empty = ""; int rv = 1, mode = 1; @@ -40,7 +41,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, if (salt == NULL && saltlen == 0) salt = (unsigned char *)empty; - kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF2, NULL); + kdf = EVP_KDF_fetch(libctx, OSSL_KDF_NAME_PBKDF2, propq); kctx = EVP_KDF_CTX_new(kdf); EVP_KDF_free(kdf); if (kctx == NULL) @@ -78,6 +79,15 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, return rv; } +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, + int saltlen, int iter, const EVP_MD *digest, int keylen, + unsigned char *out) +{ + return pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, iter, digest, + keylen, out, NULL, NULL); +} + + int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, int keylen, unsigned char *out) diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 3e3f2118a2..cc30bc3495 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include "crypto/asn1.h" @@ -38,7 +38,6 @@ #include "internal/evp.h" #include "internal/provider.h" #include "evp_local.h" -DEFINE_STACK_OF(X509_ATTRIBUTE) #include "crypto/ec.h" @@ -269,15 +268,17 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b, if (keymgmt1 != keymgmt2) return -2; + /* If the keymgmt implementations are NULL, the export failed */ + if (keymgmt1 == NULL) + return -2; + return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); } -#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { return EVP_PKEY_parameters_eq(a, b); } -#endif int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b) { @@ -297,12 +298,10 @@ int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } -#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { return EVP_PKEY_eq(a, b); } -#endif int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b) { @@ -336,7 +335,7 @@ int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b) } -static EVP_PKEY *new_raw_key_int(OPENSSL_CTX *libctx, +static EVP_PKEY *new_raw_key_int(OSSL_LIB_CTX *libctx, const char *strtype, const char *propq, int nidtype, @@ -377,10 +376,8 @@ static EVP_PKEY *new_raw_key_int(OPENSSL_CTX *libctx, strtype != NULL ? strtype : OBJ_nid2sn(nidtype), propq); - if (ctx == NULL) { - EVPerr(0, ERR_R_MALLOC_FAILURE); + if (ctx == NULL) goto err; - } /* May fail if no provider available */ ERR_set_mark(); if (EVP_PKEY_key_fromdata_init(ctx) == 1) { @@ -453,11 +450,10 @@ static EVP_PKEY *new_raw_key_int(OPENSSL_CTX *libctx, return pkey; } -EVP_PKEY *EVP_PKEY_new_raw_private_key_with_libctx(OPENSSL_CTX *libctx, - const char *keytype, - const char *propq, - const unsigned char *priv, - size_t len) +EVP_PKEY *EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX *libctx, + const char *keytype, + const char *propq, + const unsigned char *priv, size_t len) { return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, priv, len, 1); @@ -470,11 +466,9 @@ EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, return new_raw_key_int(NULL, NULL, NULL, type, e, priv, len, 1); } -EVP_PKEY *EVP_PKEY_new_raw_public_key_with_libctx(OPENSSL_CTX *libctx, - const char *keytype, - const char *propq, - const unsigned char *pub, - size_t len) +EVP_PKEY *EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX *libctx, + const char *keytype, const char *propq, + const unsigned char *pub, size_t len) { return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, pub, len, 0); @@ -525,9 +519,8 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, raw_key.len = len; raw_key.selection = OSSL_KEYMGMT_SELECT_PRIVATE_KEY; - return evp_keymgmt_export(pkey->keymgmt, pkey->keydata, - OSSL_KEYMGMT_SELECT_PRIVATE_KEY, - get_raw_key_details, &raw_key); + return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, + get_raw_key_details, &raw_key); } if (pkey->ameth == NULL) { @@ -558,9 +551,8 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, raw_key.len = len; raw_key.selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY; - return evp_keymgmt_export(pkey->keymgmt, pkey->keydata, - OSSL_KEYMGMT_SELECT_PUBLIC_KEY, - get_raw_key_details, &raw_key); + return evp_keymgmt_util_export(pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + get_raw_key_details, &raw_key); } if (pkey->ameth == NULL) { @@ -582,64 +574,79 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, return 1; } -EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, - size_t len, const EVP_CIPHER *cipher) +static EVP_PKEY *new_cmac_key_int(const unsigned char *priv, size_t len, + const char *cipher_name, + const EVP_CIPHER *cipher, + OSSL_LIB_CTX *libctx, + const char *propq, ENGINE *e) { # ifndef OPENSSL_NO_CMAC # ifndef OPENSSL_NO_ENGINE const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL; # endif - const char *cipher_name = EVP_CIPHER_name(cipher); - const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher); - OPENSSL_CTX *libctx = - prov == NULL ? NULL : ossl_provider_library_context(prov); - EVP_PKEY *ret = EVP_PKEY_new(); - EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL); - EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL; - OSSL_PARAM params[4]; - size_t paramsn = 0; - - if (ret == NULL - || cmctx == NULL - || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1, NULL)) { - /* EVPerr already called */ + OSSL_PARAM params[5], *p = params; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx; + + if (cipher != NULL) + cipher_name = EVP_CIPHER_name(cipher); + + if (cipher_name == NULL) { + EVPerr(0, EVP_R_KEY_SETUP_FAILED); + return NULL; + } + + ctx = EVP_PKEY_CTX_new_from_name(libctx, "CMAC", propq); + if (ctx == NULL) + goto err; + + if (!EVP_PKEY_key_fromdata_init(ctx)) { + EVPerr(0, EVP_R_KEY_SETUP_FAILED); goto err; } + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, + (void *)priv, len); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER, + (char *)cipher_name, 0); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, + (char *)propq, 0); # ifndef OPENSSL_NO_ENGINE if (engine_id != NULL) - params[paramsn++] = - OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_ENGINE, + (char *)engine_id, 0); # endif + *p = OSSL_PARAM_construct_end(); - params[paramsn++] = - OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, - (char *)cipher_name, 0); - params[paramsn++] = - OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, - (char *)priv, len); - params[paramsn] = OSSL_PARAM_construct_end(); - - if (!EVP_MAC_CTX_set_params(cmctx, params)) { - EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); + if (!EVP_PKEY_fromdata(ctx, &pkey, params)) { + EVPerr(0, EVP_R_KEY_SETUP_FAILED); goto err; } - ret->pkey.ptr = cmctx; - return ret; - err: - EVP_PKEY_free(ret); - EVP_MAC_CTX_free(cmctx); - EVP_MAC_free(cmac); - return NULL; + EVP_PKEY_CTX_free(ctx); + + return pkey; # else - EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return NULL; # endif } +EVP_PKEY *EVP_PKEY_new_CMAC_key_ex(const unsigned char *priv, size_t len, + const char *cipher_name, OSSL_LIB_CTX *libctx, + const char *propq) +{ + return new_cmac_key_int(priv, len, cipher_name, NULL, libctx, propq, NULL); +} + +EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, + size_t len, const EVP_CIPHER *cipher) +{ + return new_cmac_key_int(priv, len, NULL, cipher, NULL, NULL, e); +} + int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { return pkey_set_type(pkey, NULL, type, NULL, -1, NULL); @@ -650,8 +657,19 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) { + if (!evp_pkey_is_legacy(pkey)) { + const char *name = OBJ_nid2sn(type); + + if (name != NULL && EVP_PKEY_is_a(pkey, name)) + return 1; + + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return 0; + } + if (pkey->type == type) { return 1; /* it already is that type */ } @@ -668,6 +686,7 @@ int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type) pkey->type = type; return 1; } +#endif # ifndef OPENSSL_NO_ENGINE int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e) @@ -698,7 +717,7 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) int alias = type; #ifndef OPENSSL_NO_EC - if (EVP_PKEY_type(type) == EVP_PKEY_EC) { + if ((key != NULL) && (EVP_PKEY_type(type) == EVP_PKEY_EC)) { const EC_GROUP *group = EC_KEY_get0_group(key); if (group != NULL && EC_GROUP_get_curve_name(group) == NID_sm2) @@ -716,6 +735,8 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) void *EVP_PKEY_get0(const EVP_PKEY *pkey) { + if (pkey == NULL) + return NULL; if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); return NULL; @@ -857,15 +878,7 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) return ret; } -static int EVP_PKEY_set1_ECX_KEY(EVP_PKEY *pkey, int type, ECX_KEY *key) -{ - int ret = EVP_PKEY_assign(pkey, type, key); - if (ret) - ecx_key_up_ref(key); - return ret; -} - -static ECX_KEY *EVP_PKEY_get0_ECX_KEY(const EVP_PKEY *pkey, int type) +static ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type) { if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) { ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY); @@ -878,26 +891,18 @@ static ECX_KEY *EVP_PKEY_get0_ECX_KEY(const EVP_PKEY *pkey, int type) return pkey->pkey.ecx; } -static ECX_KEY *EVP_PKEY_get1_ECX_KEY(EVP_PKEY *pkey, int type) +static ECX_KEY *evp_pkey_get1_ECX_KEY(EVP_PKEY *pkey, int type) { - ECX_KEY *ret = EVP_PKEY_get0_ECX_KEY(pkey, type); + ECX_KEY *ret = evp_pkey_get0_ECX_KEY(pkey, type); if (ret != NULL) ecx_key_up_ref(ret); return ret; } # define IMPLEMENT_ECX_VARIANT(NAME) \ - int EVP_PKEY_set1_##NAME(EVP_PKEY *pkey, ECX_KEY *key) \ - { \ - return EVP_PKEY_set1_ECX_KEY(pkey, EVP_PKEY_##NAME, key); \ - } \ - ECX_KEY *EVP_PKEY_get0_##NAME(const EVP_PKEY *pkey) \ + ECX_KEY *evp_pkey_get1_##NAME(EVP_PKEY *pkey) \ { \ - return EVP_PKEY_get0_ECX_KEY(pkey, EVP_PKEY_##NAME); \ - } \ - ECX_KEY *EVP_PKEY_get1_##NAME(EVP_PKEY *pkey) \ - { \ - return EVP_PKEY_get1_ECX_KEY(pkey, EVP_PKEY_##NAME); \ + return evp_pkey_get1_ECX_KEY(pkey, EVP_PKEY_##NAME); \ } IMPLEMENT_ECX_VARIANT(X25519) IMPLEMENT_ECX_VARIANT(X448) @@ -966,54 +971,83 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey) return EVP_PKEY_type(pkey->type); } +#ifndef FIPS_MODULE +int evp_pkey_name2type(const char *name) +{ + /* + * These hard coded cases are pure hackery to get around the fact + * that names in crypto/objects/objects.txt are a mess. There is + * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's + * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1, + * the NID of which is used for EVP_PKEY_RSA. Strangely enough, + * "DSA" is accurate... but still, better be safe and hard-code + * names that we know. + * On a similar topic, EVP_PKEY_type(EVP_PKEY_SM2) will result in + * EVP_PKEY_EC, because of aliasing. + * TODO Clean this away along with all other #legacy support. + */ + int type = NID_undef; + + if (strcasecmp(name, "RSA") == 0) + type = EVP_PKEY_RSA; + else if (strcasecmp(name, "RSA-PSS") == 0) + type = EVP_PKEY_RSA_PSS; + else if (strcasecmp(name, "EC") == 0) + type = EVP_PKEY_EC; + else if (strcasecmp(name, "ED25519") == 0) + type = EVP_PKEY_ED25519; + else if (strcasecmp(name, "ED448") == 0) + type = EVP_PKEY_ED448; + else if (strcasecmp(name, "X25519") == 0) + type = EVP_PKEY_X25519; + else if (strcasecmp(name, "X448") == 0) + type = EVP_PKEY_X448; + else if (strcasecmp(name, "SM2") == 0) + type = EVP_PKEY_SM2; + else if (strcasecmp(name, "DH") == 0) + type = EVP_PKEY_DH; + else if (strcasecmp(name, "X9.42 DH") == 0) + type = EVP_PKEY_DHX; + else if (strcasecmp(name, "DSA") == 0) + type = EVP_PKEY_DSA; + + if (type == NID_undef) + type = EVP_PKEY_type(OBJ_sn2nid(name)); + if (type == NID_undef) + type = EVP_PKEY_type(OBJ_ln2nid(name)); + + return type; +} +#endif + int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name) { #ifndef FIPS_MODULE if (pkey->keymgmt == NULL) { - /* - * These hard coded cases are pure hackery to get around the fact - * that names in crypto/objects/objects.txt are a mess. There is - * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's - * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1, - * the NID of which is used for EVP_PKEY_RSA. Strangely enough, - * "DSA" is accurate... but still, better be safe and hard-code - * names that we know. - * TODO Clean this away along with all other #legacy support. - */ - int type; + int type = evp_pkey_name2type(name); - if (strcasecmp(name, "RSA") == 0) - type = EVP_PKEY_RSA; - else if (strcasecmp(name, "RSA-PSS") == 0) - type = EVP_PKEY_RSA_PSS; -#ifndef OPENSSL_NO_EC - else if (strcasecmp(name, "EC") == 0) - type = EVP_PKEY_EC; - else if (strcasecmp(name, "ED25519") == 0) - type = EVP_PKEY_ED25519; - else if (strcasecmp(name, "ED448") == 0) - type = EVP_PKEY_ED448; - else if (strcasecmp(name, "X25519") == 0) - type = EVP_PKEY_X25519; - else if (strcasecmp(name, "X448") == 0) - type = EVP_PKEY_X448; -#endif -#ifndef OPENSSL_NO_DH - else if (strcasecmp(name, "DH") == 0) - type = EVP_PKEY_DH; -#endif -#ifndef OPENSSL_NO_DSA - else if (strcasecmp(name, "DSA") == 0) - type = EVP_PKEY_DSA; -#endif - else - type = EVP_PKEY_type(OBJ_sn2nid(name)); - return EVP_PKEY_type(pkey->type) == type; + return pkey->type == type; } #endif return EVP_KEYMGMT_is_a(pkey->keymgmt, name); } +void EVP_PKEY_typenames_do_all(const EVP_PKEY *pkey, + void (*fn)(const char *name, void *data), + void *data) +{ + if (!evp_pkey_is_typed(pkey)) + return; + + if (!evp_pkey_is_provided(pkey)) { + const char *name = OBJ_nid2sn(EVP_PKEY_id(pkey)); + + fn(name, data); + return; + } + EVP_KEYMGMT_names_do_all(pkey->keymgmt, fn, data); +} + int EVP_PKEY_can_sign(const EVP_PKEY *pkey) { if (pkey->keymgmt == NULL) { @@ -1036,7 +1070,7 @@ int EVP_PKEY_can_sign(const EVP_PKEY *pkey) } } else { const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt); - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); const char *supported_sig = pkey->keymgmt->query_operation_name != NULL ? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE) @@ -1082,9 +1116,9 @@ int evp_pkey_get_EC_KEY_curve_nid(const EVP_PKEY *pkey) } else if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "SM2")) { char *curve_name = NULL; - ret = evp_keymgmt_export(pkey->keymgmt, pkey->keydata, - OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, - get_ec_curve_name_cb, &curve_name); + ret = evp_keymgmt_util_export(pkey, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + get_ec_curve_name_cb, &curve_name); if (ret) ret = ec_curve_name2nid(curve_name); OPENSSL_free(curve_name); @@ -1137,23 +1171,26 @@ static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, } static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent, - const char *propquery /* For provided serialization */, + int selection /* For provided encoding */, + OSSL_LIB_CTX *libctx /* For provided encoding */, + const char *propquery /* For provided encoding */, int (*legacy_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx), ASN1_PCTX *legacy_pctx /* For legacy print */) { int pop_f_prefix; long saved_indent; - OSSL_SERIALIZER_CTX *ctx = NULL; + OSSL_ENCODER_CTX *ctx = NULL; int ret = -2; /* default to unsupported */ if (!print_set_indent(&out, &pop_f_prefix, &saved_indent, indent)) return 0; - ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, propquery); - if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL) - ret = OSSL_SERIALIZER_to_bio(ctx, out); - OSSL_SERIALIZER_CTX_free(ctx); + ctx = OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, "TEXT", selection, + libctx, propquery); + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) + ret = OSSL_ENCODER_to_bio(ctx, out); + OSSL_ENCODER_CTX_free(ctx); if (ret != -2) goto end; @@ -1172,7 +1209,10 @@ static int print_pkey(const EVP_PKEY *pkey, BIO *out, int indent, int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ, + return print_pkey(pkey, out, indent, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS + | OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + NULL, NULL, (pkey->ameth != NULL ? pkey->ameth->pub_print : NULL), pctx); } @@ -1180,7 +1220,10 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - return print_pkey(pkey, out, indent, OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ, + return print_pkey(pkey, out, indent, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS + | OSSL_KEYMGMT_SELECT_KEYPAIR, + NULL, NULL, (pkey->ameth != NULL ? pkey->ameth->priv_print : NULL), pctx); } @@ -1188,7 +1231,8 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - return print_pkey(pkey, out, indent, OSSL_SERIALIZER_Parameters_TO_TEXT_PQ, + return print_pkey(pkey, out, indent, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + NULL, NULL, (pkey->ameth != NULL ? pkey->ameth->param_print : NULL), pctx); } @@ -1202,19 +1246,18 @@ static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op, case ASN1_PKEY_CTRL_DEFAULT_MD_NID: { char mdname[80] = ""; - int nid; int rv = EVP_PKEY_get_default_digest_name(pkey, mdname, sizeof(mdname)); - if (rv <= 0) - return rv; - nid = OBJ_sn2nid(mdname); - if (nid == NID_undef) - nid = OBJ_ln2nid(mdname); - if (nid == NID_undef) - return 0; - *(int *)arg2 = nid; - return 1; + if (rv > 0) { + int nid; + + nid = OBJ_sn2nid(mdname); + if (nid == NID_undef) + nid = OBJ_ln2nid(mdname); + *(int *)arg2 = nid; + } + return rv; } default: return -2; @@ -1337,6 +1380,32 @@ size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt) /*- All methods below can also be used in FIPS_MODULE */ +/* + * This reset function must be used very carefully, as it literally throws + * away everything in an EVP_PKEY without freeing them, and may cause leaks + * of memory, locks, what have you. + * The only reason we have this is to have the same code for EVP_PKEY_new() + * and evp_pkey_downgrade(). + */ +static int evp_pkey_reset_unlocked(EVP_PKEY *pk) +{ + if (pk == NULL) + return 0; + + memset(pk, 0, sizeof(*pk)); + pk->type = EVP_PKEY_NONE; + pk->save_type = EVP_PKEY_NONE; + pk->references = 1; + pk->save_parameters = 1; + + pk->lock = CRYPTO_THREAD_lock_new(); + if (pk->lock == NULL) { + EVPerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + EVP_PKEY *EVP_PKEY_new(void) { EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -1345,15 +1414,10 @@ EVP_PKEY *EVP_PKEY_new(void) EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); return NULL; } - ret->type = EVP_PKEY_NONE; - ret->save_type = EVP_PKEY_NONE; - ret->references = 1; - ret->save_parameters = 1; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); + + if (!evp_pkey_reset_unlocked(ret)) goto err; - } + #ifndef FIPS_MODULE if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) { EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); @@ -1624,7 +1688,7 @@ int EVP_PKEY_size(const EVP_PKEY *pkey) return size; } -void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx, +void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, EVP_KEYMGMT **keymgmt, const char *propquery) { @@ -1770,109 +1834,169 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx, } #ifndef FIPS_MODULE -int evp_pkey_downgrade(EVP_PKEY *pk) +int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src) { - EVP_KEYMGMT *keymgmt = pk->keymgmt; - void *keydata = pk->keydata; - int type = pk->type; - const char *keytype = NULL; + if (!ossl_assert(dest != NULL)) + return 0; - /* If this isn't a provider side key, we're done */ - if (keymgmt == NULL) - return 1; + if (evp_pkey_is_assigned(src) && evp_pkey_is_provided(src)) { + EVP_KEYMGMT *keymgmt = src->keymgmt; + void *keydata = src->keydata; + int type = src->type; + const char *keytype = NULL; - keytype = evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id); + keytype = evp_first_name(EVP_KEYMGMT_provider(keymgmt), + keymgmt->name_id); - /* - * If the type is EVP_PKEY_NONE, then we have a problem somewhere else - * in our code. If it's not one of the well known EVP_PKEY_xxx values, - * it should at least be EVP_PKEY_KEYMGMT at this point. - * TODO(3.0) remove this check when we're confident that the rest of the - * code treats this correctly. - */ - if (!ossl_assert(type != EVP_PKEY_NONE)) { - ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR, - "keymgmt key type = %s but legacy type = EVP_PKEY_NONE", - keytype); - return 0; - } + /* + * If the type is EVP_PKEY_NONE, then we have a problem somewhere + * else in our code. If it's not one of the well known EVP_PKEY_xxx + * values, it should at least be EVP_PKEY_KEYMGMT at this point. + * TODO(3.0) remove this check when we're confident that the rest + * of the code treats this correctly. + */ + if (!ossl_assert(type != EVP_PKEY_NONE)) { + ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR, + "keymgmt key type = %s but legacy type = EVP_PKEY_NONE", + keytype); + return 0; + } - /* Prefer the legacy key type name for error reporting */ - if (type != EVP_PKEY_KEYMGMT) - keytype = OBJ_nid2sn(type); + /* Prefer the legacy key type name for error reporting */ + if (type != EVP_PKEY_KEYMGMT) + keytype = OBJ_nid2sn(type); - /* - * To be able to downgrade, we steal the provider side "origin" keymgmt - * and keydata. We've already grabbed the pointers, so all we need to - * do is clear those pointers in |pk| and then call evp_pkey_free_it(). - * That way, we can restore |pk| if we need to. - */ - pk->keymgmt = NULL; - pk->keydata = NULL; - evp_pkey_free_it(pk); - if (EVP_PKEY_set_type(pk, type)) { - /* If the key is typed but empty, we're done */ - if (keydata == NULL) { - /* We're dropping the EVP_KEYMGMT */ - EVP_KEYMGMT_free(keymgmt); - return 1; - } + /* Make sure we have a clean slate to copy into */ + if (*dest == NULL) + *dest = EVP_PKEY_new(); + else + evp_pkey_free_it(*dest); - if (pk->ameth->import_from == NULL) { - ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION, - "key type = %s", keytype); - } else { - /* - * We perform the export in the same libctx as the keymgmt that we - * are using. - */ - OPENSSL_CTX *libctx = ossl_provider_library_context(keymgmt->prov); - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, NULL); - if (pctx == NULL) - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + if (EVP_PKEY_set_type(*dest, type)) { + /* If the key is typed but empty, we're done */ + if (keydata == NULL) + return 1; - if (pctx != NULL - && evp_keymgmt_export(keymgmt, keydata, - OSSL_KEYMGMT_SELECT_ALL, - pk->ameth->import_from, pctx)) { + if ((*dest)->ameth->import_from == NULL) { + ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION, + "key type = %s", keytype); + } else { /* - * Save the provider side data in the operation cache, so they'll - * find it again. evp_pkey_free_it() cleared the cache, so it's - * safe to assume slot zero is free. - * Note that evp_keymgmt_util_cache_keydata() increments keymgmt's - * reference count. + * We perform the export in the same libctx as the keymgmt + * that we are using. */ - evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata); - EVP_PKEY_CTX_free(pctx); + OSSL_LIB_CTX *libctx = + ossl_provider_libctx(keymgmt->prov); + EVP_PKEY_CTX *pctx = + EVP_PKEY_CTX_new_from_pkey(libctx, *dest, NULL); - /* Synchronize the dirty count */ - pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); + if (pctx == NULL) + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); - /* evp_keymgmt_export() increased the refcount... */ - EVP_KEYMGMT_free(keymgmt); - return 1; + if (pctx != NULL + && evp_keymgmt_export(keymgmt, keydata, + OSSL_KEYMGMT_SELECT_ALL, + (*dest)->ameth->import_from, + pctx)) { + /* Synchronize the dirty count */ + (*dest)->dirty_cnt_copy = (*dest)->ameth->dirty_cnt(*dest); + + EVP_PKEY_CTX_free(pctx); + return 1; + } + EVP_PKEY_CTX_free(pctx); } - EVP_PKEY_CTX_free(pctx); - } - ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE, - "key type = %s", keytype); + ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE, + "key type = %s", keytype); + } } + return 0; +} + +int evp_pkey_downgrade(EVP_PKEY *pk) +{ + EVP_PKEY tmp_copy; /* Stack allocated! */ + CRYPTO_RWLOCK *tmp_lock = NULL; /* Temporary lock */ + int rv = 0; + + if (!ossl_assert(pk != NULL)) + return 0; + /* - * Something went wrong. This could for example happen if the keymgmt - * turns out to be an HSM implementation that refuses to let go of some - * of the key data, typically the private bits. In this case, we restore - * the provider side internal "origin" and leave it at that. + * Throughout this whole function, we must ensure that we lock / unlock + * the exact same lock. Note that we do pass it around a bit. */ - if (!ossl_assert(evp_keymgmt_util_assign_pkey(pk, keymgmt, keydata))) { - /* This should not be impossible */ - ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); + if (!CRYPTO_THREAD_write_lock(pk->lock)) return 0; + + /* If this isn't an assigned provider side key, we're done */ + if (!evp_pkey_is_assigned(pk) || !evp_pkey_is_provided(pk)) { + rv = 1; + goto end; } - /* evp_keymgmt_util_assign_pkey() increased the refcount... */ - EVP_KEYMGMT_free(keymgmt); - return 0; /* No downgrade, but at least the key is restored */ + + /* + * To be able to downgrade, we steal the contents of |pk|, then reset + * it, and finally try to make it a downgraded copy. If any of that + * fails, we restore the copied contents into |pk|. + */ + tmp_copy = *pk; /* |tmp_copy| now owns THE lock */ + + if (evp_pkey_reset_unlocked(pk) + && evp_pkey_copy_downgraded(&pk, &tmp_copy)) { + /* Grab the temporary lock to avoid lock leak */ + tmp_lock = pk->lock; + + /* Restore the common attributes, then empty |tmp_copy| */ + pk->references = tmp_copy.references; + pk->lock = tmp_copy.lock; /* |pk| now owns THE lock */ + pk->attributes = tmp_copy.attributes; + pk->save_parameters = tmp_copy.save_parameters; + pk->ex_data = tmp_copy.ex_data; + + /* Ensure that stuff we've copied won't be freed */ + tmp_copy.lock = NULL; + tmp_copy.attributes = NULL; + memset(&tmp_copy.ex_data, 0, sizeof(tmp_copy.ex_data)); + + /* + * Save the provider side data in the operation cache, so they'll + * find it again. |pk| is new, so it's safe to assume slot zero + * is free. + * Note that evp_keymgmt_util_cache_keydata() increments keymgmt's + * reference count, so we need to decrement it, or there will be a + * leak. + */ + evp_keymgmt_util_cache_keydata(pk, 0, tmp_copy.keymgmt, + tmp_copy.keydata); + EVP_KEYMGMT_free(tmp_copy.keymgmt); + + /* + * Clear keymgmt and keydata from |tmp_copy|, or they'll get + * inadvertently freed. + */ + tmp_copy.keymgmt = NULL; + tmp_copy.keydata = NULL; + + evp_pkey_free_it(&tmp_copy); + rv = 1; + } else { + /* Grab the temporary lock to avoid lock leak */ + tmp_lock = pk->lock; + + /* Restore the original key */ + *pk = tmp_copy; /* |pk| now owns THE lock */ + } + + /* Free the temporary lock. It should never be NULL */ + CRYPTO_THREAD_lock_free(tmp_lock); + + end: + if (!CRYPTO_THREAD_unlock(pk->lock)) + return 0; + return rv; } #endif /* FIPS_MODULE */ @@ -1882,7 +2006,7 @@ const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey) || pkey->keymgmt == NULL || pkey->keydata == NULL) return 0; - return evp_keymgmt_gettable_params(pkey->keymgmt); + return EVP_KEYMGMT_gettable_params(pkey->keymgmt); } int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn) diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c index 44a69083b2..7d7fcbfdfd 100644 --- a/crypto/evp/p_sign.c +++ b/crypto/evp/p_sign.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,8 +14,9 @@ #include #include "crypto/evp.h" -int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, - unsigned int *siglen, EVP_PKEY *pkey) +int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char m[EVP_MAX_MD_SIZE]; unsigned int m_len = 0; @@ -30,8 +31,9 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, } else { int rv = 0; EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); + if (tmp_ctx == NULL) { - EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); @@ -44,7 +46,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, sltmp = (size_t)EVP_PKEY_size(pkey); i = 0; - pkctx = EVP_PKEY_CTX_new(pkey, NULL); + pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (pkctx == NULL) goto err; if (EVP_PKEY_sign_init(pkctx) <= 0) @@ -59,3 +61,9 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, EVP_PKEY_CTX_free(pkctx); return i; } + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey) +{ + return EVP_SignFinal_ex(ctx, sigret, siglen, pkey, NULL, NULL); +} diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c index fe4b7b568d..f4026d8a10 100644 --- a/crypto/evp/p_verify.c +++ b/crypto/evp/p_verify.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,8 +14,9 @@ #include #include "crypto/evp.h" -int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, - unsigned int siglen, EVP_PKEY *pkey) +int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *propq) { unsigned char m[EVP_MAX_MD_SIZE]; unsigned int m_len = 0; @@ -28,8 +29,9 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, } else { int rv = 0; EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new(); + if (tmp_ctx == NULL) { - EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); return 0; } rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx); @@ -41,7 +43,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, } i = -1; - pkctx = EVP_PKEY_CTX_new(pkey, NULL); + pkctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq); if (pkctx == NULL) goto err; if (EVP_PKEY_verify_init(pkctx) <= 0) @@ -53,3 +55,9 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, EVP_PKEY_CTX_free(pkctx); return i; } + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey) +{ + return EVP_VerifyFinal_ex(ctx, sigbuf, siglen, pkey, NULL, NULL); +} diff --git a/crypto/evp/pbe_scrypt.c b/crypto/evp/pbe_scrypt.c index fa7b1de17c..450e085943 100644 --- a/crypto/evp/pbe_scrypt.c +++ b/crypto/evp/pbe_scrypt.c @@ -46,7 +46,7 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, OSSL_PARAM params[7], *z = params; if (r > UINT32_MAX || p > UINT32_MAX) { - EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_PARAMETER_TOO_LARGE); + EVPerr(0, EVP_R_PARAMETER_TOO_LARGE); return 0; } @@ -62,6 +62,7 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, if (maxmem == 0) maxmem = SCRYPT_MAX_MEM; + /* Use OSSL_LIB_CTX_set0_default() if you need a library context */ kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_SCRYPT, NULL); kctx = EVP_KDF_CTX_new(kdf); EVP_KDF_free(kdf); diff --git a/crypto/evp/pkey_kdf.c b/crypto/evp/pkey_kdf.c deleted file mode 100644 index ac4a0fa461..0000000000 --- a/crypto/evp/pkey_kdf.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "internal/numbers.h" -#include "crypto/evp.h" - -#define MAX_PARAM 20 - -typedef struct { - EVP_KDF_CTX *kctx; - /* - * EVP_PKEY implementations collect bits of certain data - */ - BUF_MEM *collected_seed; - BUF_MEM *collected_info; -} EVP_PKEY_KDF_CTX; - -static void pkey_kdf_free_collected(EVP_PKEY_KDF_CTX *pkctx) -{ - BUF_MEM_free(pkctx->collected_seed); - pkctx->collected_seed = NULL; - BUF_MEM_free(pkctx->collected_info); - pkctx->collected_info = NULL; -} - -static int pkey_kdf_init(EVP_PKEY_CTX *ctx) -{ - EVP_PKEY_KDF_CTX *pkctx; - EVP_KDF_CTX *kctx; - const char *kdf_name = OBJ_nid2sn(ctx->pmeth->pkey_id); - EVP_KDF *kdf; - - pkctx = OPENSSL_zalloc(sizeof(*pkctx)); - if (pkctx == NULL) - return 0; - - kdf = EVP_KDF_fetch(NULL, kdf_name, NULL); - kctx = EVP_KDF_CTX_new(kdf); - EVP_KDF_free(kdf); - if (kctx == NULL) { - OPENSSL_free(pkctx); - return 0; - } - - pkctx->kctx = kctx; - ctx->data = pkctx; - return 1; -} - -static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx) -{ - EVP_PKEY_KDF_CTX *pkctx = ctx->data; - - EVP_KDF_CTX_free(pkctx->kctx); - pkey_kdf_free_collected(pkctx); - OPENSSL_free(pkctx); -} - -static int collect(BUF_MEM **collector, void *data, size_t datalen) -{ - size_t i; - - if (*collector == NULL) - *collector = BUF_MEM_new(); - if (*collector == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (data != NULL && datalen > 0) { - i = (*collector)->length; /* BUF_MEM_grow() changes it! */ - - if (!BUF_MEM_grow(*collector, i + datalen)) - return 0; - memcpy((*collector)->data + i, data, datalen); - } - return 1; -} - -static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - EVP_PKEY_KDF_CTX *pkctx = ctx->data; - EVP_KDF_CTX *kctx = pkctx->kctx; - enum { T_OCTET_STRING, T_UINT64, T_DIGEST, T_INT } cmd; - const char *name, *mdname; - BUF_MEM **collector = NULL; - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - switch (type) { - case EVP_PKEY_CTRL_PASS: - cmd = T_OCTET_STRING; - name = OSSL_KDF_PARAM_PASSWORD; - break; - case EVP_PKEY_CTRL_HKDF_SALT: - case EVP_PKEY_CTRL_SCRYPT_SALT: - cmd = T_OCTET_STRING; - name = OSSL_KDF_PARAM_SALT; - break; - case EVP_PKEY_CTRL_TLS_MD: - case EVP_PKEY_CTRL_HKDF_MD: - cmd = T_DIGEST; - name = OSSL_KDF_PARAM_DIGEST; - break; - case EVP_PKEY_CTRL_TLS_SECRET: - cmd = T_OCTET_STRING; - name = OSSL_KDF_PARAM_SECRET; - /* - * Perform the semantics described in - * EVP_PKEY_CTX_add1_tls1_prf_seed(3) - */ - if (ctx->pmeth->pkey_id == NID_tls1_prf) { - BUF_MEM_free(pkctx->collected_seed); - pkctx->collected_seed = NULL; - } - break; - case EVP_PKEY_CTRL_TLS_SEED: - cmd = T_OCTET_STRING; - name = OSSL_KDF_PARAM_SEED; - collector = &pkctx->collected_seed; - break; - case EVP_PKEY_CTRL_HKDF_KEY: - cmd = T_OCTET_STRING; - name = OSSL_KDF_PARAM_KEY; - break; - case EVP_PKEY_CTRL_HKDF_INFO: - cmd = T_OCTET_STRING; - name = OSSL_KDF_PARAM_INFO; - collector = &pkctx->collected_info; - break; - case EVP_PKEY_CTRL_HKDF_MODE: - cmd = T_INT; - name = OSSL_KDF_PARAM_MODE; - break; - case EVP_PKEY_CTRL_SCRYPT_N: - cmd = T_UINT64; - name = OSSL_KDF_PARAM_SCRYPT_N; - break; - case EVP_PKEY_CTRL_SCRYPT_R: - cmd = T_UINT64; /* Range checking occurs on the provider side */ - name = OSSL_KDF_PARAM_SCRYPT_R; - break; - case EVP_PKEY_CTRL_SCRYPT_P: - cmd = T_UINT64; /* Range checking occurs on the provider side */ - name = OSSL_KDF_PARAM_SCRYPT_P; - break; - case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: - cmd = T_UINT64; - name = OSSL_KDF_PARAM_SCRYPT_MAXMEM; - break; - default: - return -2; - } - - if (collector != NULL) { - switch (cmd) { - case T_OCTET_STRING: - return collect(collector, p2, p1); - default: - OPENSSL_assert("You shouldn't be here"); - break; - } - return 1; - } - - switch (cmd) { - case T_OCTET_STRING: - params[0] = - OSSL_PARAM_construct_octet_string(name, (unsigned char *)p2, - (size_t)p1); - break; - - case T_DIGEST: - mdname = EVP_MD_name((const EVP_MD *)p2); - params[0] = OSSL_PARAM_construct_utf8_string(name, (char *)mdname, 0); - break; - - /* - * These are special because the helper macros pass a pointer to the - * stack, so a local copy is required. - */ - case T_INT: - params[0] = OSSL_PARAM_construct_int(name, &p1); - break; - - case T_UINT64: - params[0] = OSSL_PARAM_construct_uint64(name, (uint64_t *)p2); - break; - } - - return EVP_KDF_CTX_set_params(kctx, params); -} - -static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value) -{ - EVP_PKEY_KDF_CTX *pkctx = ctx->data; - EVP_KDF_CTX *kctx = pkctx->kctx; - const EVP_KDF *kdf = EVP_KDF_CTX_kdf(kctx); - BUF_MEM **collector = NULL; - const OSSL_PARAM *defs = EVP_KDF_settable_ctx_params(kdf); - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - int ok = 0; - - /* Deal with ctrl name aliasing */ - if (strcmp(type, "md") == 0) - type = OSSL_KDF_PARAM_DIGEST; - /* scrypt uses 'N', params uses 'n' */ - if (strcmp(type, "N") == 0) - type = OSSL_KDF_PARAM_SCRYPT_N; - - if (!OSSL_PARAM_allocate_from_text(¶ms[0], defs, type, - value, strlen(value), NULL)) - return 0; - - /* - * We do the same special casing of seed and info here as in - * pkey_kdf_ctrl() - */ - if (strcmp(params[0].key, OSSL_KDF_PARAM_SEED) == 0) - collector = &pkctx->collected_seed; - else if (strcmp(params[0].key, OSSL_KDF_PARAM_INFO) == 0) - collector = &pkctx->collected_info; - - if (collector != NULL) - ok = collect(collector, params[0].data, params[0].data_size); - else - ok = EVP_KDF_CTX_set_params(kctx, params); - OPENSSL_free(params[0].data); - return ok; -} - -static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx) -{ - EVP_PKEY_KDF_CTX *pkctx = ctx->data; - - pkey_kdf_free_collected(pkctx); - if (pkctx->kctx != NULL) - EVP_KDF_reset(pkctx->kctx); - return 1; -} - -/* - * For fixed-output algorithms the keylen parameter is an "out" parameter - * otherwise it is an "in" parameter. - */ -static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - EVP_PKEY_KDF_CTX *pkctx = ctx->data; - EVP_KDF_CTX *kctx = pkctx->kctx; - size_t outlen = EVP_KDF_size(kctx); - int r; - - if (pkctx->collected_seed != NULL) { - OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = - OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, - pkctx->collected_seed->data, - pkctx->collected_seed->length); - - r = EVP_KDF_CTX_set_params(kctx, params); - pkey_kdf_free_collected(pkctx); - if (!r) - return 0; - } - if (pkctx->collected_info != NULL) { - OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = - OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, - pkctx->collected_info->data, - pkctx->collected_info->length); - - r = EVP_KDF_CTX_set_params(kctx, params); - pkey_kdf_free_collected(pkctx); - if (!r) - return 0; - } - if (outlen == 0 || outlen == SIZE_MAX) { - /* Variable-output algorithm */ - if (key == NULL) - return 0; - } else { - /* Fixed-output algorithm */ - *keylen = outlen; - if (key == NULL) - return 1; - } - return EVP_KDF_derive(kctx, key, *keylen); -} - -#ifndef OPENSSL_NO_SCRYPT -static const EVP_PKEY_METHOD scrypt_pkey_meth = { - EVP_PKEY_SCRYPT, - 0, - pkey_kdf_init, - 0, - pkey_kdf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - pkey_kdf_derive_init, - pkey_kdf_derive, - pkey_kdf_ctrl, - pkey_kdf_ctrl_str -}; - -const EVP_PKEY_METHOD *scrypt_pkey_method(void) -{ - return &scrypt_pkey_meth; -} -#endif - -static const EVP_PKEY_METHOD tls1_prf_pkey_meth = { - EVP_PKEY_TLS1_PRF, - 0, - pkey_kdf_init, - 0, - pkey_kdf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - pkey_kdf_derive_init, - pkey_kdf_derive, - pkey_kdf_ctrl, - pkey_kdf_ctrl_str -}; - -const EVP_PKEY_METHOD *tls1_prf_pkey_method(void) -{ - return &tls1_prf_pkey_meth; -} - -static const EVP_PKEY_METHOD hkdf_pkey_meth = { - EVP_PKEY_HKDF, - 0, - pkey_kdf_init, - 0, - pkey_kdf_cleanup, - - 0, 0, - 0, 0, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - pkey_kdf_derive_init, - pkey_kdf_derive, - pkey_kdf_ctrl, - pkey_kdf_ctrl_str -}; - -const EVP_PKEY_METHOD *hkdf_pkey_method(void) -{ - return &hkdf_pkey_meth; -} diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c deleted file mode 100644 index 7e36b3c6bd..0000000000 --- a/crypto/evp/pkey_mac.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -#include -#include -#include -#include -#include -#include -#include "crypto/evp.h" -#include "evp_local.h" - -/* MAC PKEY context structure */ - -typedef struct { - EVP_MAC_CTX *ctx; - - /* - * We know of two MAC types: - * - * 1. those who take a secret in raw form, i.e. raw data as a - * ASN1_OCTET_STRING embedded in a EVP_PKEY. So far, that's - * all of them but CMAC. - * 2. those who take a secret with associated cipher in very generic - * form, i.e. a complete EVP_MAC_CTX embedded in a PKEY. So far, - * only CMAC does this. - * - * (one might wonder why the second form isn't used for all) - */ -#define MAC_TYPE_RAW 1 /* HMAC like MAC type (all but CMAC so far) */ -#define MAC_TYPE_MAC 2 /* CMAC like MAC type (only CMAC known so far) */ - int type; - - /* The following is only used for MAC_TYPE_RAW implementations */ - struct { - const EVP_MD *md; /* temp storage of MD */ - ASN1_OCTET_STRING ktmp; /* temp storage for key */ - } raw_data; -} MAC_PKEY_CTX; - -static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx); - -static int pkey_mac_init(EVP_PKEY_CTX *ctx) -{ - MAC_PKEY_CTX *hctx; - /* We're being smart and using the same base NIDs for PKEY and for MAC */ - int nid = ctx->pmeth->pkey_id; - EVP_MAC *mac; - - ERR_set_mark(); - mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery); - ERR_pop_to_mark(); - - /* - * mac == NULL may actually be ok in some situations. In an - * EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with - * default libctx. We don't actually need the underlying MAC to be present - * to successfully set the key in that case. The resulting EVP_PKEY could - * then be used in some other libctx where the MAC *is* present - */ - - if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) { - EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (mac != NULL) { - hctx->ctx = EVP_MAC_CTX_new(mac); - if (hctx->ctx == NULL) { - OPENSSL_free(hctx); - return 0; - } - } - - if (nid == EVP_PKEY_CMAC) { - hctx->type = MAC_TYPE_MAC; - } else { - hctx->type = MAC_TYPE_RAW; - hctx->raw_data.ktmp.type = V_ASN1_OCTET_STRING; - } - - pkey_mac_cleanup(ctx); - EVP_PKEY_CTX_set_data(ctx, hctx); - ctx->keygen_info_count = 0; - - return 1; -} - -static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) -{ - MAC_PKEY_CTX *sctx, *dctx; - - sctx = EVP_PKEY_CTX_get_data(src); - - if (sctx->ctx == NULL) { - /* This actually means the fetch failed during the init call */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - if (sctx->ctx->data == NULL) - return 0; - - dctx = OPENSSL_zalloc(sizeof(*dctx)); - if (dctx == NULL) { - EVPerr(EVP_F_PKEY_MAC_COPY, ERR_R_MALLOC_FAILURE); - return 0; - } - - EVP_PKEY_CTX_set_data(dst, dctx); - dst->keygen_info_count = 0; - - dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx); - if (dctx->ctx == NULL) - goto err; - - /* - * Normally, nothing special would be done with the MAC method. In - * this particular case, though, the MAC method was fetched internally - * by pkey_mac_init() above or by EVP_PKEY_new_CMAC_key() and passed - * via the EVP_MAC_CTX, so it is effectively like every new EVP_MAC_CTX - * fetches the MAC method anew in this case. Therefore, its reference - * count must be adjusted here. - */ - if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx))) - goto err; - - dctx->type = sctx->type; - - switch (dctx->type) { - case MAC_TYPE_RAW: - dctx->raw_data.md = sctx->raw_data.md; - if (ASN1_STRING_get0_data(&sctx->raw_data.ktmp) != NULL && - !ASN1_STRING_copy(&dctx->raw_data.ktmp, &sctx->raw_data.ktmp)) - goto err; - break; - case MAC_TYPE_MAC: - /* Nothing more to do */ - break; - default: - /* This should be dead code */ - return 0; - } - return 1; - err: - pkey_mac_cleanup(dst); - return 0; -} - -static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) -{ - /* - * For the exact same reasons the MAC reference count is incremented - * in pkey_mac_copy() above, it must be explicitly freed here. - */ - - MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx); - - if (hctx != NULL) { - EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL; - - switch (hctx->type) { - case MAC_TYPE_RAW: - OPENSSL_clear_free(hctx->raw_data.ktmp.data, - hctx->raw_data.ktmp.length); - break; - } - EVP_MAC_CTX_free(hctx->ctx); - EVP_MAC_free(mac); - OPENSSL_free(hctx); - EVP_PKEY_CTX_set_data(ctx, NULL); - } -} - -static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - int nid = ctx->pmeth->pkey_id; - - switch (hctx->type) { - case MAC_TYPE_RAW: - { - ASN1_OCTET_STRING *hkey = NULL; - - if (!hctx->raw_data.ktmp.data) - return 0; - hkey = ASN1_OCTET_STRING_dup(&hctx->raw_data.ktmp); - if (!hkey) - return 0; - EVP_PKEY_assign(pkey, nid, hkey); - } - break; - case MAC_TYPE_MAC: - { - EVP_MAC_CTX *cmkey; - - if (hctx->ctx == NULL) { - /* This actually means the fetch failed during the init call */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - cmkey = EVP_MAC_CTX_dup(hctx->ctx); - if (cmkey == NULL) - return 0; - if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx))) - return 0; - EVP_PKEY_assign(pkey, nid, cmkey); - } - break; - default: - /* This should be dead code */ - return 0; - } - - return 1; -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx)); - - if (!EVP_MAC_update(hctx->ctx, data, count)) - return 0; - return 1; -} - -static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - ASN1_OCTET_STRING *key = NULL; - int rv = 1; - /* - * For MACs with the EVP_PKEY_FLAG_SIGCTX_CUSTOM flag set and that - * gets the key passed as an ASN.1 OCTET STRING, we set the key here, - * as this may be only time it's set during a DigestSign. - * - * MACs that pass around the key in form of EVP_MAC_CTX are setting - * the key through other mechanisms. (this is only CMAC for now) - */ - int set_key = - hctx->type == MAC_TYPE_RAW - && (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0; - - if (hctx->ctx == NULL) { - /* This actually means the fetch failed during the init call */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - if (set_key) { - if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx), - OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))))) - return 0; - key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx)); - if (key == NULL) - return 0; - } - - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_update_fn(mctx, int_update); - - /* Some MACs don't support this control... that's fine */ - { - OSSL_PARAM params[3]; - size_t params_n = 0; - int flags = EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT); - - /* TODO(3.0) "flags" isn't quite right, i.e. a quick hack for now */ - params[params_n++] = - OSSL_PARAM_construct_int(OSSL_MAC_PARAM_FLAGS, &flags); - if (set_key) - params[params_n++] = - OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, - key->data, key->length); - params[params_n++] = OSSL_PARAM_construct_end(); - rv = EVP_MAC_CTX_set_params(hctx->ctx, params); - } - return rv; -} - -static int pkey_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, EVP_MD_CTX *mctx) -{ - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - - return EVP_MAC_final(hctx->ctx, sig, siglen, EVP_MAC_size(hctx->ctx)); -} - -static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - - switch (type) { - - case EVP_PKEY_CTRL_CIPHER: - switch (hctx->type) { - case MAC_TYPE_RAW: - return -2; /* The raw types don't support ciphers */ - case MAC_TYPE_MAC: - { - OSSL_PARAM params[3]; - size_t params_n = 0; - char *ciphname = (char *)OBJ_nid2sn(EVP_CIPHER_nid(p2)); - -#ifndef OPENSSL_NO_ENGINE - if (ctx->engine != NULL) { - char *engid = (char *)ENGINE_get_id(ctx->engine); - - params[params_n++] = - OSSL_PARAM_construct_utf8_string("engine", engid, 0); - } -#endif - params[params_n++] = - OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, - ciphname, 0); - params[params_n] = OSSL_PARAM_construct_end(); - - if (hctx->ctx == NULL) { - /* - * This actually means the fetch failed during the init call - */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - if (!EVP_MAC_CTX_set_params(hctx->ctx, params) - || !EVP_MAC_init(hctx->ctx)) - return 0; - } - break; - default: - /* This should be dead code */ - return 0; - } - break; - - case EVP_PKEY_CTRL_MD: - switch (hctx->type) { - case MAC_TYPE_RAW: - hctx->raw_data.md = p2; - break; - case MAC_TYPE_MAC: { - EVP_MAC_CTX *new_mac_ctx; - - if (ctx->pkey == NULL) - return 0; - new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr); - if (new_mac_ctx == NULL) - return 0; - EVP_MAC_CTX_free(hctx->ctx); - hctx->ctx = new_mac_ctx; - } - break; - default: - /* This should be dead code */ - return 0; - } - break; - - case EVP_PKEY_CTRL_SET_DIGEST_SIZE: - { - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - size_t size = (size_t)p1; - size_t verify = 0; - - /* - * We verify that the length is actually set by getting back - * the same parameter and checking that it matches what we - * tried to set. - * TODO(3.0) when we have a more direct mechanism to check if - * a parameter was used, we must refactor this to use that. - */ - - params[0] = - OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size); - - if (hctx->ctx == NULL) { - /* - * This actually means the fetch failed during the init call - */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - if (!EVP_MAC_CTX_set_params(hctx->ctx, params)) - return 0; - - params[0] = - OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify); - - if (!EVP_MAC_CTX_get_params(hctx->ctx, params)) - return 0; - - /* - * Since EVP_MAC_{get,set}_ctx_params() returned successfully, - * we can only assume that the size was ignored, i.e. this - * control is unsupported. - */ - if (verify != size) - return -2; - } - break; - case EVP_PKEY_CTRL_SET_MAC_KEY: - switch (hctx->type) { - case MAC_TYPE_RAW: - if ((!p2 && p1 > 0) || (p1 < -1)) - return 0; - if (!ASN1_OCTET_STRING_set(&hctx->raw_data.ktmp, p2, p1)) - return 0; - break; - case MAC_TYPE_MAC: - { - OSSL_PARAM params[2]; - size_t params_n = 0; - - params[params_n++] = - OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, - p2, p1); - params[params_n] = OSSL_PARAM_construct_end(); - - if (hctx->ctx == NULL) { - /* - * This actually means the fetch failed during the init call - */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - return EVP_MAC_CTX_set_params(hctx->ctx, params); - } - break; - default: - /* This should be dead code */ - return 0; - } - break; - - case EVP_PKEY_CTRL_DIGESTINIT: - switch (hctx->type) { - case MAC_TYPE_RAW: - if (hctx->ctx == NULL) { - /* This actually means the fetch failed during the init call */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - - /* Ensure that we have attached the implementation */ - if (!EVP_MAC_init(hctx->ctx)) - return 0; - { - ASN1_OCTET_STRING *key = - (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; - OSSL_PARAM params[4]; - size_t params_n = 0; - char *mdname = - (char *)OBJ_nid2sn(EVP_MD_nid(hctx->raw_data.md)); - -#ifndef OPENSSL_NO_ENGINE - if (ctx->engine != NULL) { - char *engid = (char *)ENGINE_get_id(ctx->engine); - - params[params_n++] = - OSSL_PARAM_construct_utf8_string("engine", engid, 0); - } -#endif - params[params_n++] = - OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, - mdname, 0); - params[params_n++] = - OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, - key->data, key->length); - params[params_n] = OSSL_PARAM_construct_end(); - - return EVP_MAC_CTX_set_params(hctx->ctx, params); - } - break; - case MAC_TYPE_MAC: - return -2; /* The mac types don't support ciphers */ - default: - /* This should be dead code */ - return 0; - } - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - MAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx); - const EVP_MAC *mac; - OSSL_PARAM params[2]; - int ok = 0; - - if (hctx == NULL) { - EVPerr(0, EVP_R_NULL_MAC_PKEY_CTX); - return 0; - } - if (hctx->ctx == NULL) { - /* This actually means the fetch failed during the init call */ - EVPerr(0, EVP_R_FETCH_FAILED); - return 0; - } - mac = EVP_MAC_CTX_mac(hctx->ctx); - - /* - * Translation of some control names that are equivalent to a single - * parameter name. - * - * "md" and "digest" are the same thing, we use the single "digest" - * - * "digestsize" was a setting control in siphash, but naming wise, - * it's really the same as "size". - */ - if (strcmp(type, "md") == 0) - type = OSSL_MAC_PARAM_DIGEST; - else if (strcmp(type, "digestsize") == 0) - type = OSSL_MAC_PARAM_SIZE; - - if (!OSSL_PARAM_allocate_from_text(¶ms[0], - EVP_MAC_settable_ctx_params(mac), - type, value, strlen(value) + 1, NULL)) - return 0; - params[1] = OSSL_PARAM_construct_end(); - - ok = EVP_MAC_CTX_set_params(hctx->ctx, params); - OPENSSL_free(params[0].data); - return ok; -} - -static const EVP_PKEY_METHOD cmac_pkey_meth = { - EVP_PKEY_CMAC, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, - pkey_mac_init, - pkey_mac_copy, - pkey_mac_cleanup, - - 0, 0, - - 0, - pkey_mac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_signctx_init, - pkey_mac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_ctrl, - pkey_mac_ctrl_str -}; - -const EVP_PKEY_METHOD *cmac_pkey_method(void) -{ - return &cmac_pkey_meth; -} - -static const EVP_PKEY_METHOD hmac_pkey_meth = { - EVP_PKEY_HMAC, - 0, - pkey_mac_init, - pkey_mac_copy, - pkey_mac_cleanup, - - 0, 0, - - 0, - pkey_mac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_signctx_init, - pkey_mac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_ctrl, - pkey_mac_ctrl_str -}; - -const EVP_PKEY_METHOD *hmac_pkey_method(void) -{ - return &hmac_pkey_meth; -} - -static const EVP_PKEY_METHOD siphash_pkey_meth = { - EVP_PKEY_SIPHASH, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, - pkey_mac_init, - pkey_mac_copy, - pkey_mac_cleanup, - - 0, 0, - - 0, - pkey_mac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_signctx_init, - pkey_mac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_ctrl, - pkey_mac_ctrl_str -}; - -const EVP_PKEY_METHOD *siphash_pkey_method(void) -{ - return &siphash_pkey_meth; -} - -static const EVP_PKEY_METHOD poly1305_pkey_meth = { - EVP_PKEY_POLY1305, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, - pkey_mac_init, - pkey_mac_copy, - pkey_mac_cleanup, - - 0, 0, - - 0, - pkey_mac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_signctx_init, - pkey_mac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_mac_ctrl, - pkey_mac_ctrl_str -}; - -const EVP_PKEY_METHOD *poly1305_pkey_method(void) -{ - return &poly1305_pkey_meth; -} diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 1ab309329d..05394deca8 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -20,17 +20,6 @@ #include "crypto/evp.h" #include "evp_local.h" -#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_EC) -# define TMP_SM2_HACK -#endif - -/* TODO(3.0) remove when provider SM2 key generation is implemented */ -#ifdef TMP_SM2_HACK -# include -# include -# include "internal/sizes.h" -#endif - static int gen_init(EVP_PKEY_CTX *ctx, int operation) { int ret = 0; @@ -44,12 +33,6 @@ static int gen_init(EVP_PKEY_CTX *ctx, int operation) if (ctx->keymgmt == NULL || ctx->keymgmt->gen_init == NULL) goto legacy; -/* TODO remove when provider SM2 key generation is implemented */ -#ifdef TMP_SM2_HACK - if (ctx->pmeth != NULL && ctx->pmeth->pkey_id == EVP_PKEY_SM2) - goto legacy; -#endif - switch (operation) { case EVP_PKEY_OP_PARAMGEN: ctx->op.keymgmt.genctx = @@ -213,32 +196,12 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) evp_pkey_free_legacy(*ppkey); #endif -/* TODO remove when SM2 key have been cleanly separated from EC keys */ -#ifdef TMP_SM2_HACK /* - * Legacy SM2 keys are implemented as EC_KEY with a twist. The legacy - * key generation detects the SM2 curve and "magically" changes the pkey - * id accordingly. - * Since we don't have SM2 in the provider implementation, we need to - * downgrade the generated provider side key to a legacy one under the - * same conditions. - * - * THIS IS AN UGLY BUT TEMPORARY HACK + * Because we still have legacy keys, and evp_pkey_downgrade() + * TODO remove this #legacy internal keys are gone */ - { - char curve_name[OSSL_MAX_NAME_SIZE] = ""; - - if (!EVP_PKEY_get_utf8_string_param(*ppkey, OSSL_PKEY_PARAM_GROUP_NAME, - curve_name, sizeof(curve_name), - NULL) - || strcmp(curve_name, "SM2") != 0) - goto end; - } + (*ppkey)->type = ctx->legacy_keytype; - if (!evp_pkey_downgrade(*ppkey) - || !EVP_PKEY_set_alias_type(*ppkey, EVP_PKEY_SM2)) - ret = 0; -#endif goto end; legacy: @@ -376,7 +339,8 @@ static int fromdata_init(EVP_PKEY_CTX *ctx, int operation) return 1; not_supported: - ctx->operation = EVP_PKEY_OP_UNDEFINED; + if (ctx != NULL) + ctx->operation = EVP_PKEY_OP_UNDEFINED; ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 52c304227b..17a0a4704b 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -21,10 +21,12 @@ #include #include #include +#include #include "internal/cryptlib.h" #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/dh.h" +#include "crypto/ec.h" #include "internal/ffc.h" #include "internal/numbers.h" #include "internal/provider.h" @@ -32,6 +34,14 @@ #ifndef FIPS_MODULE +static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, + int keytype, int optype, + int cmd, const char *name, + const void *data, size_t data_len); +static void evp_pkey_ctx_free_cached_data(EVP_PKEY_CTX *ctx, + int cmd, const char *name); +static void evp_pkey_ctx_free_all_cached_data(EVP_PKEY_CTX *ctx); + typedef const EVP_PKEY_METHOD *(*pmeth_fn)(void); typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); @@ -40,7 +50,7 @@ static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; /* This array needs to be in order of NIDs */ static pmeth_fn standard_methods[] = { # ifndef OPENSSL_NO_RSA - rsa_pkey_method, + ossl_rsa_pkey_method, # endif # ifndef OPENSSL_NO_DH dh_pkey_method, @@ -50,39 +60,21 @@ static pmeth_fn standard_methods[] = { # endif # ifndef OPENSSL_NO_EC ec_pkey_method, -# endif - hmac_pkey_method, -# ifndef OPENSSL_NO_CMAC - cmac_pkey_method, # endif # ifndef OPENSSL_NO_RSA - rsa_pss_pkey_method, + ossl_rsa_pss_pkey_method, # endif # ifndef OPENSSL_NO_DH dhx_pkey_method, # endif -# ifndef OPENSSL_NO_SCRYPT - scrypt_pkey_method, -# endif - tls1_prf_pkey_method, # ifndef OPENSSL_NO_EC ecx25519_pkey_method, ecx448_pkey_method, -# endif - hkdf_pkey_method, -# ifndef OPENSSL_NO_POLY1305 - poly1305_pkey_method, -# endif -# ifndef OPENSSL_NO_SIPHASH - siphash_pkey_method, # endif # ifndef OPENSSL_NO_EC ed25519_pkey_method, ed448_pkey_method, # endif -# ifndef OPENSSL_NO_SM2 - sm2_pkey_method, -# endif }; DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, pmeth_fn, pmeth_func); @@ -135,61 +127,63 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; return pmeth; } -#endif /* FIPS_MODULE */ -static int is_legacy_alg(int id, const char *keytype) +/* Three possible states: */ +# define EVP_PKEY_STATE_UNKNOWN 0 +# define EVP_PKEY_STATE_LEGACY 1 +# define EVP_PKEY_STATE_PROVIDER 2 + +static int evp_pkey_ctx_state(EVP_PKEY_CTX *ctx) { -#ifndef FIPS_MODULE - /* Certain EVP_PKEY keytypes are only available in legacy form */ - if (id == -1) { - id = OBJ_sn2nid(keytype); - if (id == NID_undef) - id = OBJ_ln2nid(keytype); - if (id == NID_undef) - return 0; - } - switch (id) { - /* - * TODO(3.0): Remove SM2 and DHX when they are converted to have provider - * support - */ - case EVP_PKEY_SM2: - case EVP_PKEY_DHX: - case EVP_PKEY_SCRYPT: - case EVP_PKEY_TLS1_PRF: - case EVP_PKEY_HKDF: - case EVP_PKEY_CMAC: - case EVP_PKEY_HMAC: - case EVP_PKEY_SIPHASH: - case EVP_PKEY_POLY1305: - return 1; - default: - return 0; - } -#else - return 0; -#endif + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) + return EVP_PKEY_STATE_UNKNOWN; + + if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) + && ctx->op.kex.exchprovctx != NULL) + || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + && ctx->op.sig.sigprovctx != NULL) + || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + && ctx->op.ciph.ciphprovctx != NULL) + || (EVP_PKEY_CTX_IS_GEN_OP(ctx) + && ctx->op.keymgmt.genctx != NULL) + || (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kemprovctx != NULL)) + return EVP_PKEY_STATE_PROVIDER; + + return EVP_PKEY_STATE_LEGACY; } -static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, +static void help_get_legacy_alg_type_from_keymgmt(const char *keytype, + void *arg) +{ + int *type = arg; + + if (*type == NID_undef) + *type = evp_pkey_name2type(keytype); +} + +static int get_legacy_alg_type_from_keymgmt(const EVP_KEYMGMT *keymgmt) +{ + int type = NID_undef; + + EVP_KEYMGMT_names_do_all(keymgmt, help_get_legacy_alg_type_from_keymgmt, + &type); + return type; +} +#endif /* FIPS_MODULE */ + +static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, ENGINE *e, const char *keytype, const char *propquery, int id) { - EVP_PKEY_CTX *ret; + EVP_PKEY_CTX *ret = NULL; const EVP_PKEY_METHOD *pmeth = NULL; EVP_KEYMGMT *keymgmt = NULL; /* - * When using providers, the context is bound to the algo implementation - * later. - */ - if (pkey == NULL && e == NULL && id == -1) - goto common; - - /* - * If the internal key is provided, we extract the keytype from its + * If the given |pkey| is provided, we extract the keytype from its * keymgmt and skip over the legacy code. */ if (pkey != NULL && evp_pkey_is_provided(pkey)) { @@ -199,14 +193,24 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, keytype = evp_first_name(pkey->keymgmt->prov, pkey->keymgmt->name_id); goto common; } + #ifndef FIPS_MODULE - /* TODO(3.0) Legacy code should be removed when all is provider based */ + /* + * TODO(3.0) This legacy code section should be removed when we stop + * supporting engines + */ /* BEGIN legacy */ if (id == -1) { - if (pkey == NULL) - return NULL; - id = pkey->type; + if (pkey != NULL) + id = pkey->type; + else if (keytype != NULL) + id = evp_pkey_name2type(keytype); + if (id == NID_undef) + id = -1; } + /* If no ID was found here, we can only resort to find a keymgmt */ + if (id == -1) + goto common; /* * Here, we extract what information we can for the purpose of @@ -241,19 +245,12 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, * If an ENGINE handled this method look it up. Otherwise use internal * tables. */ - if (e) + if (e != NULL) pmeth = ENGINE_get_pkey_meth(e, id); else # endif pmeth = EVP_PKEY_meth_find(id); - if (pmeth == NULL) { -# ifndef OPENSSL_NO_ENGINE - ENGINE_finish(e); -# endif - EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); - return NULL; - } /* END legacy */ #endif /* FIPS_MODULE */ common: @@ -262,35 +259,65 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, * implementation. */ if (e == NULL && keytype != NULL) { - int legacy = is_legacy_alg(id, keytype); + keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery); + if (keymgmt == NULL) + return NULL; /* EVP_KEYMGMT_fetch() recorded an error */ - if (legacy) { - /* This could fail so ignore errors */ - ERR_set_mark(); +#ifndef FIPS_MODULE + /* + * Chase down the legacy NID, as that might be needed for diverse + * purposes, such as ensure that EVP_PKEY_type() can return sensible + * values, or that there's a better chance to "downgrade" a key when + * needed. We go through all keymgmt names, because the keytype + * that's passed to this function doesn't necessarily translate + * directly. + * TODO: Remove this when #legacy keys are gone. + */ + if (keymgmt != NULL) { + int tmp_id = get_legacy_alg_type_from_keymgmt(keymgmt); + + if (tmp_id != NID_undef) { + if (id == -1) { + id = tmp_id; + } else { + /* + * It really really shouldn't differ. If it still does, + * something is very wrong. + */ + if (!ossl_assert(id == tmp_id)) { + EVPerr(EVP_F_INT_CTX_NEW, ERR_R_INTERNAL_ERROR); + EVP_KEYMGMT_free(keymgmt); + return NULL; + } + } + } } +#endif + } - keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery); - if (legacy) { - ERR_pop_to_mark(); - } else if (keymgmt == NULL) { - EVPerr(EVP_F_INT_CTX_NEW, EVP_R_FETCH_FAILED); - return NULL; - } + if (pmeth == NULL && keymgmt == NULL) { + EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); + } else { + ret = OPENSSL_zalloc(sizeof(*ret)); + if (ret == NULL) + EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); } - ret = OPENSSL_zalloc(sizeof(*ret)); - if (ret == NULL) { - EVP_KEYMGMT_free(keymgmt); #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if ((ret == NULL || pmeth == NULL) && e != NULL) ENGINE_finish(e); #endif - EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); + + if (ret == NULL) { + EVP_KEYMGMT_free(keymgmt); return NULL; } + ret->libctx = libctx; ret->propquery = propquery; ret->keytype = keytype; ret->keymgmt = keymgmt; + ret->legacy_keytype = id; /* TODO: Remove when #legacy key are gone */ ret->engine = e; ret->pmeth = pmeth; ret->operation = EVP_PKEY_OP_UNDEFINED; @@ -311,14 +338,14 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, /*- All methods below can also be used in FIPS_MODULE */ -EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx, +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, const char *name, const char *propquery) { return int_ctx_new(libctx, NULL, NULL, name, propquery, -1); } -EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, EVP_PKEY *pkey, +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, const char *propquery) { return int_ctx_new(libctx, pkey, NULL, NULL, propquery, -1); @@ -338,9 +365,13 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx) EVP_KEYEXCH_free(ctx->op.kex.exchange); ctx->op.kex.exchprovctx = NULL; ctx->op.kex.exchange = NULL; + } else if (EVP_PKEY_CTX_IS_KEM_OP(ctx)) { + if (ctx->op.encap.kemprovctx != NULL && ctx->op.encap.kem != NULL) + ctx->op.encap.kem->freectx(ctx->op.encap.kemprovctx); + EVP_KEM_free(ctx->op.encap.kem); + ctx->op.encap.kemprovctx = NULL; + ctx->op.encap.kem = NULL; } -/* TODO(3.0): add dependancies and uncomment this when available for fips mode */ -#ifndef FIPS_MODULE else if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) { if (ctx->op.ciph.ciphprovctx != NULL && ctx->op.ciph.cipher != NULL) ctx->op.ciph.cipher->freectx(ctx->op.ciph.ciphprovctx); @@ -351,7 +382,6 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx) if (ctx->op.keymgmt.genctx != NULL && ctx->keymgmt != NULL) evp_keymgmt_gen_cleanup(ctx->keymgmt, ctx->op.keymgmt.genctx); } -#endif } void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) @@ -362,6 +392,9 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) ctx->pmeth->cleanup(ctx); evp_pkey_ctx_free_old_ops(ctx); +#ifndef FIPS_MODULE + evp_pkey_ctx_free_all_cached_data(ctx); +#endif EVP_KEYMGMT_free(ctx->keymgmt); EVP_PKEY_free(ctx->pkey); @@ -369,6 +402,7 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) #if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) ENGINE_finish(ctx->engine); #endif + BN_free(ctx->rsa_pubexp); OPENSSL_free(ctx); } @@ -502,6 +536,26 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) } return rctx; } + } else if (EVP_PKEY_CTX_IS_KEM_OP(pctx)) { + if (pctx->op.encap.kem != NULL) { + rctx->op.encap.kem = pctx->op.encap.kem; + if (!EVP_KEM_up_ref(rctx->op.encap.kem)) { + OPENSSL_free(rctx); + return NULL; + } + } + if (pctx->op.encap.kemprovctx != NULL) { + if (!ossl_assert(pctx->op.encap.kem != NULL)) + return NULL; + rctx->op.encap.kemprovctx + = pctx->op.encap.kem->dupctx(pctx->op.encap.kemprovctx); + if (rctx->op.encap.kemprovctx == NULL) { + EVP_KEM_free(rctx->op.encap.kem); + OPENSSL_free(rctx); + return NULL; + } + return rctx; + } } rctx->pmeth = pctx->pmeth; @@ -602,6 +656,12 @@ int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) && ctx->keymgmt->gen_set_params != NULL) return evp_keymgmt_gen_set_params(ctx->keymgmt, ctx->op.keymgmt.genctx, params); + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kemprovctx != NULL + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->set_ctx_params != NULL) + return ctx->op.encap.kem->set_ctx_params(ctx->op.encap.kemprovctx, + params); return 0; } @@ -625,45 +685,82 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params) && ctx->op.ciph.cipher->get_ctx_params != NULL) return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx, params); + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kemprovctx != NULL + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->get_ctx_params != NULL) + return ctx->op.encap.kem->get_ctx_params(ctx->op.encap.kemprovctx, + params); return 0; } #ifndef FIPS_MODULE const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx) { + void *provctx; + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchange != NULL - && ctx->op.kex.exchange->gettable_ctx_params != NULL) - return ctx->op.kex.exchange->gettable_ctx_params(); + && ctx->op.kex.exchange->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEYEXCH_provider(ctx->op.kex.exchange)); + return ctx->op.kex.exchange->gettable_ctx_params(provctx); + } if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) && ctx->op.sig.signature != NULL - && ctx->op.sig.signature->gettable_ctx_params != NULL) - return ctx->op.sig.signature->gettable_ctx_params(); + && ctx->op.sig.signature->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_SIGNATURE_provider(ctx->op.sig.signature)); + return ctx->op.sig.signature->gettable_ctx_params(provctx); + } if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) && ctx->op.ciph.cipher != NULL - && ctx->op.ciph.cipher->gettable_ctx_params != NULL) - return ctx->op.ciph.cipher->gettable_ctx_params(); + && ctx->op.ciph.cipher->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_ASYM_CIPHER_provider(ctx->op.ciph.cipher)); + return ctx->op.ciph.cipher->gettable_ctx_params(provctx); + } + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->gettable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEM_provider(ctx->op.encap.kem)); + return ctx->op.encap.kem->gettable_ctx_params(provctx); + } return NULL; } const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx) { + void *provctx; + if (EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchange != NULL - && ctx->op.kex.exchange->settable_ctx_params != NULL) - return ctx->op.kex.exchange->settable_ctx_params(); + && ctx->op.kex.exchange->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEYEXCH_provider(ctx->op.kex.exchange)); + return ctx->op.kex.exchange->settable_ctx_params(provctx); + } if (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) && ctx->op.sig.signature != NULL - && ctx->op.sig.signature->settable_ctx_params != NULL) - return ctx->op.sig.signature->settable_ctx_params(); + && ctx->op.sig.signature->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_SIGNATURE_provider(ctx->op.sig.signature)); + return ctx->op.sig.signature->settable_ctx_params(provctx); + } if (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) && ctx->op.ciph.cipher != NULL - && ctx->op.ciph.cipher->settable_ctx_params != NULL) - return ctx->op.ciph.cipher->settable_ctx_params(); + && ctx->op.ciph.cipher->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx( + EVP_ASYM_CIPHER_provider(ctx->op.ciph.cipher)); + return ctx->op.ciph.cipher->settable_ctx_params(provctx); + } if (EVP_PKEY_CTX_IS_GEN_OP(ctx) && ctx->keymgmt != NULL) - return evp_keymgmt_gen_settable_params(ctx->keymgmt); - + return EVP_KEYMGMT_gen_settable_params(ctx->keymgmt); + if (EVP_PKEY_CTX_IS_KEM_OP(ctx) + && ctx->op.encap.kem != NULL + && ctx->op.encap.kem->settable_ctx_params != NULL) { + provctx = ossl_provider_ctx(EVP_KEM_provider(ctx->op.encap.kem)); + return ctx->op.encap.kem->settable_ctx_params(provctx); + } return NULL; } @@ -739,7 +836,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad) int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) { - OSSL_PARAM sig_md_params[3], *p = sig_md_params; + OSSL_PARAM sig_md_params[2], *p = sig_md_params; /* 80 should be big enough */ char name[80] = ""; const EVP_MD *tmp; @@ -758,7 +855,7 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, name, sizeof(name)); - *p++ = OSSL_PARAM_construct_end(); + *p = OSSL_PARAM_construct_end(); if (!EVP_PKEY_CTX_get_params(ctx, sig_md_params)) return 0; @@ -772,21 +869,22 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) return 1; } -int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +static int evp_pkey_ctx_set_md(EVP_PKEY_CTX *ctx, const EVP_MD *md, + int fallback, const char *param, int op, + int ctrl) { - OSSL_PARAM sig_md_params[2], *p = sig_md_params; + OSSL_PARAM md_params[2], *p = md_params; const char *name; - if (ctx == NULL || !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + if (ctx == NULL || (ctx->operation & op) == 0) { ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); /* Uses the same return values as EVP_PKEY_CTX_ctrl */ return -2; } /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.sig.sigprovctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, - EVP_PKEY_CTRL_MD, 0, (void *)(md)); + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, 0, (void *)(md)); if (md == NULL) { name = ""; @@ -794,29 +892,365 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) name = EVP_MD_name(md); } - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, + *p++ = OSSL_PARAM_construct_utf8_string(param, /* * Cast away the const. This is read * only so should be safe */ (char *)name, 0); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, md_params); +} + +int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.sig.sigprovctx == NULL, + OSSL_SIGNATURE_PARAM_DIGEST, + EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD); +} + +int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_DIGEST, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_TLS_MD); +} + +static int evp_pkey_ctx_set1_octet_string(EVP_PKEY_CTX *ctx, int fallback, + const char *param, int op, int ctrl, + const unsigned char *data, + int datalen) +{ + OSSL_PARAM octet_string_params[2], *p = octet_string_params; + + if (ctx == NULL || (ctx->operation & op) == 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (fallback) + return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, datalen, (void *)(data)); + + if (datalen < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH); + return 0; + } + + *p++ = OSSL_PARAM_construct_octet_string(param, + /* + * Cast away the const. This is read + * only so should be safe + */ + (unsigned char *)data, + (size_t)datalen); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, octet_string_params); +} + +int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *ctx, + const unsigned char *sec, int seclen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SECRET, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SECRET, + sec, seclen); +} + +int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *ctx, + const unsigned char *seed, int seedlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SEED, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_TLS_SEED, + seed, seedlen); +} + +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) +{ + return evp_pkey_ctx_set_md(ctx, md, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_DIGEST, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_HKDF_MD); +} + +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SALT, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_SALT, + salt, saltlen); +} + +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const unsigned char *key, int keylen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_KEY, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_KEY, + key, keylen); +} + +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const unsigned char *info, int infolen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_INFO, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_INFO, + info, infolen); +} + +int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode) +{ + OSSL_PARAM int_params[2], *p = int_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_HKDF_MODE, mode, NULL); + + + if (mode < 0) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, int_params); +} + +int EVP_PKEY_CTX_set1_pbe_pass(EVP_PKEY_CTX *ctx, const char *pass, + int passlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_PASSWORD, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_PASS, + (const unsigned char *)pass, passlen); +} + +int EVP_PKEY_CTX_set1_scrypt_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.exchprovctx == NULL, + OSSL_KDF_PARAM_SALT, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_SALT, + salt, saltlen); +} + +static int evp_pkey_ctx_set_uint64(EVP_PKEY_CTX *ctx, const char *param, + int op, int ctrl, uint64_t val) +{ + OSSL_PARAM uint64_params[2], *p = uint64_params; + + if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (ctx->op.kex.exchprovctx == NULL) + return EVP_PKEY_CTX_ctrl_uint64(ctx, -1, op, ctrl, val); + + *p++ = OSSL_PARAM_construct_uint64(param, &val); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, uint64_params); +} + +int EVP_PKEY_CTX_set_scrypt_N(EVP_PKEY_CTX *ctx, uint64_t n) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_N, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SCRYPT_N, + n); +} + +int EVP_PKEY_CTX_set_scrypt_r(EVP_PKEY_CTX *ctx, uint64_t r) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_R, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SCRYPT_R, + r); +} + +int EVP_PKEY_CTX_set_scrypt_p(EVP_PKEY_CTX *ctx, uint64_t p) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_P, + EVP_PKEY_OP_DERIVE, EVP_PKEY_CTRL_SCRYPT_P, + p); +} + +int EVP_PKEY_CTX_set_scrypt_maxmem_bytes(EVP_PKEY_CTX *ctx, + uint64_t maxmem_bytes) +{ + return evp_pkey_ctx_set_uint64(ctx, OSSL_KDF_PARAM_SCRYPT_MAXMEM, + EVP_PKEY_OP_DERIVE, + EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, + maxmem_bytes); +} + +int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key, + int keylen) +{ + return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.keymgmt.genctx == NULL, + OSSL_PKEY_PARAM_PRIV_KEY, + EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, + key, keylen); +} + +int EVP_PKEY_CTX_set_kem_op(EVP_PKEY_CTX *ctx, const char *op) +{ + OSSL_PARAM params[2], *p = params; + + if (ctx == NULL || op == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + if (!EVP_PKEY_CTX_IS_KEM_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KEM_PARAM_OPERATION, + (char *)op, 0); + *p = OSSL_PARAM_construct_end(); + return EVP_PKEY_CTX_set_params(ctx, params); +} + +int evp_pkey_ctx_set1_id_prov(EVP_PKEY_CTX *ctx, const void *id, int len) +{ + OSSL_PARAM params[2], *p = params; + int ret; + + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_DIST_ID, + /* + * Cast away the const. This is + * read only so should be safe + */ + (void *)id, (size_t)len); + *p++ = OSSL_PARAM_construct_end(); + + ret = evp_pkey_ctx_set_params_strict(ctx, params); + if (ret == -2) + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return ret; +} + +int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, + EVP_PKEY_CTRL_SET1_ID, (int)len, (void*)(id)); +} + +static int get1_id_data(EVP_PKEY_CTX *ctx, void *id, size_t *id_len) +{ + int ret; + void *tmp_id = NULL; + OSSL_PARAM params[2], *p = params; + + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_PKEY_PARAM_DIST_ID, + &tmp_id, 0); *p++ = OSSL_PARAM_construct_end(); - return EVP_PKEY_CTX_set_params(ctx, sig_md_params); + ret = evp_pkey_ctx_get_params_strict(ctx, params); + if (ret == -2) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + } else if (ret > 0) { + size_t tmp_id_len = params[0].return_size; + + if (id != NULL) + memcpy(id, tmp_id, tmp_id_len); + if (id_len != NULL) + *id_len = tmp_id_len; + } + return ret; +} + +int evp_pkey_ctx_get1_id_prov(EVP_PKEY_CTX *ctx, void *id) +{ + return get1_id_data(ctx, id, NULL); +} + +int evp_pkey_ctx_get1_id_len_prov(EVP_PKEY_CTX *ctx, size_t *id_len) +{ + return get1_id_data(ctx, NULL, id_len); +} + +int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET1_ID, 0, (void*)id); +} + +int EVP_PKEY_CTX_get1_id_len(EVP_PKEY_CTX *ctx, size_t *id_len) +{ + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, + EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)id_len); } static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2) { - /* - * GOST CMS format is different for different cipher algorithms. - * Most of other algorithms don't have such a difference - * so this ctrl is just ignored. - */ - if (cmd == EVP_PKEY_CTRL_CIPHER) - return -2; + switch (cmd) { + case EVP_PKEY_CTRL_SET1_ID: + return evp_pkey_ctx_set1_id_prov(ctx, p2, p1); + case EVP_PKEY_CTRL_GET1_ID: + return evp_pkey_ctx_get1_id_prov(ctx, p2); + case EVP_PKEY_CTRL_GET1_ID_LEN: + return evp_pkey_ctx_get1_id_len_prov(ctx, p2); + } # ifndef OPENSSL_NO_DH + if (keytype == EVP_PKEY_DHX) { + switch (cmd) { + case EVP_PKEY_CTRL_DH_KDF_TYPE: + return EVP_PKEY_CTX_set_dh_kdf_type(ctx, p1); + case EVP_PKEY_CTRL_DH_KDF_MD: + return EVP_PKEY_CTX_set_dh_kdf_md(ctx, p2); + case EVP_PKEY_CTRL_DH_KDF_OUTLEN: + return EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, p1); + case EVP_PKEY_CTRL_DH_KDF_UKM: + return EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p2, p1); + case EVP_PKEY_CTRL_DH_KDF_OID: + return EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, p2); + case EVP_PKEY_CTRL_GET_DH_KDF_MD: + return EVP_PKEY_CTX_get_dh_kdf_md(ctx, p2); + case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN: + return EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, p2); + case EVP_PKEY_CTRL_GET_DH_KDF_UKM: + return EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p2); + case EVP_PKEY_CTRL_GET_DH_KDF_OID: + return EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, p2); + } + } if (keytype == EVP_PKEY_DH) { switch (cmd) { case EVP_PKEY_CTRL_DH_PAD: @@ -849,6 +1283,8 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, # ifndef OPENSSL_NO_EC if (keytype == EVP_PKEY_EC) { switch (cmd) { + case EVP_PKEY_CTRL_EC_PARAM_ENC: + return evp_pkey_ctx_set_ec_param_enc_prov(ctx, p1); case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, p1); case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: @@ -906,6 +1342,66 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, * or for generic controls that are the same across multiple key types. */ if (keytype == -1) { + if (optype == EVP_PKEY_OP_DERIVE) { + switch (cmd) { + /* TLS1-PRF */ + case EVP_PKEY_CTRL_TLS_MD: + return EVP_PKEY_CTX_set_tls1_prf_md(ctx, p2); + case EVP_PKEY_CTRL_TLS_SECRET: + return EVP_PKEY_CTX_set1_tls1_prf_secret(ctx, p2, p1); + case EVP_PKEY_CTRL_TLS_SEED: + return EVP_PKEY_CTX_add1_tls1_prf_seed(ctx, p2, p1); + + /* HKDF */ + case EVP_PKEY_CTRL_HKDF_MD: + return EVP_PKEY_CTX_set_hkdf_md(ctx, p2); + case EVP_PKEY_CTRL_HKDF_SALT : + return EVP_PKEY_CTX_set1_hkdf_salt(ctx, p2, p1); + case EVP_PKEY_CTRL_HKDF_KEY: + return EVP_PKEY_CTX_set1_hkdf_key(ctx, p2, p1); + case EVP_PKEY_CTRL_HKDF_INFO: + return EVP_PKEY_CTX_add1_hkdf_info(ctx, p2, p1); + case EVP_PKEY_CTRL_HKDF_MODE: + return EVP_PKEY_CTX_hkdf_mode(ctx, p1); + + /* Scrypt */ + case EVP_PKEY_CTRL_PASS: + return EVP_PKEY_CTX_set1_pbe_pass(ctx, p2, p1); + case EVP_PKEY_CTRL_SCRYPT_SALT: + return EVP_PKEY_CTX_set1_scrypt_salt(ctx, p2, p1); + case EVP_PKEY_CTRL_SCRYPT_N: + return EVP_PKEY_CTX_set_scrypt_N(ctx, p1); + case EVP_PKEY_CTRL_SCRYPT_R: + return EVP_PKEY_CTX_set_scrypt_r(ctx, p1); + case EVP_PKEY_CTRL_SCRYPT_P: + return EVP_PKEY_CTX_set_scrypt_p(ctx, p1); + case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES: + return EVP_PKEY_CTX_set_scrypt_maxmem_bytes(ctx, p1); + } + } else if (optype == EVP_PKEY_OP_KEYGEN) { + OSSL_PARAM params[2], *p = params; + + switch (cmd) { + case EVP_PKEY_CTRL_CIPHER: + { + char *ciphname = (char *)EVP_CIPHER_name(p2); + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_CIPHER, + ciphname, 0); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); + } + case EVP_PKEY_CTRL_SET_MAC_KEY: + { + *p++ = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, + p2, p1); + *p = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, params); + } + } + } switch (cmd) { case EVP_PKEY_CTRL_MD: return EVP_PKEY_CTX_set_signature_md(ctx, p2); @@ -935,56 +1431,87 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, return -2; } } + + /* + * GOST CMS format is different for different cipher algorithms. + * Most of other algorithms don't have such a difference + * so this ctrl is just ignored. + */ + if (cmd == EVP_PKEY_CTRL_CIPHER) + return -2; + return 0; } -int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, - int cmd, int p1, void *p2) +static int evp_pkey_ctx_ctrl_int(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) { - int ret; + int ret = 0; - if (ctx == NULL) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; + /* + * If the method has a |digest_custom| function, we can relax the + * operation type check, since this can be called before the operation + * is initialized. + */ + if (ctx->pmeth == NULL || ctx->pmeth->digest_custom == NULL) { + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + EVPerr(0, EVP_R_NO_OPERATION_SET); + return -1; + } + + if ((optype != -1) && !(ctx->operation & optype)) { + EVPerr(0, EVP_R_INVALID_OPERATION); + return -1; + } } - if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL) - || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) - && ctx->op.sig.sigprovctx != NULL) - || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) - && ctx->op.ciph.ciphprovctx != NULL) - || (EVP_PKEY_CTX_IS_GEN_OP(ctx) - && ctx->op.keymgmt.genctx != NULL)) + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2); + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) { + EVPerr(0, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) + return -1; - if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; + ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + + if (ret == -2) + EVPerr(0, EVP_R_COMMAND_NOT_SUPPORTED); + break; } - if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) - return -1; + return ret; +} - /* Skip the operation checks since this is called in a very early stage */ - if (ctx->pmeth->digest_custom != NULL) - goto doit; +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) +{ + int ret = 0; - if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); - return -1; + if (ctx == NULL) { + EVPerr(0, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; } - - if ((optype != -1) && !(ctx->operation & optype)) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); - return -1; + /* If unsupported, we don't want that reported here */ + ERR_set_mark(); + ret = evp_pkey_ctx_store_cached_data(ctx, keytype, optype, + cmd, NULL, p2, p1); + if (ret == -2) { + ERR_pop_to_mark(); + } else { + ERR_clear_last_mark(); + /* + * If there was an error, there was an error. + * If the operation isn't initialized yet, we also return, as + * the saved values will be used then anyway. + */ + if (ret < 1 || ctx->operation == EVP_PKEY_OP_UNDEFINED) + return ret; } - - doit: - ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); - - if (ret == -2) - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - - return ret; + return evp_pkey_ctx_ctrl_int(ctx, keytype, optype, cmd, p1, p2); } int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, @@ -996,25 +1523,9 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, const char *value) { - - /* Special cases that we intercept */ -# ifndef OPENSSL_NO_EC - /* - * We don't support encoding settings for providers, i.e. the only - * possible encoding is "named_curve", so we simply fail when something - * else is given, and otherwise just pretend all is fine. - */ - if (strcmp(name, "ec_param_enc") == 0) { - if (strcmp(value, "named_curve") == 0) { - return 1; - } else { - ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - } -# endif - - if (strcmp(name, "rsa_padding_mode") == 0) + if (strcmp(name, "md") == 0) + name = OSSL_ALG_PARAM_DIGEST; + else if (strcmp(name, "rsa_padding_mode") == 0) name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE; else if (strcmp(name, "rsa_mgf1_md") == 0) name = OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST; @@ -1058,7 +1569,7 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, name = OSSL_PKEY_PARAM_GROUP_NAME; else if (strcmp(name, "dh_rfc5114") == 0) { name = OSSL_PKEY_PARAM_GROUP_NAME; - value = ffc_named_group_from_uid(atoi(value)); + value = ossl_ffc_named_group_from_uid(atoi(value)); } else if (strcmp(name, "dh_pad") == 0) name = OSSL_EXCHANGE_PARAM_PAD; # endif @@ -1069,7 +1580,11 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE; else if (strcmp(name, "ecdh_kdf_md") == 0) name = OSSL_EXCHANGE_PARAM_KDF_DIGEST; + else if (strcmp(name, "ec_param_enc") == 0) + name = OSSL_PKEY_PARAM_EC_ENCODING; # endif + else if (strcmp(name, "N") == 0) + name = OSSL_KDF_PARAM_SCRYPT_N; { /* @@ -1098,31 +1613,163 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, } } -int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, - const char *name, const char *value) +static int evp_pkey_ctx_ctrl_str_int(EVP_PKEY_CTX *ctx, + const char *name, const char *value) { + int ret = 0; + if (ctx == NULL) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + EVPerr(0, EVP_R_COMMAND_NOT_SUPPORTED); return -2; } - if ((EVP_PKEY_CTX_IS_DERIVE_OP(ctx) && ctx->op.kex.exchprovctx != NULL) - || (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) - && ctx->op.sig.sigprovctx != NULL) - || (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) - && ctx->op.ciph.ciphprovctx != NULL) - || (EVP_PKEY_CTX_IS_GEN_OP(ctx) - && ctx->op.keymgmt.genctx != NULL)) + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: return legacy_ctrl_str_to_param(ctx, name, value); + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->ctrl_str == NULL) { + EVPerr(0, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (strcmp(name, "digest") == 0) + ret = EVP_PKEY_CTX_md(ctx, + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_MD, value); + else + ret = ctx->pmeth->ctrl_str(ctx, name, value); + break; + } - if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; + return ret; +} + +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, + const char *name, const char *value) +{ + int ret = 0; + + /* If unsupported, we don't want that reported here */ + ERR_set_mark(); + ret = evp_pkey_ctx_store_cached_data(ctx, -1, -1, -1, + name, value, strlen(value) + 1); + if (ret == -2) { + ERR_pop_to_mark(); + } else { + ERR_clear_last_mark(); + /* + * If there was an error, there was an error. + * If the operation isn't initialized yet, we also return, as + * the saved values will be used then anyway. + */ + if (ret < 1 || ctx->operation == EVP_PKEY_OP_UNDEFINED) + return ret; + } + + return evp_pkey_ctx_ctrl_str_int(ctx, name, value); +} + +static int decode_cmd(int cmd, const char *name) +{ + if (cmd == -1) { + /* + * The consequence of the assertion not being true is that this + * function will return -1, which will cause the calling functions + * to signal that the command is unsupported... in non-debug mode. + */ + if (ossl_assert(name != NULL)) + if (strcmp(name, "distid") == 0 || strcmp(name, "hexdistid") == 0) + cmd = EVP_PKEY_CTRL_SET1_ID; + } + + return cmd; +} + +static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, + int keytype, int optype, + int cmd, const char *name, + const void *data, size_t data_len) +{ + if ((keytype != -1 && ctx->pmeth->pkey_id != keytype) + || ((optype != -1) && !(ctx->operation & optype))) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + + cmd = decode_cmd(cmd, name); + switch (cmd) { + case EVP_PKEY_CTRL_SET1_ID: + evp_pkey_ctx_free_cached_data(ctx, cmd, name); + if (name != NULL) { + ctx->cached_parameters.dist_id_name = OPENSSL_strdup(name); + if (ctx->cached_parameters.dist_id_name == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + } + if (data_len > 0) { + ctx->cached_parameters.dist_id = OPENSSL_memdup(data, data_len); + if (ctx->cached_parameters.dist_id == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ctx->cached_parameters.dist_id_set = 1; + ctx->cached_parameters.dist_id_len = data_len; + return 1; + } + + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; +} + +static void evp_pkey_ctx_free_cached_data(EVP_PKEY_CTX *ctx, + int cmd, const char *name) +{ + cmd = decode_cmd(cmd, name); + switch (cmd) { + case EVP_PKEY_CTRL_SET1_ID: + OPENSSL_free(ctx->cached_parameters.dist_id); + OPENSSL_free(ctx->cached_parameters.dist_id_name); + ctx->cached_parameters.dist_id = NULL; + ctx->cached_parameters.dist_id_name = NULL; + break; } - if (strcmp(name, "digest") == 0) - return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, - value); - return ctx->pmeth->ctrl_str(ctx, name, value); +} + +static void evp_pkey_ctx_free_all_cached_data(EVP_PKEY_CTX *ctx) +{ + evp_pkey_ctx_free_cached_data(ctx, EVP_PKEY_CTRL_SET1_ID, NULL); +} + +int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx) +{ + int ret = 1; + + if (ret && ctx->cached_parameters.dist_id_set) { + const char *name = ctx->cached_parameters.dist_id_name; + const void *val = ctx->cached_parameters.dist_id; + size_t len = ctx->cached_parameters.dist_id_len; + + if (name != NULL) + ret = evp_pkey_ctx_ctrl_str_int(ctx, name, val); + else + ret = evp_pkey_ctx_ctrl_int(ctx, -1, ctx->operation, + EVP_PKEY_CTRL_SET1_ID, + (int)len, (void *)val); + } + + return ret; +} + +OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx) +{ + return ctx->libctx; +} + +const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx) +{ + return ctx->propquery; } /* Utility functions to send a string of hex string to a ctrl */ diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c index 03fd8582f8..0ea8934689 100644 --- a/crypto/evp/signature.c +++ b/crypto/evp/signature.c @@ -298,7 +298,7 @@ OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature) return signature->prov; } -EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_SIGNATURE *EVP_SIGNATURE_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties) { return evp_generic_fetch(ctx, OSSL_OP_SIGNATURE, algorithm, properties, @@ -317,7 +317,7 @@ int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature) return signature->name_id; } -void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx, +void EVP_SIGNATURE_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_SIGNATURE *signature, void *arg), void *arg) @@ -337,6 +337,28 @@ void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature, evp_names_do_all(signature->prov, signature->name_id, fn, data); } +const OSSL_PARAM *EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig) +{ + void *provctx; + + if (sig == NULL || sig->gettable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_SIGNATURE_provider(sig)); + return sig->gettable_ctx_params(provctx); +} + +const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig) +{ + void *provctx; + + if (sig == NULL || sig->settable_ctx_params == NULL) + return NULL; + + provctx = ossl_provider_ctx(EVP_SIGNATURE_provider(sig)); + return sig->settable_ctx_params(provctx); +} + static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) { int ret = 0; @@ -359,7 +381,7 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) */ ERR_set_mark(); - if (ctx->keymgmt == NULL) + if (evp_pkey_ctx_is_legacy(ctx)) goto legacy; /* @@ -460,7 +482,7 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) ctx->op.sig.sigprovctx = NULL; goto err; } - return 1; + goto end; legacy: /* @@ -501,8 +523,13 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) } if (ret <= 0) goto err; - return ret; + end: +#ifndef FIPS_MODULE + if (ret > 0) + ret = evp_pkey_ctx_use_cached_data(ctx); +#endif + return ret; err: evp_pkey_ctx_free_old_ops(ctx); ctx->operation = EVP_PKEY_OP_UNDEFINED; diff --git a/crypto/ex_data.c b/crypto/ex_data.c index 80a136164a..3b06c0b90e 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -10,11 +10,9 @@ #include "crypto/cryptlib.h" #include "internal/thread_once.h" -DEFINE_STACK_OF(void) - -int do_ex_data_init(OPENSSL_CTX *ctx) +int do_ex_data_init(OSSL_LIB_CTX *ctx) { - OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx); + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); if (global == NULL) return 0; @@ -61,10 +59,10 @@ static void cleanup_cb(EX_CALLBACK *funcs) * called under potential race-conditions anyway (it's for program shutdown * after all). */ -void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx) +void crypto_cleanup_all_ex_data_int(OSSL_LIB_CTX *ctx) { int i; - OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx); + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); if (global == NULL) return; @@ -102,12 +100,12 @@ static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, return 1; } -int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx) +int crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx) { EX_CALLBACKS *ip; EX_CALLBACK *a; int toret = 0; - OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx); + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); if (global == NULL) return 0; @@ -138,7 +136,7 @@ int CRYPTO_free_ex_index(int class_index, int idx) /* * Register a new index. */ -int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl, +int crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) @@ -146,7 +144,7 @@ int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl, int toret = -1; EX_CALLBACK *a; EX_CALLBACKS *ip; - OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx); + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); if (global == NULL) return -1; @@ -205,7 +203,7 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, * in the lock, then using them outside the lock. Note this only applies * to the global "ex_data" state (ie. class definitions), not 'ad' itself. */ -int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj, +int crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, CRYPTO_EX_DATA *ad) { int mx, i; @@ -213,7 +211,7 @@ int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj, EX_CALLBACK **storage = NULL; EX_CALLBACK *stack[10]; EX_CALLBACKS *ip; - OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ctx); + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ctx); if (global == NULL) return 0; @@ -277,7 +275,7 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, /* Nothing to copy over */ return 1; - global = openssl_ctx_get_ex_data_global(from->ctx); + global = ossl_lib_ctx_get_ex_data_global(from->ctx); if (global == NULL) return 0; @@ -344,7 +342,7 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) EX_CALLBACK *f; EX_CALLBACK *stack[10]; EX_CALLBACK **storage = NULL; - OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ad->ctx); + OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ad->ctx); if (global == NULL) goto err; @@ -404,7 +402,7 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, if (curval != NULL) return 1; - global = openssl_ctx_get_ex_data_global(ad->ctx); + global = ossl_lib_ctx_get_ex_data_global(ad->ctx); if (global == NULL) return 0; @@ -447,7 +445,11 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) return 0; } } - sk_void_set(ad->sk, idx, val); + if (sk_void_set(ad->sk, idx, val) != val) { + /* Probably the index is out of bounds */ + CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } return 1; } @@ -462,7 +464,7 @@ void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) return sk_void_value(ad->sk, idx); } -OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad) +OSSL_LIB_CTX *crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad) { return ad->ctx; } diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c index 6e269ebf56..fddd41557e 100644 --- a/crypto/ffc/ffc_backend.c +++ b/crypto/ffc/ffc_backend.c @@ -17,7 +17,7 @@ * implementations alike. */ -int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) +int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) { const OSSL_PARAM *prm; const OSSL_PARAM *param_p, *param_q, *param_g; @@ -36,7 +36,7 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) * In a no-dh build we just go straight to err because we have no * support for this. */ - if (!ffc_set_group_pqg(ffc, prm->data)) + if (!ossl_ffc_set_group_pqg(ffc, prm->data)) #endif goto err; } @@ -75,14 +75,14 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) if (prm != NULL) { if (prm->data_type != OSSL_PARAM_OCTET_STRING) goto err; - if (!ffc_params_set_seed(ffc, prm->data, prm->data_size)) + if (!ossl_ffc_params_set_seed(ffc, prm->data, prm->data_size)) goto err; } prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE); if (prm != NULL) { if (prm->data_type != OSSL_PARAM_UTF8_STRING) goto err; - ffc_params_set_flags(ffc, ffc_params_flags_from_name(prm->data)); + ossl_ffc_params_set_flags(ffc, ossl_ffc_params_flags_from_name(prm->data)); } prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST); if (prm != NULL) { @@ -96,12 +96,12 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) if (p1->data_type != OSSL_PARAM_UTF8_STRING) goto err; } - if (!ffc_set_digest(ffc, prm->data, props)) + if (!ossl_ffc_set_digest(ffc, prm->data, props)) goto err; } - ffc_params_set0_pqg(ffc, p, q, g); - ffc_params_set0_j(ffc, j); + ossl_ffc_params_set0_pqg(ffc, p, q, g); + ossl_ffc_params_set0_j(ffc, j); return 1; err: diff --git a/crypto/ffc/ffc_key_generate.c b/crypto/ffc/ffc_key_generate.c index aeabae010f..d8d2116ddc 100644 --- a/crypto/ffc/ffc_key_generate.c +++ b/crypto/ffc/ffc_key_generate.c @@ -19,8 +19,8 @@ * s is the security strength. * priv_key is the returned private key, */ -int ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params, - int N, int s, BIGNUM *priv) +int ossl_ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params, + int N, int s, BIGNUM *priv) { int ret = 0, qbits = BN_num_bits(params->q); BIGNUM *m, *two_powN = NULL; diff --git a/crypto/ffc/ffc_key_validate.c b/crypto/ffc/ffc_key_validate.c index a35f52e1b9..9f6525a2c8 100644 --- a/crypto/ffc/ffc_key_validate.c +++ b/crypto/ffc/ffc_key_validate.c @@ -16,8 +16,8 @@ * * ret contains 0 on success, or error flags (see FFC_ERROR_PUBKEY_TOO_SMALL) */ -int ffc_validate_public_key_partial(const FFC_PARAMS *params, - const BIGNUM *pub_key, int *ret) +int ossl_ffc_validate_public_key_partial(const FFC_PARAMS *params, + const BIGNUM *pub_key, int *ret) { int ok = 0; BIGNUM *tmp = NULL; @@ -58,14 +58,14 @@ int ffc_validate_public_key_partial(const FFC_PARAMS *params, /* * See SP800-56Ar3 Section 5.6.2.3.1 : FFC Full public key validation. */ -int ffc_validate_public_key(const FFC_PARAMS *params, const BIGNUM *pub_key, - int *ret) +int ossl_ffc_validate_public_key(const FFC_PARAMS *params, + const BIGNUM *pub_key, int *ret) { int ok = 0; BIGNUM *tmp = NULL; BN_CTX *ctx = NULL; - if (!ffc_validate_public_key_partial(params, pub_key, ret)) + if (!ossl_ffc_validate_public_key_partial(params, pub_key, ret)) return 0; if (params->q != NULL) { @@ -100,7 +100,8 @@ int ffc_validate_public_key(const FFC_PARAMS *params, const BIGNUM *pub_key, * is normally params->q but can be 2^N for approved safe prime groups. * Note: This assumes that the domain parameters are valid. */ -int ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv, int *ret) +int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv, + int *ret) { int ok = 0; diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c index d70aeea35b..edcb44b152 100644 --- a/crypto/ffc/ffc_params.c +++ b/crypto/ffc/ffc_params.c @@ -15,10 +15,10 @@ #include "e_os.h" /* strcasecmp */ #ifndef FIPS_MODULE -# include /* ffc_params_print */ +# include /* ossl_ffc_params_print */ #endif -void ffc_params_init(FFC_PARAMS *params) +void ossl_ffc_params_init(FFC_PARAMS *params) { memset(params, 0, sizeof(*params)); params->pcounter = -1; @@ -26,17 +26,17 @@ void ffc_params_init(FFC_PARAMS *params) params->flags = FFC_PARAM_FLAG_VALIDATE_ALL; } -void ffc_params_cleanup(FFC_PARAMS *params) +void ossl_ffc_params_cleanup(FFC_PARAMS *params) { BN_free(params->p); BN_free(params->q); BN_free(params->g); BN_free(params->j); OPENSSL_free(params->seed); - ffc_params_init(params); + ossl_ffc_params_init(params); } -void ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +void ossl_ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) { if (p != NULL && p != d->p) { BN_free(d->p); @@ -52,8 +52,8 @@ void ffc_params_set0_pqg(FFC_PARAMS *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) } } -void ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, - const BIGNUM **q, const BIGNUM **g) +void ossl_ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g) { if (p != NULL) *p = d->p; @@ -65,7 +65,7 @@ void ffc_params_get0_pqg(const FFC_PARAMS *d, const BIGNUM **p, /* j is the 'cofactor' that is optionally output for ASN1. */ -void ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) +void ossl_ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) { BN_free(d->j); d->j = NULL; @@ -73,8 +73,8 @@ void ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j) d->j = j; } -int ffc_params_set_seed(FFC_PARAMS *params, - const unsigned char *seed, size_t seedlen) +int ossl_ffc_params_set_seed(FFC_PARAMS *params, + const unsigned char *seed, size_t seedlen) { if (params == NULL) return 0; @@ -97,46 +97,55 @@ int ffc_params_set_seed(FFC_PARAMS *params, return 1; } -void ffc_params_set_gindex(FFC_PARAMS *params, int index) +void ossl_ffc_params_set_gindex(FFC_PARAMS *params, int index) { params->gindex = index; } -void ffc_params_set_pcounter(FFC_PARAMS *params, int index) +void ossl_ffc_params_set_pcounter(FFC_PARAMS *params, int index) { params->pcounter = index; } -void ffc_params_set_h(FFC_PARAMS *params, int index) +void ossl_ffc_params_set_h(FFC_PARAMS *params, int index) { params->h = index; } -void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags) +void ossl_ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags) { params->flags = flags; } -int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) +void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, + int enable) +{ + if (enable) + params->flags |= flags; + else + params->flags &= ~flags; +} + +int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props) { params->mdname = alg; params->mdprops = props; return 1; } -int ffc_params_set_validate_params(FFC_PARAMS *params, - const unsigned char *seed, size_t seedlen, - int counter) +int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, + const unsigned char *seed, + size_t seedlen, int counter) { - if (!ffc_params_set_seed(params, seed, seedlen)) + if (!ossl_ffc_params_set_seed(params, seed, seedlen)) return 0; params->pcounter = counter; return 1; } -void ffc_params_get_validate_params(const FFC_PARAMS *params, - unsigned char **seed, size_t *seedlen, - int *pcounter) +void ossl_ffc_params_get_validate_params(const FFC_PARAMS *params, + unsigned char **seed, size_t *seedlen, + int *pcounter) { if (seed != NULL) *seed = params->seed; @@ -166,7 +175,7 @@ static int ffc_bn_cpy(BIGNUM **dst, const BIGNUM *src) return 1; } -int ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) +int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) { if (!ffc_bn_cpy(&dst->p, src->p) || !ffc_bn_cpy(&dst->g, src->g) @@ -190,7 +199,7 @@ int ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src) return 1; } -int ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) +int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q) { return BN_cmp(a->p, b->p) == 0 && BN_cmp(a->g, b->g) == 0 @@ -204,7 +213,7 @@ static const OSSL_ITEM flag_map[] = { { 0, "" } }; -int ffc_params_flags_from_name(const char *name) +int ossl_ffc_params_flags_from_name(const char *name) { size_t i; @@ -215,7 +224,7 @@ int ffc_params_flags_from_name(const char *name) return NID_undef; } -const char *ffc_params_flags_to_name(int flags) +const char *ossl_ffc_params_flags_to_name(int flags) { size_t i; @@ -227,7 +236,7 @@ const char *ffc_params_flags_to_name(int flags) return ""; } -int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, +int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) { if (ffc == NULL) @@ -261,7 +270,7 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, return 0; if (ffc->nid != NID_undef) { #ifndef OPENSSL_NO_DH - const char *name = ffc_named_group_from_uid(ffc->nid); + const char *name = ossl_ffc_named_group_from_uid(ffc->nid); if (name == NULL || !ossl_param_build_set_utf8_string(bld, params, @@ -275,7 +284,7 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, } if (!ossl_param_build_set_utf8_string(bld, params, OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE, - ffc_params_flags_to_name(ffc->flags))) + ossl_ffc_params_flags_to_name(ffc->flags))) return 0; if (ffc->mdname != NULL && !ossl_param_build_set_utf8_string(bld, params, @@ -291,7 +300,7 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, } #ifndef FIPS_MODULE -int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) +int ossl_ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) { if (!ASN1_bn_print(bp, "prime P:", ffc->p, NULL, indent)) goto err; @@ -305,8 +314,10 @@ int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) goto err; if (ffc->seed != NULL) { size_t i; - BIO_indent(bp, indent, 128); - BIO_puts(bp, "seed:"); + + if (!BIO_indent(bp, indent, 128) + || BIO_puts(bp, "seed:") <= 0) + goto err; for (i = 0; i < ffc->seedlen; i++) { if ((i % 15) == 0) { if (BIO_puts(bp, "\n") <= 0 @@ -321,8 +332,8 @@ int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent) return 0; } if (ffc->pcounter != -1) { - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "counter: %d\n", ffc->pcounter) <= 0) + if (!BIO_indent(bp, indent, 128) + || BIO_printf(bp, "counter: %d\n", ffc->pcounter) <= 0) goto err; } return 1; diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c index 8a0b77e7f8..815b38efbf 100644 --- a/crypto/ffc/ffc_params_generate.c +++ b/crypto/ffc/ffc_params_generate.c @@ -37,34 +37,59 @@ * Verify that the passed in L, N pair for DH or DSA is valid. * Returns 0 if invalid, otherwise it returns the security strength. */ -static int ffc_validate_LN(size_t L, size_t N, int type) -{ -#ifndef FIPS_MODULE - if (L == 1024 && N == 160) - return 80; -#endif +#ifdef FIPS_MODULE +static int ffc_validate_LN(size_t L, size_t N, int type, int verify) +{ if (type == FFC_PARAM_TYPE_DH) { /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ if (L == 2048 && (N == 224 || N == 256)) return 112; -#ifndef OPENSSL_NO_DH +# ifndef OPENSSL_NO_DH DHerr(0, DH_R_BAD_FFC_PARAMETERS); -#endif +# endif } else if (type == FFC_PARAM_TYPE_DSA) { /* Valid DSA L,N parameters from FIPS 186-4 Section 4.2 */ + /* In fips mode 1024/160 can only be used for verification */ + if (verify && L == 1024 && N == 160) + return 80; + if (L == 2048 && (N == 224 || N == 256)) + return 112; + if (L == 3072 && N == 256) + return 128; +# ifndef OPENSSL_NO_DSA + DSAerr(0, DSA_R_BAD_FFC_PARAMETERS); +# endif + } + return 0; +} +#else +static int ffc_validate_LN(size_t L, size_t N, int type, int verify) +{ + if (type == FFC_PARAM_TYPE_DH) { + /* Allow legacy 1024/160 in non fips mode */ + if (L == 1024 && N == 160) + return 80; + /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ + if (L == 2048 && (N == 224 || N == 256)) + return 112; +# ifndef OPENSSL_NO_DH + DHerr(0, DH_R_BAD_FFC_PARAMETERS); +# endif + } else if (type == FFC_PARAM_TYPE_DSA) { if (L == 1024 && N == 160) return 80; if (L == 2048 && (N == 224 || N == 256)) return 112; if (L == 3072 && N == 256) return 128; -#ifndef OPENSSL_NO_DSA +# ifndef OPENSSL_NO_DSA DSAerr(0, DSA_R_BAD_FFC_PARAMETERS); -#endif +# endif } return 0; } +#endif /* FIPS_MODULE */ /* FIPS186-4 A.2.1 Unverifiable Generation of Generator g */ static int generate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, BIGNUM *g, @@ -295,7 +320,7 @@ static int generate_q_fips186_4(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, unsigned char md[EVP_MAX_MD_SIZE]; int mdsize = EVP_MD_size(evpmd); unsigned char *pmd; - OPENSSL_CTX *libctx = bn_get_lib_ctx(ctx); + OSSL_LIB_CTX *libctx = bn_get_libctx(ctx); /* find q */ for (;;) { @@ -366,7 +391,7 @@ static int generate_q_fips186_2(BN_CTX *ctx, BIGNUM *q, const EVP_MD *evpmd, unsigned char buf2[EVP_MAX_MD_SIZE]; unsigned char md[EVP_MAX_MD_SIZE]; int i, r, ret = 0, m = *retm; - OPENSSL_CTX *libctx = bn_get_lib_ctx(ctx); + OSSL_LIB_CTX *libctx = bn_get_libctx(ctx); /* find q */ for (;;) { @@ -485,9 +510,10 @@ static const char *default_mdname(size_t N) * - FFC_PARAM_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded, * but G is unverifiable. */ -int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int mode, int type, size_t L, size_t N, - int *res, BN_GENCB *cb) +int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb) { int ok = FFC_PARAM_RET_STATUS_FAILED; unsigned char *seed = NULL, *seed_tmp = NULL; @@ -513,9 +539,11 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, if (N == 0) N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8; def_name = default_mdname(N); - if (def_name == NULL) + if (def_name == NULL) { + *res = FFC_CHECK_INVALID_Q_VALUE; goto err; - md = EVP_MD_fetch(libctx, def_name, NULL); + } + md = EVP_MD_fetch(libctx, def_name, params->mdprops); } if (md == NULL) goto err; @@ -532,7 +560,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, * A.1.1.3 Step (3) * Check that the L,N pair is an acceptable pair. */ - if (L <= N || !ffc_validate_LN(L, N, type)) { + if (L <= N || !ffc_validate_LN(L, N, type, verify)) { *res = FFC_CHECK_BAD_LN_PAIR; goto err; } @@ -701,8 +729,8 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, goto err; if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) - && !ffc_params_validate_unverifiable_g(ctx, mont, p, q, params->g, - tmp, res)) + && !ossl_ffc_params_validate_unverifiable_g(ctx, mont, p, q, params->g, + tmp, res)) goto err; /* @@ -750,7 +778,8 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, } if (params->p == NULL || params->q == NULL || params->g == NULL) goto err; - if (!ffc_params_set_validate_params(params, seed, seedlen, pcounter)) + if (!ossl_ffc_params_set_validate_params(params, seed, seedlen, + pcounter)) goto err; params->h = hret; } @@ -773,9 +802,11 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, return ok; } -int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int mode, int type, size_t L, size_t N, - int *res, BN_GENCB *cb) +/* Note this function is only used for verification in fips mode */ +int ossl_ffc_params_FIPS186_2_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb) { int ok = FFC_PARAM_RET_STATUS_FAILED; unsigned char seed[SHA256_DIGEST_LENGTH]; @@ -793,6 +824,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, size_t seed_len = params->seedlen; int verify = (mode == FFC_PARAM_MODE_VERIFY); unsigned int flags = verify ? params->flags : 0; + const char *def_name; *res = 0; @@ -801,7 +833,12 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, } else { if (N == 0) N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8; - md = EVP_MD_fetch(libctx, default_mdname(N), NULL); + def_name = default_mdname(N); + if (def_name == NULL) { + *res = FFC_CHECK_INVALID_Q_VALUE; + goto err; + } + md = EVP_MD_fetch(libctx, def_name, params->mdprops); } if (md == NULL) goto err; @@ -809,16 +846,15 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, N = EVP_MD_size(md) * 8; qsize = N >> 3; -#ifdef FIPS_MODULE /* - * FIPS 186-4 states that validation can only be done for this pair. - * (Even though the original spec allowed L = 512 + 64*j (j = 0.. 8)) + * The original spec allowed L = 512 + 64*j (j = 0.. 8) + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf + * says that 512 can be used for legacy verification. */ - if (L != 1024 || N != 160) { + if (L < 512) { *res = FFC_CHECK_BAD_LN_PAIR; goto err; } -#endif if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && qsize != SHA256_DIGEST_LENGTH) { @@ -827,9 +863,6 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, goto err; } - if (L < 512) - L = 512; - L = (L + 63) / 64 * 64; if (seed_in != NULL) { @@ -958,8 +991,9 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, if (!generate_unverifiable_g(ctx, mont, g, tmp, p, r0, test, &hret)) goto err; } else if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) - && !ffc_params_validate_unverifiable_g(ctx, mont, p, q, - params->g, tmp, res)) { + && !ossl_ffc_params_validate_unverifiable_g(ctx, mont, p, q, + params->g, tmp, + res)) { goto err; } @@ -981,7 +1015,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, } if (params->p == NULL || params->q == NULL || params->g == NULL) goto err; - if (!ffc_params_set_validate_params(params, seed, qsize, pcounter)) + if (!ossl_ffc_params_set_validate_params(params, seed, qsize, pcounter)) goto err; params->h = hret; } @@ -999,21 +1033,21 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, return ok; } -int ffc_params_FIPS186_4_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int type, size_t L, size_t N, - int *res, BN_GENCB *cb) +int ossl_ffc_params_FIPS186_4_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb) { - return ffc_params_FIPS186_4_gen_verify(libctx, params, - FFC_PARAM_MODE_GENERATE, - type, L, N, res, cb); + return ossl_ffc_params_FIPS186_4_gen_verify(libctx, params, + FFC_PARAM_MODE_GENERATE, + type, L, N, res, cb); } /* This should no longer be used in FIPS mode */ -int ffc_params_FIPS186_2_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int type, size_t L, size_t N, - int *res, BN_GENCB *cb) +int ossl_ffc_params_FIPS186_2_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb) { - return ffc_params_FIPS186_2_gen_verify(libctx, params, - FFC_PARAM_MODE_GENERATE, - type, L, N, res, cb); + return ossl_ffc_params_FIPS186_2_gen_verify(libctx, params, + FFC_PARAM_MODE_GENERATE, + type, L, N, res, cb); } diff --git a/crypto/ffc/ffc_params_validate.c b/crypto/ffc/ffc_params_validate.c index 821ff3e88a..22983d62ef 100644 --- a/crypto/ffc/ffc_params_validate.c +++ b/crypto/ffc/ffc_params_validate.c @@ -16,9 +16,10 @@ #include "internal/ffc.h" /* FIPS186-4 A.2.2 Unverifiable partial validation of Generator g */ -int ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, - const BIGNUM *p, const BIGNUM *q, - const BIGNUM *g, BIGNUM *tmp, int *ret) +int ossl_ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, + const BIGNUM *p, const BIGNUM *q, + const BIGNUM *g, BIGNUM *tmp, + int *ret) { /* * A.2.2 Step (1) AND @@ -44,8 +45,9 @@ int ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, return 1; } -int ffc_params_FIPS186_4_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, - int type, int *res, BN_GENCB *cb) +int ossl_ffc_params_FIPS186_4_validate(OSSL_LIB_CTX *libctx, + const FFC_PARAMS *params, int type, + int *res, BN_GENCB *cb) { size_t L, N; @@ -55,18 +57,19 @@ int ffc_params_FIPS186_4_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */ L = BN_num_bits(params->p); N = BN_num_bits(params->q); - return ffc_params_FIPS186_4_gen_verify(libctx, (FFC_PARAMS *)params, - FFC_PARAM_MODE_VERIFY, type, - L, N, res, cb); + return ossl_ffc_params_FIPS186_4_gen_verify(libctx, (FFC_PARAMS *)params, + FFC_PARAM_MODE_VERIFY, type, + L, N, res, cb); } /* This may be used in FIPS mode to validate deprecated FIPS-186-2 Params */ -int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, - int type, int *res, BN_GENCB *cb) +int ossl_ffc_params_FIPS186_2_validate(OSSL_LIB_CTX *libctx, + const FFC_PARAMS *params, int type, + int *res, BN_GENCB *cb) { size_t L, N; - if (params->p == NULL || params->q == NULL) { + if (params == NULL || params->p == NULL || params->q == NULL) { *res = FFC_CHECK_INVALID_PQ; return FFC_PARAM_RET_STATUS_FAILED; } @@ -74,9 +77,9 @@ int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */ L = BN_num_bits(params->p); N = BN_num_bits(params->q); - return ffc_params_FIPS186_2_gen_verify(libctx, (FFC_PARAMS *)params, - FFC_PARAM_MODE_VERIFY, type, - L, N, res, cb); + return ossl_ffc_params_FIPS186_2_gen_verify(libctx, (FFC_PARAMS *)params, + FFC_PARAM_MODE_VERIFY, type, + L, N, res, cb); } /* @@ -85,7 +88,8 @@ int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, * extra parameters such as the digest and seed, which may not be available for * this test. */ -int ffc_params_simple_validate(OPENSSL_CTX *libctx, FFC_PARAMS *params, int type) +int ossl_ffc_params_simple_validate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type) { int ret, res = 0; int save_gindex; @@ -99,7 +103,14 @@ int ffc_params_simple_validate(OPENSSL_CTX *libctx, FFC_PARAMS *params, int type params->flags = FFC_PARAM_FLAG_VALIDATE_G; params->gindex = FFC_UNVERIFIABLE_GINDEX; - ret = ffc_params_FIPS186_4_validate(libctx, params, type, &res, NULL); +#ifndef FIPS_MODULE + if (save_flags & FFC_PARAM_FLAG_VALIDATE_LEGACY) + ret = ossl_ffc_params_FIPS186_2_validate(libctx, params, type, &res, + NULL); + else +#endif + ret = ossl_ffc_params_FIPS186_4_validate(libctx, params, type, &res, + NULL); params->flags = save_flags; params->gindex = save_gindex; return ret != FFC_PARAM_RET_STATUS_FAILED; diff --git a/crypto/getenv.c b/crypto/getenv.c index a49a06f8ed..e79b6cc161 100644 --- a/crypto/getenv.c +++ b/crypto/getenv.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,9 +13,81 @@ #include #include "internal/cryptlib.h" +#include "e_os.h" char *ossl_safe_getenv(const char *name) { +#if defined(_WIN32) && defined(CP_UTF8) && !defined(_WIN32_WCE) + if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) != 0) { + char *val = NULL; + int vallen = 0; + WCHAR *namew = NULL; + WCHAR *valw = NULL; + DWORD envlen = 0; + DWORD dwFlags = MB_ERR_INVALID_CHARS; + int rsize, fsize; + UINT curacp; + + curacp = GetACP(); + + /* + * For the code pages listed below, dwFlags must be set to 0. + * Otherwise, the function fails with ERROR_INVALID_FLAGS. + */ + if (curacp == 50220 || curacp == 50221 || curacp == 50222 || + curacp == 50225 || curacp == 50227 || curacp == 50229 || + (57002 <= curacp && curacp <=57011) || curacp == 65000 || + curacp == 42) + dwFlags = 0; + + /* query for buffer len */ + rsize = MultiByteToWideChar(curacp, dwFlags, name, -1, NULL, 0); + /* if name is valid string and can be converted to wide string */ + if (rsize > 0) + namew = _malloca(rsize * sizeof(WCHAR)); + + if (NULL != namew) { + /* convert name to wide string */ + fsize = MultiByteToWideChar(curacp, dwFlags, name, -1, namew, rsize); + /* if conversion is ok, then determine value string size in wchars */ + if (fsize > 0) + envlen = GetEnvironmentVariableW(namew, NULL, 0); + } + + if (envlen > 0) + valw = _malloca(envlen * sizeof(WCHAR)); + + if (NULL != valw) { + /* if can get env value as wide string */ + if (GetEnvironmentVariableW(namew, valw, envlen) < envlen) { + /* determine value string size in utf-8 */ + vallen = WideCharToMultiByte(CP_UTF8, 0, valw, -1, NULL, 0, + NULL, NULL); + } + } + + if (vallen > 0) + val = OPENSSL_malloc(vallen); + + if (NULL != val) { + /* convert value string from wide to utf-8 */ + if (WideCharToMultiByte(CP_UTF8, 0, valw, -1, val, vallen, + NULL, NULL) == 0) { + OPENSSL_free(val); + val = NULL; + } + } + + if (NULL != namew) + _freea(namew); + + if (NULL != valw) + _freea(valw); + + return val; + } +#endif + #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) # if __GLIBC_PREREQ(2, 17) # define SECURE_GETENV diff --git a/crypto/hmac/build.info b/crypto/hmac/build.info index 4ed90c09f4..b828ab122e 100644 --- a/crypto/hmac/build.info +++ b/crypto/hmac/build.info @@ -2,5 +2,5 @@ LIBS=../../libcrypto $COMMON=hmac.c -SOURCE[../../libcrypto]=$COMMON hm_ameth.c +SOURCE[../../libcrypto]=$COMMON SOURCE[../../providers/libfips.a]=$COMMON diff --git a/crypto/hmac/hm_ameth.c b/crypto/hmac/hm_ameth.c deleted file mode 100644 index a0e1556b41..0000000000 --- a/crypto/hmac/hm_ameth.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * HMAC low level APIs are deprecated for public use, but still ok for internal - * use. - */ -#include "internal/deprecated.h" - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" -#include "crypto/evp.h" - -/* - * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output - * length and to free up an HMAC key. - */ - -static int hmac_size(const EVP_PKEY *pkey) -{ - return EVP_MAX_MD_SIZE; -} - -static void hmac_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); - if (os) { - if (os->data) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_sha256; - return 1; - - default: - return -2; - } -} - -static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)); -} - -static int hmac_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, - size_t len) -{ - ASN1_OCTET_STRING *os; - - if (pkey->pkey.ptr != NULL) - return 0; - - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - return 0; - - - if (!ASN1_OCTET_STRING_set(os, priv, len)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - - pkey->pkey.ptr = os; - return 1; -} - -static int hmac_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, - size_t *len) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - - if (priv == NULL) { - *len = ASN1_STRING_length(os); - return 1; - } - - if (os == NULL || *len < (size_t)ASN1_STRING_length(os)) - return 0; - - *len = ASN1_STRING_length(os); - memcpy(priv, ASN1_STRING_get0_data(os), *len); - - return 1; -} - -const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { - EVP_PKEY_HMAC, - EVP_PKEY_HMAC, - 0, - - "HMAC", - "OpenSSL HMAC method", - - 0, 0, hmac_pkey_public_cmp, 0, - - 0, 0, 0, - - hmac_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - hmac_key_free, - hmac_pkey_ctrl, - NULL, - NULL, - - NULL, - NULL, - NULL, - - NULL, - NULL, - NULL, - - hmac_set_priv_key, - NULL, - hmac_get_priv_key, - NULL, -}; diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c index 3e1be1f569..1a68228548 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -25,8 +25,6 @@ #include "http_local.h" -DEFINE_STACK_OF(CONF_VALUE) - #define HTTP_PREFIX "HTTP/" #define HTTP_VERSION_PATT "1." /* allow 1.x */ #define HTTP_VERSION_STR_LEN 3 @@ -1005,7 +1003,8 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, return NULL; for (;;) { - if (!OSSL_HTTP_parse_url(current_url, &host, &port, &path, &use_ssl)) + if (!OSSL_HTTP_parse_url(current_url, &host, &port, NULL /* port_num */, + &path, &use_ssl)) break; new_rpath: diff --git a/crypto/http/http_err.c b/crypto/http/http_err.c index 7b6f295170..13779fac84 100644 --- a/crypto/http/http_err.c +++ b/crypto/http/http_err.c @@ -26,6 +26,11 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = { {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_SENDING), "error sending"}, {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INCONSISTENT_CONTENT_LENGTH), "inconsistent content length"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER), + "invalid port number"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PATH), "invalid url path"}, + {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PREFIX), + "invalid url prefix"}, {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED), "max resp len exceeded"}, {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING), diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c index 5da5b1e724..be790bda90 100644 --- a/crypto/http/http_lib.c +++ b/crypto/http/http_lib.c @@ -21,19 +21,12 @@ */ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, - char **ppath, int *pssl) + int *pport_num, char **ppath, int *pssl) { char *p, *buf; - char *host; - const char *port = OSSL_HTTP_PORT; - size_t https_len = strlen(OSSL_HTTPS_NAME); - - if (!ossl_assert(https_len >= strlen(OSSL_HTTP_NAME))) - return 0; - if (url == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } + char *host, *host_end; + const char *path, *port = OSSL_HTTP_PORT; + long portnum = 80; if (phost != NULL) *phost = NULL; @@ -44,59 +37,90 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, if (pssl != NULL) *pssl = 0; + if (url == NULL) { + HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* dup the buffer since we are going to mess with it */ if ((buf = OPENSSL_strdup(url)) == NULL) goto err; - /* Check for initial colon */ - p = strchr(buf, ':'); - if (p == NULL || (size_t)(p - buf) > https_len) { + /* check for optional prefix "http[s]://" */ + p = strstr(buf, "://"); + if (p == NULL) { p = buf; } else { - *(p++) = '\0'; - + *p = '\0'; /* p points to end of scheme name */ if (strcmp(buf, OSSL_HTTPS_NAME) == 0) { if (pssl != NULL) *pssl = 1; port = OSSL_HTTPS_PORT; + portnum = 443; } else if (strcmp(buf, OSSL_HTTP_NAME) != 0) { - goto parse_err; + HTTPerr(0, HTTP_R_INVALID_URL_PREFIX); + goto err; } - - /* Check for double slash */ - if ((p[0] != '/') || (p[1] != '/')) - goto parse_err; - p += 2; + p += 3; } host = p; - /* Check for trailing part of path */ - p = strchr(p, '/'); - if (ppath != NULL && (*ppath = OPENSSL_strdup(p == NULL ? "/" : p)) == NULL) - goto err; - if (p != NULL) - *p = '\0'; /* Set start of path to 0 so hostname[:port] is valid */ - - p = host; + /* parse host name/address as far as needed here */ if (host[0] == '[') { - /* ipv6 literal */ + /* ipv6 literal, which may include ':' */ host++; - p = strchr(host, ']'); - if (p == NULL) + host_end = strchr(host, ']'); + if (host_end == NULL) goto parse_err; - *p = '\0'; - p++; + *host_end++ = '\0'; + } else { + host_end = strchr(host, ':'); /* look for start of optional port */ + if (host_end == NULL) + host_end = strchr(host, '/'); /* look for start of optional path */ + if (host_end == NULL) + /* the remaining string is just the hostname */ + host_end = host + strlen(host); } - /* Look for optional ':' for port number */ - if ((p = strchr(p, ':'))) { - *p = '\0'; - port = p + 1; + /* parse optional port specification starting with ':' */ + p = host_end; + if (*p == ':') { + port = ++p; + if (pport_num == NULL) { + p = strchr(port, '/'); + if (p == NULL) + p = host_end + 1 + strlen(port); + } else { /* make sure a numerical port value is given */ + portnum = strtol(port, &p, 10); + if (p == port || (*p != '\0' && *p != '/')) + goto parse_err; + if (portnum <= 0 || portnum >= 65536) { + HTTPerr(0, HTTP_R_INVALID_PORT_NUMBER); + goto err; + } + } + } + *host_end = '\0'; + *p = '\0'; /* terminate port string */ + + /* check for optional path at end of url starting with '/' */ + path = url + (p - buf); + /* cannot use p + 1 because *p is '\0' and path must start with '/' */ + if (*path == '\0') { + path = "/"; + } else if (*path != '/') { + HTTPerr(0, HTTP_R_INVALID_URL_PATH); + goto parse_err; } + if (phost != NULL && (*phost = OPENSSL_strdup(host)) == NULL) goto err; if (pport != NULL && (*pport = OPENSSL_strdup(port)) == NULL) goto err; + if (pport_num != NULL) + *pport_num = (int)portnum; + if (ppath != NULL && (*ppath = OPENSSL_strdup(path)) == NULL) + goto err; OPENSSL_free(buf); return 1; diff --git a/crypto/init.c b/crypto/init.c index 34dd724bc5..cfd4eab9ed 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -339,7 +339,7 @@ void OPENSSL_cleanup(void) /* * TODO(3.0): This function needs looking at with a view to moving most/all - * of this into onfree handlers in OPENSSL_CTX. + * of this into onfree handlers in OSSL_LIB_CTX. */ /* If we've not been inited then no need to deinit */ @@ -396,7 +396,7 @@ void OPENSSL_cleanup(void) * - rand_cleanup_int could call an ENGINE's RAND cleanup function so * must be called before engine_cleanup_int() * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up - * before the ex data handlers are wiped during default openssl_ctx deinit. + * before the ex data handlers are wiped during default ossl_lib_ctx deinit. * - conf_modules_free_int() can end up in ENGINE code so must be called * before engine_cleanup_int() * - ENGINEs and additional EVP algorithms might use added OIDs names so @@ -412,11 +412,14 @@ void OPENSSL_cleanup(void) OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n"); engine_cleanup_int(); #endif + +#ifndef OPENSSL_NO_DEPRECATED_3_0 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n"); ossl_store_cleanup_int(); +#endif - OSSL_TRACE(INIT, "OPENSSL_cleanup: openssl_ctx_default_deinit()\n"); - openssl_ctx_default_deinit(); + OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n"); + ossl_lib_ctx_default_deinit(); ossl_cleanup_thread(); @@ -455,7 +458,7 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { /* * TODO(3.0): This function needs looking at with a view to moving most/all - * of this into OPENSSL_CTX. + * of this into OSSL_LIB_CTX. */ if (stopped) { diff --git a/crypto/initthread.c b/crypto/initthread.c index c9a34a77db..f460252ff9 100644 --- a/crypto/initthread.c +++ b/crypto/initthread.c @@ -208,12 +208,12 @@ void ossl_cleanup_thread(void) destructor_key.sane = -1; } -void OPENSSL_thread_stop_ex(OPENSSL_CTX *ctx) +void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx) { - ctx = openssl_ctx_get_concrete(ctx); + ctx = ossl_lib_ctx_get_concrete(ctx); /* * TODO(3.0). It would be nice if we could figure out a way to do this on - * all threads that have used the OPENSSL_CTX when the OPENSSL_CTX is freed. + * all threads that have used the OSSL_LIB_CTX when the context is freed. * This is currently not possible due to the use of thread local variables. */ ossl_ctx_thread_stop(ctx); @@ -242,7 +242,7 @@ void ossl_ctx_thread_stop(void *arg) #else -static void *thread_event_ossl_ctx_new(OPENSSL_CTX *libctx) +static void *thread_event_ossl_ctx_new(OSSL_LIB_CTX *libctx) { THREAD_EVENT_HANDLER **hands = NULL; CRYPTO_THREAD_LOCAL *tlocal = OPENSSL_zalloc(sizeof(*tlocal)); @@ -273,7 +273,7 @@ static void thread_event_ossl_ctx_free(void *tlocal) OPENSSL_free(tlocal); } -static const OPENSSL_CTX_METHOD thread_event_ossl_ctx_method = { +static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = { thread_event_ossl_ctx_new, thread_event_ossl_ctx_free, }; @@ -281,10 +281,10 @@ static const OPENSSL_CTX_METHOD thread_event_ossl_ctx_method = { void ossl_ctx_thread_stop(void *arg) { THREAD_EVENT_HANDLER **hands; - OPENSSL_CTX *ctx = arg; + OSSL_LIB_CTX *ctx = arg; CRYPTO_THREAD_LOCAL *local - = openssl_ctx_get_data(ctx, OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX, - &thread_event_ossl_ctx_method); + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, + &thread_event_ossl_ctx_method); if (local == NULL) return; @@ -329,22 +329,22 @@ int ossl_init_thread_start(const void *index, void *arg, THREAD_EVENT_HANDLER **hands; THREAD_EVENT_HANDLER *hand; #ifdef FIPS_MODULE - OPENSSL_CTX *ctx = arg; + OSSL_LIB_CTX *ctx = arg; /* * In FIPS mode the list of THREAD_EVENT_HANDLERs is unique per combination - * of OPENSSL_CTX and thread. This is because in FIPS mode each OPENSSL_CTX - * gets informed about thread stop events individually. + * of OSSL_LIB_CTX and thread. This is because in FIPS mode each + * OSSL_LIB_CTX gets informed about thread stop events individually. */ CRYPTO_THREAD_LOCAL *local - = openssl_ctx_get_data(ctx, OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX, - &thread_event_ossl_ctx_method); + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX, + &thread_event_ossl_ctx_method); #else /* * Outside of FIPS mode the list of THREAD_EVENT_HANDLERs is unique per - * thread, but may hold multiple OPENSSL_CTXs. We only get told about + * thread, but may hold multiple OSSL_LIB_CTXs. We only get told about * thread stop events globally, so we have to ensure all affected - * OPENSSL_CTXs are informed. + * OSSL_LIB_CTXs are informed. */ CRYPTO_THREAD_LOCAL *local = &destructor_key.value; #endif @@ -392,13 +392,14 @@ static int init_thread_deregister(void *index, int all) for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) { THREAD_EVENT_HANDLER **hands = sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i); - THREAD_EVENT_HANDLER *curr = *hands, *prev = NULL, *tmp; + THREAD_EVENT_HANDLER *curr = NULL, *prev = NULL, *tmp; if (hands == NULL) { if (!all) CRYPTO_THREAD_unlock(gtr->lock); return 0; } + curr = *hands; while (curr != NULL) { if (all || curr->index == index) { if (prev != NULL) diff --git a/crypto/md5/build.info b/crypto/md5/build.info index d4494b274d..bbb70fde3c 100644 --- a/crypto/md5/build.info +++ b/crypto/md5/build.info @@ -14,12 +14,25 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -SOURCE[../../libcrypto]=md5_dgst.c md5_one.c md5_sha1.c $MD5ASM +$COMMON=md5_dgst.c md5_one.c md5_sha1.c $MD5ASM +SOURCE[../../libcrypto]=$COMMON +SOURCE[../../providers/libimplementations.a]=$COMMON + +# A no-deprecated no-shared build ends up with double function definitions +# without conditioning this on dso. The issue is MD5 which is needed in the +# legacy provider for one of the spliced algorithms, however it resides in the +# default provider. A no-deprecated build removes the external definition from +# libcrypto and this means that the code needs to be in liblegacy. However, +# when building without 'dso', liblegacy is included in libcrypto. +IF[{- !$disabled{dso} -}] + SOURCE[../../providers/liblegacy.a]=$COMMON +ENDIF # Implementations are now spread across several libraries, so the defines # need to be applied to all affected libraries and modules. DEFINE[../../libcrypto]=$MD5DEF DEFINE[../../providers/libimplementations.a]=$MD5DEF +DEFINE[../../providers/liblegacy.a]=$MD5DEF GENERATE[md5-586.s]=asm/md5-586.pl diff --git a/crypto/modes/asm/aesni-gcm-x86_64.pl b/crypto/modes/asm/aesni-gcm-x86_64.pl index 37953109a5..eaf4d9c755 100644 --- a/crypto/modes/asm/aesni-gcm-x86_64.pl +++ b/crypto/modes/asm/aesni-gcm-x86_64.pl @@ -67,7 +67,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/modes/asm/ghash-x86_64.pl b/crypto/modes/asm/ghash-x86_64.pl index 5a8d2e0b69..6709f96492 100644 --- a/crypto/modes/asm/ghash-x86_64.pl +++ b/crypto/modes/asm/ghash-x86_64.pl @@ -117,7 +117,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c index 27e29c3cc6..c8bfdb0c51 100644 --- a/crypto/modes/siv128.c +++ b/crypto/modes/siv128.c @@ -142,7 +142,7 @@ __owur static ossl_inline int siv128_do_encrypt(EVP_CIPHER_CTX *ctx, unsigned ch */ SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER *cbc, EVP_CIPHER *ctr, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { SIV128_CONTEXT *ctx; int ret; @@ -162,19 +162,16 @@ SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, */ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, const EVP_CIPHER *cbc, const EVP_CIPHER *ctr, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { static const unsigned char zero[SIV_LEN] = { 0 }; size_t out_len = SIV_LEN; EVP_MAC_CTX *mac_ctx = NULL; OSSL_PARAM params[3]; - const char *cbc_name = EVP_CIPHER_name(cbc); + const char *cbc_name; - params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, - (char *)cbc_name, 0); - params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, - (void *)key, klen); - params[2] = OSSL_PARAM_construct_end(); + if (ctx == NULL) + return 0; memset(&ctx->d, 0, sizeof(ctx->d)); EVP_CIPHER_CTX_free(ctx->cipher_ctx); @@ -184,8 +181,17 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, ctx->cipher_ctx = NULL; ctx->mac_ctx_init = NULL; - if (key == NULL || cbc == NULL || ctr == NULL - || (ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL + if (key == NULL || cbc == NULL || ctr == NULL) + return 0; + + cbc_name = EVP_CIPHER_name(cbc); + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, + (char *)cbc_name, 0); + params[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)key, klen); + params[2] = OSSL_PARAM_construct_end(); + + if ((ctx->cipher_ctx = EVP_CIPHER_CTX_new()) == NULL || (ctx->mac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, propq)) == NULL || (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index decf33ef9b..440fd1d6af 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -10,7 +10,7 @@ */ /* Serialized OID's */ -static const unsigned char so[7845] = { +static const unsigned char so[7947] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -1086,9 +1086,24 @@ static const unsigned char so[7845] = { 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x05, /* [ 7820] OBJ_XmppAddr */ 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x07, /* [ 7828] OBJ_SRVName */ 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x08, /* [ 7836] OBJ_NAIRealm */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1D, /* [ 7844] OBJ_cmcArchive */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1E, /* [ 7852] OBJ_id_kp_bgpsec_router */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1F, /* [ 7860] OBJ_id_kp_BrandIndicatorforMessageIdentification */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x20, /* [ 7868] OBJ_cmKGA */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x11, /* [ 7876] OBJ_id_it_caCerts */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x12, /* [ 7884] OBJ_id_it_rootCaKeyUpdate */ + 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x13, /* [ 7892] OBJ_id_it_certReqTemplate */ + 0x2A,0x85,0x03,0x64,0x05, /* [ 7900] OBJ_OGRNIP */ + 0x2A,0x85,0x03,0x64,0x71, /* [ 7905] OBJ_classSignTool */ + 0x2A,0x85,0x03,0x64,0x71,0x01, /* [ 7910] OBJ_classSignToolKC1 */ + 0x2A,0x85,0x03,0x64,0x71,0x02, /* [ 7916] OBJ_classSignToolKC2 */ + 0x2A,0x85,0x03,0x64,0x71,0x03, /* [ 7922] OBJ_classSignToolKC3 */ + 0x2A,0x85,0x03,0x64,0x71,0x04, /* [ 7928] OBJ_classSignToolKB1 */ + 0x2A,0x85,0x03,0x64,0x71,0x05, /* [ 7934] OBJ_classSignToolKB2 */ + 0x2A,0x85,0x03,0x64,0x71,0x06, /* [ 7940] OBJ_classSignToolKA1 */ }; -#define NUM_NID 1219 +#define NUM_NID 1234 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2309,9 +2324,24 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"modp_6144", "modp_6144", NID_modp_6144}, {"modp_8192", "modp_8192", NID_modp_8192}, {"KxGOST18", "kx-gost18", NID_kx_gost18}, + {"cmcArchive", "CMC Archive Server", NID_cmcArchive, 8, &so[7844]}, + {"id-kp-bgpsec-router", "BGPsec Router", NID_id_kp_bgpsec_router, 8, &so[7852]}, + {"id-kp-BrandIndicatorforMessageIdentification", "Brand Indicator for Message Identification", NID_id_kp_BrandIndicatorforMessageIdentification, 8, &so[7860]}, + {"cmKGA", "Certificate Management Key Generation Authority", NID_cmKGA, 8, &so[7868]}, + {"id-it-caCerts", "id-it-caCerts", NID_id_it_caCerts, 8, &so[7876]}, + {"id-it-rootCaKeyUpdate", "id-it-rootCaKeyUpdate", NID_id_it_rootCaKeyUpdate, 8, &so[7884]}, + {"id-it-certReqTemplate", "id-it-certReqTemplate", NID_id_it_certReqTemplate, 8, &so[7892]}, + {"OGRNIP", "OGRNIP", NID_OGRNIP, 5, &so[7900]}, + {"classSignTool", "Class of Signing Tool", NID_classSignTool, 5, &so[7905]}, + {"classSignToolKC1", "Class of Signing Tool KC1", NID_classSignToolKC1, 6, &so[7910]}, + {"classSignToolKC2", "Class of Signing Tool KC2", NID_classSignToolKC2, 6, &so[7916]}, + {"classSignToolKC3", "Class of Signing Tool KC3", NID_classSignToolKC3, 6, &so[7922]}, + {"classSignToolKB1", "Class of Signing Tool KB1", NID_classSignToolKB1, 6, &so[7928]}, + {"classSignToolKB2", "Class of Signing Tool KB2", NID_classSignToolKB2, 6, &so[7934]}, + {"classSignToolKA1", "Class of Signing Tool KA1", NID_classSignToolKA1, 6, &so[7940]}, }; -#define NUM_SN 1210 +#define NUM_SN 1225 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2512,6 +2542,7 @@ static const unsigned int sn_objs[NUM_SN] = { 178, /* "OCSP" */ 180, /* "OCSPSigning" */ 1005, /* "OGRN" */ + 1226, /* "OGRNIP" */ 379, /* "ORG" */ 18, /* "OU" */ 749, /* "Oakley-EC2N-3" */ @@ -2690,8 +2721,17 @@ static const unsigned int sn_objs[NUM_SN] = { 883, /* "certificateRevocationList" */ 54, /* "challengePassword" */ 407, /* "characteristic-two-field" */ + 1227, /* "classSignTool" */ + 1233, /* "classSignToolKA1" */ + 1231, /* "classSignToolKB1" */ + 1232, /* "classSignToolKB2" */ + 1228, /* "classSignToolKC1" */ + 1229, /* "classSignToolKC2" */ + 1230, /* "classSignToolKC3" */ 395, /* "clearance" */ 130, /* "clientAuth" */ + 1222, /* "cmKGA" */ + 1219, /* "cmcArchive" */ 1131, /* "cmcCA" */ 1132, /* "cmcRA" */ 131, /* "codeSigning" */ @@ -2931,8 +2971,10 @@ static const unsigned int sn_objs[NUM_SN] = { 1104, /* "id-hmacWithSHA3-384" */ 1105, /* "id-hmacWithSHA3-512" */ 260, /* "id-it" */ + 1223, /* "id-it-caCerts" */ 302, /* "id-it-caKeyUpdateInfo" */ 298, /* "id-it-caProtEncCert" */ + 1225, /* "id-it-certReqTemplate" */ 311, /* "id-it-confirmWaitTime" */ 303, /* "id-it-currentCRL" */ 300, /* "id-it-encKeyPairTypes" */ @@ -2942,12 +2984,15 @@ static const unsigned int sn_objs[NUM_SN] = { 312, /* "id-it-origPKIMessage" */ 301, /* "id-it-preferredSymmAlg" */ 309, /* "id-it-revPassphrase" */ + 1224, /* "id-it-rootCaKeyUpdate" */ 299, /* "id-it-signKeyPairTypes" */ 305, /* "id-it-subscriptionRequest" */ 306, /* "id-it-subscriptionResponse" */ 784, /* "id-it-suppLangTags" */ 304, /* "id-it-unsupportedOIDs" */ 128, /* "id-kp" */ + 1221, /* "id-kp-BrandIndicatorforMessageIdentification" */ + 1220, /* "id-kp-bgpsec-router" */ 280, /* "id-mod-attribute-cert" */ 274, /* "id-mod-cmc" */ 277, /* "id-mod-cmp" */ @@ -3525,7 +3570,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1093, /* "x509ExtAdmission" */ }; -#define NUM_LN 1210 +#define NUM_LN 1225 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3533,16 +3578,27 @@ static const unsigned int ln_objs[NUM_LN] = { 910, /* "Any Extended Key Usage" */ 664, /* "Any language" */ 177, /* "Authority Information Access" */ + 1220, /* "BGPsec Router" */ 365, /* "Basic OCSP Response" */ 285, /* "Biometric Info" */ + 1221, /* "Brand Indicator for Message Identification" */ 179, /* "CA Issuers" */ 785, /* "CA Repository" */ + 1219, /* "CMC Archive Server" */ 1131, /* "CMC Certificate Authority" */ 1132, /* "CMC Registration Authority" */ 954, /* "CT Certificate SCTs" */ 952, /* "CT Precertificate Poison" */ 951, /* "CT Precertificate SCTs" */ 953, /* "CT Precertificate Signer" */ + 1222, /* "Certificate Management Key Generation Authority" */ + 1227, /* "Class of Signing Tool" */ + 1233, /* "Class of Signing Tool KA1" */ + 1231, /* "Class of Signing Tool KB1" */ + 1232, /* "Class of Signing Tool KB2" */ + 1228, /* "Class of Signing Tool KC1" */ + 1229, /* "Class of Signing Tool KC2" */ + 1230, /* "Class of Signing Tool KC3" */ 131, /* "Code Signing" */ 1024, /* "Ctrl/Provision WAP Termination" */ 1023, /* "Ctrl/provision WAP Access" */ @@ -3663,6 +3719,7 @@ static const unsigned int ln_objs[NUM_LN] = { 371, /* "OCSP Service Locator" */ 180, /* "OCSP Signing" */ 1005, /* "OGRN" */ + 1226, /* "OGRNIP" */ 161, /* "PBES2" */ 69, /* "PBKDF2" */ 162, /* "PBMAC1" */ @@ -4144,8 +4201,10 @@ static const unsigned int ln_objs[NUM_LN] = { 508, /* "id-hex-multipart-message" */ 507, /* "id-hex-partial-message" */ 260, /* "id-it" */ + 1223, /* "id-it-caCerts" */ 302, /* "id-it-caKeyUpdateInfo" */ 298, /* "id-it-caProtEncCert" */ + 1225, /* "id-it-certReqTemplate" */ 311, /* "id-it-confirmWaitTime" */ 303, /* "id-it-currentCRL" */ 300, /* "id-it-encKeyPairTypes" */ @@ -4155,6 +4214,7 @@ static const unsigned int ln_objs[NUM_LN] = { 312, /* "id-it-origPKIMessage" */ 301, /* "id-it-preferredSymmAlg" */ 309, /* "id-it-revPassphrase" */ + 1224, /* "id-it-rootCaKeyUpdate" */ 299, /* "id-it-signKeyPairTypes" */ 305, /* "id-it-subscriptionRequest" */ 306, /* "id-it-subscriptionResponse" */ @@ -4739,7 +4799,7 @@ static const unsigned int ln_objs[NUM_LN] = { 125, /* "zlib compression" */ }; -#define NUM_OBJ 1081 +#define NUM_OBJ 1096 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -4993,8 +5053,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { 974, /* OBJ_id_tc26 1 2 643 7 1 */ 1005, /* OBJ_OGRN 1 2 643 100 1 */ 1006, /* OBJ_SNILS 1 2 643 100 3 */ + 1226, /* OBJ_OGRNIP 1 2 643 100 5 */ 1007, /* OBJ_subjectSignTool 1 2 643 100 111 */ 1008, /* OBJ_issuerSignTool 1 2 643 100 112 */ + 1227, /* OBJ_classSignTool 1 2 643 100 113 */ 184, /* OBJ_X9_57 1 2 840 10040 */ 405, /* OBJ_ansi_X9_62 1 2 840 10045 */ 389, /* OBJ_Enterprises 1 3 6 1 4 1 */ @@ -5083,6 +5145,12 @@ static const unsigned int obj_objs[NUM_OBJ] = { 818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ 977, /* OBJ_id_tc26_algorithms 1 2 643 7 1 1 */ 994, /* OBJ_id_tc26_constants 1 2 643 7 1 2 */ + 1228, /* OBJ_classSignToolKC1 1 2 643 100 113 1 */ + 1229, /* OBJ_classSignToolKC2 1 2 643 100 113 2 */ + 1230, /* OBJ_classSignToolKC3 1 2 643 100 113 3 */ + 1231, /* OBJ_classSignToolKB1 1 2 643 100 113 4 */ + 1232, /* OBJ_classSignToolKB2 1 2 643 100 113 5 */ + 1233, /* OBJ_classSignToolKA1 1 2 643 100 113 6 */ 1, /* OBJ_rsadsi 1 2 840 113549 */ 185, /* OBJ_X9cm 1 2 840 10040 4 */ 1031, /* OBJ_id_pkinit 1 3 6 1 5 2 3 */ @@ -5345,6 +5413,10 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1030, /* OBJ_sendProxiedOwner 1 3 6 1 5 5 7 3 26 */ 1131, /* OBJ_cmcCA 1 3 6 1 5 5 7 3 27 */ 1132, /* OBJ_cmcRA 1 3 6 1 5 5 7 3 28 */ + 1219, /* OBJ_cmcArchive 1 3 6 1 5 5 7 3 29 */ + 1220, /* OBJ_id_kp_bgpsec_router 1 3 6 1 5 5 7 3 30 */ + 1221, /* OBJ_id_kp_BrandIndicatorforMessageIdentification 1 3 6 1 5 5 7 3 31 */ + 1222, /* OBJ_cmKGA 1 3 6 1 5 5 7 3 32 */ 298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ 299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ 300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ @@ -5361,6 +5433,9 @@ static const unsigned int obj_objs[NUM_OBJ] = { 311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ 312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ 784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ + 1223, /* OBJ_id_it_caCerts 1 3 6 1 5 5 7 4 17 */ + 1224, /* OBJ_id_it_rootCaKeyUpdate 1 3 6 1 5 5 7 4 18 */ + 1225, /* OBJ_id_it_certReqTemplate 1 3 6 1 5 5 7 4 19 */ 313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ 314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ 323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 6d2c0d74a8..7d1d70ea28 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1216,3 +1216,18 @@ modp_4096 1215 modp_6144 1216 modp_8192 1217 kx_gost18 1218 +cmcArchive 1219 +id_kp_bgpsec_router 1220 +id_kp_BrandIndicatorforMessageIdentification 1221 +cmKGA 1222 +id_it_caCerts 1223 +id_it_rootCaKeyUpdate 1224 +id_it_certReqTemplate 1225 +OGRNIP 1226 +classSignTool 1227 +classSignToolKC1 1228 +classSignToolKC2 1229 +classSignToolKC3 1230 +classSignToolKB1 1231 +classSignToolKB2 1232 +classSignToolKA1 1233 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index b19454209b..8aef90d952 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -509,6 +509,7 @@ id-qt 1 : id-qt-cps : Policy Qualifier CPS id-qt 2 : id-qt-unotice : Policy Qualifier User Notice id-qt 3 : textNotice +# https://www.iana.org/assignments/smi-numbers/smi-numbers.xhtml#smi-numbers-1.3.6.1.5.5.7.3 # PKIX key purpose identifiers !Cname server-auth id-kp 1 : serverAuth : TLS Web Server Authentication @@ -541,7 +542,12 @@ id-kp 25 : sendOwner : Send Owner id-kp 26 : sendProxiedOwner : Send Proxied Owner id-kp 27 : cmcCA : CMC Certificate Authority id-kp 28 : cmcRA : CMC Registration Authority +id-kp 29 : cmcArchive : CMC Archive Server +id-kp 30 : id-kp-bgpsec-router : BGPsec Router +id-kp 31 : id-kp-BrandIndicatorforMessageIdentification : Brand Indicator for Message Identification +id-kp 32 : cmKGA : Certificate Management Key Generation Authority +# https://www.iana.org/assignments/smi-numbers/smi-numbers.xhtml#smi-numbers-1.3.6.1.5.5.7.4 # CMP information types id-it 1 : id-it-caProtEncCert id-it 2 : id-it-signKeyPairTypes @@ -561,6 +567,9 @@ id-it 13 : id-it-implicitConfirm id-it 14 : id-it-confirmWaitTime id-it 15 : id-it-origPKIMessage id-it 16 : id-it-suppLangTags +id-it 17 : id-it-caCerts +id-it 18 : id-it-rootCaKeyUpdate +id-it 19 : id-it-certReqTemplate # CRMF registration id-pkip 1 : id-regCtrl @@ -1397,8 +1406,16 @@ id-tc26-gost-28147-constants 1 : id-tc26-gost-28147-param-Z : GOST 28147-89 TC26 member-body 643 3 131 1 1 : INN : INN member-body 643 100 1 : OGRN : OGRN member-body 643 100 3 : SNILS : SNILS +member-body 643 100 5 : OGRNIP : OGRNIP member-body 643 100 111 : subjectSignTool : Signing Tool of Subject member-body 643 100 112 : issuerSignTool : Signing Tool of Issuer +member-body 643 100 113 : classSignTool : Class of Signing Tool +member-body 643 100 113 1 : classSignToolKC1 : Class of Signing Tool KC1 +member-body 643 100 113 2 : classSignToolKC2 : Class of Signing Tool KC2 +member-body 643 100 113 3 : classSignToolKC3 : Class of Signing Tool KC3 +member-body 643 100 113 4 : classSignToolKB1 : Class of Signing Tool KB1 +member-body 643 100 113 5 : classSignToolKB2 : Class of Signing Tool KB2 +member-body 643 100 113 6 : classSignToolKA1 : Class of Signing Tool KA1 #GOST R34.13-2015 Grasshopper "Kuznechik" : kuznyechik-ecb diff --git a/crypto/ocsp/ocsp_cl.c b/crypto/ocsp/ocsp_cl.c index 95b16dce55..33d77af426 100644 --- a/crypto/ocsp/ocsp_cl.c +++ b/crypto/ocsp/ocsp_cl.c @@ -18,10 +18,6 @@ #include #include "ocsp_local.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(OCSP_ONEREQ) -DEFINE_STACK_OF(OCSP_SINGLERESP) - /* * Utility functions related to sending OCSP requests and extracting relevant * information from the response. @@ -81,14 +77,7 @@ int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) return 0; if (cert == NULL) return 1; - if (sig->certs == NULL - && (sig->certs = sk_X509_new_null()) == NULL) - return 0; - - if (!sk_X509_push(sig->certs, cert)) - return 0; - X509_up_ref(cert); - return 1; + return X509_add_cert_new(&sig->certs, cert, X509_ADD_FLAG_UP_REF); } /* diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c index 7cd36723e2..518e0432a3 100644 --- a/crypto/ocsp/ocsp_err.c +++ b/crypto/ocsp/ocsp_err.c @@ -17,6 +17,8 @@ static const ERR_STRING_DATA OCSP_str_reasons[] = { {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_ERR), "digest err"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_NAME_ERR), "digest name err"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_SIZE_ERR), "digest size err"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), "error in nextupdate field"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_THISUPDATE_FIELD), diff --git a/crypto/ocsp/ocsp_ext.c b/crypto/ocsp/ocsp_ext.c index 77e67840b8..c2b61bd4f2 100644 --- a/crypto/ocsp/ocsp_ext.c +++ b/crypto/ocsp/ocsp_ext.c @@ -16,9 +16,6 @@ #include #include -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF(ACCESS_DESCRIPTION) - /* Standard wrapper functions for extensions */ /* OCSP request extensions */ diff --git a/crypto/ocsp/ocsp_local.h b/crypto/ocsp/ocsp_local.h index 3ae337faeb..1e7de1384f 100644 --- a/crypto/ocsp/ocsp_local.h +++ b/crypto/ocsp/ocsp_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include "crypto/x509.h" /* for X509_add_cert_new() */ + /*- CertID ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier, * issuerNameHash OCTET STRING, -- Hash of Issuer's DN @@ -232,5 +234,5 @@ struct ocsp_service_locator_st { &(a)->optionalSignature->signatureAlgorithm,\ (a)->optionalSignature->signature,&(a)->tbsRequest,r) -# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ +# define OCSP_BASICRESP_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ &(a)->signatureAlgorithm,(a)->signature,&(a)->tbsResponseData,r) diff --git a/crypto/ocsp/ocsp_prn.c b/crypto/ocsp/ocsp_prn.c index c782a8e531..654ddbc7ff 100644 --- a/crypto/ocsp/ocsp_prn.c +++ b/crypto/ocsp/ocsp_prn.c @@ -14,10 +14,6 @@ #include "internal/cryptlib.h" #include -DEFINE_STACK_OF(OCSP_ONEREQ) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(OCSP_SINGLERESP) - static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) { BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); diff --git a/crypto/ocsp/ocsp_srv.c b/crypto/ocsp/ocsp_srv.c index 3cfe3649cc..22f637548d 100644 --- a/crypto/ocsp/ocsp_srv.c +++ b/crypto/ocsp/ocsp_srv.c @@ -16,10 +16,6 @@ #include #include "ocsp_local.h" -DEFINE_STACK_OF(OCSP_ONEREQ) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(OCSP_SINGLERESP) - /* * Utility functions related to sending OCSP responses and extracting * relevant information from the request. @@ -162,14 +158,7 @@ OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) { - if (resp->certs == NULL - && (resp->certs = sk_X509_new_null()) == NULL) - return 0; - - if (!sk_X509_push(resp->certs, cert)) - return 0; - X509_up_ref(cert); - return 1; + return X509_add_cert_new(&resp->certs, cert, X509_ADD_FLAG_UP_REF); } /* @@ -264,7 +253,7 @@ int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert) } int OCSP_RESPID_set_by_key_ex(OCSP_RESPID *respid, X509 *cert, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { ASN1_OCTET_STRING *byKey = NULL; unsigned char md[SHA_DIGEST_LENGTH]; @@ -301,7 +290,7 @@ int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert) return OCSP_RESPID_set_by_key_ex(respid, cert, NULL, NULL); } -int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OPENSSL_CTX *libctx, +int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OSSL_LIB_CTX *libctx, const char *propq) { EVP_MD *sha1 = NULL; diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c index 0dccb24eb5..0cd59f9221 100644 --- a/crypto/ocsp/ocsp_vfy.c +++ b/crypto/ocsp/ocsp_vfy.c @@ -12,10 +12,6 @@ #include #include -DEFINE_STACK_OF(OCSP_ONEREQ) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(OCSP_SINGLERESP) - static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, unsigned long flags); static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); @@ -29,77 +25,111 @@ static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, const X509_NAME *nm, STACK_OF(X509) *certs, unsigned long flags); -/* Verify a basic response message */ +/* Returns 1 on success, 0 on failure, or -1 on fatal error */ +static int ocsp_verify_signer(X509 *signer, int response, + X509_STORE *st, unsigned long flags, + STACK_OF(X509) *untrusted, STACK_OF(X509) **chain) +{ + X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + X509_VERIFY_PARAM *vp; + int ret = -1; + + if (ctx == NULL) { + OCSPerr(0, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!X509_STORE_CTX_init(ctx, st, signer, untrusted)) { + OCSPerr(0, ERR_R_X509_LIB); + goto end; + } + if ((vp = X509_STORE_CTX_get0_param(ctx)) == NULL) + goto end; + if ((flags & OCSP_PARTIAL_CHAIN) != 0) + X509_VERIFY_PARAM_set_flags(vp, X509_V_FLAG_PARTIAL_CHAIN); + if (response + && X509_get_ext_by_NID(signer, NID_id_pkix_OCSP_noCheck, -1) >= 0) + /* + * Locally disable revocation status checking for OCSP responder cert. + * Done here for CRLs; TODO should be done also for OCSP-based checks. + */ + X509_VERIFY_PARAM_clear_flags(vp, X509_V_FLAG_CRL_CHECK); + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); + X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST); + /* TODO: why is X509_TRUST_OCSP_REQUEST set? Seems to get ignored. */ + + ret = X509_verify_cert(ctx); + if (ret <= 0) { + ret = X509_STORE_CTX_get_error(ctx); + OCSPerr(0, OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(ret)); + goto end; + } + if (chain != NULL) + *chain = X509_STORE_CTX_get1_chain(ctx); + + end: + X509_STORE_CTX_free(ctx); + return ret; +} +static int ocsp_verify(OCSP_REQUEST *req, OCSP_BASICRESP *bs, + X509 *signer, unsigned long flags) +{ + EVP_PKEY *skey; + int ret = 1; + + if ((flags & OCSP_NOSIGS) == 0) { + if ((skey = X509_get0_pubkey(signer)) == NULL) { + OCSPerr(0, OCSP_R_NO_SIGNER_KEY); + return -1; + } + if (req != NULL) + ret = OCSP_REQUEST_verify(req, skey); + else + ret = OCSP_BASICRESP_verify(bs, skey); + if (ret <= 0) + OCSPerr(0, OCSP_R_SIGNATURE_FAILURE); + } + return ret; +} + +/* Verify a basic response message */ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags) { X509 *signer, *x; STACK_OF(X509) *chain = NULL; STACK_OF(X509) *untrusted = NULL; - X509_STORE_CTX *ctx = NULL; - int i, ret = ocsp_find_signer(&signer, bs, certs, flags); + int ret = ocsp_find_signer(&signer, bs, certs, flags); - if (!ret) { + if (ret == 0) { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); goto end; } - ctx = X509_STORE_CTX_new(); - if (ctx == NULL) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0) flags |= OCSP_NOVERIFY; - if (!(flags & OCSP_NOSIGS)) { - EVP_PKEY *skey; - skey = X509_get0_pubkey(signer); - if (skey == NULL) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_NO_SIGNER_KEY); - goto err; - } - ret = OCSP_BASICRESP_verify(bs, skey, 0); - if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); - goto end; - } - } - if (!(flags & OCSP_NOVERIFY)) { - int init_res; - if (flags & OCSP_NOCHAIN) { + + if ((ret = ocsp_verify(NULL, bs, signer, flags)) <= 0) + goto end; + if ((flags & OCSP_NOVERIFY) == 0) { + ret = -1; + if ((flags & OCSP_NOCHAIN) != 0) { untrusted = NULL; - } else if (bs->certs && certs) { + } else if (bs->certs != NULL && certs != NULL) { untrusted = sk_X509_dup(bs->certs); - for (i = 0; i < sk_X509_num(certs); i++) { - if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - } + if (!X509_add_certs(untrusted, certs, X509_ADD_FLAG_DEFAULT)) + goto end; } else if (certs != NULL) { untrusted = certs; } else { untrusted = bs->certs; } - init_res = X509_STORE_CTX_init(ctx, st, signer, untrusted); - if (!init_res) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); - goto f_err; - } - - X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); - ret = X509_verify_cert(ctx); - chain = X509_STORE_CTX_get1_chain(ctx); - if (ret <= 0) { - i = X509_STORE_CTX_get_error(ctx); - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, - OCSP_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(i)); + ret = ocsp_verify_signer(signer, 1, st, flags, untrusted, &chain); + if (ret <= 0) goto end; - } - if (flags & OCSP_NOCHECKS) { + if ((flags & OCSP_NOCHECKS) != 0) { ret = 1; goto end; } @@ -117,38 +147,29 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, * Easy case: explicitly trusted. Get root CA and check for explicit * trust */ - if (flags & OCSP_NOEXPLICIT) + if ((flags & OCSP_NOEXPLICIT) != 0) goto end; x = sk_X509_value(chain, sk_X509_num(chain) - 1); if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); - goto err; + ret = 0; + goto end; } ret = 1; } + end: - X509_STORE_CTX_free(ctx); sk_X509_pop_free(chain, X509_free); if (bs->certs && certs) sk_X509_free(untrusted); return ret; - - err: - ret = 0; - goto end; - f_err: - ret = -1; - goto end; } int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, STACK_OF(X509) *extra_certs) { - int ret; - - ret = ocsp_find_signer(signer, bs, extra_certs, 0); - return (ret > 0) ? 1 : 0; + return ocsp_find_signer(signer, bs, extra_certs, 0) > 0; } static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, @@ -156,11 +177,12 @@ static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, { X509 *signer; OCSP_RESPID *rid = &bs->tbsResponseData.responderId; - if ((signer = ocsp_find_signer_sk(certs, rid))) { + + if ((signer = ocsp_find_signer_sk(certs, rid)) != NULL) { *psigner = signer; return 2; } - if (!(flags & OCSP_NOINTERN) && + if ((flags & OCSP_NOINTERN) == 0 && (signer = ocsp_find_signer_sk(bs->certs, rid))) { *psigner = signer; return 1; @@ -190,8 +212,9 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) /* Calculate hash of each key and compare */ for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); - X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); - if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) + if (!X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL)) + break; + if (memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH) == 0) return x; } return NULL; @@ -199,11 +222,10 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain) { - STACK_OF(OCSP_SINGLERESP) *sresp; + STACK_OF(OCSP_SINGLERESP) *sresp = bs->tbsResponseData.responses; X509 *signer, *sca; OCSP_CERTID *caid = NULL; - int i; - sresp = bs->tbsResponseData.responses; + int ret; if (sk_X509_num(chain) <= 0) { OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); @@ -211,20 +233,20 @@ static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain) } /* See if the issuer IDs match. */ - i = ocsp_check_ids(sresp, &caid); + ret = ocsp_check_ids(sresp, &caid); /* If ID mismatch or other error then return */ - if (i <= 0) - return i; + if (ret <= 0) + return ret; signer = sk_X509_value(chain, 0); /* Check to see if OCSP responder CA matches request CA */ if (sk_X509_num(chain) > 1) { sca = sk_X509_value(chain, 1); - i = ocsp_match_issuerid(sca, caid, sresp); - if (i < 0) - return i; - if (i) { + ret = ocsp_match_issuerid(sca, caid, sresp); + if (ret < 0) + return ret; + if (ret != 0) { /* We have a match, if extensions OK then success */ if (ocsp_check_delegated(signer)) return 1; @@ -258,7 +280,6 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; *ret = NULL; - for (i = 1; i < idcount; i++) { tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; /* Check to see if IDs match */ @@ -277,52 +298,59 @@ static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) return 1; } +/* + * Match the certificate issuer ID. + * Returns -1 on fatal error, 0 if there is no match and 1 if there is a match. + */ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, STACK_OF(OCSP_SINGLERESP) *sresp) { /* If only one ID to match then do it */ - if (cid) { - const EVP_MD *dgst; + if (cid != NULL) { + const EVP_MD *dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm); const X509_NAME *iname; int mdlen; unsigned char md[EVP_MAX_MD_SIZE]; - if ((dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm)) - == NULL) { - OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, - OCSP_R_UNKNOWN_MESSAGE_DIGEST); + + if (dgst == NULL) { + OCSPerr(0, OCSP_R_UNKNOWN_MESSAGE_DIGEST); return -1; } mdlen = EVP_MD_size(dgst); - if (mdlen < 0) + if (mdlen < 0) { + OCSPerr(0, OCSP_R_DIGEST_SIZE_ERR); return -1; - if ((cid->issuerNameHash.length != mdlen) || - (cid->issuerKeyHash.length != mdlen)) + } + if (cid->issuerNameHash.length != mdlen || + cid->issuerKeyHash.length != mdlen) return 0; iname = X509_get_subject_name(cert); - if (!X509_NAME_digest(iname, dgst, md, NULL)) + if (!X509_NAME_digest(iname, dgst, md, NULL)) { + OCSPerr(0, OCSP_R_DIGEST_NAME_ERR); return -1; - if (memcmp(md, cid->issuerNameHash.data, mdlen)) + } + if (memcmp(md, cid->issuerNameHash.data, mdlen) != 0) return 0; - X509_pubkey_digest(cert, dgst, md, NULL); - if (memcmp(md, cid->issuerKeyHash.data, mdlen)) + if (!X509_pubkey_digest(cert, dgst, md, NULL)) { + OCSPerr(0, OCSP_R_DIGEST_ERR); + return -1; + } + if (memcmp(md, cid->issuerKeyHash.data, mdlen) != 0) return 0; - - return 1; - } else { /* We have to match the whole lot */ int i, ret; OCSP_CERTID *tmpid; + for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; ret = ocsp_match_issuerid(cert, tmpid, NULL); if (ret <= 0) return ret; } - return 1; } - + return 1; } static int ocsp_check_delegated(X509 *x) @@ -335,86 +363,46 @@ static int ocsp_check_delegated(X509 *x) } /* - * Verify an OCSP request. This is fortunately much easier than OCSP response - * verify. Just find the signers certificate and verify it against a given - * trust value. + * Verify an OCSP request. This is much easier than OCSP response verify. + * Just find the signer's certificate and verify it against a given trust value. + * Returns 1 on success, 0 on failure and on fatal error. */ - int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags) { X509 *signer; const X509_NAME *nm; GENERAL_NAME *gen; - int ret = 0; - X509_STORE_CTX *ctx = X509_STORE_CTX_new(); - - if (ctx == NULL) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } + int ret; if (!req->optionalSignature) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); - goto err; + return 0; } gen = req->tbsRequest.requestorName; if (!gen || gen->type != GEN_DIRNAME) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); - goto err; + return 0; /* not returning -1 here for backward compatibility*/ } nm = gen->d.directoryName; ret = ocsp_req_find_signer(&signer, req, nm, certs, flags); if (ret <= 0) { OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); - goto err; + return 0; /* not returning -1 here for backward compatibility*/ } - if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0) flags |= OCSP_NOVERIFY; - if (!(flags & OCSP_NOSIGS)) { - EVP_PKEY *skey; - skey = X509_get0_pubkey(signer); - ret = OCSP_REQUEST_verify(req, skey); - if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); - goto err; - } - } - if (!(flags & OCSP_NOVERIFY)) { - int init_res; - if (flags & OCSP_NOCHAIN) - init_res = X509_STORE_CTX_init(ctx, store, signer, NULL); - else - init_res = X509_STORE_CTX_init(ctx, store, signer, - req->optionalSignature->certs); - if (!init_res) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); - goto err; - } - - X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER); - X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST); - ret = X509_verify_cert(ctx); - if (ret <= 0) { - ret = X509_STORE_CTX_get_error(ctx); - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(ret)); - goto err; - } - } - ret = 1; - goto end; - -err: - ret = 0; -end: - X509_STORE_CTX_free(ctx); - return ret; + if ((ret = ocsp_verify(req, NULL, signer, flags)) <= 0) + return 0; /* not returning 'ret' here for backward compatibility*/ + if ((flags & OCSP_NOVERIFY) != 0) + return 1; + return ocsp_verify_signer(signer, 0, store, flags, + (flags & OCSP_NOCHAIN) != 0 ? + NULL : req->optionalSignature->certs, NULL) > 0; + /* using '> 0' here to avoid breaking backward compatibility returning -1 */ } static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, @@ -422,16 +410,16 @@ static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, unsigned long flags) { X509 *signer; - if (!(flags & OCSP_NOINTERN)) { + + if ((flags & OCSP_NOINTERN) == 0) { signer = X509_find_by_subject(req->optionalSignature->certs, nm); - if (signer) { + if (signer != NULL) { *psigner = signer; return 1; } } - signer = X509_find_by_subject(certs, nm); - if (signer) { + if ((signer = X509_find_by_subject(certs, nm)) != NULL) { *psigner = signer; return 2; } diff --git a/crypto/ocsp/v3_ocsp.c b/crypto/ocsp/v3_ocsp.c index 1501321948..2f2684b9a4 100644 --- a/crypto/ocsp/v3_ocsp.c +++ b/crypto/ocsp/v3_ocsp.c @@ -16,8 +16,6 @@ # include # include "../x509/ext_dat.h" -DEFINE_STACK_OF(ACCESS_DESCRIPTION) - /* * OCSP extensions and a couple of CRL entry extensions */ diff --git a/crypto/params.c b/crypto/params.c index 67ca4f0c83..4f7e25e0ca 100644 --- a/crypto/params.c +++ b/crypto/params.c @@ -969,3 +969,29 @@ OSSL_PARAM OSSL_PARAM_construct_end(void) return end; } + +static int get_string_ptr_internal(const OSSL_PARAM *p, const void **val, + size_t *used_len, unsigned int type) +{ + if (val == NULL || p == NULL || p->data_type != type) + return 0; + if (used_len != NULL) + *used_len = p->data_size; + *val = p->data; + return 1; +} + +int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val) +{ + return OSSL_PARAM_get_utf8_ptr(p, val) + || get_string_ptr_internal(p, (const void **)val, NULL, + OSSL_PARAM_UTF8_STRING); +} + +int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val, + size_t *used_len) +{ + return OSSL_PARAM_get_octet_ptr(p, val, used_len) + || get_string_ptr_internal(p, val, used_len, OSSL_PARAM_OCTET_STRING); +} + diff --git a/crypto/passphrase.c b/crypto/passphrase.c new file mode 100644 index 0000000000..170374f9d9 --- /dev/null +++ b/crypto/passphrase.c @@ -0,0 +1,325 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/passphrase.h" + +void ossl_pw_clear_passphrase_data(struct ossl_passphrase_data_st *data) +{ + if (data != NULL) { + if (data->type == is_expl_passphrase) + OPENSSL_clear_free(data->_.expl_passphrase.passphrase_copy, + data->_.expl_passphrase.passphrase_len); + ossl_pw_clear_passphrase_cache(data); + memset(data, 0, sizeof(*data)); + } +} + +void ossl_pw_clear_passphrase_cache(struct ossl_passphrase_data_st *data) +{ + OPENSSL_clear_free(data->cached_passphrase, data->cached_passphrase_len); + data->cached_passphrase = NULL; +} + +int ossl_pw_set_passphrase(struct ossl_passphrase_data_st *data, + const unsigned char *passphrase, + size_t passphrase_len) +{ + if (!ossl_assert(data != NULL && passphrase != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_expl_passphrase; + data->_.expl_passphrase.passphrase_copy = + OPENSSL_memdup(passphrase, passphrase_len); + if (data->_.expl_passphrase.passphrase_copy == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + data->_.expl_passphrase.passphrase_len = passphrase_len; + return 1; +} + +int ossl_pw_set_pem_password_cb(struct ossl_passphrase_data_st *data, + pem_password_cb *cb, void *cbarg) +{ + if (!ossl_assert(data != NULL && cb != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_pem_password; + data->_.pem_password.password_cb = cb; + data->_.pem_password.password_cbarg = cbarg; + return 1; +} + +int ossl_pw_set_ossl_passphrase_cb(struct ossl_passphrase_data_st *data, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) +{ + if (!ossl_assert(data != NULL && cb != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_ossl_passphrase; + data->_.ossl_passphrase.passphrase_cb = cb; + data->_.ossl_passphrase.passphrase_cbarg = cbarg; + return 1; +} + +int ossl_pw_set_ui_method(struct ossl_passphrase_data_st *data, + const UI_METHOD *ui_method, void *ui_data) +{ + if (!ossl_assert(data != NULL && ui_method != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ossl_pw_clear_passphrase_data(data); + data->type = is_ui_method; + data->_.ui_method.ui_method = ui_method; + data->_.ui_method.ui_method_data = ui_data; + return 1; +} + +int ossl_pw_enable_passphrase_caching(struct ossl_passphrase_data_st *data) +{ + data->flag_cache_passphrase = 1; + return 1; +} + +int ossl_pw_disable_passphrase_caching(struct ossl_passphrase_data_st *data) +{ + data->flag_cache_passphrase = 0; + return 1; +} + + +/*- + * UI_METHOD processor. It differs from UI_UTIL_read_pw() like this: + * + * 1. It constructs a prompt on its own, based on |prompt_info|. + * 2. It allocates a buffer for verification on its own. + * 3. It raises errors. + * 4. It reports back the length of the prompted pass phrase. + */ +static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len, + const char *prompt_info, int verify, + const UI_METHOD *ui_method, void *ui_data) +{ + char *prompt = NULL, *vpass = NULL; + int prompt_idx = -1, verify_idx = -1; + UI *ui = NULL; + int ret = 0; + + if (!ossl_assert(pass != NULL && pass_size != 0 && pass_len != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((ui = UI_new()) == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ui_method != NULL) { + UI_set_method(ui, ui_method); + if (ui_data != NULL) + UI_add_user_data(ui, ui_data); + } + + /* Get an application constructed prompt */ + prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); + if (prompt == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto end; + } + + prompt_idx = UI_add_input_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + pass, 0, pass_size - 1) - 1; + if (prompt_idx < 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + goto end; + } + + if (verify) { + /* Get a buffer for verification prompt */ + vpass = OPENSSL_zalloc(pass_size); + if (vpass == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + goto end; + } + verify_idx = UI_add_verify_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + vpass, 0, pass_size - 1, + pass) - 1; + if (verify_idx < 0) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + goto end; + } + } + + switch (UI_process(ui)) { + case -2: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERRUPTED_OR_CANCELLED); + break; + case -1: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB); + break; + default: + *pass_len = (size_t)UI_get_result_length(ui, prompt_idx); + ret = 1; + break; + } + + end: + OPENSSL_free(vpass); + OPENSSL_free(prompt); + UI_free(ui); + return ret; +} + +/* Central pw prompting dispatcher */ +int ossl_pw_get_passphrase(char *pass, size_t pass_size, size_t *pass_len, + const OSSL_PARAM params[], int verify, + struct ossl_passphrase_data_st *data) +{ + const char *source = NULL; + size_t source_len = 0; + const char *prompt_info = NULL; + const UI_METHOD *ui_method = NULL; + UI_METHOD *allocated_ui_method = NULL; + void *ui_data = NULL; + const OSSL_PARAM *p = NULL; + int ret; + + /* Handle explicit and cached passphrases */ + + if (data->type == is_expl_passphrase) { + source = data->_.expl_passphrase.passphrase_copy; + source_len = data->_.expl_passphrase.passphrase_len; + } else if (data->flag_cache_passphrase && data->cached_passphrase != NULL) { + source = data->cached_passphrase; + source_len = data->cached_passphrase_len; + } + + if (source != NULL) { + if (source_len > pass_size) + source_len = pass_size; + memcpy(pass, source, source_len); + *pass_len = source_len; + return 1; + } + + /* Handle the is_ossl_passphrase case... that's pretty direct */ + + if (data->type == is_ossl_passphrase) { + OSSL_PASSPHRASE_CALLBACK *cb = data->_.ossl_passphrase.passphrase_cb; + void *cbarg = data->_.ossl_passphrase.passphrase_cbarg; + + ret = cb(pass, pass_size, pass_len, params, cbarg); + goto do_cache; + } + + /* Handle the is_pem_password and is_ui_method cases */ + + if ((p = OSSL_PARAM_locate_const(params, + OSSL_PASSPHRASE_PARAM_INFO)) != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT, + "Prompt info data type incorrect"); + return 0; + } + prompt_info = p->data; + } + + if (data->type == is_pem_password) { + /* We use a UI wrapper for PEM */ + pem_password_cb *cb = data->_.pem_password.password_cb; + + ui_method = allocated_ui_method = + UI_UTIL_wrap_read_pem_callback(cb, verify); + ui_data = data->_.pem_password.password_cbarg; + + if (ui_method == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } else if (data->type == is_ui_method) { + ui_method = data->_.ui_method.ui_method; + ui_data = data->_.ui_method.ui_method_data; + } + + if (ui_method == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); + return 0; + } + + ret = do_ui_passphrase(pass, pass_size, pass_len, prompt_info, verify, + ui_method, ui_data); + + UI_destroy_method(allocated_ui_method); + + do_cache: + if (ret && data->flag_cache_passphrase) { + if (data->cached_passphrase == NULL + || *pass_len > data->cached_passphrase_len) { + void *new_cache = + OPENSSL_clear_realloc(data->cached_passphrase, + data->cached_passphrase_len, + *pass_len + 1); + + if (new_cache == NULL) { + OPENSSL_cleanse(pass, *pass_len); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + data->cached_passphrase = new_cache; + } + memcpy(data->cached_passphrase, pass, *pass_len); + data->cached_passphrase[*pass_len] = '\0'; + data->cached_passphrase_len = *pass_len; + } + + return ret; +} + +int ossl_pw_pem_password(char *buf, int size, int rwflag, void *userdata) +{ + size_t password_len = 0; + OSSL_PARAM params[] = { + OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, NULL, 0), + OSSL_PARAM_END + }; + + params[0].data = "PEM"; + if (ossl_pw_get_passphrase(buf, (size_t)size, &password_len, params, + rwflag, userdata)) + return (int)password_len; + return -1; +} + +int ossl_pw_passphrase_callback_enc(char *pass, size_t pass_size, + size_t *pass_len, + const OSSL_PARAM params[], void *arg) +{ + return ossl_pw_get_passphrase(pass, pass_size, pass_len, params, 1, arg); +} + +int ossl_pw_passphrase_callback_dec(char *pass, size_t pass_size, + size_t *pass_len, + const OSSL_PARAM params[], void *arg) +{ + return ossl_pw_get_passphrase(pass, pass_size, pass_len, params, 0, arg); +} diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index 9b803082c6..bf7159a6ad 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -181,4 +181,3 @@ IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) #endif IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) -IMPLEMENT_PEM_read(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/crypto/pem/pem_err.c b/crypto/pem/pem_err.c index 014aade185..132b15cb37 100644 --- a/crypto/pem/pem_err.c +++ b/crypto/pem/pem_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -52,6 +52,8 @@ static const ERR_STRING_DATA PEM_str_reasons[] = { "unsupported encryption"}, {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_KEY_COMPONENTS), "unsupported key components"}, + {ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE), + "unsupported public key type"}, {0, NULL} }; diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c index a3981c9dda..2284959e91 100644 --- a/crypto/pem/pem_info.c +++ b/crypto/pem/pem_info.c @@ -23,13 +23,10 @@ #include #include -DEFINE_STACK_OF(X509_INFO) - #ifndef OPENSSL_NO_STDIO STACK_OF(X509_INFO) -*PEM_X509_INFO_read_with_libctx(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u, - OPENSSL_CTX *libctx, const char *propq) +*PEM_X509_INFO_read_ex(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, + void *u, OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; STACK_OF(X509_INFO) *ret; @@ -39,7 +36,7 @@ STACK_OF(X509_INFO) return 0; } BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_X509_INFO_read_bio_with_libctx(b, sk, cb, u, libctx, propq); + ret = PEM_X509_INFO_read_bio_ex(b, sk, cb, u, libctx, propq); BIO_free(b); return ret; } @@ -47,14 +44,14 @@ STACK_OF(X509_INFO) STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u) { - return PEM_X509_INFO_read_with_libctx(fp, sk, cb, u, NULL, NULL); + return PEM_X509_INFO_read_ex(fp, sk, cb, u, NULL, NULL); } #endif STACK_OF(X509_INFO) -*PEM_X509_INFO_read_bio_with_libctx(BIO *bp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u, - OPENSSL_CTX *libctx, const char *propq) +*PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, + const char *propq) { X509_INFO *xi = NULL; char *name = NULL, *header = NULL; @@ -100,7 +97,7 @@ STACK_OF(X509_INFO) goto err; goto start; } - xi->x509 = X509_new_with_libctx(libctx, propq); + xi->x509 = X509_new_ex(libctx, propq); if (xi->x509 == NULL) goto err; pp = &(xi->x509); @@ -113,7 +110,7 @@ STACK_OF(X509_INFO) goto err; goto start; } - xi->x509 = X509_new_with_libctx(libctx, propq); + xi->x509 = X509_new_ex(libctx, propq); if (xi->x509 == NULL) goto err; pp = &(xi->x509); @@ -270,7 +267,7 @@ STACK_OF(X509_INFO) STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u) { - return PEM_X509_INFO_read_bio_with_libctx(bp, sk, cb, u, NULL, NULL); + return PEM_X509_INFO_read_bio_ex(bp, sk, cb, u, NULL, NULL); } /* A TJH addition */ diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h index 2fb1e6f4d5..39dc462e54 100644 --- a/crypto/pem/pem_local.h +++ b/crypto/pem/pem_local.h @@ -12,18 +12,38 @@ * moved here. */ +#include #include -#include +#include -/* Alternative IMPLEMENT macros for provided serializers */ +/* + * Selectors, named according to the ASN.1 names used throughout libcrypto. + * + * Note that these are not absolutely mandatory, they are rather a wishlist + * of sorts. The provider implementations are free to make choices that + * make sense for them, based on these selectors. + * For example, the EC backend is likely to really just output the private + * key to a PKCS#8 structure, even thought PEM_SELECTION_PrivateKey specifies + * the public key as well. This is fine, as long as the corresponding + * decoding operation can return an object that contains what libcrypto + * expects. + */ +# define PEM_SELECTION_PUBKEY \ + (OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_PUBLIC_KEY) +# define PEM_SELECTION_PrivateKey \ + (OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_KEYPAIR) +# define PEM_SELECTION_Parameters OSSL_KEYMGMT_SELECT_ALL_PARAMETERS + +/* Alternative IMPLEMENT macros for provided encoders */ # define IMPLEMENT_PEM_provided_write_body_vars(type, asn1) \ int ret = 0; \ - const char *pq = OSSL_SERIALIZER_##asn1##_TO_PEM_PQ; \ - OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_##type(x, pq); \ + OSSL_ENCODER_CTX *ctx = \ + OSSL_ENCODER_CTX_new_by_##type(x, "PEM", PEM_SELECTION_##asn1, \ + NULL, NULL); \ \ - if (ctx != NULL && OSSL_SERIALIZER_CTX_get_serializer(ctx) == NULL) { \ - OSSL_SERIALIZER_CTX_free(ctx); \ + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) == 0) { \ + OSSL_ENCODER_CTX_free(ctx); \ goto legacy; \ } # define IMPLEMENT_PEM_provided_write_body_pass() \ @@ -38,31 +58,31 @@ } \ if (enc != NULL) { \ ret = 0; \ - if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \ - NULL)) { \ + if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \ + NULL)) { \ ret = 1; \ if (kstr != NULL \ - && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, kstr, klen)) \ + && !OSSL_ENCODER_CTX_set_passphrase(ctx, kstr, klen)) \ ret = 0; \ else if (cb != NULL \ - && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, \ - cb, u)) \ + && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx, \ + cb, u)) \ ret = 0; \ } \ } \ if (!ret) { \ - OSSL_SERIALIZER_CTX_free(ctx); \ + OSSL_ENCODER_CTX_free(ctx); \ return 0; \ } # define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \ - ret = OSSL_SERIALIZER_to_##outtype(ctx, out); \ - OSSL_SERIALIZER_CTX_free(ctx); \ + ret = OSSL_ENCODER_to_##outtype(ctx, out); \ + OSSL_ENCODER_CTX_free(ctx); \ return ret # define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ writename) \ legacy: \ return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ - x, NULL, NULL, 0, NULL, NULL) + x, NULL, NULL, 0, NULL, NULL) # define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ writename) \ legacy: \ @@ -114,15 +134,15 @@ IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \ IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) -# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \ - IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \ +# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \ IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) -# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \ +# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \ IMPLEMENT_PEM_read(name, type, str, asn1) \ IMPLEMENT_PEM_provided_write(name, type, str, asn1) -# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \ +# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \ IMPLEMENT_PEM_read(name, type, str, asn1) \ IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c index 12a25b7a82..2abf687cbd 100644 --- a/crypto/pem/pem_pk8.c +++ b/crypto/pem/pem_pk8.c @@ -9,24 +9,27 @@ #include #include "internal/cryptlib.h" +#include #include #include #include #include #include #include -#include +#include static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, const char *kstr, int klen, - pem_password_cb *cb, void *u); + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); #ifndef OPENSSL_NO_STDIO static int do_pk8pkey_fp(FILE *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, const char *kstr, int klen, - pem_password_cb *cb, void *u); + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); #endif /* * These functions write a private key in PKCS#8 format: it is a "drop in" @@ -39,39 +42,40 @@ int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u, NULL, NULL); } int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u, NULL, NULL); } int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u, NULL, NULL); } int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, int nid, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u, NULL, NULL); } static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, const char *kstr, int klen, - pem_password_cb *cb, void *u) + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; - const char *pq = isder - ? OSSL_SERIALIZER_PrivateKey_TO_DER_PQ - : OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ; - OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(x, pq); + const char *outtype = isder ? "DER" : "PEM"; + OSSL_ENCODER_CTX *ctx = + OSSL_ENCODER_CTX_new_by_EVP_PKEY(x, outtype, OSSL_KEYMGMT_SELECT_ALL, + libctx, propq); if (ctx == NULL) return 0; @@ -90,12 +94,11 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, } } - if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL) { + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0) { ret = 1; if (enc != NULL) { ret = 0; - if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), - NULL)) { + if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), NULL)) { const unsigned char *ukstr = (const unsigned char *)kstr; /* @@ -106,14 +109,14 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, */ ret = 1; if (kstr != NULL - && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, ukstr, klen)) + && !OSSL_ENCODER_CTX_set_passphrase(ctx, ukstr, klen)) ret = 0; else if (cb != NULL - && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, cb, u)) + && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx, cb, u)) ret = 0; } } - ret = ret && OSSL_SERIALIZER_to_bio(ctx, bp); + ret = ret && OSSL_ENCODER_to_bio(ctx, bp); } else { X509_SIG *p8; PKCS8_PRIV_KEY_INFO *p8inf; @@ -153,7 +156,7 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, legacy_end: PKCS8_PRIV_KEY_INFO_free(p8inf); } - OSSL_SERIALIZER_CTX_free(ctx); + OSSL_ENCODER_CTX_free(ctx); return ret; } @@ -200,33 +203,34 @@ int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u, NULL, NULL); } int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, int nid, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u, NULL, NULL); } int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, int nid, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u, NULL, NULL); } int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { - return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u, NULL, NULL); } static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, const char *kstr, int klen, - pem_password_cb *cb, void *u) + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) { BIO *bp; int ret; @@ -235,7 +239,7 @@ static int do_pk8pkey_fp(FILE *fp, const EVP_PKEY *x, int isder, int nid, PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB); return 0; } - ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u, libctx, propq); BIO_free(bp); return ret; } @@ -261,4 +265,4 @@ IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, - PKCS8_PRIV_KEY_INFO) + PKCS8_PRIV_KEY_INFO) diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index c60eed97c0..214fd1267c 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -7,6 +7,9 @@ * https://www.openssl.org/source/license.html */ +/* We need to use some STORE deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include "internal/cryptlib.h" #include @@ -19,7 +22,6 @@ #include #include #include -#include #include "crypto/store.h" #include "crypto/asn1.h" #include "crypto/evp.h" @@ -27,34 +29,61 @@ int pem_check_suffix(const char *pem_str, const char *suffix); -EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u, OPENSSL_CTX *libctx, - const char *propq) +static EVP_PKEY *pem_read_bio_key(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq, + int expected_store_info_type, + int try_secure) { EVP_PKEY *ret = NULL; OSSL_STORE_CTX *ctx = NULL; OSSL_STORE_INFO *info = NULL; - UI_METHOD *ui_method = NULL; + const UI_METHOD *ui_method = NULL; + UI_METHOD *allocated_ui_method = NULL; - if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) + if (expected_store_info_type != OSSL_STORE_INFO_PKEY + && expected_store_info_type != OSSL_STORE_INFO_PUBKEY + && expected_store_info_type != OSSL_STORE_INFO_PARAMS) { + ERR_raise(ERR_LIB_PEM, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + if (u != NULL && cb == NULL) + cb = PEM_def_callback; + if (cb == NULL) + ui_method = UI_null(); + else + ui_method = allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0); + if (ui_method == NULL) return NULL; if ((ctx = OSSL_STORE_attach(bp, "file", libctx, propq, ui_method, u, NULL, NULL)) == NULL) goto err; #ifndef OPENSSL_NO_SECURE_HEAP - { +# ifndef OPENSSL_NO_DEPRECATED_3_0 + if (try_secure) { int on = 1; if (!OSSL_STORE_ctrl(ctx, OSSL_STORE_C_USE_SECMEM, &on)) goto err; } +# endif #endif while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { - if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) { - ret = OSSL_STORE_INFO_get1_PKEY(info); - break; + if (OSSL_STORE_INFO_get_type(info) == expected_store_info_type) { + switch (expected_store_info_type) { + case OSSL_STORE_INFO_PKEY: + ret = OSSL_STORE_INFO_get1_PKEY(info); + break; + case OSSL_STORE_INFO_PUBKEY: + ret = OSSL_STORE_INFO_get1_PUBKEY(info); + break; + case OSSL_STORE_INFO_PARAMS: + ret = OSSL_STORE_INFO_get1_PARAMS(info); + break; + } } OSSL_STORE_INFO_free(info); info = NULL; @@ -65,11 +94,57 @@ EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, err: OSSL_STORE_close(ctx); - UI_destroy_method(ui_method); + UI_destroy_method(allocated_ui_method); OSSL_STORE_INFO_free(info); return ret; } +EVP_PKEY *PEM_read_bio_PUBKEY_ex(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return pem_read_bio_key(bp, x, cb, u, libctx, propq, + OSSL_STORE_INFO_PUBKEY, 0); +} + +EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + return PEM_read_bio_PUBKEY_ex(bp, x, cb, u, NULL, NULL); +} + +#ifndef OPENSSL_NO_STDIO +EVP_PKEY *PEM_read_PUBKEY_ex(FILE *fp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + BIO *b; + EVP_PKEY *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(0, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio_PUBKEY_ex(b, x, cb, u, libctx, propq); + BIO_free(b); + return ret; +} + +EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) +{ + return PEM_read_PUBKEY_ex(fp, x, cb, u, NULL, NULL); +} +#endif + +EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return pem_read_bio_key(bp, x, cb, u, libctx, propq, + OSSL_STORE_INFO_PKEY, 1); +} + EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) { @@ -90,45 +165,50 @@ PEM_write_cb_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio) return PEM_write_bio_PrivateKey_traditional(out, x, enc, kstr, klen, cb, u); } +/* + * Note: there is no way to tell a provided pkey encoder to use "traditional" + * encoding. Therefore, if the pkey is provided, we try to take a copy + * TODO: when #legacy keys are gone, this function will not be possible any + * more and should be removed. + */ int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, const unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { char pem_str[80]; - BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); - return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, - pem_str, bp, x, enc, kstr, klen, cb, u); -} - -EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) -{ - EVP_PKEY *ret = NULL; - OSSL_STORE_CTX *ctx = NULL; - OSSL_STORE_INFO *info = NULL; + EVP_PKEY *copy = NULL; + int ret; - if ((ctx = OSSL_STORE_attach(bp, "file", NULL, NULL, UI_null(), NULL, - NULL, NULL)) == NULL) - goto err; + if (evp_pkey_is_assigned(x) + && evp_pkey_is_provided(x) + && evp_pkey_copy_downgraded(©, x)) + x = copy; - while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { - if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PARAMS) { - ret = OSSL_STORE_INFO_get1_PARAMS(info); - break; - } - OSSL_STORE_INFO_free(info); - info = NULL; + if (x->ameth == NULL || x->ameth->old_priv_encode == NULL) { + ERR_raise(ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return 0; } + BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); + ret = PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_str, bp, x, enc, kstr, klen, cb, u); - if (ret != NULL && x != NULL) - *x = ret; - - err: - OSSL_STORE_close(ctx); - OSSL_STORE_INFO_free(info); + EVP_PKEY_free(copy); return ret; } +EVP_PKEY *PEM_read_bio_Parameters_ex(BIO *bp, EVP_PKEY **x, + OSSL_LIB_CTX *libctx, const char *propq) +{ + return pem_read_bio_key(bp, x, NULL, NULL, libctx, propq, + OSSL_STORE_INFO_PARAMS, 0); +} + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) +{ + return PEM_read_bio_Parameters_ex(bp, x, NULL, NULL); +} + PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio) { char pem_str[80]; @@ -147,7 +227,7 @@ PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio) #ifndef OPENSSL_NO_STDIO EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u, OPENSSL_CTX *libctx, + void *u, OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 6d85a8a4e1..95d1ff5a94 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -20,7 +20,7 @@ #include "internal/cryptlib.h" #include -#include "internal/pem_int.h" +#include "internal/pem.h" #include #include #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) @@ -186,28 +186,27 @@ static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) } -static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, - int ispub) +EVP_PKEY *ossl_b2i(const unsigned char **in, unsigned int length, int *ispub) { const unsigned char *p = *in; unsigned int bitlen, magic; int isdss; - if (ossl_do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) { - PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); + if (ossl_do_blob_header(&p, length, &magic, &bitlen, &isdss, ispub) <= 0) { + PEMerr(0, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); return NULL; } length -= 16; - if (length < blob_length(bitlen, isdss, ispub)) { - PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); + if (length < blob_length(bitlen, isdss, *ispub)) { + PEMerr(0, PEM_R_KEYBLOB_TOO_SHORT); return NULL; } if (isdss) - return b2i_dss(&p, bitlen, ispub); + return b2i_dss(&p, bitlen, *ispub); else - return b2i_rsa(&p, bitlen, ispub); + return b2i_rsa(&p, bitlen, *ispub); } -static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) +EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub) { const unsigned char *p; unsigned char hdr_buf[16], *buf = NULL; @@ -215,33 +214,33 @@ static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) int isdss; EVP_PKEY *ret = NULL; if (BIO_read(in, hdr_buf, 16) != 16) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + PEMerr(0, PEM_R_KEYBLOB_TOO_SHORT); return NULL; } p = hdr_buf; - if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) + if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, ispub) <= 0) return NULL; - length = blob_length(bitlen, isdss, ispub); + length = blob_length(bitlen, isdss, *ispub); if (length > BLOB_MAX_LENGTH) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG); + PEMerr(0, PEM_R_HEADER_TOO_LONG); return NULL; } buf = OPENSSL_malloc(length); if (buf == NULL) { - PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); + PEMerr(0, ERR_R_MALLOC_FAILURE); goto err; } p = buf; if (BIO_read(in, buf, length) != (int)length) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + PEMerr(0, PEM_R_KEYBLOB_TOO_SHORT); goto err; } if (isdss) - ret = b2i_dss(&p, bitlen, ispub); + ret = b2i_dss(&p, bitlen, *ispub); else - ret = b2i_rsa(&p, bitlen, ispub); + ret = b2i_rsa(&p, bitlen, *ispub); err: OPENSSL_free(buf); @@ -391,22 +390,30 @@ static EVP_PKEY *b2i_rsa(const unsigned char **in, EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) { - return do_b2i(in, length, 0); + int ispub = 0; + + return ossl_b2i(in, length, &ispub); } EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) { - return do_b2i(in, length, 1); + int ispub = 1; + + return ossl_b2i(in, length, &ispub); } EVP_PKEY *b2i_PrivateKey_bio(BIO *in) { - return do_b2i_bio(in, 0); + int ispub = 0; + + return ossl_b2i_bio(in, &ispub); } EVP_PKEY *b2i_PublicKey_bio(BIO *in) { - return do_b2i_bio(in, 1); + int ispub = 1; + + return ossl_b2i_bio(in, &ispub); } static void write_ledword(unsigned char **out, unsigned int dw) @@ -852,9 +859,9 @@ static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel, if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL)) goto error; OPENSSL_cleanse(keybuf, 20); - if (!EVP_DecryptUpdate(cctx, p, &enctmplen, p, pklen - 8)) + if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8)) goto error; - if (!EVP_DecryptFinal_ex(cctx, p + enctmplen, &enctmplen)) + if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen)) goto error; } diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c index e2ca95bcfa..da228336eb 100644 --- a/crypto/pkcs12/p12_attr.c +++ b/crypto/pkcs12/p12_attr.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID, - V_ASN1_OCTET_STRING, name, namelen)) + V_ASN1_OCTET_STRING, name, namelen) != NULL) return 1; else return 0; @@ -39,7 +39,7 @@ int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_ASC, (unsigned char *)name, namelen)) + MBSTRING_ASC, (unsigned char *)name, namelen) != NULL) return 1; else return 0; @@ -49,7 +49,7 @@ int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_UTF8, (unsigned char *)name, namelen)) + MBSTRING_UTF8, (unsigned char *)name, namelen) != NULL) return 1; else return 0; @@ -59,7 +59,7 @@ int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_BMP, name, namelen)) + MBSTRING_BMP, name, namelen) != NULL) return 1; else return 0; @@ -68,7 +68,25 @@ int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) { if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name, - MBSTRING_ASC, (unsigned char *)name, namelen)) + MBSTRING_ASC, (unsigned char *)name, namelen) != NULL) + return 1; + else + return 0; +} + +int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, nid, type, bytes, len) != NULL) + return 1; + else + return 0; +} + +int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&bag->attrib, attrname, type, bytes, len) != NULL) return 1; else return 0; diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c index f75b2437c9..88571fd165 100644 --- a/crypto/pkcs12/p12_crt.c +++ b/crypto/pkcs12/p12_crt.c @@ -12,10 +12,6 @@ #include #include "p12_local.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(PKCS7) -DEFINE_STACK_OF(PKCS12_SAFEBAG) - static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag); @@ -207,6 +203,24 @@ PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, } +PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags, + int nid_type, const unsigned char *value, int len) +{ + PKCS12_SAFEBAG *bag = NULL; + + /* Add secret, storing the value as an octet string */ + if ((bag = PKCS12_SAFEBAG_create_secret(nid_type, V_ASN1_OCTET_STRING, value, len)) == NULL) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + err: + PKCS12_SAFEBAG_free(bag); + return NULL; +} + int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, int nid_safe, int iter, const char *pass) { diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c index b9d13d9cf5..cabfe07908 100644 --- a/crypto/pkcs12/p12_decr.c +++ b/crypto/pkcs12/p12_decr.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,22 +24,49 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, unsigned char *out = NULL; int outlen, i; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + int max_out_len, mac_len = 0; if (ctx == NULL) { PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); goto err; } - /* Decrypt data */ + /* Process data */ if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, - algor->parameter, ctx, en_de)) { - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, - PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); + algor->parameter, ctx, en_de)) goto err; + + /* + * GOST algorithm specifics: + * OMAC algorithm calculate and encrypt MAC of the encrypted objects + * It's appended to encrypted text on encrypting + * MAC should be processed on decrypting separately from plain text + */ + max_out_len = inlen + EVP_CIPHER_CTX_block_size(ctx); + if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) { + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_CIPHER_CTX_encrypting(ctx)) { + max_out_len += mac_len; + } else { + if (inlen < mac_len) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, + PKCS12_R_UNSUPPORTED_PKCS12_MODE); + goto err; + } + inlen -= mac_len; + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, + (int)mac_len, (unsigned char *)in+inlen) < 0) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } } - if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx))) - == NULL) { + if ((out = OPENSSL_malloc(max_out_len)) == NULL) { PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); goto err; } @@ -60,6 +87,16 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, goto err; } outlen += i; + if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) { + if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, + (int)mac_len, out+outlen) < 0) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + outlen += mac_len; + } + } if (datalen) *datalen = outlen; if (data) @@ -79,17 +116,14 @@ void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, const char *pass, int passlen, const ASN1_OCTET_STRING *oct, int zbuf) { - unsigned char *out; + unsigned char *out = NULL; const unsigned char *p; void *ret; - int outlen; + int outlen = 0; if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, - &out, &outlen, 0)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, - PKCS12_R_PKCS12_PBE_CRYPT_ERROR); + &out, &outlen, 0)) return NULL; - } p = out; OSSL_TRACE_BEGIN(PKCS12_DECRYPT) { BIO_printf(trc_out, "\n"); diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c index 4849cbd5bc..20a29c7d44 100644 --- a/crypto/pkcs12/p12_key.c +++ b/crypto/pkcs12/p12_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,11 +12,9 @@ #include #include #include - -/* PKCS12 compatible key/IV generation */ -#ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -#endif +#include +#include +#include "internal/provider.h" int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, @@ -35,10 +33,8 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, } ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, id, iter, n, out, md_type); - if (ret <= 0) - return 0; OPENSSL_clear_free(unipass, uniplen); - return ret; + return ret > 0; } int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, @@ -58,26 +54,45 @@ int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, } ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, id, iter, n, out, md_type); - if (ret <= 0) - return 0; OPENSSL_clear_free(unipass, uniplen); - return ret; + return ret > 0; } int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type) { - unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL; - int Slen, Plen, Ilen; - int i, j, u, v; - int ret = 0; - EVP_MD_CTX *ctx = NULL; - unsigned char *tmpout = out; - int tmpn = n; + int res = 0; + EVP_KDF *kdf; + EVP_KDF_CTX *ctx; + OSSL_PARAM params[6], *p = params; - ctx = EVP_MD_CTX_new(); + if (n <= 0) + return 0; + + /* + * The parameter query isn't available but the library context can be + * extracted from the passed digest. + */ + kdf = EVP_KDF_fetch(ossl_provider_libctx(EVP_MD_provider(md_type)), + "PKCS12KDF", NULL); + if (kdf == NULL) + return 0; + ctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); if (ctx == NULL) + return 0; + + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)EVP_MD_name(md_type), 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, + pass, passlen); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + salt, saltlen); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS12_ID, &id); + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ITER, &iter); + *p = OSSL_PARAM_construct_end(); + if (!EVP_KDF_CTX_set_params(ctx, params)) goto err; OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { @@ -89,77 +104,16 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, BIO_hex_string(trc_out, 0, saltlen, salt, saltlen); BIO_printf(trc_out, "\n"); } OSSL_TRACE_END(PKCS12_KEYGEN); - v = EVP_MD_block_size(md_type); - u = EVP_MD_size(md_type); - if (u < 0 || v <= 0) - goto err; - D = OPENSSL_malloc(v); - Ai = OPENSSL_malloc(u); - B = OPENSSL_malloc(v + 1); - Slen = v * ((saltlen + v - 1) / v); - if (passlen) - Plen = v * ((passlen + v - 1) / v); - else - Plen = 0; - Ilen = Slen + Plen; - I = OPENSSL_malloc(Ilen); - if (D == NULL || Ai == NULL || B == NULL || I == NULL) - goto err; - for (i = 0; i < v; i++) - D[i] = id; - p = I; - for (i = 0; i < Slen; i++) - *p++ = salt[i % saltlen]; - for (i = 0; i < Plen; i++) - *p++ = pass[i % passlen]; - for (;;) { - if (!EVP_DigestInit_ex(ctx, md_type, NULL) - || !EVP_DigestUpdate(ctx, D, v) - || !EVP_DigestUpdate(ctx, I, Ilen) - || !EVP_DigestFinal_ex(ctx, Ai, NULL)) - goto err; - for (j = 1; j < iter; j++) { - if (!EVP_DigestInit_ex(ctx, md_type, NULL) - || !EVP_DigestUpdate(ctx, Ai, u) - || !EVP_DigestFinal_ex(ctx, Ai, NULL)) - goto err; - } - memcpy(out, Ai, min(n, u)); - if (u >= n) { - OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { - BIO_printf(trc_out, "Output KEY (length %d)\n", tmpn); - BIO_hex_string(trc_out, 0, tmpn, tmpout, tmpn); - BIO_printf(trc_out, "\n"); - } OSSL_TRACE_END(PKCS12_KEYGEN); - ret = 1; - goto end; - } - n -= u; - out += u; - for (j = 0; j < v; j++) - B[j] = Ai[j % u]; - for (j = 0; j < Ilen; j += v) { - int k; - unsigned char *Ij = I + j; - uint16_t c = 1; - /* Work out Ij = Ij + B + 1 */ - for (k = v - 1; k >= 0; k--) { - c += Ij[k] + B[k]; - Ij[k] = (unsigned char)c; - c >>= 8; - } - } + if (EVP_KDF_derive(ctx, out, (size_t)n)) { + res = 1; + OSSL_TRACE_BEGIN(PKCS12_KEYGEN) { + BIO_printf(trc_out, "Output KEY (length %d)\n", n); + BIO_hex_string(trc_out, 0, n, out, n); + BIO_printf(trc_out, "\n"); + } OSSL_TRACE_END(PKCS12_KEYGEN); } - err: - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); - - end: - OPENSSL_free(Ai); - OPENSSL_free(B); - OPENSSL_free(D); - OPENSSL_free(I); - EVP_MD_CTX_free(ctx); - return ret; + EVP_KDF_CTX_free(ctx); + return res; } diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c index 88925f76d9..ad1f4ee1ed 100644 --- a/crypto/pkcs12/p12_kiss.c +++ b/crypto/pkcs12/p12_kiss.c @@ -10,10 +10,7 @@ #include #include "internal/cryptlib.h" #include - -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(PKCS7) -DEFINE_STACK_OF(PKCS12_SAFEBAG) +#include "crypto/x509.h" /* for X509_add_cert_new() */ /* Simplified PKCS#12 routines */ @@ -29,8 +26,8 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, /* * Parse and decrypt a PKCS#12 structure returning user key, user cert and * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it - * should point to a valid STACK structure. pkey and cert can be passed - * uninitialised. + * should point to a valid STACK structure. pkey and/or cert may be NULL; + * if non-NULL the variables they point to can be passed uninitialised. */ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, @@ -39,9 +36,9 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) *ocerts = NULL; X509 *x = NULL; - if (pkey) + if (pkey != NULL) *pkey = NULL; - if (cert) + if (cert != NULL) *cert = NULL; /* Check for NULL PKCS12 structure */ @@ -75,53 +72,55 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, goto err; } - /* Allocate stack for other certificates */ - ocerts = sk_X509_new_null(); - - if (!ocerts) { + /* If needed, allocate stack for other certificates */ + if ((cert != NULL || ca != NULL) + && (ocerts = sk_X509_new_null()) == NULL) { PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); goto err; } if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); + int err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) != ERR_LIB_EVP + && ERR_GET_REASON(err) != EVP_R_UNSUPPORTED_ALGORITHM) + PKCS12err(0, PKCS12_R_PARSE_ERROR); goto err; } - while ((x = sk_X509_pop(ocerts))) { + /* Split the certs in ocerts over *cert and *ca as far as requested */ + while ((x = sk_X509_shift(ocerts)) != NULL) { if (pkey != NULL && *pkey != NULL && cert != NULL && *cert == NULL) { + int match; + ERR_set_mark(); - if (X509_check_private_key(x, *pkey)) { + match = X509_check_private_key(x, *pkey); + ERR_pop_to_mark(); + if (match) { *cert = x; - x = NULL; + continue; } - ERR_pop_to_mark(); } - if (ca && x) { - if (*ca == NULL) - *ca = sk_X509_new_null(); - if (*ca == NULL) + if (ca != NULL) { + if (!X509_add_cert_new(ca, x, X509_ADD_FLAG_DEFAULT)) goto err; - if (!sk_X509_push(*ca, x)) - goto err; - x = NULL; + continue; } X509_free(x); } - - sk_X509_pop_free(ocerts, X509_free); + sk_X509_free(ocerts); return 1; err: - if (pkey) { + if (pkey != NULL) { EVP_PKEY_free(*pkey); *pkey = NULL; } - if (cert) { + if (cert != NULL) { X509_free(*cert); *cert = NULL; } @@ -133,6 +132,7 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, /* Parse the outer PKCS#12 structure */ +/* pkey and/or ocerts may be NULL */ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { @@ -167,6 +167,7 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, return 1; } +/* pkey and/or ocerts may be NULL */ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { @@ -179,6 +180,7 @@ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, return 1; } +/* pkey and/or ocerts may be NULL */ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) { @@ -215,7 +217,8 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, break; case NID_certBag: - if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) + if (ocerts == NULL + || PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) return 1; if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL) return 0; @@ -226,6 +229,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, if (fname) { int len, r; unsigned char *data; + len = ASN1_STRING_to_UTF8(&data, fname); if (len >= 0) { r = X509_alias_set1(x509, data, len); diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c index a83d745bd5..7f04ce10de 100644 --- a/crypto/pkcs12/p12_npas.c +++ b/crypto/pkcs12/p12_npas.c @@ -15,9 +15,6 @@ #include #include "p12_local.h" -DEFINE_STACK_OF(PKCS7) -DEFINE_STACK_OF(PKCS12_SAFEBAG) - /* PKCS#12 password change routine */ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass); @@ -160,8 +157,10 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL) return 0; X509_SIG_get0(bag->value.shkeybag, &shalg, NULL); - if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen)) + if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen)) { + PKCS8_PRIV_KEY_INFO_free(p8); return 0; + } p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, p8_iter, p8); PKCS8_PRIV_KEY_INFO_free(p8); diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c index ccb9acb17e..3da437f7ea 100644 --- a/crypto/pkcs12/p12_sbag.c +++ b/crypto/pkcs12/p12_sbag.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -71,6 +71,16 @@ int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag) return OBJ_obj2nid(bag->value.bag->type); } +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag) +{ + return bag->value.bag->type; +} + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag) +{ + return bag->value.bag->value.other; +} + X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag) { if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag) @@ -103,6 +113,60 @@ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl) NID_x509Crl, NID_crlBag); } +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len) +{ + PKCS12_BAGS *bag; + PKCS12_SAFEBAG *safebag; + + if ((bag = PKCS12_BAGS_new()) == NULL) { + PKCS12err(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(type); + + switch(vtype) { + case V_ASN1_OCTET_STRING: + { + ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new(); + + if (strtmp == NULL) { + PKCS12err(0, ERR_R_MALLOC_FAILURE); + goto err; + } + /* Pack data into an octet string */ + if (!ASN1_OCTET_STRING_set(strtmp, value, len)) { + ASN1_OCTET_STRING_free(strtmp); + PKCS12err(0, PKCS12_R_ENCODE_ERROR); + goto err; + } + bag->value.other = ASN1_TYPE_new(); + if (bag->value.other == NULL) { + ASN1_OCTET_STRING_free(strtmp); + PKCS12err(0, ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_TYPE_set(bag->value.other, vtype, strtmp); + } + break; + + default: + PKCS12err(0, PKCS12_R_INVALID_TYPE); + goto err; + } + + if ((safebag = PKCS12_SAFEBAG_new()) == NULL) { + PKCS12err(0, ERR_R_MALLOC_FAILURE); + goto err; + } + safebag->value.bag = bag; + safebag->type = OBJ_nid2obj(NID_secretBag); + return safebag; + + err: + PKCS12_BAGS_free(bag); + return NULL; +} + /* Turn PKCS8 object into a keybag */ PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8) diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c index c3ad2bf708..ae835c57be 100644 --- a/crypto/pkcs12/pk12err.c +++ b/crypto/pkcs12/pk12err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,6 +27,7 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = { "invalid null argument"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_NULL_PKCS12_POINTER), "invalid null pkcs12 pointer"}, + {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_TYPE), "invalid type"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_IV_GEN_ERROR), "iv gen error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_KEY_GEN_ERROR), "key gen error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_ABSENT), "mac absent"}, @@ -38,12 +39,8 @@ static const ERR_STRING_DATA PKCS12_str_reasons[] = { {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PARSE_ERROR), "parse error"}, - {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), - "pkcs12 algor cipherinit error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_CIPHERFINAL_ERROR), "pkcs12 cipherfinal error"}, - {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_PBE_CRYPT_ERROR), - "pkcs12 pbe crypt error"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), "unknown digest algorithm"}, {ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_UNSUPPORTED_PKCS12_MODE), diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c index 08852418cc..9820d1b8eb 100644 --- a/crypto/pkcs7/pk7_asn1.c +++ b/crypto/pkcs7/pk7_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,7 @@ #include #include #include +#include "pk7_local.h" /* PKCS#7 ASN1 module */ @@ -62,7 +63,52 @@ ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { ASN1_ADB_OBJECT(PKCS7) }ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7) -IMPLEMENT_ASN1_FUNCTIONS(PKCS7) +PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) +{ + PKCS7 *ret; + + ret = (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (PKCS7_it())); + if (ret != NULL && a != NULL) + pkcs7_resolve_libctx(ret); + return ret; +} + +int i2d_PKCS7(const PKCS7 *a, unsigned char **out) +{ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, (PKCS7_it()));\ +} + +PKCS7 *PKCS7_new(void) +{ + return (PKCS7 *)ASN1_item_new(ASN1_ITEM_rptr(PKCS7)); +} + +PKCS7 *PKCS7_new_ex(OSSL_LIB_CTX *libctx, const char *propq) +{ + PKCS7 *pkcs7 = PKCS7_new(); + + if (pkcs7 != NULL) { + pkcs7->ctx.libctx = libctx; + pkcs7->ctx.propq = NULL; + if (propq != NULL) { + pkcs7->ctx.propq = OPENSSL_strdup(propq); + if (pkcs7->ctx.propq == NULL) { + PKCS7_free(pkcs7); + pkcs7 = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } + } + } + return pkcs7; +} + +void PKCS7_free(PKCS7 *p7) +{ + if (p7 != NULL) { + OPENSSL_free(p7->ctx.propq); + ASN1_item_free((ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); + } +} IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) diff --git a/crypto/pkcs7/pk7_attr.c b/crypto/pkcs7/pk7_attr.c index 926a02a32e..7df05c8084 100644 --- a/crypto/pkcs7/pk7_attr.c +++ b/crypto/pkcs7/pk7_attr.c @@ -17,8 +17,6 @@ #include #include -DEFINE_STACK_OF(X509_ALGOR) - int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap) { diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index b815a4a77b..3598d5f121 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -14,17 +14,13 @@ #include #include #include - -DEFINE_STACK_OF(X509_ALGOR) -DEFINE_STACK_OF(X509_ATTRIBUTE) -DEFINE_STACK_OF(PKCS7_RECIP_INFO) -DEFINE_STACK_OF(PKCS7_SIGNER_INFO) +#include "pk7_local.h" static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value); static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); -static int PKCS7_type_is_other(PKCS7 *p7) +int PKCS7_type_is_other(PKCS7 *p7) { int isOther = 1; @@ -47,7 +43,7 @@ static int PKCS7_type_is_other(PKCS7 *p7) } -static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) +ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) { if (PKCS7_type_is_data(p7)) return p7->d.data; @@ -57,22 +53,37 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) return NULL; } -static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) +static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg, + const PKCS7_CTX *ctx) { BIO *btmp; + const char *name; + EVP_MD *fetched = NULL; const EVP_MD *md; + if ((btmp = BIO_new(BIO_f_md())) == NULL) { PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); goto err; } - md = EVP_get_digestbyobj(alg->algorithm); + name = OBJ_nid2sn(OBJ_obj2nid(alg->algorithm)); + + (void)ERR_set_mark(); + fetched = EVP_MD_fetch(ctx->libctx, name, ctx->propq); + if (fetched != NULL) + md = fetched; + else + md = EVP_get_digestbyname(name); + if (md == NULL) { + (void)ERR_clear_last_mark(); PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } + (void)ERR_pop_to_mark(); BIO_set_md(btmp, md); + EVP_MD_free(fetched); if (*pbio == NULL) *pbio = btmp; else if (!BIO_push(*pbio, btmp)) { @@ -86,7 +97,6 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) err: BIO_free(btmp); return 0; - } static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, @@ -97,12 +107,13 @@ static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *ek = NULL; int ret = 0; size_t eklen; + const PKCS7_CTX *ctx = ri->ctx; pkey = X509_get0_pubkey(ri->cert); if (pkey == NULL) return 0; - pctx = EVP_PKEY_CTX_new(pkey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq); if (pctx == NULL) return 0; @@ -148,8 +159,9 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, unsigned char *ek = NULL; size_t eklen; int ret = -1; + const PKCS7_CTX *ctx = ri->ctx; - pctx = EVP_PKEY_CTX_new(pkey, NULL); + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq); if (pctx == NULL) return -1; @@ -201,17 +213,22 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) int i; BIO *out = NULL, *btmp = NULL; X509_ALGOR *xa = NULL; + EVP_CIPHER *fetched_cipher = NULL; + const EVP_CIPHER *cipher; const EVP_CIPHER *evp_cipher = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; X509_ALGOR *xalg = NULL; PKCS7_RECIP_INFO *ri = NULL; ASN1_OCTET_STRING *os = NULL; + const PKCS7_CTX *p7_ctx; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); return NULL; } + p7_ctx = pkcs7_get0_ctx(p7); + /* * The content field in the PKCS7 ContentInfo is optional, but that really * only applies to inner content (precisely, detached signatures). @@ -266,10 +283,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) } for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) - if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) + if (!pkcs7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i), p7_ctx)) goto err; - if (xa && !PKCS7_bio_add_digest(&out, xa)) + if (xa && !pkcs7_bio_add_digest(&out, xa, p7_ctx)) goto err; if (evp_cipher != NULL) { @@ -287,10 +304,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) ivlen = EVP_CIPHER_iv_length(evp_cipher); xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); if (ivlen > 0) - if (RAND_bytes(iv, ivlen) <= 0) + if (RAND_bytes_ex(p7_ctx->libctx, iv, ivlen) <= 0) goto err; - if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) + + (void)ERR_set_mark(); + fetched_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, + EVP_CIPHER_name(evp_cipher), + p7_ctx->propq); + (void)ERR_pop_to_mark(); + if (fetched_cipher != NULL) + cipher = fetched_cipher; + else + cipher = evp_cipher; + + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) <= 0) goto err; + + EVP_CIPHER_free(fetched_cipher); + fetched_cipher = NULL; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) goto err; if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) @@ -342,6 +374,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) return out; err: + EVP_CIPHER_free(fetched_cipher); BIO_free_all(out); BIO_free_all(btmp); return NULL; @@ -361,12 +394,14 @@ static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) /* int */ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) { - int i, j, len; + int i, len; BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; X509_ALGOR *xa; ASN1_OCTET_STRING *data_body = NULL; - const EVP_MD *evp_md; - const EVP_CIPHER *evp_cipher = NULL; + EVP_MD *evp_md = NULL; + const EVP_MD *md; + EVP_CIPHER *evp_cipher = NULL; + const EVP_CIPHER *cipher = NULL; EVP_CIPHER_CTX *evp_ctx = NULL; X509_ALGOR *enc_alg = NULL; STACK_OF(X509_ALGOR) *md_sk = NULL; @@ -374,12 +409,16 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) PKCS7_RECIP_INFO *ri = NULL; unsigned char *ek = NULL, *tkey = NULL; int eklen = 0, tkeylen = 0; + const char *name; + const PKCS7_CTX *p7_ctx; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); return NULL; } + p7_ctx = pkcs7_get0_ctx(p7); + if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); return NULL; @@ -410,24 +449,45 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.signed_and_enveloped->enc_data->enc_data; enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { + + name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)); + + (void)ERR_set_mark(); + evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq); + if (evp_cipher != NULL) + cipher = evp_cipher; + else + cipher = EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } + (void)ERR_pop_to_mark(); break; case NID_pkcs7_enveloped: rsk = p7->d.enveloped->recipientinfo; enc_alg = p7->d.enveloped->enc_data->algorithm; /* data_body is NULL if the optional EncryptedContent is missing. */ data_body = p7->d.enveloped->enc_data->enc_data; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { + name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)); + + (void)ERR_set_mark(); + evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq); + if (evp_cipher != NULL) + cipher = evp_cipher; + else + cipher = EVP_get_cipherbyname(name); + + if (cipher == NULL) { + (void)ERR_clear_last_mark(); PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CIPHER_TYPE); goto err; } + (void)ERR_pop_to_mark(); break; default: PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); @@ -449,15 +509,25 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) goto err; } - j = OBJ_obj2nid(xa->algorithm); - evp_md = EVP_get_digestbynid(j); - if (evp_md == NULL) { + name = OBJ_nid2sn(OBJ_obj2nid(xa->algorithm)); + + (void)ERR_set_mark(); + evp_md = EVP_MD_fetch(p7_ctx->libctx, name, p7_ctx->propq); + if (evp_md != NULL) + md = evp_md; + else + md = EVP_get_digestbyname(name); + + if (md == NULL) { + (void)ERR_clear_last_mark(); PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNKNOWN_DIGEST_TYPE); goto err; } + (void)ERR_pop_to_mark(); - BIO_set_md(btmp, evp_md); + BIO_set_md(btmp, md); + EVP_MD_free(evp_md); if (out == NULL) out = btmp; else @@ -466,7 +536,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } } - if (evp_cipher != NULL) { + if (cipher != NULL) { if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); goto err; @@ -504,13 +574,14 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) */ for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { ri = sk_PKCS7_RECIP_INFO_value(rsk, i); - + ri->ctx = p7_ctx; if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, - EVP_CIPHER_key_length(evp_cipher)) < 0) + EVP_CIPHER_key_length(cipher)) < 0) goto err; ERR_clear_error(); } } else { + ri->ctx = p7_ctx; /* Only exit on fatal errors, not decrypt failure */ if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0) goto err; @@ -519,7 +590,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) evp_ctx = NULL; BIO_get_cipher_ctx(etmp, &evp_ctx); - if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) + if (EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0) <= 0) goto err; if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) goto err; @@ -585,9 +656,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } BIO_push(out, bio); bio = NULL; + EVP_CIPHER_free(evp_cipher); return out; err: + EVP_CIPHER_free(evp_cipher); OPENSSL_clear_free(ek, eklen); OPENSSL_clear_free(tkey, tkeylen); BIO_free_all(out); @@ -658,12 +731,15 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; ASN1_OCTET_STRING *os = NULL; + const PKCS7_CTX *p7_ctx; if (p7 == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); return 0; } + p7_ctx = pkcs7_get0_ctx(p7); + if (p7->d.ptr == NULL) { PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); return 0; @@ -771,7 +847,8 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) if (abuf == NULL) goto err; - if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) { + if (!EVP_SignFinal_ex(ctx_tmp, abuf, &abuflen, si->pkey, + p7_ctx->libctx, p7_ctx->propq)) { OPENSSL_free(abuf); PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); goto err; @@ -830,6 +907,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) int alen; size_t siglen; const EVP_MD *md = NULL; + const PKCS7_CTX *ctx = si->ctx; md = EVP_get_digestbyobj(si->digest_alg->algorithm); if (md == NULL) @@ -837,11 +915,12 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) mctx = EVP_MD_CTX_new(); if (mctx == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE); + PKCS7err(0, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + if (EVP_DigestSignInit_ex(mctx, &pctx, EVP_MD_name(md), ctx->libctx, + ctx->propq, si->pkey) <= 0) goto err; /* @@ -863,7 +942,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) #if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + PKCS7err(0, PKCS7_R_CTRL_ERROR); goto err; } #endif @@ -903,7 +982,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) #if 0 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + PKCS7err(0, PKCS7_R_CTRL_ERROR); goto err; } #endif @@ -918,7 +997,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) OPENSSL_free(abuf); EVP_MD_CTX_free(mctx); return 0; - } int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, @@ -983,11 +1061,14 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, { ASN1_OCTET_STRING *os; EVP_MD_CTX *mdc_tmp, *mdc; + const EVP_MD *md; + EVP_MD *fetched_md = NULL; int ret = 0, i; int md_type; STACK_OF(X509_ATTRIBUTE) *sk; BIO *btmp; EVP_PKEY *pkey; + const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7); mdc_tmp = EVP_MD_CTX_new(); if (mdc_tmp == NULL) { @@ -1055,8 +1136,19 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, goto err; } - if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL)) + (void)ERR_set_mark(); + fetched_md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(md_type), ctx->propq); + + if (fetched_md != NULL) + md = fetched_md; + else + md = EVP_get_digestbynid(md_type); + + if (md == NULL || !EVP_VerifyInit_ex(mdc_tmp, md, NULL)) { + (void)ERR_clear_last_mark(); goto err; + } + (void)ERR_pop_to_mark(); alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); @@ -1078,7 +1170,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, goto err; } - i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey); + i = EVP_VerifyFinal_ex(mdc_tmp, os->data, os->length, pkey, ctx->libctx, + ctx->propq); if (i <= 0) { PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); ret = -1; @@ -1087,6 +1180,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, ret = 1; err: EVP_MD_CTX_free(mdc_tmp); + EVP_MD_free(fetched_md); return ret; } diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index cb8c67b65a..da3336982e 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -13,12 +13,8 @@ #include #include "crypto/asn1.h" #include "crypto/evp.h" - -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509_ALGOR) -DEFINE_STACK_OF(PKCS7_RECIP_INFO) -DEFINE_STACK_OF(PKCS7_SIGNER_INFO) +#include "crypto/x509.h" /* for sk_X509_add1_cert() */ +#include "pk7_local.h" long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) { @@ -236,6 +232,7 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) } } + psi->ctx = pkcs7_get0_ctx(p7); if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) return 0; return 1; @@ -259,18 +256,7 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) return 0; } - if (*sk == NULL) - *sk = sk_X509_new_null(); - if (*sk == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return 0; - } - X509_up_ref(x509); - if (!sk_X509_push(*sk, x509)) { - X509_free(x509); - return 0; - } - return 1; + return X509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF); } int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) @@ -327,6 +313,17 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, ASN1_INTEGER_dup(X509_get0_serialNumber(x509)))) goto err; + /* + * TODO(3.0) Adapt for provider-native keys + * Meanwhile, we downgrade the key. + * #legacy + */ + if (!evp_pkey_downgrade(pkey)) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + /* lets keep the pkey around for a while */ EVP_PKEY_up_ref(pkey); p7i->pkey = pkey; @@ -380,6 +377,70 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, return NULL; } +static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7) +{ + if (PKCS7_type_is_signed(p7)) + return p7->d.sign->cert; + if (PKCS7_type_is_signedAndEnveloped(p7)) + return p7->d.signed_and_enveloped->cert; + return NULL; +} + +static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7) +{ + if (PKCS7_type_is_signedAndEnveloped(p7)) + return p7->d.signed_and_enveloped->recipientinfo; + if (PKCS7_type_is_enveloped(p7)) + return p7->d.enveloped->recipientinfo; + return NULL; +} + +/* + * Set up the library context into any loaded structure that needs it. + * i.e loaded X509 objects. + */ +void pkcs7_resolve_libctx(PKCS7 *p7) +{ + int i; + const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7); + STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7); + STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7); + STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7); + + if (ctx == NULL) + return; + + for (i = 0; i < sk_X509_num(certs); i++) + x509_set0_libctx(sk_X509_value(certs, i), ctx->libctx, ctx->propq); + + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) { + PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i); + + x509_set0_libctx(ri->cert, ctx->libctx, ctx->propq); + } + + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + + if (si != NULL) + si->ctx = ctx; + } +} + +const PKCS7_CTX *pkcs7_get0_ctx(const PKCS7 *p7) +{ + return p7 != NULL ? &p7->ctx : NULL; +} + +OSSL_LIB_CTX *pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx) +{ + return ctx != NULL ? ctx->libctx : NULL; +} +const char *pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx) +{ + return ctx != NULL ? ctx->propq : NULL; +} + int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) { if (PKCS7_type_is_digest(p7)) { @@ -435,6 +496,7 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) goto err; if (!PKCS7_add_recipient_info(p7, ri)) goto err; + ri->ctx = pkcs7_get0_ctx(p7); return ri; err: PKCS7_RECIP_INFO_free(ri); @@ -547,6 +609,7 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) } ec->cipher = cipher; + ec->ctx = pkcs7_get0_ctx(p7); return 1; } diff --git a/crypto/pkcs7/pk7_local.h b/crypto/pkcs7/pk7_local.h new file mode 100644 index 0000000000..5db0127e1d --- /dev/null +++ b/crypto/pkcs7/pk7_local.h @@ -0,0 +1,14 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "crypto/pkcs7.h" + +const PKCS7_CTX *pkcs7_get0_ctx(const PKCS7 *p7); +OSSL_LIB_CTX *pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx); +const char *pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx); diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c index 6f3981ec6b..381df40a94 100644 --- a/crypto/pkcs7/pk7_mime.c +++ b/crypto/pkcs7/pk7_mime.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,7 @@ #include "internal/cryptlib.h" #include #include +#include "pk7_local.h" /* PKCS#7 wrappers round generalised stream and MIME routines */ @@ -30,6 +31,8 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) { STACK_OF(X509_ALGOR) *mdalgs; int ctype_nid = OBJ_obj2nid(p7->type); + const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7); + if (ctype_nid == NID_pkcs7_signed) mdalgs = p7->d.sign->md_algs; else @@ -37,12 +40,24 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) flags ^= SMIME_OLDMIME; - return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, - ctype_nid, NID_undef, mdalgs, - ASN1_ITEM_rptr(PKCS7)); + return SMIME_write_ASN1_ex(bio, (ASN1_VALUE *)p7, data, flags, ctype_nid, + NID_undef, mdalgs, ASN1_ITEM_rptr(PKCS7), + pkcs7_ctx_get0_libctx(ctx), + pkcs7_ctx_get0_propq(ctx)); +} + +PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7) +{ + PKCS7 *ret; + + ret = (PKCS7 *)SMIME_read_ASN1_ex(bio, bcont, ASN1_ITEM_rptr(PKCS7), + (ASN1_VALUE **)p7); + if (ret != NULL && p7 != NULL) + pkcs7_resolve_libctx(ret); + return ret; } PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) { - return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); + return SMIME_read_PKCS7_ex(bio, bcont, NULL); } diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 385b4af42e..8e16e63971 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -13,24 +13,22 @@ #include "internal/cryptlib.h" #include #include +#include "pk7_local.h" #define BUFFERSIZE 4096 -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_ATTRIBUTE) -DEFINE_STACK_OF(X509_ALGOR) -DEFINE_STACK_OF(PKCS7_SIGNER_INFO) static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); -PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, - BIO *data, int flags) +PKCS7 *PKCS7_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags, OSSL_LIB_CTX *libctx, + const char *propq) { PKCS7 *p7; int i; - if ((p7 = PKCS7_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE); + if ((p7 = PKCS7_new_ex(libctx, propq)) == NULL) { + PKCS7err(0, ERR_R_MALLOC_FAILURE); return NULL; } @@ -41,7 +39,7 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, goto err; if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { - PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); + PKCS7err(0, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); goto err; } @@ -66,6 +64,13 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, return NULL; } +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags) +{ + return PKCS7_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL); +} + + int PKCS7_final(PKCS7 *p7, BIO *data, int flags) { BIO *p7bio; @@ -84,10 +89,8 @@ int PKCS7_final(PKCS7 *p7, BIO *data, int flags) PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN); goto err; } - ret = 1; - - err: +err: BIO_free_all(p7bio); return ret; @@ -116,6 +119,7 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, { PKCS7_SIGNER_INFO *si = NULL; STACK_OF(X509_ALGOR) *smcap = NULL; + if (!X509_check_private_key(signcert, pkey)) { PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); @@ -128,6 +132,7 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, return NULL; } + si->ctx = pkcs7_get0_ctx(p7); if (!(flags & PKCS7_NOCERTS)) { if (!PKCS7_add_certificate(p7, signcert)) goto err; @@ -162,7 +167,8 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, if (flags & PKCS7_REUSE_DIGEST) { if (!pkcs7_copy_existing_digest(p7, si)) goto err; - if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si)) + if (!(flags & PKCS7_PARTIAL) + && !PKCS7_SIGNER_INFO_sign(si)) goto err; } } @@ -197,7 +203,7 @@ static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) } - if (osdig) + if (osdig != NULL) return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, @@ -217,20 +223,21 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, int i, j = 0, k, ret = 0; BIO *p7bio = NULL; BIO *tmpin = NULL, *tmpout = NULL; + const PKCS7_CTX *p7_ctx; if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER); + PKCS7err(0, PKCS7_R_INVALID_NULL_POINTER); return 0; } if (!PKCS7_type_is_signed(p7)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE); + PKCS7err(0, PKCS7_R_WRONG_CONTENT_TYPE); return 0; } /* Check for no data and no content: no data to verify signature */ if (PKCS7_get_detached(p7) && !indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT); + PKCS7err(0, PKCS7_R_NO_CONTENT); return 0; } @@ -243,7 +250,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, * process is different, but the existing PKCs7 verification works. */ if (!PKCS7_get_detached(p7) && indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT); + PKCS7err(0, PKCS7_R_CONTENT_AND_DATA_PRESENT); return 0; } } @@ -251,17 +258,17 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, sinfos = PKCS7_get_signer_info(p7); if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA); + PKCS7err(0, PKCS7_R_NO_SIGNATURES_ON_DATA); return 0; } signers = PKCS7_get0_signers(p7, certs, flags); - if (!signers) + if (signers == NULL) return 0; /* Now verify the certificates */ - - cert_ctx = X509_STORE_CTX_new(); + p7_ctx = pkcs7_get0_ctx(p7); + cert_ctx = X509_STORE_CTX_new_ex(p7_ctx->libctx, p7_ctx->propq); if (cert_ctx == NULL) goto err; if (!(flags & PKCS7_NOVERIFY)) @@ -270,12 +277,12 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, if (!(flags & PKCS7_NOCHAIN)) { if (!X509_STORE_CTX_init(cert_ctx, store, signer, p7->d.sign->cert)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + PKCS7err(0, ERR_R_X509_LIB); goto err; } X509_STORE_CTX_set_default(cert_ctx, "smime_sign"); } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + PKCS7err(0, ERR_R_X509_LIB); goto err; } if (!(flags & PKCS7_NOCRL)) @@ -285,8 +292,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, j = X509_STORE_CTX_get_error(cert_ctx); X509_STORE_CTX_cleanup(cert_ctx); if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, - PKCS7_R_CERTIFICATE_VERIFY_ERROR); + PKCS7err(0, PKCS7_R_CERTIFICATE_VERIFY_ERROR); ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(j)); goto err; @@ -305,9 +311,9 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, char *ptr; long len; len = BIO_get_mem_data(indata, &ptr); - tmpin = BIO_new_mem_buf(ptr, len); + tmpin = (len == 0) ? indata : BIO_new_mem_buf(ptr, len); if (tmpin == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + PKCS7err(0, ERR_R_MALLOC_FAILURE); goto err; } } else @@ -318,7 +324,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, if (flags & PKCS7_TEXT) { if ((tmpout = BIO_new(BIO_s_mem())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + PKCS7err(0, ERR_R_MALLOC_FAILURE); goto err; } BIO_set_mem_eof_return(tmpout, 0); @@ -327,7 +333,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, /* We now have to 'read' from p7bio to calculate digests etc. */ if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + PKCS7err(0, ERR_R_MALLOC_FAILURE); goto err; } for (;;) { @@ -340,7 +346,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, if (flags & PKCS7_TEXT) { if (!SMIME_text(tmpout, out)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR); + PKCS7err(0, PKCS7_R_SMIME_TEXT_ERROR); BIO_free(tmpout); goto err; } @@ -354,7 +360,7 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, signer = sk_X509_value(signers, i); j = PKCS7_signatureVerify(p7bio, p7, si, signer); if (j <= 0) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); + PKCS7err(0, PKCS7_R_SIGNATURE_FAILURE); goto err; } } @@ -437,29 +443,31 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, /* Build a complete PKCS#7 enveloped data */ -PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, - int flags) +PKCS7 *PKCS7_encrypt_ex(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, int flags, + OSSL_LIB_CTX *libctx, const char *propq) { PKCS7 *p7; BIO *p7bio = NULL; int i; X509 *x509; - if ((p7 = PKCS7_new()) == NULL) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE); + + if ((p7 = PKCS7_new_ex(libctx, propq)) == NULL) { + PKCS7err(0, ERR_R_MALLOC_FAILURE); return NULL; } if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) goto err; if (!PKCS7_set_cipher(p7, cipher)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER); + PKCS7err(0, PKCS7_R_ERROR_SETTING_CIPHER); goto err; } for (i = 0; i < sk_X509_num(certs); i++) { x509 = sk_X509_value(certs, i); if (!PKCS7_add_recipient(p7, x509)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT); + PKCS7err(0, PKCS7_R_ERROR_ADDING_RECIPIENT); goto err; } } @@ -478,6 +486,13 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, } +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags) +{ + return PKCS7_encrypt_ex(certs, in, cipher, flags, NULL, NULL); +} + + int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) { BIO *tmpmem; diff --git a/crypto/poly1305/asm/poly1305-x86.pl b/crypto/poly1305/asm/poly1305-x86.pl index f58af00837..c91d01fb3b 100755 --- a/crypto/poly1305/asm/poly1305-x86.pl +++ b/crypto/poly1305/asm/poly1305-x86.pl @@ -70,7 +70,7 @@ $avx = ($1>=2.09) + ($1>=2.10); } - if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) { + if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } } diff --git a/crypto/poly1305/asm/poly1305-x86_64.pl b/crypto/poly1305/asm/poly1305-x86_64.pl index dbcd0463cb..fa9bfb7a7b 100755 --- a/crypto/poly1305/asm/poly1305-x86_64.pl +++ b/crypto/poly1305/asm/poly1305-x86_64.pl @@ -91,7 +91,7 @@ $avx = ($1>=10) + ($1>=12); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/poly1305/build.info b/crypto/poly1305/build.info index 6425a01583..9e4085f9fa 100644 --- a/crypto/poly1305/build.info +++ b/crypto/poly1305/build.info @@ -29,12 +29,12 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF -SOURCE[../../libcrypto]=poly1305_ameth.c poly1305.c $POLY1305ASM +SOURCE[../../libcrypto]=poly1305.c $POLY1305ASM # Implementations are now spread across several libraries, so the defines # need to be applied to all affected libraries and modules. DEFINE[../../libcrypto]=$POLY1305DEF -DEFINE[../providers/libimplementations.a]=$POLY1305DEF +DEFINE[../../providers/libimplementations.a]=$POLY1305DEF GENERATE[poly1305-sparcv9.S]=asm/poly1305-sparcv9.pl INCLUDE[poly1305-sparcv9.o]=.. diff --git a/crypto/poly1305/poly1305_ameth.c b/crypto/poly1305/poly1305_ameth.c deleted file mode 100644 index 2feec9ccc3..0000000000 --- a/crypto/poly1305/poly1305_ameth.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" -#include "crypto/poly1305.h" -#include "crypto/evp.h" - -/* - * POLY1305 "ASN1" method. This is just here to indicate the maximum - * POLY1305 output length and to free up a POLY1305 key. - */ - -static int poly1305_size(const EVP_PKEY *pkey) -{ - return POLY1305_DIGEST_SIZE; -} - -static void poly1305_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); - if (os != NULL) { - if (os->data != NULL) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int poly1305_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - /* nothing, (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */ - return -2; -} - -static int poly1305_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)); -} - -static int poly1305_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, - size_t len) -{ - ASN1_OCTET_STRING *os; - - if (pkey->pkey.ptr != NULL || len != POLY1305_KEY_SIZE) - return 0; - - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - return 0; - - if (!ASN1_OCTET_STRING_set(os, priv, len)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - - pkey->pkey.ptr = os; - return 1; -} - -static int poly1305_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, - size_t *len) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - - if (priv == NULL) { - *len = POLY1305_KEY_SIZE; - return 1; - } - - if (os == NULL || *len < POLY1305_KEY_SIZE) - return 0; - - memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os)); - *len = POLY1305_KEY_SIZE; - - return 1; -} - -const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth = { - EVP_PKEY_POLY1305, - EVP_PKEY_POLY1305, - 0, - - "POLY1305", - "OpenSSL POLY1305 method", - - 0, 0, poly1305_pkey_public_cmp, 0, - - 0, 0, 0, - - poly1305_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - poly1305_key_free, - poly1305_pkey_ctrl, - NULL, - NULL, - - NULL, - NULL, - NULL, - - NULL, - NULL, - NULL, - - poly1305_set_priv_key, - NULL, - poly1305_get_priv_key, - NULL, -}; diff --git a/crypto/property/defn_cache.c b/crypto/property/defn_cache.c index 9bfbd13144..b3aefe8f8e 100644 --- a/crypto/property/defn_cache.c +++ b/crypto/property/defn_cache.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -57,22 +57,23 @@ static void property_defns_free(void *vproperty_defns) } } -static void *property_defns_new(OPENSSL_CTX *ctx) { +static void *property_defns_new(OSSL_LIB_CTX *ctx) { return lh_PROPERTY_DEFN_ELEM_new(&property_defn_hash, &property_defn_cmp); } -static const OPENSSL_CTX_METHOD property_defns_method = { +static const OSSL_LIB_CTX_METHOD property_defns_method = { property_defns_new, property_defns_free, }; -OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop) +OSSL_PROPERTY_LIST *ossl_prop_defn_get(OSSL_LIB_CTX *ctx, const char *prop) { PROPERTY_DEFN_ELEM elem, *r; LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; - property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX, - &property_defns_method); + property_defns = ossl_lib_ctx_get_data(ctx, + OSSL_LIB_CTX_PROPERTY_DEFN_INDEX, + &property_defns_method); if (property_defns == NULL) return NULL; @@ -81,15 +82,16 @@ OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop) return r != NULL ? r->defn : NULL; } -int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop, +int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop, OSSL_PROPERTY_LIST *pl) { PROPERTY_DEFN_ELEM elem, *old, *p = NULL; size_t len; LHASH_OF(PROPERTY_DEFN_ELEM) *property_defns; - property_defns = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_DEFN_INDEX, - &property_defns_method); + property_defns = ossl_lib_ctx_get_data(ctx, + OSSL_LIB_CTX_PROPERTY_DEFN_INDEX, + &property_defns_method); if (property_defns == NULL) return 0; diff --git a/crypto/property/property.c b/crypto/property/property.c index 645e361b0a..9cfca81190 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -57,7 +57,7 @@ typedef struct { } ALGORITHM; struct ossl_method_store_st { - OPENSSL_CTX *ctx; + OSSL_LIB_CTX *ctx; size_t nelem; SPARSE_ARRAY_OF(ALGORITHM) *algs; int need_flush; @@ -85,21 +85,26 @@ static void ossl_ctx_global_properties_free(void *vstore) } } -static void *ossl_ctx_global_properties_new(OPENSSL_CTX *ctx) +static void *ossl_ctx_global_properties_new(OSSL_LIB_CTX *ctx) { return OPENSSL_zalloc(sizeof(OSSL_PROPERTY_LIST **)); } -static const OPENSSL_CTX_METHOD ossl_ctx_global_properties_method = { +static const OSSL_LIB_CTX_METHOD ossl_ctx_global_properties_method = { ossl_ctx_global_properties_new, ossl_ctx_global_properties_free, }; -OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OPENSSL_CTX *libctx) +OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OSSL_LIB_CTX *libctx, + int loadconfig) { - return openssl_ctx_get_data(libctx, OPENSSL_CTX_GLOBAL_PROPERTIES, - &ossl_ctx_global_properties_method); +#ifndef FIPS_MODULE + if (loadconfig && !OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) + return NULL; +#endif + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_GLOBAL_PROPERTIES, + &ossl_ctx_global_properties_method); } static int ossl_method_up_ref(METHOD *method) @@ -164,10 +169,10 @@ static void alg_cleanup(ossl_uintmax_t idx, ALGORITHM *a) } /* - * The OPENSSL_CTX param here allows access to underlying property data needed + * The OSSL_LIB_CTX param here allows access to underlying property data needed * for computation */ -OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx) +OSSL_METHOD_STORE *ossl_method_store_new(OSSL_LIB_CTX *ctx) { OSSL_METHOD_STORE *res; @@ -311,7 +316,7 @@ int ossl_method_store_remove(OSSL_METHOD_STORE *store, int nid, if (impl->method.method == method) { impl_free(impl); - sk_IMPLEMENTATION_delete(alg->impls, i); + (void)sk_IMPLEMENTATION_delete(alg->impls, i); ossl_property_unlock(store); return 1; } @@ -352,7 +357,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, if (prop_query != NULL) p2 = pq = ossl_parse_query(store->ctx, prop_query); - plp = ossl_ctx_global_properties(store->ctx); + plp = ossl_ctx_global_properties(store->ctx, 1); if (plp != NULL && *plp != NULL) { if (pq == NULL) { pq = *plp; @@ -394,10 +399,19 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, return ret; } -static void impl_cache_flush_alg(ossl_uintmax_t idx, ALGORITHM *alg) +static void impl_cache_flush_alg(ossl_uintmax_t idx, ALGORITHM *alg, void *arg) { + SPARSE_ARRAY_OF(ALGORITHM) *algs = arg; + lh_QUERY_doall(alg->cache, &impl_cache_free); - lh_QUERY_flush(alg->cache); + if (algs != NULL) { + sk_IMPLEMENTATION_pop_free(alg->impls, &impl_free); + lh_QUERY_free(alg->cache); + OPENSSL_free(alg); + ossl_sa_ALGORITHM_set(algs, idx, NULL); + } else { + lh_QUERY_flush(alg->cache); + } } static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid) @@ -406,14 +420,16 @@ static void ossl_method_cache_flush(OSSL_METHOD_STORE *store, int nid) if (alg != NULL) { store->nelem -= lh_QUERY_num_items(alg->cache); - impl_cache_flush_alg(0, alg); + impl_cache_flush_alg(0, alg, NULL); } } -void ossl_method_store_flush_cache(OSSL_METHOD_STORE *store) +void ossl_method_store_flush_cache(OSSL_METHOD_STORE *store, int all) { + void *arg = (all != 0 ? store->algs : NULL); + ossl_property_write_lock(store); - ossl_sa_ALGORITHM_doall(store->algs, &impl_cache_flush_alg); + ossl_sa_ALGORITHM_doall_arg(store->algs, &impl_cache_flush_alg, arg); store->nelem = 0; ossl_property_unlock(store); } diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h index 639af5591d..89020e606e 100644 --- a/crypto/property/property_local.h +++ b/crypto/property/property_local.h @@ -14,9 +14,9 @@ typedef int OSSL_PROPERTY_IDX; /* Property string functions */ -OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s, +OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s, int create); -OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, +OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s, int create); /* Property list functions */ @@ -24,8 +24,8 @@ void ossl_property_free(OSSL_PROPERTY_LIST *p); int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query); /* Property definition cache functions */ -OSSL_PROPERTY_LIST *ossl_prop_defn_get(OPENSSL_CTX *ctx, const char *prop); -int ossl_prop_defn_set(OPENSSL_CTX *ctx, const char *prop, +OSSL_PROPERTY_LIST *ossl_prop_defn_get(OSSL_LIB_CTX *ctx, const char *prop); +int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop, OSSL_PROPERTY_LIST *pl); /* Property cache lock / unlock */ diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index 91b830c2e5..9bc89f4d42 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -80,7 +80,7 @@ static int match(const char *t[], const char m[], size_t m_len) return 0; } -static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create, +static int parse_name(OSSL_LIB_CTX *ctx, const char *t[], int create, OSSL_PROPERTY_IDX *idx) { char name[100]; @@ -187,7 +187,7 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res) return 1; } -static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim, +static int parse_string(OSSL_LIB_CTX *ctx, const char *t[], char delim, PROPERTY_DEFINITION *res, const int create) { char v[1000]; @@ -218,7 +218,7 @@ static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim, return !err; } -static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[], +static int parse_unquoted(OSSL_LIB_CTX *ctx, const char *t[], PROPERTY_DEFINITION *res, const int create) { char v[1000]; @@ -251,7 +251,7 @@ static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[], return !err; } -static int parse_value(OPENSSL_CTX *ctx, const char *t[], +static int parse_value(OSSL_LIB_CTX *ctx, const char *t[], PROPERTY_DEFINITION *res, int create) { const char *s = *t; @@ -326,7 +326,7 @@ static OSSL_PROPERTY_LIST *stack_to_property_list(STACK_OF(PROPERTY_DEFINITION) return r; } -OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) +OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn) { PROPERTY_DEFINITION *prop = NULL; OSSL_PROPERTY_LIST *res = NULL; @@ -385,7 +385,7 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn) return res; } -OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s) +OSSL_PROPERTY_LIST *ossl_parse_query(OSSL_LIB_CTX *ctx, const char *s) { STACK_OF(PROPERTY_DEFINITION) *sk; OSSL_PROPERTY_LIST *res = NULL; @@ -453,7 +453,7 @@ int ossl_property_has_optional(const OSSL_PROPERTY_LIST *query) return query->has_optional ? 1 : 0; } -int ossl_property_is_enabled(OPENSSL_CTX *ctx, const char *property_name, +int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name, const OSSL_PROPERTY_LIST *prop_list) { int i; @@ -590,15 +590,15 @@ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, return r; } -int ossl_property_parse_init(OPENSSL_CTX *ctx) +int ossl_property_parse_init(OSSL_LIB_CTX *ctx) { static const char *const predefined_names[] = { "provider", /* Name of provider (default, legacy, fips) */ "version", /* Version number of this provider */ "fips", /* FIPS validated or FIPS supporting algorithm */ - "format", /* output format for serializers */ - "type", /* output type for serializers */ - "input", /* input type for deserializers */ + "output", /* Output type for encoders */ + "input", /* Input type for decoders */ + "structure", /* Structure name for encoders and decoders */ }; size_t i; diff --git a/crypto/property/property_string.c b/crypto/property/property_string.c index 55d34688db..90bb322faa 100644 --- a/crypto/property/property_string.c +++ b/crypto/property/property_string.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -81,7 +81,7 @@ static void property_string_data_free(void *vpropdata) OPENSSL_free(propdata); } -static void *property_string_data_new(OPENSSL_CTX *ctx) { +static void *property_string_data_new(OSSL_LIB_CTX *ctx) { PROPERTY_STRING_DATA *propdata = OPENSSL_zalloc(sizeof(*propdata)); if (propdata == NULL) @@ -104,7 +104,7 @@ static void *property_string_data_new(OPENSSL_CTX *ctx) { return NULL; } -static const OPENSSL_CTX_METHOD property_string_data_method = { +static const OSSL_LIB_CTX_METHOD property_string_data_method = { property_string_data_new, property_string_data_free, }; @@ -147,12 +147,12 @@ static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t, return ps != NULL ? ps->idx : 0; } -OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s, +OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s, int create) { PROPERTY_STRING_DATA *propdata - = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX, - &property_string_data_method); + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); if (propdata == NULL) return 0; @@ -161,12 +161,12 @@ OSSL_PROPERTY_IDX ossl_property_name(OPENSSL_CTX *ctx, const char *s, s); } -OSSL_PROPERTY_IDX ossl_property_value(OPENSSL_CTX *ctx, const char *s, +OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s, int create) { PROPERTY_STRING_DATA *propdata - = openssl_ctx_get_data(ctx, OPENSSL_CTX_PROPERTY_STRING_INDEX, - &property_string_data_method); + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX, + &property_string_data_method); if (propdata == NULL) return 0; diff --git a/crypto/provider.c b/crypto/provider.c index 8646aef771..53db7a6229 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -10,9 +10,10 @@ #include #include #include +#include #include "internal/provider.h" -OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name) +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name) { OSSL_PROVIDER *prov = NULL; @@ -29,13 +30,21 @@ OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name) return prov; } +OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name) +{ + /* Any attempt to load a provider disables auto-loading of defaults */ + if (ossl_provider_disable_fallback_loading(libctx)) + return OSSL_PROVIDER_try_load(libctx, name); + return NULL; +} + int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov) { ossl_provider_free(prov); return 1; } -int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name) +int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name) { OSSL_PROVIDER *prov = NULL; int available = 0; @@ -69,6 +78,11 @@ void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov) return ossl_provider_prov_ctx(prov); } +int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov) +{ + return ossl_provider_self_test(prov); +} + int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov, const char *capability, OSSL_CALLBACK *cb, @@ -77,7 +91,7 @@ int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov, return ossl_provider_get_capabilities(prov, capability, cb, arg); } -int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name, +int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_fn) { OSSL_PROVIDER *prov = NULL; @@ -106,7 +120,7 @@ const char *OSSL_PROVIDER_name(const OSSL_PROVIDER *prov) return ossl_provider_name(prov); } -int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, +int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, int (*cb)(OSSL_PROVIDER *provider, void *cbdata), void *cbdata) diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index ce09fae7d3..f4f88e7100 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -15,7 +15,6 @@ #include "internal/provider.h" DEFINE_STACK_OF(OSSL_PROVIDER) -DEFINE_STACK_OF(CONF_VALUE) /* PROVIDER config module */ @@ -71,7 +70,7 @@ static int provider_conf_params(OSSL_PROVIDER *prov, return ok; } -static int provider_conf_load(OPENSSL_CTX *libctx, const char *name, +static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name, const char *value, const CONF *cnf) { int i; @@ -89,6 +88,7 @@ static int provider_conf_load(OPENSSL_CTX *libctx, const char *name, if (!ecmds) { CRYPTOerr(CRYPTO_F_PROVIDER_CONF_LOAD, CRYPTO_R_PROVIDER_SECTION_ERROR); + ERR_add_error_data(3, "section=", value, " not found"); return 0; } diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 79c330383c..52e68641ae 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -14,6 +14,7 @@ #include #include #include "crypto/cryptlib.h" +#include "crypto/evp.h" /* evp_method_store_flush */ #include "internal/nelem.h" #include "internal/thread_once.h" #include "internal/provider.h" @@ -53,7 +54,7 @@ struct ossl_provider_st { DSO *module; OSSL_provider_init_fn *init_function; STACK_OF(INFOPAIR) *parameters; - OPENSSL_CTX *libctx; /* The library context this instance is in */ + OSSL_LIB_CTX *libctx; /* The library context this instance is in */ struct provider_store_st *store; /* The store this instance belongs to */ #ifndef FIPS_MODULE /* @@ -71,6 +72,7 @@ struct ossl_provider_st { OSSL_FUNC_provider_gettable_params_fn *gettable_params; OSSL_FUNC_provider_get_params_fn *get_params; OSSL_FUNC_provider_get_capabilities_fn *get_capabilities; + OSSL_FUNC_provider_self_test_fn *self_test; OSSL_FUNC_provider_query_operation_fn *query_operation; /* @@ -136,7 +138,7 @@ static void provider_store_free(void *vstore) OPENSSL_free(store); } -static void *provider_store_new(OPENSSL_CTX *ctx) +static void *provider_store_new(OSSL_LIB_CTX *ctx) { struct provider_store_st *store = OPENSSL_zalloc(sizeof(*store)); const struct predefined_providers_st *p = NULL; @@ -177,23 +179,34 @@ static void *provider_store_new(OPENSSL_CTX *ctx) return store; } -static const OPENSSL_CTX_METHOD provider_store_method = { +static const OSSL_LIB_CTX_METHOD provider_store_method = { provider_store_new, provider_store_free, }; -static struct provider_store_st *get_provider_store(OPENSSL_CTX *libctx) +static struct provider_store_st *get_provider_store(OSSL_LIB_CTX *libctx) { struct provider_store_st *store = NULL; - store = openssl_ctx_get_data(libctx, OPENSSL_CTX_PROVIDER_STORE_INDEX, - &provider_store_method); + store = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_PROVIDER_STORE_INDEX, + &provider_store_method); if (store == NULL) CRYPTOerr(CRYPTO_F_GET_PROVIDER_STORE, ERR_R_INTERNAL_ERROR); return store; } -OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name, +int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx) +{ + struct provider_store_st *store; + + if ((store = get_provider_store(libctx)) != NULL) { + store->use_fallbacks = 0; + return 1; + } + return 0; +} + +OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, int noconfig) { struct provider_store_st *store = NULL; @@ -258,7 +271,7 @@ int ossl_provider_up_ref(OSSL_PROVIDER *prov) return ref; } -OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, +OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_function, int noconfig) { @@ -417,7 +430,8 @@ int ossl_provider_add_parameter(OSSL_PROVIDER *prov, */ static const OSSL_DISPATCH *core_dispatch; /* Define further down */ -int OSSL_PROVIDER_set_default_search_path(OPENSSL_CTX *libctx, const char *path) +int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, + const char *path) { struct provider_store_st *store; char *p = NULL; @@ -544,6 +558,10 @@ static int provider_activate(OSSL_PROVIDER *prov) prov->get_params = OSSL_FUNC_provider_get_params(provider_dispatch); break; + case OSSL_FUNC_PROVIDER_SELF_TEST: + prov->self_test = + OSSL_FUNC_provider_self_test(provider_dispatch); + break; case OSSL_FUNC_PROVIDER_GET_CAPABILITIES: prov->get_capabilities = OSSL_FUNC_provider_get_capabilities(provider_dispatch); @@ -707,7 +725,7 @@ static void provider_activate_fallbacks(struct provider_store_st *store) } } -int ossl_provider_forall_loaded(OPENSSL_CTX *ctx, +int ossl_provider_forall_loaded(OSSL_LIB_CTX *ctx, int (*cb)(OSSL_PROVIDER *provider, void *cbdata), void *cbdata) @@ -799,7 +817,7 @@ void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov) return NULL; } -OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov) +OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov) { /* TODO(3.0) just: return prov->libctx; */ return prov != NULL ? prov->libctx : NULL; @@ -824,6 +842,18 @@ int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) ? 0 : prov->get_params(prov->provctx, params); } +int ossl_provider_self_test(const OSSL_PROVIDER *prov) +{ + int ret; + + if (prov->self_test == NULL) + return 1; + ret = prov->self_test(prov->provctx); + if (ret == 0) + evp_method_store_flush(ossl_provider_libctx(prov)); + return ret; +} + int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, const char *capability, OSSL_CALLBACK *cb, @@ -833,12 +863,12 @@ int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, ? 1 : prov->get_capabilities(prov->provctx, capability, cb, arg); } - const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, int operation_id, int *no_cache) { - return prov->query_operation(prov->provctx, operation_id, no_cache); + return prov->query_operation == NULL + ? NULL : prov->query_operation(prov->provctx, operation_id, no_cache); } int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) @@ -847,14 +877,17 @@ int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) unsigned char bit = (1 << (bitnum % 8)) & 0xFF; if (provider->operation_bits_sz <= byte) { - provider->operation_bits = OPENSSL_realloc(provider->operation_bits, - byte + 1); - if (provider->operation_bits == NULL) { + unsigned char *tmp = OPENSSL_realloc(provider->operation_bits, + byte + 1); + + if (tmp == NULL) { ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } + provider->operation_bits = tmp; memset(provider->operation_bits + provider->operation_bits_sz, '\0', byte + 1 - provider->operation_bits_sz); + provider->operation_bits_sz = byte + 1; } provider->operation_bits[byte] |= bit; return 1; @@ -908,7 +941,7 @@ static const OSSL_PARAM param_types[] = { static OSSL_FUNC_core_gettable_params_fn core_gettable_params; static OSSL_FUNC_core_get_params_fn core_get_params; static OSSL_FUNC_core_thread_start_fn core_thread_start; -static OSSL_FUNC_core_get_library_context_fn core_get_libctx; +static OSSL_FUNC_core_get_libctx_fn core_get_libctx; #ifndef FIPS_MODULE static OSSL_FUNC_core_new_error_fn core_new_error; static OSSL_FUNC_core_set_error_debug_fn core_set_error_debug; @@ -964,7 +997,7 @@ static OPENSSL_CORE_CTX *core_get_libctx(const OSSL_CORE_HANDLE *handle) */ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; - return (OPENSSL_CORE_CTX *)ossl_provider_library_context(prov); + return (OPENSSL_CORE_CTX *)ossl_provider_libctx(prov); } static int core_thread_start(const OSSL_CORE_HANDLE *handle, @@ -1047,7 +1080,7 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle) static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, - { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx }, + { OSSL_FUNC_CORE_GET_LIBCTX, (void (*)(void))core_get_libctx }, { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start }, #ifndef FIPS_MODULE { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error }, @@ -1063,6 +1096,7 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))BIO_write_ex }, { OSSL_FUNC_BIO_GETS, (void (*)(void))BIO_gets }, { OSSL_FUNC_BIO_PUTS, (void (*)(void))BIO_puts }, + { OSSL_FUNC_BIO_CTRL, (void (*)(void))BIO_ctrl }, { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free }, { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf }, { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, diff --git a/crypto/punycode.c b/crypto/punycode.c new file mode 100644 index 0000000000..385b4b1df4 --- /dev/null +++ b/crypto/punycode.c @@ -0,0 +1,338 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "crypto/punycode.h" + +static const unsigned int base = 36; +static const unsigned int tmin = 1; +static const unsigned int tmax = 26; +static const unsigned int skew = 38; +static const unsigned int damp = 700; +static const unsigned int initial_bias = 72; +static const unsigned int initial_n = 0x80; +static const unsigned int maxint = 0xFFFFFFFF; +static const char delimiter = '-'; + +#define LABEL_BUF_SIZE 512 + +/*- + * Pseudocode: + * + * function adapt(delta,numpoints,firsttime): + * if firsttime then let delta = delta div damp + * else let delta = delta div 2 + * let delta = delta + (delta div numpoints) + * let k = 0 + * while delta > ((base - tmin) * tmax) div 2 do begin + * let delta = delta div (base - tmin) + * let k = k + base + * end + * return k + (((base - tmin + 1) * delta) div (delta + skew)) + */ + +static int adapt(unsigned int delta, unsigned int numpoints, + unsigned int firsttime) +{ + unsigned int k = 0; + + delta = (firsttime) ? delta / damp : delta / 2; + delta = delta + delta / numpoints; + + while (delta > ((base - tmin) * tmax) / 2) { + delta = delta / (base - tmin); + k = k + base; + } + + return k + (((base - tmin + 1) * delta) / (delta + skew)); +} + +static ossl_inline int is_basic(unsigned int a) +{ + return (a < 0x80) ? 1 : 0; +} + +/*- + * code points digit-values + * ------------ ---------------------- + * 41..5A (A-Z) = 0 to 25, respectively + * 61..7A (a-z) = 0 to 25, respectively + * 30..39 (0-9) = 26 to 35, respectively + */ +static ossl_inline int digit_decoded(const unsigned char a) +{ + if (a >= 0x41 && a <= 0x5A) + return a - 0x41; + + if (a >= 0x61 && a <= 0x7A) + return a - 0x61; + + if (a >= 0x30 && a <= 0x39) + return a - 0x30 + 26; + + return -1; +} + +/*- + * Pseudocode: + * + * function ossl_punycode_decode + * let n = initial_n + * let i = 0 + * let bias = initial_bias + * let output = an empty string indexed from 0 + * consume all code points before the last delimiter (if there is one) + * and copy them to output, fail on any non-basic code point + * if more than zero code points were consumed then consume one more + * (which will be the last delimiter) + * while the input is not exhausted do begin + * let oldi = i + * let w = 1 + * for k = base to infinity in steps of base do begin + * consume a code point, or fail if there was none to consume + * let digit = the code point's digit-value, fail if it has none + * let i = i + digit * w, fail on overflow + * let t = tmin if k <= bias {+ tmin}, or + * tmax if k >= bias + tmax, or k - bias otherwise + * if digit < t then break + * let w = w * (base - t), fail on overflow + * end + * let bias = adapt(i - oldi, length(output) + 1, test oldi is 0?) + * let n = n + i div (length(output) + 1), fail on overflow + * let i = i mod (length(output) + 1) + * {if n is a basic code point then fail} + * insert n into output at position i + * increment i + * end + */ + +int ossl_punycode_decode(const char *pEncoded, const size_t enc_len, + unsigned int *pDecoded, unsigned int *pout_length) +{ + unsigned int n = initial_n; + unsigned int i = 0; + unsigned int bias = initial_bias; + size_t processed_in = 0, written_out = 0; + unsigned int max_out = *pout_length; + + unsigned int basic_count = 0; + unsigned int loop; + + for (loop = 0; loop < enc_len; loop++) { + if (pEncoded[loop] == delimiter) + basic_count = loop; + } + + if (basic_count > 0) { + if (basic_count > max_out) + return 0; + + for (loop = 0; loop < basic_count; loop++) { + if (is_basic(pEncoded[loop]) == 0) + return 0; + + pDecoded[loop] = pEncoded[loop]; + written_out++; + } + processed_in = basic_count + 1; + } + + for (loop = processed_in; loop < enc_len;) { + unsigned int oldi = i; + unsigned int w = 1; + unsigned int k, t; + int digit; + + for (k = base;; k += base) { + if (loop >= enc_len) + return 0; + + digit = digit_decoded(pEncoded[loop]); + loop++; + + if (digit < 0) + return 0; + if ((unsigned int)digit > (maxint - i) / w) + return 0; + + i = i + digit * w; + t = (k <= bias) ? tmin : (k >= bias + tmax) ? tmax : k - bias; + + if ((unsigned int)digit < t) + break; + + if (w > maxint / (base - t)) + return 0; + w = w * (base - t); + } + + bias = adapt(i - oldi, written_out + 1, (oldi == 0)); + if (i / (written_out + 1) > maxint - n) + return 0; + n = n + i / (written_out + 1); + i %= (written_out + 1); + + if (written_out > max_out) + return 0; + + memmove(pDecoded + i + 1, pDecoded + i, + (written_out - i) * sizeof *pDecoded); + pDecoded[i] = n; + i++; + written_out++; + } + + *pout_length = written_out; + return 1; +} + +/* + * Encode a code point using UTF-8 + * return number of bytes on success, 0 on failure + * (also produces U+FFFD, which uses 3 bytes on failure) + */ +static int codepoint2utf8(unsigned char *out, unsigned long utf) +{ + if (utf <= 0x7F) { + /* Plain ASCII */ + out[0] = (unsigned char)utf; + out[1] = 0; + return 1; + } else if (utf <= 0x07FF) { + /* 2-byte unicode */ + out[0] = (unsigned char)(((utf >> 6) & 0x1F) | 0xC0); + out[1] = (unsigned char)(((utf >> 0) & 0x3F) | 0x80); + out[2] = 0; + return 2; + } else if (utf <= 0xFFFF) { + /* 3-byte unicode */ + out[0] = (unsigned char)(((utf >> 12) & 0x0F) | 0xE0); + out[1] = (unsigned char)(((utf >> 6) & 0x3F) | 0x80); + out[2] = (unsigned char)(((utf >> 0) & 0x3F) | 0x80); + out[3] = 0; + return 3; + } else if (utf <= 0x10FFFF) { + /* 4-byte unicode */ + out[0] = (unsigned char)(((utf >> 18) & 0x07) | 0xF0); + out[1] = (unsigned char)(((utf >> 12) & 0x3F) | 0x80); + out[2] = (unsigned char)(((utf >> 6) & 0x3F) | 0x80); + out[3] = (unsigned char)(((utf >> 0) & 0x3F) | 0x80); + out[4] = 0; + return 4; + } else { + /* error - use replacement character */ + out[0] = (unsigned char)0xEF; + out[1] = (unsigned char)0xBF; + out[2] = (unsigned char)0xBD; + out[3] = 0; + return 0; + } +} + +/*- + * Return values: + * 1 - ok, *outlen contains valid buf length + * 0 - ok but buf was too short, *outlen contains valid buf length + * -1 - bad string passed + */ + +int ossl_a2ulabel(const char *in, char *out, size_t *outlen) +{ + /*- + * Domain name has some parts consisting of ASCII chars joined with dot. + * If a part is shorter than 5 chars, it becomes U-label as is. + * If it does not start with xn--, it becomes U-label as is. + * Otherwise we try to decode it. + */ + char *outptr = out; + const char *inptr = in; + size_t size = 0; + int result = 1; + + unsigned int buf[LABEL_BUF_SIZE]; /* It's a hostname */ + if (out == NULL) + result = 0; + + while (1) { + char *tmpptr = strchr(inptr, '.'); + size_t delta = (tmpptr) ? (size_t)(tmpptr - inptr) : strlen(inptr); + + if (strncmp(inptr, "xn--", 4) != 0) { + size += delta + 1; + + if (size >= *outlen - 1) + result = 0; + + if (result > 0) { + memcpy(outptr, inptr, delta + 1); + outptr += delta + 1; + } + } else { + unsigned int bufsize = LABEL_BUF_SIZE; + unsigned int i; + + if (ossl_punycode_decode(inptr + 4, delta - 4, buf, &bufsize) <= 0) + return -1; + + for (i = 0; i < bufsize; i++) { + unsigned char seed[6]; + size_t utfsize = codepoint2utf8(seed, buf[i]); + if (utfsize == 0) + return -1; + + size += utfsize; + if (size >= *outlen - 1) + result = 0; + + if (result > 0) { + memcpy(outptr, seed, utfsize); + outptr += utfsize; + } + } + + if (tmpptr != NULL) { + *outptr = '.'; + outptr++; + size++; + if (size >= *outlen - 1) + result = 0; + } + } + + if (tmpptr == NULL) + break; + + inptr = tmpptr + 1; + } + + return result; +} + +/*- + * a MUST be A-label + * u MUST be U-label + * Returns 0 if compared values are equal + * 1 if not + * -1 in case of errors + */ + +int ossl_a2ucompare(const char *a, const char *u) +{ + char a_ulabel[LABEL_BUF_SIZE]; + size_t a_size = sizeof(a_ulabel); + + if (ossl_a2ulabel(a, a_ulabel, &a_size) <= 0) { + return -1; + } + + return (strcmp(a_ulabel, u) == 0) ? 0 : 1; +} diff --git a/crypto/rand/build.info b/crypto/rand/build.info index 7776ca8820..f58a026f3b 100644 --- a/crypto/rand/build.info +++ b/crypto/rand/build.info @@ -1,6 +1,6 @@ LIBS=../../libcrypto -$COMMON=drbg_lib.c rand_lib.c +$COMMON=rand_lib.c rand_meth.c $CRYPTO=randfile.c rand_err.c rand_deprecated.c IF[{- !$disabled{'egd'} -}] diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c deleted file mode 100644 index d2566920cd..0000000000 --- a/crypto/rand/drbg_lib.c +++ /dev/null @@ -1,1016 +0,0 @@ -/* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * RAND_DRBG_set is deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include "rand_local.h" -#include "internal/thread_once.h" -#include "crypto/rand.h" -#include "crypto/cryptlib.h" - -/* - * Support framework for NIST SP 800-90A DRBG - * - * See manual page RAND_DRBG(7) for a general overview. - * - * The OpenSSL model is to have new and free functions, and that new - * does all initialization. That is not the NIST model, which has - * instantiation and un-instantiate, and re-use within a new/free - * lifecycle. (No doubt this comes from the desire to support hardware - * DRBG, where allocation of resources on something like an HSM is - * a much bigger deal than just re-setting an allocated resource.) - */ - - -typedef struct drbg_global_st { - /* - * The three shared DRBG instances - * - * There are three shared DRBG instances: , , and - * . The and DRBGs are secondary ones. - * These are used for non-secret (e.g. nonces) and secret - * (e.g. private keys) data respectively. - */ - CRYPTO_RWLOCK *lock; - - /* - * The DRBG - * - * Not used directly by the application, only for reseeding the two other - * DRBGs. It reseeds itself by pulling either randomness from os entropy - * sources or by consuming randomness which was added by RAND_add(). - * - * The DRBG is a global instance which is accessed concurrently by - * all threads. The necessary locking is managed automatically by its child - * DRBG instances during reseeding. - */ - RAND_DRBG *primary_drbg; - /* - * The DRBG - * - * Used by default for generating random bytes using RAND_bytes(). - * - * The secondary DRBG is thread-local, i.e., there is one instance - * per thread. - */ - CRYPTO_THREAD_LOCAL public_drbg; - /* - * The DRBG - * - * Used by default for generating private keys using RAND_priv_bytes() - * - * The secondary DRBG is thread-local, i.e., there is one - * instance per thread. - */ - CRYPTO_THREAD_LOCAL private_drbg; -} DRBG_GLOBAL; - -#define RAND_DRBG_TYPE_FLAGS ( \ - RAND_DRBG_FLAG_PRIMARY | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE ) - -#define RAND_DRBG_TYPE_PRIMARY 0 -#define RAND_DRBG_TYPE_PUBLIC 1 -#define RAND_DRBG_TYPE_PRIVATE 2 - -/* Defaults */ -static int rand_drbg_type[3] = { - RAND_DRBG_TYPE, /* Primary */ - RAND_DRBG_TYPE, /* Public */ - RAND_DRBG_TYPE /* Private */ -}; -static unsigned int rand_drbg_flags[3] = { - RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIMARY, /* Primary */ - RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC, /* Public */ - RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE /* Private */ -}; - -static unsigned int primary_reseed_interval = PRIMARY_RESEED_INTERVAL; -static unsigned int secondary_reseed_interval = SECONDARY_RESEED_INTERVAL; - -static time_t primary_reseed_time_interval = PRIMARY_RESEED_TIME_INTERVAL; -static time_t secondary_reseed_time_interval = SECONDARY_RESEED_TIME_INTERVAL; - -/* A logical OR of all used DRBG flag bits (currently there is only one) */ -static const unsigned int rand_drbg_used_flags = - RAND_DRBG_FLAG_CTR_NO_DF | RAND_DRBG_FLAG_HMAC | RAND_DRBG_TYPE_FLAGS; - - -static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, - int drbg_type); - -static int get_drbg_params(int type, unsigned int flags, const char **name, - OSSL_PARAM params[3]) -{ - OSSL_PARAM *p = params; - - switch (type) { - case 0: - return 1; - default: - return 0; - -#define CTR(v) \ - *name = "CTR-DRBG"; \ - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, v, 0) - - case NID_aes_128_ctr: - CTR(SN_aes_128_ctr); - break; - case NID_aes_192_ctr: - CTR(SN_aes_192_ctr); - break; - case NID_aes_256_ctr: - CTR(SN_aes_256_ctr); - break; - -#define DGST(v) \ - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, v, 0); \ - if ((flags & RAND_DRBG_FLAG_HMAC) == 0) { \ - *name = "HASH-DRBG"; \ - } else { \ - *name = "HMAC-DRBG"; \ - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_MAC, \ - SN_hmac, 0); \ - } - - case NID_sha1: - DGST(SN_sha1); - break; - case NID_sha224: - DGST(SN_sha224); - break; - case NID_sha256: - DGST(SN_sha256); - break; - case NID_sha384: - DGST(SN_sha384); - break; - case NID_sha512: - DGST(SN_sha512); - break; - case NID_sha512_224: - DGST(SN_sha512_224); - break; - case NID_sha512_256: - DGST(SN_sha512_256); - break; - case NID_sha3_224: - DGST(SN_sha3_224); - break; - case NID_sha3_256: - DGST(SN_sha3_256); - break; - case NID_sha3_384: - DGST(SN_sha3_384); - break; - case NID_sha3_512: - DGST(SN_sha3_512); - } - *p = OSSL_PARAM_construct_end(); - return 1; -} - -/* - * Initialize the OPENSSL_CTX global DRBGs on first use. - * Returns the allocated global data on success or NULL on failure. - */ -static void *drbg_ossl_ctx_new(OPENSSL_CTX *libctx) -{ - DRBG_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl)); - - if (dgbl == NULL) - return NULL; - -#ifndef FIPS_MODULE - /* - * We need to ensure that base libcrypto thread handling has been - * initialised. - */ - OPENSSL_init_crypto(0, NULL); -#endif - - dgbl->lock = CRYPTO_THREAD_lock_new(); - if (dgbl->lock == NULL) - goto err0; - - if (!CRYPTO_THREAD_init_local(&dgbl->private_drbg, NULL)) - goto err1; - - if (!CRYPTO_THREAD_init_local(&dgbl->public_drbg, NULL)) - goto err2; - - return dgbl; - - err2: - CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); - err1: - CRYPTO_THREAD_lock_free(dgbl->lock); - err0: - OPENSSL_free(dgbl); - return NULL; -} - -static void drbg_ossl_ctx_free(void *vdgbl) -{ - DRBG_GLOBAL *dgbl = vdgbl; - - if (dgbl == NULL) - return; - - CRYPTO_THREAD_lock_free(dgbl->lock); - RAND_DRBG_free(dgbl->primary_drbg); - CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); - CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg); - - OPENSSL_free(dgbl); -} - -static const OPENSSL_CTX_METHOD drbg_ossl_ctx_method = { - drbg_ossl_ctx_new, - drbg_ossl_ctx_free, -}; - -static DRBG_GLOBAL *drbg_get_global(OPENSSL_CTX *libctx) -{ - return openssl_ctx_get_data(libctx, OPENSSL_CTX_DRBG_INDEX, - &drbg_ossl_ctx_method); -} - -/* - * Set the |drbg|'s callback data pointer for the entropy and nonce callbacks - * - * The ownership of the context data remains with the caller, - * i.e., it is the caller's responsibility to keep it available as long - * as it is need by the callbacks and free it after use. - * - * Setting the callback data is allowed only if the drbg has not been - * initialized yet. Otherwise, the operation will fail. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *data) -{ - if (EVP_RAND_state(drbg->rand) != EVP_RAND_STATE_UNINITIALISED - || drbg->parent != NULL) - return 0; - - drbg->callback_data = data; - return 1; -} - -/* Retrieve the callback data pointer */ -void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg) -{ - return drbg->callback_data; -} - -/* - * Set/initialize |drbg| to be of type |type|, with optional |flags|. - * - * If |type| and |flags| are zero, use the defaults - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) -{ - OSSL_PARAM params[6], *p = params; - unsigned int reseed_interval; - time_t reseed_time_interval; - const char *name = NULL; - EVP_RAND *rand; - EVP_RAND_CTX *pctx; - int use_df; - - RAND_DRBG_get_entropy_fn get_entropy = drbg->get_entropy; - RAND_DRBG_cleanup_entropy_fn cleanup_entropy = drbg->cleanup_entropy; - RAND_DRBG_get_nonce_fn get_nonce = drbg->get_nonce; - RAND_DRBG_cleanup_nonce_fn cleanup_nonce = drbg->cleanup_nonce; - - if (type == 0 && flags == 0) { - type = rand_drbg_type[RAND_DRBG_TYPE_PRIMARY]; - flags = rand_drbg_flags[RAND_DRBG_TYPE_PRIMARY]; - } - - if (drbg->parent == NULL) { - reseed_interval = primary_reseed_interval; - reseed_time_interval = primary_reseed_time_interval; - } else { - reseed_interval = secondary_reseed_interval; - reseed_time_interval = secondary_reseed_time_interval; - } - *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, - &reseed_interval); - *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, - &reseed_time_interval); - use_df = (flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0; - *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF, &use_df); - - if (!get_drbg_params(type, flags, &name, p)) { - RANDerr(0, RAND_R_UNSUPPORTED_DRBG_TYPE); - return 0; - } - - rand = EVP_RAND_fetch(drbg->libctx, name, NULL); - if (rand == NULL) { - RANDerr(0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); - return 0; - } - - EVP_RAND_CTX_free(drbg->rand); - drbg->rand = NULL; - - drbg->flags = flags; - drbg->type = type; - - pctx = drbg->parent != NULL ? drbg->parent->rand : NULL; - drbg->rand = EVP_RAND_CTX_new(rand, pctx); - EVP_RAND_free(rand); - if (drbg->rand == NULL) { - RANDerr(0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); - goto err; - } - - if (!EVP_RAND_set_ctx_params(drbg->rand, params)) { - RANDerr(0, RAND_R_ERROR_INITIALISING_DRBG); - goto err; - } - - if (!RAND_DRBG_set_callbacks(drbg, - get_entropy, cleanup_entropy, - get_nonce, cleanup_nonce)) { - RANDerr(0, RAND_R_ERROR_INITIALISING_DRBG); - goto err; - } - - return 1; -err: - EVP_RAND_CTX_free(drbg->rand); - drbg->rand = NULL; - drbg->type = 0; - drbg->flags = 0; - return 0; -} - -/* - * Set/initialize default |type| and |flag| for new drbg instances. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_defaults(int type, unsigned int flags) -{ - int all; - const char *name; - OSSL_PARAM params[3]; - - if (!get_drbg_params(type, flags, &name, params)) { - RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_TYPE); - return 0; - } - - if ((flags & ~rand_drbg_used_flags) != 0) { - RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_FLAGS); - return 0; - } - - all = ((flags & RAND_DRBG_TYPE_FLAGS) == 0); - if (all || (flags & RAND_DRBG_FLAG_PRIMARY) != 0) { - rand_drbg_type[RAND_DRBG_TYPE_PRIMARY] = type; - rand_drbg_flags[RAND_DRBG_TYPE_PRIMARY] = flags - | RAND_DRBG_FLAG_PRIMARY; - } - if (all || (flags & RAND_DRBG_FLAG_PUBLIC) != 0) { - rand_drbg_type[RAND_DRBG_TYPE_PUBLIC] = type; - rand_drbg_flags[RAND_DRBG_TYPE_PUBLIC] = flags | RAND_DRBG_FLAG_PUBLIC; - } - if (all || (flags & RAND_DRBG_FLAG_PRIVATE) != 0) { - rand_drbg_type[RAND_DRBG_TYPE_PRIVATE] = type; - rand_drbg_flags[RAND_DRBG_TYPE_PRIVATE] = flags - | RAND_DRBG_FLAG_PRIVATE; - } - return 1; -} - - -/* - * Allocate memory and initialize a new DRBG. - * The |parent|, if not NULL, will be used as random source for reseeding. - * - * Returns a pointer to the new DRBG instance on success, NULL on failure. - */ -static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx, - int type, - unsigned int flags, - RAND_DRBG *parent) -{ - RAND_DRBG *drbg = OPENSSL_zalloc(sizeof(*drbg)); - - if (drbg == NULL) { - RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - drbg->libctx = ctx; - drbg->parent = parent; - - if (RAND_DRBG_set(drbg, type, flags) == 0) - goto err; - - return drbg; - - err: - RAND_DRBG_free(drbg); - - return NULL; -} - -RAND_DRBG *RAND_DRBG_new_ex(OPENSSL_CTX *ctx, int type, unsigned int flags, - RAND_DRBG *parent) -{ - return rand_drbg_new(ctx, type, flags, parent); -} - -RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent) -{ - return RAND_DRBG_new_ex(NULL, type, flags, parent); -} - -/* - * Uninstantiate |drbg| and free all memory. - */ -void RAND_DRBG_free(RAND_DRBG *drbg) -{ - if (drbg == NULL) - return; - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data); - EVP_RAND_CTX_free(drbg->rand); - OPENSSL_free(drbg); -} - -/* - * Instantiate |drbg|, after it has been initialized. Use |pers| and - * |perslen| as prediction-resistance input. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_instantiate(RAND_DRBG *drbg, - const unsigned char *pers, size_t perslen) -{ - return EVP_RAND_instantiate(drbg->rand, EVP_RAND_strength(drbg->rand), 0, - pers, perslen); -} - -/* - * Uninstantiate |drbg|. Must be instantiated before it can be used. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_uninstantiate(RAND_DRBG *drbg) -{ - int index = -1, type, flags; - - if (!EVP_RAND_uninstantiate(drbg->rand)) - return 0; - - /* The reset uses the default values for type and flags */ - if (drbg->flags & RAND_DRBG_FLAG_PRIMARY) - index = RAND_DRBG_TYPE_PRIMARY; - else if (drbg->flags & RAND_DRBG_FLAG_PRIVATE) - index = RAND_DRBG_TYPE_PRIVATE; - else if (drbg->flags & RAND_DRBG_FLAG_PUBLIC) - index = RAND_DRBG_TYPE_PUBLIC; - - if (index != -1) { - flags = rand_drbg_flags[index]; - type = rand_drbg_type[index]; - } else { - flags = drbg->flags; - type = drbg->type; - } - return RAND_DRBG_set(drbg, type, flags); -} - -/* - * Reseed |drbg|, mixing in the specified data - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_reseed(RAND_DRBG *drbg, - const unsigned char *adin, size_t adinlen, - int prediction_resistance) -{ - return EVP_RAND_reseed(drbg->rand, prediction_resistance, NULL, 0, - adin, adinlen); -} - -/* - * Generate |outlen| bytes into the buffer at |out|. Reseed if we need - * to or if |prediction_resistance| is set. Additional input can be - * sent in |adin| and |adinlen|. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success, 0 on failure. - * - */ -int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, - int prediction_resistance, - const unsigned char *adin, size_t adinlen) -{ - return EVP_RAND_generate(drbg->rand, out, outlen, 0, - prediction_resistance, adin, adinlen); -} - -/* - * Generates |outlen| random bytes and stores them in |out|. It will - * using the given |drbg| to generate the bytes. - * - * Requires that drbg->lock is already locked for write, if non-null. - * - * Returns 1 on success 0 on failure. - */ -int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) -{ - return EVP_RAND_generate(drbg->rand, out, outlen, 0, 0, NULL, 0); -} - -/* DRBG call back shims */ -static int rand_drbg_get_entroy_cb(const OSSL_PARAM *params, OSSL_PARAM *out, - void *vdrbg) -{ - RAND_DRBG *drbg = (RAND_DRBG *)vdrbg; - int entropy = 0, prediction_resistance = 0; - size_t min_len = 0, max_len = 2048; - const OSSL_PARAM *p; - OSSL_PARAM *q; - - if (drbg->get_entropy == NULL) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_ENTROPY_REQUIRED); - if (p == NULL || !OSSL_PARAM_get_int(p, &entropy)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_PREDICTION_RESISTANCE); - if (p == NULL || !OSSL_PARAM_get_int(p, &prediction_resistance)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_MAX_LENGTH); - if (p == NULL || !OSSL_PARAM_get_size_t(p, &max_len)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_MIN_LENGTH); - if (p == NULL || !OSSL_PARAM_get_size_t(p, &min_len)) - return 0; - - q = OSSL_PARAM_locate(out, OSSL_DRBG_PARAM_RANDOM_DATA); - if (q == NULL || q->data_type != OSSL_PARAM_OCTET_PTR || q->data == NULL) - return 0; - - q->return_size = drbg->get_entropy(drbg, (unsigned char **)q->data, entropy, - min_len, max_len, prediction_resistance); - return 1; -} - -static int rand_drbg_cleanup_entropy_cb(const OSSL_PARAM *params, void *vdrbg) -{ - RAND_DRBG *drbg = (RAND_DRBG *)vdrbg; - const OSSL_PARAM *p; - size_t sz; - - if (drbg->cleanup_entropy == NULL) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_SIZE); - if (p == NULL || !OSSL_PARAM_get_size_t(p, &sz)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RANDOM_DATA); - if (p == NULL || p->data_type != OSSL_PARAM_OCTET_PTR) - return 0; - - drbg->cleanup_entropy(drbg, p->data, sz); - return 1; -} - -static int rand_drbg_get_nonce_cb(const OSSL_PARAM *params, OSSL_PARAM *out, - void *vdrbg) -{ - RAND_DRBG *drbg = (RAND_DRBG *)vdrbg; - int entropy = 0; - size_t min_len = 0, max_len = 10240; - const OSSL_PARAM *p; - OSSL_PARAM *q; - - if (drbg->get_nonce == NULL) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_ENTROPY_REQUIRED); - if (p == NULL || !OSSL_PARAM_get_int(p, &entropy)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_MAX_LENGTH); - if (p == NULL || !OSSL_PARAM_get_size_t(p, &max_len)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_MIN_LENGTH); - if (p == NULL || !OSSL_PARAM_get_size_t(p, &min_len)) - return 0; - - q = OSSL_PARAM_locate(out, OSSL_DRBG_PARAM_RANDOM_DATA); - if (q == NULL || q->data_type != OSSL_PARAM_OCTET_PTR || q->data == NULL) - return 0; - - q->return_size = drbg->get_nonce(drbg, (unsigned char **)q->data, entropy, - min_len, max_len); - return 1; -} - -static int rand_drbg_cleanup_nonce_cb(const OSSL_PARAM *params, void *vdrbg) -{ - RAND_DRBG *drbg = (RAND_DRBG *)vdrbg; - const OSSL_PARAM *p; - size_t sz; - - if (drbg->cleanup_nonce == NULL) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_SIZE); - if (p == NULL || !OSSL_PARAM_get_size_t(p, &sz)) - return 0; - - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RANDOM_DATA); - if (p == NULL || p->data_type != OSSL_PARAM_OCTET_PTR) - return 0; - - drbg->cleanup_nonce(drbg, p->data, sz); - return 1; -} - -/* - * Set the RAND_DRBG callbacks for obtaining entropy and nonce. - * - * Setting the callbacks is allowed only if the drbg has not been - * initialized yet. Otherwise, the operation will fail. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, - RAND_DRBG_get_entropy_fn get_entropy, - RAND_DRBG_cleanup_entropy_fn cleanup_entropy, - RAND_DRBG_get_nonce_fn get_nonce, - RAND_DRBG_cleanup_nonce_fn cleanup_nonce) -{ - EVP_RAND_CTX *rand = drbg->rand; - OSSL_INOUT_CALLBACK *g_ent = NULL, *g_nonce = NULL; - OSSL_CALLBACK *c_ent = NULL, *c_nonce = NULL; - - if (get_entropy != NULL) { - g_ent = &rand_drbg_get_entroy_cb; - c_ent = &rand_drbg_cleanup_entropy_cb; - } - if (get_nonce != NULL) { - g_nonce = rand_drbg_get_nonce_cb; - c_nonce = rand_drbg_cleanup_nonce_cb; - } - if (!EVP_RAND_set_callbacks(rand, g_ent, c_ent, g_nonce, c_nonce, drbg)) - return 0; - - drbg->get_entropy = g_ent != NULL ? get_entropy : NULL; - drbg->cleanup_entropy = c_ent != NULL ? cleanup_entropy : NULL; - drbg->get_nonce = g_nonce != NULL ? get_nonce : NULL; - drbg->cleanup_nonce = c_nonce != NULL ? cleanup_nonce : NULL; - return 1; -} - -/* - * Set the reseed interval. - * - * The drbg will reseed automatically whenever the number of generate - * requests exceeds the given reseed interval. If the reseed interval - * is 0, then this feature is disabled. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval) -{ - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - if (interval > MAX_RESEED_INTERVAL) - return 0; - params[0] = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, - &interval); - return EVP_RAND_set_ctx_params(drbg->rand, params); -} - -/* - * Set the reseed time interval. - * - * The drbg will reseed automatically whenever the time elapsed since - * the last reseeding exceeds the given reseed time interval. For safety, - * a reseeding will also occur if the clock has been reset to a smaller - * value. - * - * Returns 1 on success, 0 on failure. - */ -int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval) -{ - OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - if (interval > MAX_RESEED_TIME_INTERVAL) - return 0; - params[0] = - OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, - &interval); - return EVP_RAND_set_ctx_params(drbg->rand, params); -} - -/* - * Set the default values for reseed (time) intervals of new DRBG instances - * - * The default values can be set independently for primary DRBG instances - * (without a parent) and secondary DRBG instances (with parent). - * - * Returns 1 on success, 0 on failure. - */ - -int RAND_DRBG_set_reseed_defaults( - unsigned int _primary_reseed_interval, - unsigned int _secondary_reseed_interval, - time_t _primary_reseed_time_interval, - time_t _secondary_reseed_time_interval - ) -{ - if (_primary_reseed_interval > MAX_RESEED_INTERVAL - || _secondary_reseed_interval > MAX_RESEED_INTERVAL) - return 0; - - if (_primary_reseed_time_interval > MAX_RESEED_TIME_INTERVAL - || _secondary_reseed_time_interval > MAX_RESEED_TIME_INTERVAL) - return 0; - - primary_reseed_interval = _primary_reseed_interval; - secondary_reseed_interval = _secondary_reseed_interval; - - primary_reseed_time_interval = _primary_reseed_time_interval; - secondary_reseed_time_interval = _secondary_reseed_time_interval; - - return 1; -} - -/* - * Get and set the EXDATA - */ -int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg) -{ - return CRYPTO_set_ex_data(&drbg->ex_data, idx, arg); -} - -void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx) -{ - return CRYPTO_get_ex_data(&drbg->ex_data, idx); -} - -/* - * The following functions provide a RAND_METHOD that works on the - * global DRBG. They lock. - */ - -/* - * Allocates a new global DRBG on the secure heap (if enabled) and - * initializes it with default settings. - * - * Returns a pointer to the new DRBG instance on success, NULL on failure. - */ -static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, int drbg_type) -{ - RAND_DRBG *drbg; - - drbg = RAND_DRBG_new_ex(ctx, rand_drbg_type[drbg_type], - rand_drbg_flags[drbg_type], parent); - if (drbg == NULL) - return NULL; - - /* Only the primary DRBG needs to have a lock */ - if (parent == NULL && EVP_RAND_enable_locking(drbg->rand) == 0) - goto err; - - /* - * Ignore instantiation error to support just-in-time instantiation. - * - * The state of the drbg will be checked in RAND_DRBG_generate() and - * an automatic recovery is attempted. - */ - (void)RAND_DRBG_instantiate(drbg, NULL, 0); - return drbg; - -err: - RAND_DRBG_free(drbg); - return NULL; -} - -static void drbg_delete_thread_state(void *arg) -{ - OPENSSL_CTX *ctx = arg; - DRBG_GLOBAL *dgbl = drbg_get_global(ctx); - RAND_DRBG *drbg; - - if (dgbl == NULL) - return; - drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg); - CRYPTO_THREAD_set_local(&dgbl->public_drbg, NULL); - RAND_DRBG_free(drbg); - - drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg); - CRYPTO_THREAD_set_local(&dgbl->private_drbg, NULL); - RAND_DRBG_free(drbg); -} - -/* Implements the default OpenSSL RAND_bytes() method */ -static int drbg_bytes(unsigned char *out, int count) -{ - int ret; - RAND_DRBG *drbg = RAND_DRBG_get0_public(); - - if (drbg == NULL) - return 0; - - ret = RAND_DRBG_bytes(drbg, out, count); - - return ret; -} - -/* Implements the default OpenSSL RAND_add() method */ -static int drbg_add(const void *buf, int num, double randomness) -{ - RAND_DRBG *drbg = RAND_DRBG_get0_master(); - - if (drbg == NULL || num <= 0) - return 0; - - return EVP_RAND_reseed(drbg->rand, 0, NULL, 0, buf, num); -} - -/* Implements the default OpenSSL RAND_seed() method */ -static int drbg_seed(const void *buf, int num) -{ - return drbg_add(buf, num, num); -} - -/* Implements the default OpenSSL RAND_status() method */ -static int drbg_status(void) -{ - int ret; - RAND_DRBG *drbg = RAND_DRBG_get0_master(); - - if (drbg == NULL) - return 0; - - ret = EVP_RAND_state(drbg->rand) == EVP_RAND_STATE_READY ? 1 : 0; - return ret; -} - -int RAND_DRBG_verify_zeroization(RAND_DRBG *drbg) -{ - return EVP_RAND_verify_zeroization(drbg->rand); -} - -/* - * Get the primary DRBG. - * Returns pointer to the DRBG on success, NULL on failure. - * - */ -RAND_DRBG *OPENSSL_CTX_get0_primary_drbg(OPENSSL_CTX *ctx) -{ - DRBG_GLOBAL *dgbl = drbg_get_global(ctx); - - if (dgbl == NULL) - return NULL; - - if (dgbl->primary_drbg == NULL) { - if (!CRYPTO_THREAD_write_lock(dgbl->lock)) - return NULL; - if (dgbl->primary_drbg == NULL) - dgbl->primary_drbg = drbg_setup(ctx, NULL, RAND_DRBG_TYPE_PRIMARY); - CRYPTO_THREAD_unlock(dgbl->lock); - } - return dgbl->primary_drbg; -} - -RAND_DRBG *RAND_DRBG_get0_master(void) -{ - return OPENSSL_CTX_get0_primary_drbg(NULL); -} - -/* - * Get the public DRBG. - * Returns pointer to the DRBG on success, NULL on failure. - */ -RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx) -{ - DRBG_GLOBAL *dgbl = drbg_get_global(ctx); - RAND_DRBG *drbg, *primary; - - if (dgbl == NULL) - return NULL; - - drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg); - if (drbg == NULL) { - primary = OPENSSL_CTX_get0_primary_drbg(ctx); - if (primary == NULL) - return NULL; - - ctx = openssl_ctx_get_concrete(ctx); - /* - * If the private_drbg is also NULL then this is the first time we've - * used this thread. - */ - if (CRYPTO_THREAD_get_local(&dgbl->private_drbg) == NULL - && !ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state)) - return NULL; - drbg = drbg_setup(ctx, primary, RAND_DRBG_TYPE_PUBLIC); - CRYPTO_THREAD_set_local(&dgbl->public_drbg, drbg); - } - return drbg; -} - -RAND_DRBG *RAND_DRBG_get0_public(void) -{ - return OPENSSL_CTX_get0_public_drbg(NULL); -} - -/* - * Get the private DRBG. - * Returns pointer to the DRBG on success, NULL on failure. - */ -RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx) -{ - DRBG_GLOBAL *dgbl = drbg_get_global(ctx); - RAND_DRBG *drbg, *primary; - - if (dgbl == NULL) - return NULL; - - drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg); - if (drbg == NULL) { - primary = OPENSSL_CTX_get0_primary_drbg(ctx); - if (primary == NULL) - return NULL; - - ctx = openssl_ctx_get_concrete(ctx); - /* - * If the public_drbg is also NULL then this is the first time we've - * used this thread. - */ - if (CRYPTO_THREAD_get_local(&dgbl->public_drbg) == NULL - && !ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state)) - return NULL; - drbg = drbg_setup(ctx, primary, RAND_DRBG_TYPE_PRIVATE); - CRYPTO_THREAD_set_local(&dgbl->private_drbg, drbg); - } - return drbg; -} - -RAND_DRBG *RAND_DRBG_get0_private(void) -{ - return OPENSSL_CTX_get0_private_drbg(NULL); -} - -RAND_METHOD rand_meth = { - drbg_seed, - drbg_bytes, - NULL, - drbg_add, - drbg_bytes, - drbg_status -}; - -RAND_METHOD *RAND_OpenSSL(void) -{ -#ifndef FIPS_MODULE - return &rand_meth; -#else - return NULL; -#endif -} diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c index cd87531943..dc1833169c 100644 --- a/crypto/rand/rand_egd.c +++ b/crypto/rand/rand_egd.c @@ -54,6 +54,60 @@ struct sockaddr_un { # include # include +# if defined(OPENSSL_SYS_TANDEM) +/* + * HPNS: + * + * Our current MQ 5.3 EGD requies compatability-mode sockets + * This code forces the mode to compatibility if required + * and then restores the mode. + * + * Needs review: + * + * The better long-term solution is to either run two EGD's each in one of + * the two modes or revise the EGD code to listen on two different sockets + * (each in one of the two modes). + */ +_variable +int hpns_socket(int family, + int type, + int protocol, + char* transport) +{ + int socket_rc; + char current_transport[20]; + +# define AF_UNIX_PORTABILITY "$ZAFN2" +# define AF_UNIX_COMPATIBILITY "$ZPLS" + + if (!_arg_present(transport) || transport != NULL || transport[0] == '\0') + return socket(family, type, protocol); + + socket_transport_name_get(AF_UNIX, current_transport, 20); + + if (strcmp(current_transport,transport) == 0) + return socket(family, type, protocol); + + /* set the requested socket transport */ + if (socket_transport_name_set(AF_UNIX, transport)) + return -1; + + socket_rc = socket(family,type,protocol); + + /* set mode back to what it was */ + if (socket_transport_name_set(AF_UNIX, current_transport)) + return -1; + + return socket_rc; +} + +/*#define socket(a,b,c,...) hpns_socket(a,b,c,__VA_ARGS__) */ + +static int hpns_connect_attempt = 0; + +# endif /* defined(OPENSSL_SYS_HPNS) */ + + int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) { FILE *fp = NULL; @@ -71,7 +125,11 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) return -1; strcpy(addr.sun_path, path); i = offsetof(struct sockaddr_un, sun_path) + strlen(path); +#if defined(OPENSSL_SYS_TANDEM) + fd = hpns_socket(AF_UNIX, SOCK_STREAM, 0, AF_UNIX_COMPATIBILITY); +#else fd = socket(AF_UNIX, SOCK_STREAM, 0); +#endif if (fd == -1 || (fp = fdopen(fd, "r+")) == NULL) return -1; setbuf(fp, NULL); @@ -100,6 +158,18 @@ int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) /* No error, try again */ break; default: +# if defined(OPENSSL_SYS_TANDEM) + if (hpns_connect_attempt == 0) { + /* try the other kind of AF_UNIX socket */ + close(fd); + fd = hpns_socket(AF_UNIX, SOCK_STREAM, 0, AF_UNIX_PORTABILITY); + if (fd == -1) + return -1; + ++hpns_connect_attempt; + break; /* try the connect again */ + } +# endif + ret = -1; goto err; } diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index 39f547c7f1..b70cc4cb9f 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -79,6 +79,10 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { "too little nonce requested"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_TOO_MUCH_NONCE_REQUESTED), "too much nonce requested"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_CREATE_DRBG), + "unable to create drbg"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_FETCH_DRBG), + "unable to fetch drbg"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER), "unable to get parent reseed prop counter"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH), diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index d43b4fb8db..d388d8908a 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -12,10 +12,16 @@ #include #include +#include +#include +#include +#include #include "internal/cryptlib.h" #include #include "crypto/rand.h" +#include "crypto/cryptlib.h" #include +#include #include "internal/thread_once.h" #include "rand_local.h" #include "e_os.h" @@ -105,16 +111,17 @@ int RAND_poll(void) { const RAND_METHOD *meth = RAND_get_rand_method(); int ret = meth == RAND_OpenSSL(); - RAND_POOL *pool; if (meth == NULL) return 0; +#ifndef OPENSSL_NO_DEPRECATED_3_0 if (!ret) { /* fill random pool and seed the current legacy RNG */ - pool = rand_pool_new(RAND_DRBG_STRENGTH, 1, - (RAND_DRBG_STRENGTH + 7) / 8, - RAND_POOL_MAX_LENGTH); + RAND_POOL *pool = rand_pool_new(RAND_DRBG_STRENGTH, 1, + (RAND_DRBG_STRENGTH + 7) / 8, + RAND_POOL_MAX_LENGTH); + if (pool == NULL) return 0; @@ -131,6 +138,7 @@ int RAND_poll(void) err: rand_pool_free(pool); } +#endif return ret; } @@ -235,15 +243,15 @@ int RAND_pseudo_bytes(unsigned char *buf, int num) int RAND_status(void) { - RAND_DRBG *drbg; + EVP_RAND_CTX *rand; const RAND_METHOD *meth = RAND_get_rand_method(); if (meth != NULL && meth != RAND_OpenSSL()) return meth->status != NULL ? meth->status() : 0; - if ((drbg = RAND_DRBG_get0_master()) == NULL || drbg->rand == NULL) - return EVP_RAND_STATE_UNINITIALISED; - return EVP_RAND_state(drbg->rand) == EVP_RAND_STATE_READY; + if ((rand = RAND_get0_primary(NULL)) == NULL) + return 0; + return EVP_RAND_state(rand) == EVP_RAND_STATE_READY; } #else /* !FIPS_MODULE */ @@ -258,9 +266,9 @@ const RAND_METHOD *RAND_get_rand_method(void) * the default method, then just call RAND_bytes(). Otherwise make * sure we're instantiated and use the private DRBG. */ -int RAND_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) +int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, int num) { - RAND_DRBG *drbg; + EVP_RAND_CTX *rand; const RAND_METHOD *meth = RAND_get_rand_method(); if (meth != NULL && meth != RAND_OpenSSL()) { @@ -270,9 +278,9 @@ int RAND_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) return -1; } - drbg = OPENSSL_CTX_get0_private_drbg(ctx); - if (drbg != NULL) - return RAND_DRBG_bytes(drbg, buf, num); + rand = RAND_get0_private(ctx); + if (rand != NULL) + return EVP_RAND_generate(rand, buf, num, 0, 0, NULL, 0); return 0; } @@ -282,9 +290,9 @@ int RAND_priv_bytes(unsigned char *buf, int num) return RAND_priv_bytes_ex(NULL, buf, num); } -int RAND_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) +int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, int num) { - RAND_DRBG *drbg; + EVP_RAND_CTX *rand; const RAND_METHOD *meth = RAND_get_rand_method(); if (meth != NULL && meth != RAND_OpenSSL()) { @@ -294,9 +302,9 @@ int RAND_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num) return -1; } - drbg = OPENSSL_CTX_get0_public_drbg(ctx); - if (drbg != NULL) - return RAND_DRBG_bytes(drbg, buf, num); + rand = RAND_get0_public(ctx); + if (rand != NULL) + return EVP_RAND_generate(rand, buf, num, 0, 0, NULL, 0); return 0; } @@ -305,3 +313,355 @@ int RAND_bytes(unsigned char *buf, int num) { return RAND_bytes_ex(NULL, buf, num); } + +typedef struct rand_global_st { + /* + * The three shared DRBG instances + * + * There are three shared DRBG instances: , , and + * . The and DRBGs are secondary ones. + * These are used for non-secret (e.g. nonces) and secret + * (e.g. private keys) data respectively. + */ + CRYPTO_RWLOCK *lock; + + /* + * The DRBG + * + * Not used directly by the application, only for reseeding the two other + * DRBGs. It reseeds itself by pulling either randomness from os entropy + * sources or by consuming randomness which was added by RAND_add(). + * + * The DRBG is a global instance which is accessed concurrently by + * all threads. The necessary locking is managed automatically by its child + * DRBG instances during reseeding. + */ + EVP_RAND_CTX *primary; + + /* + * The DRBG + * + * Used by default for generating random bytes using RAND_bytes(). + * + * The secondary DRBG is thread-local, i.e., there is one instance + * per thread. + */ + CRYPTO_THREAD_LOCAL public; + + /* + * The DRBG + * + * Used by default for generating private keys using RAND_priv_bytes() + * + * The secondary DRBG is thread-local, i.e., there is one + * instance per thread. + */ + CRYPTO_THREAD_LOCAL private; + + /* Which RNG is being used by default and it's configuration settings */ + char *rng_name; + char *rng_cipher; + char *rng_digest; + char *rng_propq; +} RAND_GLOBAL; + +/* + * Initialize the OSSL_LIB_CTX global DRBGs on first use. + * Returns the allocated global data on success or NULL on failure. + */ +static void *rand_ossl_ctx_new(OSSL_LIB_CTX *libctx) +{ + RAND_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl)); + + if (dgbl == NULL) + return NULL; + +#ifndef FIPS_MODULE + /* + * We need to ensure that base libcrypto thread handling has been + * initialised. + */ + OPENSSL_init_crypto(0, NULL); +#endif + + dgbl->lock = CRYPTO_THREAD_lock_new(); + if (dgbl->lock == NULL) + goto err1; + + if (!CRYPTO_THREAD_init_local(&dgbl->private, NULL)) + goto err1; + + if (!CRYPTO_THREAD_init_local(&dgbl->public, NULL)) + goto err2; + + return dgbl; + + err2: + CRYPTO_THREAD_cleanup_local(&dgbl->private); + err1: + CRYPTO_THREAD_lock_free(dgbl->lock); + OPENSSL_free(dgbl); + return NULL; +} + +static void rand_ossl_ctx_free(void *vdgbl) +{ + RAND_GLOBAL *dgbl = vdgbl; + + if (dgbl == NULL) + return; + + CRYPTO_THREAD_lock_free(dgbl->lock); + EVP_RAND_CTX_free(dgbl->primary); + CRYPTO_THREAD_cleanup_local(&dgbl->private); + CRYPTO_THREAD_cleanup_local(&dgbl->public); + OPENSSL_free(dgbl->rng_name); + OPENSSL_free(dgbl->rng_cipher); + OPENSSL_free(dgbl->rng_digest); + OPENSSL_free(dgbl->rng_propq); + + OPENSSL_free(dgbl); +} + +static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = { + rand_ossl_ctx_new, + rand_ossl_ctx_free, +}; + +static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_INDEX, + &rand_drbg_ossl_ctx_method); +} + +static void rand_delete_thread_state(void *arg) +{ + OSSL_LIB_CTX *ctx = arg; + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *rand; + + if (dgbl == NULL) + return; + + rand = CRYPTO_THREAD_get_local(&dgbl->public); + CRYPTO_THREAD_set_local(&dgbl->public, NULL); + EVP_RAND_CTX_free(rand); + + rand = CRYPTO_THREAD_get_local(&dgbl->private); + CRYPTO_THREAD_set_local(&dgbl->private, NULL); + EVP_RAND_CTX_free(rand); +} + +static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, + unsigned int reseed_interval, + time_t reseed_time_interval) +{ + EVP_RAND *rand; + RAND_GLOBAL *dgbl = rand_get_global(libctx); + EVP_RAND_CTX *ctx; + OSSL_PARAM params[7], *p = params; + char *name, *cipher; + + name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG"; + rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq); + if (rand == NULL) { + RANDerr(0, RAND_R_UNABLE_TO_FETCH_DRBG); + return NULL; + } + ctx = EVP_RAND_CTX_new(rand, parent); + EVP_RAND_free(rand); + if (ctx == NULL) { + RANDerr(0, RAND_R_UNABLE_TO_CREATE_DRBG); + return NULL; + } + + /* + * Rather than trying to decode the DRBG settings, just pass them through + * and rely on the other end to ignore those it doesn't care about. + */ + cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR"; + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, + cipher, 0); + if (dgbl->rng_digest != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, + dgbl->rng_digest, 0); + if (dgbl->rng_propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, + dgbl->rng_propq, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0); + *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, + &reseed_interval); + *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, + &reseed_time_interval); + *p = OSSL_PARAM_construct_end(); + if (!EVP_RAND_set_ctx_params(ctx, params)) { + RANDerr(0, RAND_R_ERROR_INITIALISING_DRBG); + EVP_RAND_CTX_free(ctx); + return NULL; + } + if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0)) { + RANDerr(0, RAND_R_ERROR_INSTANTIATING_DRBG); + EVP_RAND_CTX_free(ctx); + return NULL; + } + return ctx; +} + +/* + * Get the primary random generator. + * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. + * + */ +EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + + if (dgbl == NULL) + return NULL; + + if (dgbl->primary == NULL) { + if (!CRYPTO_THREAD_write_lock(dgbl->lock)) + return NULL; + if (dgbl->primary == NULL) + dgbl->primary = rand_new_drbg(ctx, NULL, PRIMARY_RESEED_INTERVAL, + PRIMARY_RESEED_TIME_INTERVAL); + CRYPTO_THREAD_unlock(dgbl->lock); + } + return dgbl->primary; +} + +/* + * Get the public random generator. + * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. + */ +EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *rand, *primary; + + if (dgbl == NULL) + return NULL; + + rand = CRYPTO_THREAD_get_local(&dgbl->public); + if (rand == NULL) { + primary = RAND_get0_primary(ctx); + if (primary == NULL) + return NULL; + + ctx = ossl_lib_ctx_get_concrete(ctx); + /* + * If the private is also NULL then this is the first time we've + * used this thread. + */ + if (CRYPTO_THREAD_get_local(&dgbl->private) == NULL + && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) + return NULL; + rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, + SECONDARY_RESEED_TIME_INTERVAL); + CRYPTO_THREAD_set_local(&dgbl->public, rand); + } + return rand; +} + +/* + * Get the private random generator. + * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. + */ +EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + EVP_RAND_CTX *rand, *primary; + + if (dgbl == NULL) + return NULL; + + rand = CRYPTO_THREAD_get_local(&dgbl->private); + if (rand == NULL) { + primary = RAND_get0_primary(ctx); + if (primary == NULL) + return NULL; + + ctx = ossl_lib_ctx_get_concrete(ctx); + /* + * If the public is also NULL then this is the first time we've + * used this thread. + */ + if (CRYPTO_THREAD_get_local(&dgbl->public) == NULL + && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) + return NULL; + rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, + SECONDARY_RESEED_TIME_INTERVAL); + CRYPTO_THREAD_set_local(&dgbl->private, rand); + } + return rand; +} + +#ifndef FIPS_MODULE +static int random_set_string(char **p, const char *s) +{ + char *d = OPENSSL_strdup(s); + + if (d == NULL) { + CRYPTOerr(0, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_free(*p); + *p = d; + return 1; +} + +/* + * Load the DRBG definitions from a configuration file. + */ +static int random_conf_init(CONF_IMODULE *md, const CONF *cnf) +{ + STACK_OF(CONF_VALUE) *elist; + CONF_VALUE *cval; + RAND_GLOBAL *dgbl = rand_get_global(cnf->libctx); + int i, r = 1; + + OSSL_TRACE1(CONF, "Loading random module: section %s\n", + CONF_imodule_get_value(md)); + + /* Value is a section containing RANDOM configuration */ + elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); + if (elist == NULL) { + CRYPTOerr(0, CRYPTO_R_RANDOM_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { + cval = sk_CONF_VALUE_value(elist, i); + if (strcasecmp(cval->name, "random") == 0) { + if (!random_set_string(&dgbl->rng_name, cval->value)) + return 0; + } else if (strcasecmp(cval->name, "cipher") == 0) { + if (!random_set_string(&dgbl->rng_cipher, cval->value)) + return 0; + } else if (strcasecmp(cval->name, "digest") == 0) { + if (!random_set_string(&dgbl->rng_digest, cval->value)) + return 0; + } else if (strcasecmp(cval->name, "properties") == 0) { + if (!random_set_string(&dgbl->rng_propq, cval->value)) + return 0; + } else { + CRYPTOerr(0, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION); + ERR_add_error_data(4, "name=", cval->name, ", value=", cval->value); + r = 0; + } + } + return r; +} + + +static void random_conf_deinit(CONF_IMODULE *md) +{ + OSSL_TRACE(CONF, "Cleaned up random\n"); +} + +void ossl_random_add_conf_module(void) +{ + OSSL_TRACE(CONF, "Adding config module 'random'\n"); + CONF_module_add("random", random_conf_init, random_conf_deinit); +} +#endif diff --git a/crypto/rand/rand_local.h b/crypto/rand/rand_local.h index 73751d25e4..d1c9bd7fec 100644 --- a/crypto/rand/rand_local.h +++ b/crypto/rand/rand_local.h @@ -15,48 +15,16 @@ # include # include # include -# include +# include # include "internal/tsan_assist.h" # include "crypto/rand.h" -# include "internal/numbers.h" - -/* Maximum reseed intervals */ -# define MAX_RESEED_INTERVAL (1 << 24) -# define MAX_RESEED_TIME_INTERVAL (1 << 20) /* approx. 12 days */ - /* Default reseed intervals */ # define PRIMARY_RESEED_INTERVAL (1 << 8) # define SECONDARY_RESEED_INTERVAL (1 << 16) # define PRIMARY_RESEED_TIME_INTERVAL (60 * 60) /* 1 hour */ # define SECONDARY_RESEED_TIME_INTERVAL (7 * 60) /* 7 minutes */ -/* - * The state of all types of DRBGs. - */ -struct rand_drbg_st { - CRYPTO_RWLOCK *lock; - /* The library context this DRBG is associated with, if any */ - OPENSSL_CTX *libctx; - RAND_DRBG *parent; - int type; /* the nid of the underlying algorithm */ - unsigned short flags; /* various external flags */ - - /* Application data, mainly used in the KATs. */ - CRYPTO_EX_DATA ex_data; - - /* Implementation */ - EVP_RAND_CTX *rand; - - /* Callback functions. See comments in rand_lib.c */ - RAND_DRBG_get_entropy_fn get_entropy; - RAND_DRBG_cleanup_entropy_fn cleanup_entropy; - RAND_DRBG_get_nonce_fn get_nonce; - RAND_DRBG_cleanup_nonce_fn cleanup_nonce; - - void *callback_data; -}; - /* The global RAND method, and the global buffer and DRBG instance. */ extern RAND_METHOD rand_meth; diff --git a/crypto/rand/rand_meth.c b/crypto/rand/rand_meth.c new file mode 100644 index 0000000000..e9237a4cd9 --- /dev/null +++ b/crypto/rand/rand_meth.c @@ -0,0 +1,69 @@ +/* + * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "rand_local.h" + +/* Implements the default OpenSSL RAND_add() method */ +static int drbg_add(const void *buf, int num, double randomness) +{ + EVP_RAND_CTX *drbg = RAND_get0_primary(NULL); + + if (drbg == NULL || num <= 0) + return 0; + + return EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num); +} + +/* Implements the default OpenSSL RAND_seed() method */ +static int drbg_seed(const void *buf, int num) +{ + return drbg_add(buf, num, num); +} + +/* Implements the default OpenSSL RAND_status() method */ +static int drbg_status(void) +{ + EVP_RAND_CTX *drbg = RAND_get0_primary(NULL); + + if (drbg == NULL) + return 0; + + return EVP_RAND_state(drbg) == EVP_RAND_STATE_READY ? 1 : 0; +} + +/* Implements the default OpenSSL RAND_bytes() method */ +static int drbg_bytes(unsigned char *out, int count) +{ + EVP_RAND_CTX *drbg = RAND_get0_public(NULL); + + if (drbg == NULL) + return 0; + + return EVP_RAND_generate(drbg, out, count, 0, 0, NULL, 0); +} + +RAND_METHOD rand_meth = { + drbg_seed, + drbg_bytes, + NULL, + drbg_add, + drbg_bytes, + drbg_status +}; + +RAND_METHOD *RAND_OpenSSL(void) +{ +#ifndef FIPS_MODULE + return &rand_meth; +#else + return NULL; +#endif +} diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index b27d0fb0e9..2bdd76c078 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -16,7 +16,6 @@ #include #include -#include #include #ifdef OPENSSL_SYS_VMS diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index f5911ad233..d767e4a9f0 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include "crypto/asn1.h" @@ -26,13 +25,6 @@ #include "crypto/rsa.h" #include "rsa_local.h" -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si); -static int rsa_cms_verify(CMS_SignerInfo *si); -static int rsa_cms_decrypt(CMS_RecipientInfo *ri); -static int rsa_cms_encrypt(CMS_RecipientInfo *ri); -#endif - static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); static int rsa_sync_to_pss_params_30(RSA *rsa); @@ -113,10 +105,8 @@ static int rsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) return 0; - if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { - RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) return 0; - } if (!rsa_param_decode(rsa, alg)) { RSA_free(rsa); return 0; @@ -144,6 +134,15 @@ static int rsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + /* + * Don't check the public/private key, this is mostly for smart + * cards. + */ + if (((RSA_flags(a->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) + || (RSA_flags(b->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) { + return 1; + } + if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) return 0; @@ -155,10 +154,8 @@ static int old_rsa_priv_decode(EVP_PKEY *pkey, { RSA *rsa; - if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) { - RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) return 0; - } EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); return 1; } @@ -251,14 +248,6 @@ static void int_rsa_free(EVP_PKEY *pkey) RSA_free(pkey->pkey.rsa); } -static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) -{ - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) - return NULL; - return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR), - alg->parameter); -} - static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, int indent) { @@ -310,7 +299,7 @@ static int rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, goto err; if (BIO_puts(bp, " with ") <= 0) goto err; - maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + maskHash = x509_algor_mgf1_decode(pss->maskGenAlgorithm); if (maskHash != NULL) { if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) goto err; @@ -466,7 +455,7 @@ static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) return NULL; if (pss->maskGenAlgorithm != NULL) { - pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + pss->maskHash = x509_algor_mgf1_decode(pss->maskGenAlgorithm); if (pss->maskHash == NULL) { RSA_PSS_PARAMS_free(pss); return NULL; @@ -515,29 +504,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) if (arg1 == 0) PKCS7_RECIP_INFO_get0_alg(arg2, &alg); break; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) - return rsa_cms_sign(arg2); - else if (arg1 == 1) - return rsa_cms_verify(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (pkey_is_pss(pkey)) - return -2; - if (arg1 == 0) - return rsa_cms_encrypt(arg2); - else if (arg1 == 1) - return rsa_cms_decrypt(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - if (pkey_is_pss(pkey)) - return -2; - *(int *)arg2 = CMS_RECIPINFO_TRANS; - return 1; -#endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: if (pkey->pkey.rsa->pss != NULL) { @@ -565,58 +531,6 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) } -/* allocate and set algorithm ID from EVP_MD, default SHA1 */ -static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) -{ - if (md == NULL || EVP_MD_type(md) == NID_sha1) - return 1; - *palg = X509_ALGOR_new(); - if (*palg == NULL) - return 0; - X509_ALGOR_set_md(*palg, md); - return 1; -} - -/* Allocate and set MGF1 algorithm ID from EVP_MD */ -static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) -{ - X509_ALGOR *algtmp = NULL; - ASN1_STRING *stmp = NULL; - - *palg = NULL; - if (mgf1md == NULL || EVP_MD_type(mgf1md) == NID_sha1) - return 1; - /* need to embed algorithm ID inside another */ - if (!rsa_md_to_algor(&algtmp, mgf1md)) - goto err; - if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL) - goto err; - *palg = X509_ALGOR_new(); - if (*palg == NULL) - goto err; - X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); - stmp = NULL; - err: - ASN1_STRING_free(stmp); - X509_ALGOR_free(algtmp); - if (*palg) - return 1; - return 0; -} - -/* convert algorithm ID to EVP_MD, default SHA1 */ -static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) -{ - const EVP_MD *md; - - if (!alg) - return EVP_sha1(); - md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL) - RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST); - return md; -} - /* * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter, * suitable for setting an AlgorithmIdentifier. @@ -626,7 +540,6 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); - RSA *rsa = EVP_PKEY_get0_RSA(pk); int saltlen; if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) @@ -638,7 +551,7 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2 || saltlen == -3) { - saltlen = RSA_size(rsa) - EVP_MD_size(sigmd) - 2; + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if ((EVP_PKEY_bits(pk) & 0x7) == 1) saltlen--; if (saltlen < 0) @@ -662,13 +575,13 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } - if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) + if (!x509_algor_new_from_md(&pss->hashAlgorithm, sigmd)) goto err; if (mgf1md == NULL) mgf1md = sigmd; - if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) + if (!x509_algor_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) goto err; - if (!rsa_md_to_algor(&pss->maskHash, mgf1md)) + if (!x509_algor_new_from_md(&pss->maskHash, mgf1md)) goto err; return pss; err: @@ -676,7 +589,7 @@ RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, return NULL; } -static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) +ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) { RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); ASN1_STRING *os; @@ -695,8 +608,8 @@ static ASN1_STRING *rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) * passed to pkctx instead. */ -static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, - X509_ALGOR *sigalg, EVP_PKEY *pkey) +int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + const X509_ALGOR *sigalg, EVP_PKEY *pkey) { int rv = -1; int saltlen; @@ -705,14 +618,14 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + RSAerr(0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } /* Decode PSS parameters */ pss = rsa_pss_decode(sigalg); if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); + RSAerr(0, RSA_R_INVALID_PSS_PARAMETERS); goto err; } @@ -725,7 +638,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) goto err; if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); + RSAerr(0, RSA_R_DIGEST_DOES_NOT_MATCH); goto err; } } @@ -772,24 +685,24 @@ static int rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, RSA_PSS_PARAMS_30 pss_params; /* Get the defaults from the ONE place */ - (void)rsa_pss_params_30_set_defaults(&pss_params); + (void)ossl_rsa_pss_params_30_set_defaults(&pss_params); if (pss == NULL) return 0; - *pmd = rsa_algor_to_md(pss->hashAlgorithm); + *pmd = x509_algor_get_md(pss->hashAlgorithm); if (*pmd == NULL) return 0; - *pmgf1md = rsa_algor_to_md(pss->maskHash); + *pmgf1md = x509_algor_get_md(pss->maskHash); if (*pmgf1md == NULL) return 0; if (pss->saltLength) *psaltlen = ASN1_INTEGER_get(pss->saltLength); else - *psaltlen = rsa_pss_params_30_saltlen(&pss_params); + *psaltlen = ossl_rsa_pss_params_30_saltlen(&pss_params); if (pss->trailerField) *ptrailerField = ASN1_INTEGER_get(pss->trailerField); else - *ptrailerField = rsa_pss_params_30_trailerfield(&pss_params);; + *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);; return 1; } @@ -833,94 +746,41 @@ static int rsa_sync_to_pss_params_30(RSA *rsa) return 0; md_nid = EVP_MD_type(md); mgf1md_nid = EVP_MD_type(mgf1md); - if (!rsa_pss_params_30_set_defaults(&pss_params) - || !rsa_pss_params_30_set_hashalg(&pss_params, md_nid) - || !rsa_pss_params_30_set_maskgenhashalg(&pss_params, mgf1md_nid) - || !rsa_pss_params_30_set_saltlen(&pss_params, saltlen) - || !rsa_pss_params_30_set_trailerfield(&pss_params, trailerField)) + if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) + || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) + || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, + mgf1md_nid) + || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) + || !ossl_rsa_pss_params_30_set_trailerfield(&pss_params, + trailerField)) return 0; rsa->pss_params = pss_params; } return 1; } -#ifndef OPENSSL_NO_CMS -static int rsa_cms_verify(CMS_SignerInfo *si) -{ - int nid, nid2; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - nid = OBJ_obj2nid(alg->algorithm); - if (nid == EVP_PKEY_RSA_PSS) - return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); - /* Only PSS allowed for PSS keys */ - if (pkey_ctx_is_pss(pkctx)) { - RSAerr(RSA_F_RSA_CMS_VERIFY, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return 0; - } - if (nid == NID_rsaEncryption) - return 1; - /* Workaround for some implementation that use a signature OID */ - if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { - if (nid2 == NID_rsaEncryption) - return 1; - } - return 0; -} -#endif - /* * Customised RSA item verification routine. This is called when a signature * is encountered requiring special handling. We currently only handle PSS. */ -static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, - EVP_PKEY *pkey) +static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, + const void *asn, const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *sig, EVP_PKEY *pkey) { /* Sanity check: make sure it is PSS */ if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); return -1; } - if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { + if (ossl_rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { /* Carry on */ return 2; } return -1; } -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si) -{ - int pad_mode = RSA_PKCS1_PADDING; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - ASN1_STRING *os = NULL; - - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* We don't support it */ - if (pad_mode != RSA_PKCS1_PSS_PADDING) - return 0; - os = rsa_ctx_to_pss_string(pkctx); - if (!os) - return 0; - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); - return 1; -} -#endif - -static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, +static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) { @@ -933,7 +793,7 @@ static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { ASN1_STRING *os1 = NULL; - os1 = rsa_ctx_to_pss_string(pkctx); + os1 = ossl_rsa_ctx_to_pss_string(pkctx); if (!os1) return 0; /* Duplicate parameters if we have to */ @@ -1006,165 +866,6 @@ static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, return rv; } -#ifndef OPENSSL_NO_CMS -static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) -{ - RSA_OAEP_PARAMS *oaep; - - oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), - alg->parameter); - - if (oaep == NULL) - return NULL; - - if (oaep->maskGenFunc != NULL) { - oaep->maskHash = rsa_mgf1_decode(oaep->maskGenFunc); - if (oaep->maskHash == NULL) { - RSA_OAEP_PARAMS_free(oaep); - return NULL; - } - } - return oaep; -} - -static int rsa_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pkctx; - X509_ALGOR *cmsalg; - int nid; - int rv = -1; - unsigned char *label = NULL; - int labellen = 0; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_OAEP_PARAMS *oaep; - - pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (pkctx == NULL) - return 0; - if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) - return -1; - nid = OBJ_obj2nid(cmsalg->algorithm); - if (nid == NID_rsaEncryption) - return 1; - if (nid != NID_rsaesOaep) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); - return -1; - } - /* Decode OAEP parameters */ - oaep = rsa_oaep_decode(cmsalg); - - if (oaep == NULL) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); - goto err; - } - - mgf1md = rsa_algor_to_md(oaep->maskHash); - if (mgf1md == NULL) - goto err; - md = rsa_algor_to_md(oaep->hashFunc); - if (md == NULL) - goto err; - - if (oaep->pSourceFunc != NULL) { - X509_ALGOR *plab = oaep->pSourceFunc; - - if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); - goto err; - } - if (plab->parameter->type != V_ASN1_OCTET_STRING) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); - goto err; - } - - label = plab->parameter->value.octet_string->data; - /* Stop label being freed when OAEP parameters are freed */ - plab->parameter->value.octet_string->data = NULL; - labellen = plab->parameter->value.octet_string->length; - } - - if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) - goto err; - if (label != NULL - && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) - goto err; - /* Carry on */ - rv = 1; - - err: - RSA_OAEP_PARAMS_free(oaep); - return rv; -} - -static int rsa_cms_encrypt(CMS_RecipientInfo *ri) -{ - const EVP_MD *md, *mgf1md; - RSA_OAEP_PARAMS *oaep = NULL; - ASN1_STRING *os = NULL; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; - unsigned char *label; - - if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) - return 0; - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* Not supported */ - if (pad_mode != RSA_PKCS1_OAEP_PADDING) - return 0; - if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) - goto err; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) - goto err; - labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); - if (labellen < 0) - goto err; - oaep = RSA_OAEP_PARAMS_new(); - if (oaep == NULL) - goto err; - if (!rsa_md_to_algor(&oaep->hashFunc, md)) - goto err; - if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) - goto err; - if (labellen > 0) { - ASN1_OCTET_STRING *los; - oaep->pSourceFunc = X509_ALGOR_new(); - if (oaep->pSourceFunc == NULL) - goto err; - los = ASN1_OCTET_STRING_new(); - if (los == NULL) - goto err; - if (!ASN1_OCTET_STRING_set(los, label, labellen)) { - ASN1_OCTET_STRING_free(los); - goto err; - } - X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), - V_ASN1_OCTET_STRING, los); - } - /* create string with pss parameter encoding. */ - if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) - goto err; - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); - os = NULL; - rv = 1; - err: - RSA_OAEP_PARAMS_free(oaep); - ASN1_STRING_free(os); - return rv; -} -#endif - static int rsa_pkey_check(const EVP_PKEY *pkey) { return RSA_check_key_ex(pkey->pkey.rsa, NULL); @@ -1188,7 +889,7 @@ static size_t rsa_pkey_dirty_cnt(const EVP_PKEY *pkey) */ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, void *to_keydata, EVP_KEYMGMT *to_keymgmt, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { RSA *rsa = from->pkey.rsa; OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new(); @@ -1209,7 +910,7 @@ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, if (RSA_get0_n(rsa) == NULL || RSA_get0_e(rsa) == NULL) goto err; - if (!rsa_todata(rsa, tmpl, NULL)) + if (!ossl_rsa_todata(rsa, tmpl, NULL)) goto err; selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; @@ -1218,18 +919,20 @@ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, if (rsa->pss != NULL) { const EVP_MD *md = NULL, *mgf1md = NULL; - int md_nid, mgf1md_nid, saltlen; + int md_nid, mgf1md_nid, saltlen, trailerfield; RSA_PSS_PARAMS_30 pss_params; - if (!rsa_pss_get_param(rsa->pss, &md, &mgf1md, &saltlen)) + if (!rsa_pss_get_param_unverified(rsa->pss, &md, &mgf1md, + &saltlen, &trailerfield)) goto err; md_nid = EVP_MD_type(md); mgf1md_nid = EVP_MD_type(mgf1md); - if (!rsa_pss_params_30_set_defaults(&pss_params) - || !rsa_pss_params_30_set_hashalg(&pss_params, md_nid) - || !rsa_pss_params_30_set_maskgenhashalg(&pss_params, mgf1md_nid) - || !rsa_pss_params_30_set_saltlen(&pss_params, saltlen) - || !rsa_pss_params_30_todata(&pss_params, propq, tmpl, NULL)) + if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) + || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) + || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, + mgf1md_nid) + || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) + || !ossl_rsa_pss_params_30_todata(&pss_params, tmpl, NULL)) goto err; selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; } @@ -1251,7 +954,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, { EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); - RSA *rsa = rsa_new_with_ctx(pctx->libctx); + RSA *rsa = ossl_rsa_new_with_ctx(pctx->libctx); RSA_PSS_PARAMS_30 rsa_pss_params = { 0, }; int ok = 0; @@ -1263,7 +966,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); RSA_set_flags(rsa, rsa_type); - if (!rsa_pss_params_30_fromdata(&rsa_pss_params, params, pctx->libctx)) + if (!ossl_rsa_pss_params_30_fromdata(&rsa_pss_params, params, pctx->libctx)) goto err; switch (rsa_type) { @@ -1272,7 +975,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, * Were PSS parameters filled in? * In that case, something's wrong */ - if (!rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) + if (!ossl_rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) goto err; break; case RSA_FLAG_TYPE_RSASSAPSS: @@ -1280,11 +983,11 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, * Were PSS parameters filled in? In that case, create the old * RSA_PSS_PARAMS structure. Otherwise, this is an unrestricted key. */ - if (!rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) { + if (!ossl_rsa_pss_params_30_is_unrestricted(&rsa_pss_params)) { /* Create the older RSA_PSS_PARAMS from RSA_PSS_PARAMS_30 data */ - int mdnid = rsa_pss_params_30_hashalg(&rsa_pss_params); - int mgf1mdnid = rsa_pss_params_30_maskgenhashalg(&rsa_pss_params); - int saltlen = rsa_pss_params_30_saltlen(&rsa_pss_params); + int mdnid = ossl_rsa_pss_params_30_hashalg(&rsa_pss_params); + int mgf1mdnid = ossl_rsa_pss_params_30_maskgenhashalg(&rsa_pss_params); + int saltlen = ossl_rsa_pss_params_30_saltlen(&rsa_pss_params); const EVP_MD *md = EVP_get_digestbynid(mdnid); const EVP_MD *mgf1md = EVP_get_digestbynid(mgf1mdnid); @@ -1297,7 +1000,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, goto err; } - if (!rsa_fromdata(rsa, params)) + if (!ossl_rsa_fromdata(rsa, params)) goto err; switch (rsa_type) { @@ -1316,7 +1019,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, } static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq) { return rsa_int_export_to(from, RSA_FLAG_TYPE_RSA, to_keydata, @@ -1324,7 +1027,7 @@ static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, } static int rsa_pss_pkey_export_to(const EVP_PKEY *from, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq) { return rsa_int_export_to(from, RSA_FLAG_TYPE_RSASSAPSS, to_keydata, diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c index 985a21127a..f64fb34d52 100644 --- a/crypto/rsa/rsa_backend.c +++ b/crypto/rsa/rsa_backend.c @@ -48,7 +48,7 @@ static int collect_numbers(STACK_OF(BIGNUM) *numbers, return 1; } -int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]) +int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]) { const OSSL_PARAM *param_n, *param_e, *param_d; BIGNUM *n = NULL, *e = NULL, *d = NULL; @@ -75,16 +75,16 @@ int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]) if (is_private) { if (!collect_numbers(factors = sk_BIGNUM_new_null(), params, - rsa_mp_factor_names) + ossl_rsa_mp_factor_names) || !collect_numbers(exps = sk_BIGNUM_new_null(), params, - rsa_mp_exp_names) + ossl_rsa_mp_exp_names) || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params, - rsa_mp_coeff_names)) + ossl_rsa_mp_coeff_names)) goto err; /* It's ok if this private key just has n, e and d */ if (sk_BIGNUM_num(factors) != 0 - && !rsa_set0_all_params(rsa, factors, exps, coeffs)) + && !ossl_rsa_set0_all_params(rsa, factors, exps, coeffs)) goto err; } @@ -106,7 +106,7 @@ int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]) DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) -int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) +int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) { int ret = 0; const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; @@ -118,7 +118,11 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) goto err; RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); - rsa_get0_all_params(rsa, factors, exps, coeffs); + ossl_rsa_get0_all_params(rsa, factors, exps, coeffs); + + if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n) + || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e)) + goto err; /* Check private key data integrity */ if (rsa_d != NULL) { @@ -134,18 +138,20 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) if (numprimes != 0 && (numprimes < 2 || numexps < 2 || numcoeffs < 1)) goto err; - } - if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n) - || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e) - || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, rsa_d) - || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_factor_names, - factors) - || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_exp_names, - exps) - || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_coeff_names, - coeffs)) + if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, + rsa_d) + || !ossl_param_build_set_multi_key_bn(bld, params, + ossl_rsa_mp_factor_names, + factors) + || !ossl_param_build_set_multi_key_bn(bld, params, + ossl_rsa_mp_exp_names, exps) + || !ossl_param_build_set_multi_key_bn(bld, params, + ossl_rsa_mp_coeff_names, + coeffs)) goto err; + } + #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) /* The acvp test results are not meant for export so check for bld == NULL */ if (bld == NULL) @@ -159,26 +165,27 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) return ret; } -int rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, const char *propq, - OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) +int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, + OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) { - if (!rsa_pss_params_30_is_unrestricted(pss)) { - int hashalg_nid = rsa_pss_params_30_hashalg(pss); - int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss); - int maskgenhashalg_nid = rsa_pss_params_30_maskgenhashalg(pss); - int saltlen = rsa_pss_params_30_saltlen(pss); - int default_hashalg_nid = rsa_pss_params_30_hashalg(NULL); - int default_maskgenalg_nid = rsa_pss_params_30_maskgenalg(NULL); - int default_maskgenhashalg_nid = rsa_pss_params_30_maskgenhashalg(NULL); + if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) { + int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss); + int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss); + int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); + int saltlen = ossl_rsa_pss_params_30_saltlen(pss); + int default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL); + int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); + int default_maskgenhashalg_nid = + ossl_rsa_pss_params_30_maskgenhashalg(NULL); const char *mdname = (hashalg_nid == default_hashalg_nid - ? NULL : rsa_oaeppss_nid2name(hashalg_nid)); + ? NULL : ossl_rsa_oaeppss_nid2name(hashalg_nid)); const char *mgfname = (maskgenalg_nid == default_maskgenalg_nid - ? NULL : rsa_oaeppss_nid2name(maskgenalg_nid)); + ? NULL : ossl_rsa_oaeppss_nid2name(maskgenalg_nid)); const char *mgf1mdname = (maskgenhashalg_nid == default_maskgenhashalg_nid - ? NULL : rsa_oaeppss_nid2name(maskgenhashalg_nid)); + ? NULL : ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid)); const char *key_md = OSSL_PKEY_PARAM_RSA_DIGEST; const char *key_mgf = OSSL_PKEY_PARAM_RSA_MASKGENFUNC; const char *key_mgf1_md = OSSL_PKEY_PARAM_RSA_MGF1_DIGEST; @@ -203,17 +210,21 @@ int rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, const char *propq, return 1; } -int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, - const OSSL_PARAM params[], OPENSSL_CTX *libctx) +int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, + const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx) { const OSSL_PARAM *param_md, *param_mgf, *param_mgf1md, *param_saltlen; + const OSSL_PARAM *param_propq; + const char *propq = NULL; EVP_MD *md = NULL, *mgf1md = NULL; int saltlen; int ret = 0; if (pss_params == NULL) return 0; - + param_propq = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS); param_md = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST); param_mgf = @@ -223,6 +234,10 @@ int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, param_saltlen = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN); + if (param_propq != NULL) { + if (param_propq->data_type == OSSL_PARAM_UTF8_STRING) + propq = param_propq->data; + } /* * If we get any of the parameters, we know we have at least some * restrictions, so we start by setting default values, and let each @@ -230,11 +245,11 @@ int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, */ if (param_md != NULL || param_mgf != NULL || param_mgf1md != NULL || param_saltlen != NULL) - if (!rsa_pss_params_30_set_defaults(pss_params)) + if (!ossl_rsa_pss_params_30_set_defaults(pss_params)) return 0; if (param_mgf != NULL) { - int default_maskgenalg_nid = rsa_pss_params_30_maskgenalg(NULL); + int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); const char *mgfname = NULL; if (param_mgf->data_type == OSSL_PARAM_UTF8_STRING) @@ -244,7 +259,7 @@ int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, /* TODO Revisit this if / when a new MGF algorithm appears */ if (strcasecmp(param_mgf->data, - rsa_mgf_nid2name(default_maskgenalg_nid)) != 0) + ossl_rsa_mgf_nid2name(default_maskgenalg_nid)) != 0) return 0; } @@ -261,9 +276,9 @@ int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mdname)) goto err; - if ((md = EVP_MD_fetch(libctx, mdname, NULL)) == NULL - || !rsa_pss_params_30_set_hashalg(pss_params, - rsa_oaeppss_md2nid(md))) + if ((md = EVP_MD_fetch(libctx, mdname, propq)) == NULL + || !ossl_rsa_pss_params_30_set_hashalg(pss_params, + ossl_rsa_oaeppss_md2nid(md))) goto err; } @@ -275,15 +290,15 @@ int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgf1mdname)) goto err; - if ((mgf1md = EVP_MD_fetch(libctx, mgf1mdname, NULL)) == NULL - || !rsa_pss_params_30_set_maskgenhashalg(pss_params, - rsa_oaeppss_md2nid(mgf1md))) + if ((mgf1md = EVP_MD_fetch(libctx, mgf1mdname, propq)) == NULL + || !ossl_rsa_pss_params_30_set_maskgenhashalg( + pss_params, ossl_rsa_oaeppss_md2nid(mgf1md))) goto err; } if (param_saltlen != NULL) { if (!OSSL_PARAM_get_int(param_saltlen, &saltlen) - || !rsa_pss_params_30_set_saltlen(pss_params, saltlen)) + || !ossl_rsa_pss_params_30_set_saltlen(pss_params, saltlen)) goto err; } diff --git a/crypto/rsa/rsa_chk.c b/crypto/rsa/rsa_chk.c index 0bbb6dac03..5a0ef7679b 100644 --- a/crypto/rsa/rsa_chk.c +++ b/crypto/rsa/rsa_chk.c @@ -230,20 +230,20 @@ static int rsa_validate_keypair_multiprime(const RSA *key, BN_GENCB *cb) } #endif /* FIPS_MODULE */ -int rsa_validate_public(const RSA *key) +int ossl_rsa_validate_public(const RSA *key) { - return rsa_sp800_56b_check_public(key); + return ossl_rsa_sp800_56b_check_public(key); } -int rsa_validate_private(const RSA *key) +int ossl_rsa_validate_private(const RSA *key) { - return rsa_sp800_56b_check_private(key); + return ossl_rsa_sp800_56b_check_private(key); } -int rsa_validate_pairwise(const RSA *key) +int ossl_rsa_validate_pairwise(const RSA *key) { #ifdef FIPS_MODULE - return rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key)); + return ossl_rsa_sp800_56b_check_keypair(key, NULL, -1, RSA_bits(key)); #else return rsa_validate_keypair_multiprime(key, NULL); #endif @@ -257,9 +257,9 @@ int RSA_check_key(const RSA *key) int RSA_check_key_ex(const RSA *key, BN_GENCB *cb) { #ifdef FIPS_MODULE - return rsa_validate_public(key) - && rsa_validate_private(key) - && rsa_validate_pairwise(key); + return ossl_rsa_validate_public(key) + && ossl_rsa_validate_private(key) + && ossl_rsa_validate_pairwise(key); #else return rsa_validate_keypair_multiprime(key, cb); #endif /* FIPS_MODULE */ diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index 1cdc8d91e8..9ee5998829 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -24,10 +24,11 @@ #include "internal/cryptlib.h" #include #include +#include "prov/providercommon.h" #include "rsa_local.h" static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg); -static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, +static int rsa_keygen(OSSL_LIB_CTX *libctx, RSA *rsa, int bits, int primes, BIGNUM *e_value, BN_GENCB *cb, int pairwise_test); /* @@ -66,7 +67,7 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, else return 0; } -#endif /* FIPS_MODUKE */ +#endif /* FIPS_MODULE */ return rsa_keygen(rsa->libctx, rsa, bits, primes, e_value, cb, 0); } @@ -91,7 +92,7 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes, } /* A bad value for e can cause infinite loops */ - if (e_value != NULL && !rsa_check_public_exponent(e_value)) { + if (e_value != NULL && !ossl_rsa_check_public_exponent(e_value)) { RSAerr(0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); return 0; } @@ -418,7 +419,7 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes, } #endif /* FIPS_MODULE */ -static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, +static int rsa_keygen(OSSL_LIB_CTX *libctx, RSA *rsa, int bits, int primes, BIGNUM *e_value, BN_GENCB *cb, int pairwise_test) { int ok = 0; @@ -428,7 +429,7 @@ static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, * the older rsa_multiprime_keygen(). */ if (primes == 2 && bits >= 2048) - ok = rsa_sp800_56b_generate_key(rsa, bits, e_value, cb); + ok = ossl_rsa_sp800_56b_generate_key(rsa, bits, e_value, cb); #ifndef FIPS_MODULE else ok = rsa_multiprime_keygen(rsa, bits, primes, e_value, cb); @@ -444,6 +445,7 @@ static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg); ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg); if (!ok) { + ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT); /* Clear intermediate results */ BN_clear_free(rsa->d); BN_clear_free(rsa->p); diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 428cd145fa..e4315f06cd 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -27,7 +27,7 @@ #include "crypto/security_bits.h" #include "rsa_local.h" -static RSA *rsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx); +static RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx); #ifndef FIPS_MODULE RSA *RSA_new(void) @@ -66,12 +66,12 @@ RSA *RSA_new_method(ENGINE *engine) } #endif -RSA *rsa_new_with_ctx(OPENSSL_CTX *libctx) +RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx) { return rsa_new_intern(NULL, libctx); } -static RSA *rsa_new_intern(ENGINE *engine, OPENSSL_CTX *libctx) +static RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx) { RSA *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -189,7 +189,7 @@ int RSA_up_ref(RSA *r) return i > 1 ? 1 : 0; } -OPENSSL_CTX *rsa_get0_libctx(RSA *r) +OSSL_LIB_CTX *ossl_rsa_get0_libctx(RSA *r) { return r->libctx; } @@ -654,7 +654,7 @@ const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) } /* Internal */ -RSA_PSS_PARAMS_30 *rsa_get0_pss_params_30(RSA *r) +RSA_PSS_PARAMS_30 *ossl_rsa_get0_pss_params_30(RSA *r) { return &r->pss_params; } @@ -699,9 +699,9 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2) DEFINE_STACK_OF(BIGNUM) -int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, - const STACK_OF(BIGNUM) *exps, - const STACK_OF(BIGNUM) *coeffs) +int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, + const STACK_OF(BIGNUM) *exps, + const STACK_OF(BIGNUM) *coeffs) { #ifndef FIPS_MODULE STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL; @@ -797,9 +797,9 @@ int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) -int rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, - STACK_OF(BIGNUM_const) *exps, - STACK_OF(BIGNUM_const) *coeffs) +int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, + STACK_OF(BIGNUM_const) *exps, + STACK_OF(BIGNUM_const) *coeffs) { #ifndef FIPS_MODULE RSA_PRIME_INFO *pinfo; @@ -1006,7 +1006,7 @@ int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) return -1; /* May be NULL meaning "unknown" */ - *md = EVP_get_digestbyname(name); + *md = evp_get_digestbyname_ex(ctx->libctx, name); return 1; } @@ -1159,7 +1159,7 @@ int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md) return -1; /* May be NULL meaning "unknown" */ - *md = EVP_get_digestbyname(name); + *md = evp_get_digestbyname_ex(ctx->libctx, name); return 1; } @@ -1345,7 +1345,9 @@ int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) return 1; } -int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) +static int evp_pkey_ctx_set_rsa_keygen_pubexp_intern(EVP_PKEY_CTX *ctx, + BIGNUM *pubexp, + int copy) { OSSL_PARAM_BLD *tmpl; OSSL_PARAM *params; @@ -1362,9 +1364,15 @@ int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) return -1; /* TODO(3.0): Remove this eventually when no more legacy */ - if (ctx->op.keymgmt.genctx == NULL) - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp); + if (ctx->op.keymgmt.genctx == NULL) { + if (copy == 1) + pubexp = BN_dup(pubexp); + ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp); + if ((copy == 1) && (ret <= 0)) + BN_free(pubexp); + return ret; + } if ((tmpl = OSSL_PARAM_BLD_new()) == NULL) return 0; @@ -1377,9 +1385,28 @@ int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) ret = EVP_PKEY_CTX_set_params(ctx, params); OSSL_PARAM_BLD_free_params(params); + + /* + * Satisfy memory semantics for pre-3.0 callers of + * EVP_PKEY_CTX_set_rsa_keygen_pubexp(): their expectation is that input + * pubexp BIGNUM becomes managed by the EVP_PKEY_CTX on success. + */ + if ((copy == 0) && (ret > 0)) + ctx->rsa_pubexp = pubexp; + return ret; } +int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) +{ + return evp_pkey_ctx_set_rsa_keygen_pubexp_intern(ctx, pubexp, 0); +} + +int EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp) +{ + return evp_pkey_ctx_set_rsa_keygen_pubexp_intern(ctx, pubexp, 1); +} + int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes) { OSSL_PARAM params[2], *p = params; diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h index 666e18ec65..60e590998b 100644 --- a/crypto/rsa/rsa_local.h +++ b/crypto/rsa/rsa_local.h @@ -56,7 +56,7 @@ struct rsa_st { */ int dummy_zero; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; int32_t version; const RSA_METHOD *meth; /* functional reference if 'meth' is ENGINE-provided */ @@ -169,39 +169,38 @@ RSA_PRIME_INFO *rsa_multip_info_new(void); int rsa_multip_calc_product(RSA *rsa); int rsa_multip_cap(int bits); -int rsa_sp800_56b_validate_strength(int nbits, int strength); -int rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, - int nbits); -int rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, - BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, - BIGNUM *p1q1); - -int rsa_check_public_exponent(const BIGNUM *e); -int rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx); -int rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx); -int rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx); -int rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx); - -int rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx); -int rsa_sp800_56b_check_public(const RSA *rsa); -int rsa_sp800_56b_check_private(const RSA *rsa); -int rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, - int strength, int nbits); -int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, - BN_GENCB *cb); - -int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, - const BIGNUM *e, BN_CTX *ctx); -int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, - int nbits, const BIGNUM *e, BN_CTX *ctx, - BN_GENCB *cb); - -int rsa_padding_add_SSLv23_with_libctx(OPENSSL_CTX *libctx, unsigned char *to, - int tlen, const unsigned char *from, - int flen); -int rsa_padding_add_PKCS1_type_2_with_libctx(OPENSSL_CTX *libctx, - unsigned char *to, int tlen, - const unsigned char *from, - int flen); +int ossl_rsa_sp800_56b_validate_strength(int nbits, int strength); +int ossl_rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, + int nbits); +int ossl_rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, + BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, + BIGNUM *p1q1); + +int ossl_rsa_check_public_exponent(const BIGNUM *e); +int ossl_rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx); +int ossl_rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx); +int ossl_rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx); +int ossl_rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx); + +int ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx); +int ossl_rsa_sp800_56b_check_public(const RSA *rsa); +int ossl_rsa_sp800_56b_check_private(const RSA *rsa); +int ossl_rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, + int strength, int nbits); +int ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, + BN_GENCB *cb); + +int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, + const BIGNUM *e, BN_CTX *ctx); +int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, + int nbits, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); + +int ossl_rsa_padding_add_SSLv23_ex(OSSL_LIB_CTX *libctx, unsigned char *to, + int tlen, const unsigned char *from, + int flen); +int ossl_rsa_padding_add_PKCS1_type_2_ex(OSSL_LIB_CTX *libctx, unsigned char *to, + int tlen, const unsigned char *from, + int flen); #endif /* OSSL_CRYPTO_RSA_LOCAL_H */ diff --git a/crypto/rsa/rsa_mp_names.c b/crypto/rsa/rsa_mp_names.c index 15b1b9e0da..8291b79e7a 100644 --- a/crypto/rsa/rsa_mp_names.c +++ b/crypto/rsa/rsa_mp_names.c @@ -20,7 +20,7 @@ * A fixed table of names for the RSA prime factors starting with * P,Q and up to 8 additional primes. */ -const char *rsa_mp_factor_names[] = { +const char *ossl_rsa_mp_factor_names[] = { OSSL_PKEY_PARAM_RSA_FACTOR1, OSSL_PKEY_PARAM_RSA_FACTOR2, #ifndef FIPS_MODULE @@ -40,7 +40,7 @@ const char *rsa_mp_factor_names[] = { * A fixed table of names for the RSA exponents starting with * DP,DQ and up to 8 additional exponents. */ -const char *rsa_mp_exp_names[] = { +const char *ossl_rsa_mp_exp_names[] = { OSSL_PKEY_PARAM_RSA_EXPONENT1, OSSL_PKEY_PARAM_RSA_EXPONENT2, #ifndef FIPS_MODULE @@ -60,10 +60,10 @@ const char *rsa_mp_exp_names[] = { * A fixed table of names for the RSA coefficients starting with * QINV and up to 8 additional exponents. */ -const char *rsa_mp_coeff_names[] = { +const char *ossl_rsa_mp_coeff_names[] = { OSSL_PKEY_PARAM_RSA_COEFFICIENT1, - OSSL_PKEY_PARAM_RSA_COEFFICIENT2, #ifndef FIPS_MODULE + OSSL_PKEY_PARAM_RSA_COEFFICIENT2, OSSL_PKEY_PARAM_RSA_COEFFICIENT3, OSSL_PKEY_PARAM_RSA_COEFFICIENT4, OSSL_PKEY_PARAM_RSA_COEFFICIENT5, diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c index ce98802070..809e752bee 100644 --- a/crypto/rsa/rsa_oaep.c +++ b/crypto/rsa/rsa_oaep.c @@ -40,9 +40,8 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, const unsigned char *from, int flen, const unsigned char *param, int plen) { - return rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(NULL, to, tlen, from, - flen, param, plen, NULL, - NULL); + return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(NULL, to, tlen, from, flen, + param, plen, NULL, NULL); } /* @@ -52,13 +51,12 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, * Step numbers are included here but not in the constant time inverse below * to avoid complicating an already difficult enough function. */ -int rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(OPENSSL_CTX *libctx, - unsigned char *to, int tlen, - const unsigned char *from, - int flen, - const unsigned char *param, - int plen, const EVP_MD *md, - const EVP_MD *mgf1md) +int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx, + unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md) { int rv = 0; int i, emlen = tlen - 1; @@ -141,9 +139,8 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, const unsigned char *param, int plen, const EVP_MD *md, const EVP_MD *mgf1md) { - return rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(NULL, to, tlen, from, - flen, param, plen, md, - mgf1md); + return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(NULL, to, tlen, from, flen, + param, plen, md, mgf1md); } int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index b996e4d05e..139fb16268 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -111,18 +111,17 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, switch (padding) { case RSA_PKCS1_PADDING: - i = rsa_padding_add_PKCS1_type_2_with_libctx(rsa->libctx, buf, num, - from, flen); + i = ossl_rsa_padding_add_PKCS1_type_2_ex(rsa->libctx, buf, num, + from, flen); break; case RSA_PKCS1_OAEP_PADDING: - i = rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(rsa->libctx, buf, num, - from, flen, NULL, 0, - NULL, NULL); + i = ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(rsa->libctx, buf, num, + from, flen, NULL, 0, + NULL, NULL); break; #ifndef FIPS_MODULE case RSA_SSLV23_PADDING: - i = rsa_padding_add_SSLv23_with_libctx(rsa->libctx, buf, num, from, - flen); + i = ossl_rsa_padding_add_SSLv23_ex(rsa->libctx, buf, num, from, flen); break; #endif case RSA_NO_PADDING: diff --git a/crypto/rsa/rsa_pk1.c b/crypto/rsa/rsa_pk1.c index b594534563..daa8297300 100644 --- a/crypto/rsa/rsa_pk1.c +++ b/crypto/rsa/rsa_pk1.c @@ -124,10 +124,9 @@ int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, return j; } -int rsa_padding_add_PKCS1_type_2_with_libctx(OPENSSL_CTX *libctx, - unsigned char *to, int tlen, - const unsigned char *from, - int flen) +int ossl_rsa_padding_add_PKCS1_type_2_ex(OSSL_LIB_CTX *libctx, unsigned char *to, + int tlen, const unsigned char *from, + int flen) { int i, j; unsigned char *p; @@ -165,7 +164,7 @@ int rsa_padding_add_PKCS1_type_2_with_libctx(OPENSSL_CTX *libctx, int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, const unsigned char *from, int flen) { - return rsa_padding_add_PKCS1_type_2_with_libctx(NULL, to, tlen, from, flen); + return ossl_rsa_padding_add_PKCS1_type_2_ex(NULL, to, tlen, from, flen); } int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, @@ -279,7 +278,7 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, } /* - * rsa_padding_check_PKCS1_type_2_TLS() checks and removes the PKCS1 type 2 + * ossl_rsa_padding_check_PKCS1_type_2_TLS() checks and removes the PKCS1 type 2 * padding from a decrypted RSA message in a TLS signature. The result is stored * in the buffer pointed to by |to| which should be |tlen| bytes long. |tlen| * must be at least SSL_MAX_MASTER_KEY_LENGTH. The original decrypted message @@ -299,10 +298,11 @@ int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, * decrypted data will be randomly generated (as per * https://tools.ietf.org/html/rfc5246#section-7.4.7.1). */ -int rsa_padding_check_PKCS1_type_2_TLS(OPENSSL_CTX *libctx, unsigned char *to, - size_t tlen, const unsigned char *from, - size_t flen, int client_version, - int alt_version) +int ossl_rsa_padding_check_PKCS1_type_2_TLS(OSSL_LIB_CTX *libctx, + unsigned char *to, size_t tlen, + const unsigned char *from, + size_t flen, int client_version, + int alt_version) { unsigned int i, good, version_good; unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index e899fbd605..edaa769a6f 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -653,9 +653,8 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, BIGNUM *pubexp = NULL; if (!BN_asc2bn(&pubexp, value)) return 0; - ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); - if (ret <= 0) - BN_free(pubexp); + ret = EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, pubexp); + BN_free(pubexp); return ret; } @@ -799,7 +798,7 @@ static const EVP_PKEY_METHOD rsa_pkey_meth = { pkey_rsa_ctrl_str }; -const EVP_PKEY_METHOD *rsa_pkey_method(void) +const EVP_PKEY_METHOD *ossl_rsa_pkey_method(void) { return &rsa_pkey_meth; } @@ -875,7 +874,7 @@ static const EVP_PKEY_METHOD rsa_pss_pkey_meth = { pkey_rsa_ctrl_str }; -const EVP_PKEY_METHOD *rsa_pss_pkey_method(void) +const EVP_PKEY_METHOD *ossl_rsa_pss_pkey_method(void) { return &rsa_pss_pkey_meth; } diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c index a5bcdfe1ff..e3a548d2e3 100644 --- a/crypto/rsa/rsa_pss.c +++ b/crypto/rsa/rsa_pss.c @@ -288,7 +288,7 @@ static const RSA_PSS_PARAMS_30 default_RSASSA_PSS_params = { 1 /* default trailerField (0xBC) */ }; -int rsa_pss_params_30_set_defaults(RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_set_defaults(RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return 0; @@ -296,7 +296,7 @@ int rsa_pss_params_30_set_defaults(RSA_PSS_PARAMS_30 *rsa_pss_params) return 1; } -int rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params) { static RSA_PSS_PARAMS_30 pss_params_cmp = { 0, }; @@ -305,15 +305,15 @@ int rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params) sizeof(*rsa_pss_params)) == 0; } -int rsa_pss_params_30_copy(RSA_PSS_PARAMS_30 *to, - const RSA_PSS_PARAMS_30 *from) +int ossl_rsa_pss_params_30_copy(RSA_PSS_PARAMS_30 *to, + const RSA_PSS_PARAMS_30 *from) { memcpy(to, from, sizeof(*to)); return 1; } -int rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int hashalg_nid) +int ossl_rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int hashalg_nid) { if (rsa_pss_params == NULL) return 0; @@ -321,8 +321,8 @@ int rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, return 1; } -int rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int maskgenalg_nid) +int ossl_rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int maskgenalg_nid) { if (rsa_pss_params == NULL) return 0; @@ -330,8 +330,8 @@ int rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, return 1; } -int rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int maskgenhashalg_nid) +int ossl_rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int maskgenhashalg_nid) { if (rsa_pss_params == NULL) return 0; @@ -339,8 +339,8 @@ int rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, return 1; } -int rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, - int saltlen) +int ossl_rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, + int saltlen) { if (rsa_pss_params == NULL) return 0; @@ -348,8 +348,8 @@ int rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, return 1; } -int rsa_pss_params_30_set_trailerfield(RSA_PSS_PARAMS_30 *rsa_pss_params, - int trailerfield) +int ossl_rsa_pss_params_30_set_trailerfield(RSA_PSS_PARAMS_30 *rsa_pss_params, + int trailerfield) { if (rsa_pss_params == NULL) return 0; @@ -357,35 +357,35 @@ int rsa_pss_params_30_set_trailerfield(RSA_PSS_PARAMS_30 *rsa_pss_params, return 1; } -int rsa_pss_params_30_hashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_hashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.hash_algorithm_nid; return rsa_pss_params->hash_algorithm_nid; } -int rsa_pss_params_30_maskgenalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_maskgenalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.mask_gen.algorithm_nid; return rsa_pss_params->mask_gen.algorithm_nid; } -int rsa_pss_params_30_maskgenhashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_maskgenhashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.hash_algorithm_nid; return rsa_pss_params->mask_gen.hash_algorithm_nid; } -int rsa_pss_params_30_saltlen(const RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_saltlen(const RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.salt_len; return rsa_pss_params->salt_len; } -int rsa_pss_params_30_trailerfield(const RSA_PSS_PARAMS_30 *rsa_pss_params) +int ossl_rsa_pss_params_30_trailerfield(const RSA_PSS_PARAMS_30 *rsa_pss_params) { if (rsa_pss_params == NULL) return default_RSASSA_PSS_params.trailer_field; diff --git a/crypto/rsa/rsa_schemes.c b/crypto/rsa/rsa_schemes.c index 7a54296a59..98ab13956d 100644 --- a/crypto/rsa/rsa_schemes.c +++ b/crypto/rsa/rsa_schemes.c @@ -67,18 +67,18 @@ static int md_is_a(const void *md, const char *name) return EVP_MD_is_a(md, name); } -int rsa_oaeppss_md2nid(const EVP_MD *md) +int ossl_rsa_oaeppss_md2nid(const EVP_MD *md) { return meth2nid(md, md_is_a, oaeppss_name_nid_map, OSSL_NELEM(oaeppss_name_nid_map)); } -const char *rsa_oaeppss_nid2name(int md) +const char *ossl_rsa_oaeppss_nid2name(int md) { return nid2name(md, oaeppss_name_nid_map, OSSL_NELEM(oaeppss_name_nid_map)); } -const char *rsa_mgf_nid2name(int mgf) +const char *ossl_rsa_mgf_nid2name(int mgf) { if (mgf == NID_mgf1) return SN_mgf1; diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index e3425b9e36..bef062d1bd 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -150,7 +150,7 @@ ENCODE_DIGESTINFO_SHA(sha3_512, 0x0a, SHA512_DIGEST_LENGTH) *len = sizeof(digestinfo_##name##_der); \ return digestinfo_##name##_der; -const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len) +const unsigned char *ossl_rsa_digestinfo_encoding(int md_nid, size_t *len) { switch (md_nid) { #ifndef FIPS_MODULE @@ -250,7 +250,7 @@ static int encode_pkcs1(unsigned char **out, size_t *out_len, int type, RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } - di_prefix = rsa_digestinfo_encoding(type, &di_prefix_len); + di_prefix = ossl_rsa_digestinfo_encoding(type, &di_prefix_len); if (di_prefix == NULL) { RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c index 9840d08285..2cdc2fa5e6 100644 --- a/crypto/rsa/rsa_sp800_56b_check.c +++ b/crypto/rsa/rsa_sp800_56b_check.c @@ -21,7 +21,7 @@ * 6.4.1.2.3: rsakpv1-crt Step 7 * 6.4.1.3.3: rsakpv2-crt Step 7 */ -int rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx) +int ossl_rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx) { int ret = 0; BIGNUM *r = NULL, *p1 = NULL, *q1 = NULL; @@ -85,7 +85,7 @@ int rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx) * * (√2)(2^(nbits/2 - 1) = (√2/2)(2^(nbits/2)) */ -int rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx) +int ossl_rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx) { int ret = 0; BIGNUM *low; @@ -133,7 +133,7 @@ int rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx) * * See SP800-56Br1 6.4.1.2.3 Step 5 (a to d) & (e to h). */ -int rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx) +int ossl_rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx) { int ret = 0; BIGNUM *p1 = NULL, *gcd = NULL; @@ -141,7 +141,7 @@ int rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx) /* (Steps 5 a-b) prime test */ if (BN_check_prime(p, ctx, NULL) != 1 /* (Step 5c) (√2)(2^(nbits/2 - 1) <= p <= 2^(nbits/2 - 1) */ - || rsa_check_prime_factor_range(p, nbits, ctx) != 1) + || ossl_rsa_check_prime_factor_range(p, nbits, ctx) != 1) return 0; BN_CTX_start(ctx); @@ -172,7 +172,7 @@ int rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx) * (Step 6a) 2^(nBit/2) < d < LCM(p–1, q–1). * (Step 6b) 1 = (d*e) mod LCM(p–1, q–1) */ -int rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx) +int ossl_rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx) { int ret; BIGNUM *r, *p1, *q1, *lcm, *p1q1, *gcd; @@ -201,7 +201,8 @@ int rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx) } ret = (ret /* LCM(p - 1, q - 1) */ - && (rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) == 1) + && (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, + p1q1) == 1) /* (Step 6a) d < LCM(p - 1, q - 1) */ && (BN_cmp(rsa->d, lcm) < 0) /* (Step 6b) 1 = (e . d) mod LCM(p - 1, q - 1) */ @@ -229,7 +230,7 @@ static int bn_is_three(const BIGNUM *bn) #endif /* FIPS_MODULE */ /* Check exponent is odd, and has a bitlen ranging from [17..256] */ -int rsa_check_public_exponent(const BIGNUM *e) +int ossl_rsa_check_public_exponent(const BIGNUM *e) { int bitlen; @@ -247,7 +248,7 @@ int rsa_check_public_exponent(const BIGNUM *e) * SP800-56Br1 6.4.1.2.1 (Step 5i): |p - q| > 2^(nbits/2 - 100) * i.e- numbits(p-q-1) > (nbits/2 -100) */ -int rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, +int ossl_rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, int nbits) { int bitlen = (nbits >> 1) - 100; @@ -270,9 +271,9 @@ int rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, * Caller should ensure that lcm, gcd, p1, q1, p1q1 are flagged with * BN_FLG_CONSTTIME. */ -int rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, - BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, - BIGNUM *p1q1) +int ossl_rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, + BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, + BIGNUM *p1q1) { return BN_sub(p1, p, BN_value_one()) /* p-1 */ && BN_sub(q1, q, BN_value_one()) /* q-1 */ @@ -286,7 +287,7 @@ int rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, * SP800-89 5.3.3 (Explicit) Partial Public Key Validation for RSA * caveat is that the modulus must be as specified in SP800-56Br1 */ -int rsa_sp800_56b_check_public(const RSA *rsa) +int ossl_rsa_sp800_56b_check_public(const RSA *rsa) { int ret = 0, status; #ifdef FIPS_MODULE @@ -304,19 +305,18 @@ int rsa_sp800_56b_check_public(const RSA *rsa) * NOTE: changed to allow keys >= 2048 */ nbits = BN_num_bits(rsa->n); - if (!rsa_sp800_56b_validate_strength(nbits, -1)) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_PUBLIC, RSA_R_INVALID_KEY_LENGTH); + if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1)) { + RSAerr(0, RSA_R_INVALID_KEY_LENGTH); return 0; } #endif if (!BN_is_odd(rsa->n)) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_PUBLIC, RSA_R_INVALID_MODULUS); + RSAerr(0, RSA_R_INVALID_MODULUS); return 0; } /* (Steps b-c): 2^16 < e < 2^256, n and e must be odd */ - if (!rsa_check_public_exponent(rsa->e)) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_PUBLIC, - RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + if (!ossl_rsa_check_public_exponent(rsa->e)) { + RSAerr(0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); return 0; } @@ -330,13 +330,13 @@ int rsa_sp800_56b_check_public(const RSA *rsa) * The modulus has no factors smaller than 752. */ if (!BN_gcd(gcd, rsa->n, bn_get0_small_factors(), ctx) || !BN_is_one(gcd)) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_PUBLIC, RSA_R_INVALID_MODULUS); + RSAerr(0, RSA_R_INVALID_MODULUS); goto err; } ret = bn_miller_rabin_is_prime(rsa->n, 0, ctx, NULL, 1, &status); if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_PUBLIC, RSA_R_INVALID_MODULUS); + RSAerr(0, RSA_R_INVALID_MODULUS); ret = 0; goto err; } @@ -351,7 +351,7 @@ int rsa_sp800_56b_check_public(const RSA *rsa) /* * Perform validation of the RSA private key to check that 0 < D < N. */ -int rsa_sp800_56b_check_private(const RSA *rsa) +int ossl_rsa_sp800_56b_check_private(const RSA *rsa) { if (rsa->d == NULL || rsa->n == NULL) return 0; @@ -369,8 +369,8 @@ int rsa_sp800_56b_check_private(const RSA *rsa) * 6.4.1.2.3 "rsakpv1 - crt" * 6.4.1.3.3 "rsakpv2 - crt" */ -int rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, - int strength, int nbits) +int ossl_rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, + int strength, int nbits) { int ret = 0; BN_CTX *ctx = NULL; @@ -381,31 +381,30 @@ int rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, || rsa->e == NULL || rsa->d == NULL || rsa->n == NULL) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, RSA_R_INVALID_REQUEST); + RSAerr(0, RSA_R_INVALID_REQUEST); return 0; } /* (Step 1): Check Ranges */ - if (!rsa_sp800_56b_validate_strength(nbits, strength)) + if (!ossl_rsa_sp800_56b_validate_strength(nbits, strength)) return 0; /* If the exponent is known */ if (efixed != NULL) { /* (2): Check fixed exponent matches public exponent. */ if (BN_cmp(efixed, rsa->e) != 0) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, RSA_R_INVALID_REQUEST); + RSAerr(0, RSA_R_INVALID_REQUEST); return 0; } } /* (Step 1.c): e is odd integer 65537 <= e < 2^256 */ - if (!rsa_check_public_exponent(rsa->e)) { + if (!ossl_rsa_check_public_exponent(rsa->e)) { /* exponent out of range */ - RSAerr(RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, - RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + RSAerr(0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); return 0; } /* (Step 3.b): check the modulus */ if (nbits != BN_num_bits(rsa->n)) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, RSA_R_INVALID_KEYPAIR); + RSAerr(0, RSA_R_INVALID_KEYPAIR); return 0; } @@ -419,20 +418,20 @@ int rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, goto err; /* (Step 4.c): Check n = pq */ if (BN_cmp(rsa->n, r) != 0) { - RSAerr(RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, RSA_R_INVALID_REQUEST); + RSAerr(0, RSA_R_INVALID_REQUEST); goto err; } /* (Step 5): check prime factors p & q */ - ret = rsa_check_prime_factor(rsa->p, rsa->e, nbits, ctx) - && rsa_check_prime_factor(rsa->q, rsa->e, nbits, ctx) - && (rsa_check_pminusq_diff(r, rsa->p, rsa->q, nbits) > 0) + ret = ossl_rsa_check_prime_factor(rsa->p, rsa->e, nbits, ctx) + && ossl_rsa_check_prime_factor(rsa->q, rsa->e, nbits, ctx) + && (ossl_rsa_check_pminusq_diff(r, rsa->p, rsa->q, nbits) > 0) /* (Step 6): Check the private exponent d */ - && rsa_check_private_exponent(rsa, nbits, ctx) + && ossl_rsa_check_private_exponent(rsa, nbits, ctx) /* 6.4.1.2.3 (Step 7): Check the CRT components */ - && rsa_check_crt_components(rsa, ctx); + && ossl_rsa_check_crt_components(rsa, ctx); if (ret != 1) - RSAerr(RSA_F_RSA_SP800_56B_CHECK_KEYPAIR, RSA_R_INVALID_KEYPAIR); + RSAerr(0, RSA_R_INVALID_KEYPAIR); err: BN_clear(r); diff --git a/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/rsa/rsa_sp800_56b_gen.c index df15b8ce87..e8fdcd8940 100644 --- a/crypto/rsa/rsa_sp800_56b_gen.c +++ b/crypto/rsa/rsa_sp800_56b_gen.c @@ -53,8 +53,9 @@ * Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in. * (Required for CAVS testing). */ -int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, int nbits, - const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) +int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, + int nbits, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) { int ret = 0, ok; /* Temp allocated BIGNUMS */ @@ -87,13 +88,12 @@ int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, int nbits, * Signature Generation and Key Agree/Transport. */ if (nbits < RSA_FIPS1864_MIN_KEYGEN_KEYSIZE) { - RSAerr(RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES, RSA_R_KEY_SIZE_TOO_SMALL); + RSAerr(0, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } - if (!rsa_check_public_exponent(e)) { - RSAerr(RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES, - RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + if (!ossl_rsa_check_public_exponent(e)) { + RSAerr(0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); return 0; } @@ -131,14 +131,14 @@ int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, int nbits, goto err; /* (Step 6) |Xp - Xq| > 2^(nbitlen/2 - 100) */ - ok = rsa_check_pminusq_diff(tmp, Xpo, Xqo, nbits); + ok = ossl_rsa_check_pminusq_diff(tmp, Xpo, Xqo, nbits); if (ok < 0) goto err; if (ok == 0) continue; /* (Step 6) |p - q| > 2^(nbitlen/2 - 100) */ - ok = rsa_check_pminusq_diff(tmp, rsa->p, rsa->q, nbits); + ok = ossl_rsa_check_pminusq_diff(tmp, rsa->p, rsa->q, nbits); if (ok < 0) goto err; if (ok == 0) @@ -169,18 +169,18 @@ int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, int nbits, * strength is unknown. * Returns: 1 if the key size matches the target strength, or 0 otherwise. */ -int rsa_sp800_56b_validate_strength(int nbits, int strength) +int ossl_rsa_sp800_56b_validate_strength(int nbits, int strength) { int s = (int)ifc_ffc_compute_security_bits(nbits); #ifdef FIPS_MODULE if (s < RSA_FIPS1864_MIN_KEYGEN_STRENGTH || s > RSA_FIPS1864_MAX_KEYGEN_STRENGTH) { - RSAerr(RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH, RSA_R_INVALID_MODULUS); + RSAerr(0, RSA_R_INVALID_MODULUS); return 0; } #endif if (strength != -1 && s != strength) { - RSAerr(RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH, RSA_R_INVALID_STRENGTH); + RSAerr(0, RSA_R_INVALID_STRENGTH); return 0; } return 1; @@ -206,8 +206,8 @@ int rsa_sp800_56b_validate_strength(int nbits, int strength) * 0 = d is too small, * 1 = success. */ -int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, - const BIGNUM *e, BN_CTX *ctx) +int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, + const BIGNUM *e, BN_CTX *ctx) { int ret = -1; BIGNUM *p1, *q1, *lcm, *p1q1, *gcd; @@ -228,7 +228,7 @@ int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, BN_set_flags(gcd, BN_FLG_CONSTTIME); /* LCM((p-1, q-1)) */ - if (rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) != 1) + if (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) != 1) goto err; /* copy e */ @@ -330,8 +330,8 @@ int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, * cb An optional BIGNUM callback. * Returns: 1 if successfully generated otherwise it returns 0. */ -int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, - BN_GENCB *cb) +int ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, + BN_GENCB *cb) { int ret = 0; int ok; @@ -344,7 +344,7 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, #endif /* (Steps 1a-1b) : Currently ignores the strength check */ - if (!rsa_sp800_56b_validate_strength(nbits, -1)) + if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1)) return 0; ctx = BN_CTX_new_ex(rsa->libctx); @@ -363,11 +363,10 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, for (;;) { /* (Step 2) Generate prime factors */ - if (!rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx, - cb)) + if (!ossl_rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx, cb)) goto err; /* (Steps 3-5) Compute params d, n, dP, dQ, qInv */ - ok = rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx); + ok = ossl_rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx); if (ok < 0) goto err; if (ok > 0) @@ -376,7 +375,7 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, } /* (Step 6) Do pairwise test - optional validity test has been omitted */ - ret = rsa_sp800_56b_pairwise_test(rsa, ctx); + ret = ossl_rsa_sp800_56b_pairwise_test(rsa, ctx); err: if (efixed == NULL) BN_free(e); @@ -390,7 +389,7 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, * * Returns 1 if the RSA key passes the pairwise test or 0 it it fails. */ -int rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx) +int ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx) { int ret = 0; BIGNUM *k, *tmp; @@ -407,7 +406,7 @@ int rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx) && BN_mod_exp(tmp, tmp, rsa->d, rsa->n, ctx) && BN_cmp(k, tmp) == 0); if (ret == 0) - RSAerr(RSA_F_RSA_SP800_56B_PAIRWISE_TEST, RSA_R_PAIRWISE_TEST_FAILURE); + RSAerr(0, RSA_R_PAIRWISE_TEST_FAILURE); err: BN_CTX_end(ctx); return ret; diff --git a/crypto/rsa/rsa_ssl.c b/crypto/rsa/rsa_ssl.c index 1cca8d0b09..7e688aa9bc 100644 --- a/crypto/rsa/rsa_ssl.c +++ b/crypto/rsa/rsa_ssl.c @@ -21,9 +21,9 @@ #include "internal/constant_time.h" #include "rsa_local.h" -int rsa_padding_add_SSLv23_with_libctx(OPENSSL_CTX *libctx, unsigned char *to, - int tlen, const unsigned char *from, - int flen) +int ossl_rsa_padding_add_SSLv23_ex(OSSL_LIB_CTX *libctx, unsigned char *to, + int tlen, const unsigned char *from, + int flen) { int i, j; unsigned char *p; @@ -63,7 +63,7 @@ int rsa_padding_add_SSLv23_with_libctx(OPENSSL_CTX *libctx, unsigned char *to, int RSA_padding_add_SSLv23(unsigned char *to, int tlen, const unsigned char *from, int flen) { - return rsa_padding_add_SSLv23_with_libctx(NULL, to, tlen, from, flen); + return ossl_rsa_padding_add_SSLv23_ex(NULL, to, tlen, from, flen); } /* diff --git a/crypto/self_test_core.c b/crypto/self_test_core.c index 1a6f828c1d..a4f6c9ab2a 100644 --- a/crypto/self_test_core.c +++ b/crypto/self_test_core.c @@ -31,7 +31,8 @@ struct ossl_self_test_st void *cb_arg; }; -static void *self_test_set_callback_new(OPENSSL_CTX *ctx) +#ifndef FIPS_MODULE +static void *self_test_set_callback_new(OSSL_LIB_CTX *ctx) { SELF_TEST_CB *stcb; @@ -44,19 +45,18 @@ static void self_test_set_callback_free(void *stcb) OPENSSL_free(stcb); } -static const OPENSSL_CTX_METHOD self_test_set_callback_method = { +static const OSSL_LIB_CTX_METHOD self_test_set_callback_method = { self_test_set_callback_new, self_test_set_callback_free, }; -static SELF_TEST_CB *get_self_test_callback(OPENSSL_CTX *libctx) +static SELF_TEST_CB *get_self_test_callback(OSSL_LIB_CTX *libctx) { - return openssl_ctx_get_data(libctx, OPENSSL_CTX_SELF_TEST_CB_INDEX, - &self_test_set_callback_method); + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_SELF_TEST_CB_INDEX, + &self_test_set_callback_method); } -#ifndef FIPS_MODULE -void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb, +void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb, void *cbarg) { SELF_TEST_CB *stcb = get_self_test_callback(libctx); @@ -66,9 +66,8 @@ void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb, stcb->cbarg = cbarg; } } -#endif /* FIPS_MODULE */ -void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb, +void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, void **cbarg) { SELF_TEST_CB *stcb = get_self_test_callback(libctx); @@ -78,6 +77,7 @@ void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb, if (cbarg != NULL) *cbarg = (stcb != NULL ? stcb->cbarg : NULL); } +#endif /* FIPS_MODULE */ static void self_test_setparams(OSSL_SELF_TEST *st) { @@ -157,12 +157,15 @@ void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret) * is modified (corrupted). This is used to modify output signatures or * ciphertext before they are verified or decrypted. */ -void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes) +int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes) { if (st != NULL && st->cb != NULL) { st->phase = OSSL_SELF_TEST_PHASE_CORRUPT; self_test_setparams(st); - if (!st->cb(st->params, st->cb_arg)) + if (!st->cb(st->params, st->cb_arg)) { bytes[0] ^= 1; + return 1; + } } + return 0; } diff --git a/crypto/serializer/build.info b/crypto/serializer/build.info deleted file mode 100644 index 11f8889b6b..0000000000 --- a/crypto/serializer/build.info +++ /dev/null @@ -1,8 +0,0 @@ -SOURCE[../../libcrypto]=serdes_pass.c - -SOURCE[../../libcrypto]=serializer_meth.c serializer_lib.c serializer_pkey.c -SOURCE[../../libcrypto]=deserializer_meth.c deserializer_lib.c \ - deserializer_pkey.c - -SOURCE[../../libcrypto]=serializer_err.c -SOURCE[../../libcrypto]=deserializer_err.c diff --git a/crypto/serializer/deserializer_lib.c b/crypto/serializer/deserializer_lib.c deleted file mode 100644 index aa3b552786..0000000000 --- a/crypto/serializer/deserializer_lib.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "serializer_local.h" -#include "e_os.h" - -struct deser_process_data_st { - OSSL_DESERIALIZER_CTX *ctx; - - /* Current BIO */ - BIO *bio; - - /* Index of the current deserializer instance to be processed */ - size_t current_deser_inst_index; -}; - -static int deser_process(const OSSL_PARAM params[], void *arg); - -int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in) -{ - struct deser_process_data_st data; - int ok = 0; - - memset(&data, 0, sizeof(data)); - data.ctx = ctx; - data.bio = in; - - ok = deser_process(NULL, &data); - - /* Clear any internally cached passphrase */ - if (!ctx->flag_user_passphrase) { - OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0); - ctx->flag_user_passphrase = 0; - } - return ok; -} - -#ifndef OPENSSL_NO_STDIO -static BIO *bio_from_file(FILE *fp) -{ - BIO *b; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_BIO_LIB); - return NULL; - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - return b; -} - -int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *fp) -{ - BIO *b = bio_from_file(fp); - int ret = 0; - - if (b != NULL) - ret = OSSL_DESERIALIZER_from_bio(ctx, b); - - BIO_free(b); - return ret; -} -#endif - -int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx, - const char *input_type) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - /* - * NULL is a valid starting input type, and means that the caller leaves - * it to code to discover what the starting input type is. - */ - ctx->start_input_type = input_type; - return 1; -} - -int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx, - OSSL_DESERIALIZER *deser) -{ - OSSL_DESERIALIZER_INSTANCE *deser_inst = NULL; - const OSSL_PROVIDER *prov = NULL; - OSSL_PARAM params[2]; - void *provctx = NULL; - - if (!ossl_assert(ctx != NULL) || !ossl_assert(deser != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (deser->get_params == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, - OSSL_DESERIALIZER_R_MISSING_GET_PARAMS); - return 0; - } - - if (ctx->deser_insts == NULL - && (ctx->deser_insts = - sk_OSSL_DESERIALIZER_INSTANCE_new_null()) == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - return 0; - } - if ((deser_inst = OPENSSL_zalloc(sizeof(*deser_inst))) == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!OSSL_DESERIALIZER_up_ref(deser)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_INTERNAL_ERROR); - goto err; - } - deser_inst->deser = deser; - - prov = OSSL_DESERIALIZER_provider(deser_inst->deser); - provctx = OSSL_PROVIDER_get0_provider_ctx(prov); - - /* Cache the input type for this serializer */ - params[0] = - OSSL_PARAM_construct_utf8_ptr(OSSL_DESERIALIZER_PARAM_INPUT_TYPE, - (char **)&deser_inst->input_type, 0); - params[1] = OSSL_PARAM_construct_end(); - - if (!deser_inst->deser->get_params(params) - || !OSSL_PARAM_modified(¶ms[0])) - goto err; - - if ((deser_inst->deserctx = deser_inst->deser->newctx(provctx)) - == NULL) - goto err; - - if (sk_OSSL_DESERIALIZER_INSTANCE_push(ctx->deser_insts, deser_inst) <= 0) - goto err; - - return 1; - err: - if (deser_inst != NULL) { - if (deser_inst->deser != NULL) - deser_inst->deser->freectx(deser_inst->deserctx); - OSSL_DESERIALIZER_free(deser_inst->deser); - OPENSSL_free(deser_inst); - } - return 0; -} - -int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx, - OPENSSL_CTX *libctx, const char *propq) -{ - /* - * This function goes through existing deserializer methods in - * |ctx->deser_insts|, and tries to fetch new deserializers that produce - * what the existing ones want as input, and push those newly fetched - * deserializers on top of the same stack. - * Then it does the same again, but looping over the newly fetched - * deserializers, until there are no more serializers to be fetched, or - * when we have done this 10 times. - * - * we do this with sliding windows on the stack by keeping track of indexes - * and of the end. - * - * +----------------+ - * | DER to RSA | <--- w_prev_start - * +----------------+ - * | DER to DSA | - * +----------------+ - * | DER to DH | - * +----------------+ - * | PEM to DER | <--- w_prev_end, w_new_start - * +----------------+ - * <--- w_new_end - */ - size_t w_prev_start, w_prev_end; /* "previous" deserializers */ - size_t w_new_start, w_new_end; /* "new" deserializers */ - size_t count = 0; /* Calculates how many were added in each iteration */ - size_t depth = 0; /* Counts the number of iterations */ - - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - /* - * If there is no stack of OSSL_DESERIALIZER_INSTANCE, we have nothing - * more to add. That's fine. - */ - if (ctx->deser_insts == NULL) - return 1; - - w_prev_start = 0; - w_prev_end = sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts); - do { - size_t i; - - w_new_start = w_new_end = w_prev_end; - - for (i = w_prev_start; i < w_prev_end; i++) { - OSSL_DESERIALIZER_INSTANCE *deser_inst = - sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i); - const char *name = deser_inst->input_type; - OSSL_DESERIALIZER *deser = NULL; - - /* - * If the caller has specified what the initial input should be, - * and the deserializer implementation we're looking at has that - * input type, there's no point adding on more implementations - * on top of this one, so we don't. - */ - if (ctx->start_input_type != NULL - && strcasecmp(ctx->start_input_type, - deser_inst->input_type) != 0) - continue; - - ERR_set_mark(); - deser = OSSL_DESERIALIZER_fetch(libctx, name, propq); - ERR_pop_to_mark(); - - if (deser != NULL) { - size_t j; - - /* - * Check that we don't already have this deserializer in our - * stack We only need to check among the newly added ones. - */ - for (j = w_new_start; j < w_new_end; j++) { - OSSL_DESERIALIZER_INSTANCE *check_inst = - sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, j); - - if (deser == check_inst->deser) { - /* We found it, so drop the new fetch */ - OSSL_DESERIALIZER_free(deser); - deser = NULL; - break; - } - } - } - - if (deser == NULL) - continue; - - /* - * Apart from keeping w_new_end up to date, We don't care about - * errors here. If it doesn't collect, then it doesn't... - */ - if (OSSL_DESERIALIZER_CTX_add_deserializer(ctx, deser)) /* ref++ */ - w_new_end++; - OSSL_DESERIALIZER_free(deser); /* ref-- */ - } - /* How many were added in this iteration */ - count = w_new_end - w_new_start; - - /* Slide the "previous deserializer" windows */ - w_prev_start = w_new_start; - w_prev_end = w_new_end; - - depth++; - } while (count != 0 && depth <= 10); - - return 1; -} - -int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx) -{ - if (ctx == NULL || ctx->deser_insts == NULL) - return 0; - return sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts); -} - -int OSSL_DESERIALIZER_CTX_set_construct(OSSL_DESERIALIZER_CTX *ctx, - OSSL_DESERIALIZER_CONSTRUCT *construct) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - ctx->construct = construct; - return 1; -} - -int OSSL_DESERIALIZER_CTX_set_construct_data(OSSL_DESERIALIZER_CTX *ctx, - void *construct_data) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - ctx->construct_data = construct_data; - return 1; -} - -int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx, - OSSL_DESERIALIZER_CLEANUP *cleanup) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - ctx->cleanup = cleanup; - return 1; -} - -OSSL_DESERIALIZER_CONSTRUCT * -OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx) -{ - if (ctx == NULL) - return NULL; - return ctx->construct; -} - -void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx) -{ - if (ctx == NULL) - return NULL; - return ctx->construct_data; -} - -OSSL_DESERIALIZER_CLEANUP * -OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx) -{ - if (ctx == NULL) - return NULL; - return ctx->cleanup; -} - -int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst, - void *reference, size_t reference_sz, - OSSL_CALLBACK *export_cb, void *export_cbarg) -{ - if (!(ossl_assert(deser_inst != NULL) - && ossl_assert(reference != NULL) - && ossl_assert(export_cb != NULL) - && ossl_assert(export_cbarg != NULL))) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return deser_inst->deser->export_object(deser_inst->deserctx, - reference, reference_sz, - export_cb, export_cbarg); -} - -OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer - (OSSL_DESERIALIZER_INSTANCE *deser_inst) -{ - if (deser_inst == NULL) - return NULL; - return deser_inst->deser; -} - -void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx - (OSSL_DESERIALIZER_INSTANCE *deser_inst) -{ - if (deser_inst == NULL) - return NULL; - return deser_inst->deserctx; -} - -static int deser_process(const OSSL_PARAM params[], void *arg) -{ - struct deser_process_data_st *data = arg; - OSSL_DESERIALIZER_CTX *ctx = data->ctx; - OSSL_DESERIALIZER_INSTANCE *deser_inst = NULL; - OSSL_DESERIALIZER *deser = NULL; - BIO *bio = data->bio; - long loc; - size_t i; - int ok = 0; - /* For recursions */ - struct deser_process_data_st new_data; - - memset(&new_data, 0, sizeof(new_data)); - new_data.ctx = data->ctx; - - if (params == NULL) { - /* First iteration, where we prepare for what is to come */ - - data->current_deser_inst_index = - OSSL_DESERIALIZER_CTX_num_deserializers(ctx); - - bio = data->bio; - } else { - const OSSL_PARAM *p; - - deser_inst = - sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, - data->current_deser_inst_index); - deser = OSSL_DESERIALIZER_INSTANCE_deserializer(deser_inst); - - if (ctx->construct != NULL - && ctx->construct(deser_inst, params, ctx->construct_data)) { - ok = 1; - goto end; - } - - /* The constructor didn't return success */ - - /* - * so we try to use the object we got and feed it to any next - * deserializer that will take it. Object references are not - * allowed for this. - * If this data isn't present, deserialization has failed. - */ - - p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_DATA); - if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) - goto end; - new_data.bio = BIO_new_mem_buf(p->data, (int)p->data_size); - if (new_data.bio == NULL) - goto end; - bio = new_data.bio; - } - - /* - * If we have no more deserializers to look through at this point, - * we failed - */ - if (data->current_deser_inst_index == 0) - goto end; - - if ((loc = BIO_tell(bio)) < 0) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_BIO_LIB); - goto end; - } - - for (i = data->current_deser_inst_index; i-- > 0;) { - OSSL_DESERIALIZER_INSTANCE *new_deser_inst = - sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i); - OSSL_DESERIALIZER *new_deser = - OSSL_DESERIALIZER_INSTANCE_deserializer(new_deser_inst); - - /* - * If |deser| is NULL, it means we've just started, and the caller - * may have specified what it expects the initial input to be. If - * that's the case, we do this extra check. - */ - if (deser == NULL && ctx->start_input_type != NULL - && strcasecmp(ctx->start_input_type, - new_deser_inst->input_type) != 0) - continue; - - /* - * If we have a previous deserializer, we check that the input type - * of the next to be used matches the type of this previous one. - * deser_inst->input_type is a cache of the parameter "input-type" - * value for that deserializer. - */ - if (deser != NULL - && !OSSL_DESERIALIZER_is_a(deser, new_deser_inst->input_type)) - continue; - - /* - * Checking the return value of BIO_reset() or BIO_seek() is unsafe. - * Furthermore, BIO_reset() is unsafe to use if the source BIO happens - * to be a BIO_s_mem(), because the earlier BIO_tell() gives us zero - * no matter where we are in the underlying buffer we're reading from. - * - * So, we simply do a BIO_seek(), and use BIO_tell() that we're back - * at the same position. This is a best effort attempt, but BIO_seek() - * and BIO_tell() should come as a pair... - */ - (void)BIO_seek(bio, loc); - if (BIO_tell(bio) != loc) - goto end; - - /* Recurse */ - new_data.current_deser_inst_index = i; - ok = new_deser->deserialize(new_deser_inst->deserctx, - (OSSL_CORE_BIO *)bio, - deser_process, &new_data, - ctx->passphrase_cb, - new_data.ctx); - if (ok) - break; - } - - end: - BIO_free(new_data.bio); - return ok; -} diff --git a/crypto/serializer/deserializer_meth.c b/crypto/serializer/deserializer_meth.c deleted file mode 100644 index 4739c2956d..0000000000 --- a/crypto/serializer/deserializer_meth.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "internal/core.h" -#include "internal/namemap.h" -#include "internal/property.h" -#include "internal/provider.h" -#include "crypto/serializer.h" -#include "serializer_local.h" - -static void OSSL_DESERIALIZER_INSTANCE_free(OSSL_DESERIALIZER_INSTANCE *instance); - -/* - * Deserializer can have multiple names, separated with colons in a name string - */ -#define NAME_SEPARATOR ':' - -/* Simple method structure constructor and destructor */ -static OSSL_DESERIALIZER *ossl_deserializer_new(void) -{ - OSSL_DESERIALIZER *deser = NULL; - - if ((deser = OPENSSL_zalloc(sizeof(*deser))) == NULL - || (deser->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { - OSSL_DESERIALIZER_free(deser); - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - return NULL; - } - - deser->base.refcnt = 1; - - return deser; -} - -int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *deser) -{ - int ref = 0; - - CRYPTO_UP_REF(&deser->base.refcnt, &ref, deser->base.lock); - return 1; -} - -void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *deser) -{ - int ref = 0; - - if (deser == NULL) - return; - - CRYPTO_DOWN_REF(&deser->base.refcnt, &ref, deser->base.lock); - if (ref > 0) - return; - ossl_provider_free(deser->base.prov); - CRYPTO_THREAD_lock_free(deser->base.lock); - OPENSSL_free(deser); -} - -/* Permanent deserializer method store, constructor and destructor */ -static void deserializer_store_free(void *vstore) -{ - ossl_method_store_free(vstore); -} - -static void *deserializer_store_new(OPENSSL_CTX *ctx) -{ - return ossl_method_store_new(ctx); -} - - -static const OPENSSL_CTX_METHOD deserializer_store_method = { - deserializer_store_new, - deserializer_store_free, -}; - -/* Data to be passed through ossl_method_construct() */ -struct deserializer_data_st { - OPENSSL_CTX *libctx; - OSSL_METHOD_CONSTRUCT_METHOD *mcm; - int id; /* For get_deserializer_from_store() */ - const char *names; /* For get_deserializer_from_store() */ - const char *propquery; /* For get_deserializer_from_store() */ -}; - -/* - * Generic routines to fetch / create DESERIALIZER methods with - * ossl_method_construct() - */ - -/* Temporary deserializer method store, constructor and destructor */ -static void *alloc_tmp_deserializer_store(OPENSSL_CTX *ctx) -{ - return ossl_method_store_new(ctx); -} - - static void dealloc_tmp_deserializer_store(void *store) -{ - if (store != NULL) - ossl_method_store_free(store); -} - -/* Get the permanent deserializer store */ -static OSSL_METHOD_STORE *get_deserializer_store(OPENSSL_CTX *libctx) -{ - return openssl_ctx_get_data(libctx, OPENSSL_CTX_DESERIALIZER_STORE_INDEX, - &deserializer_store_method); -} - -/* Get deserializer methods from a store, or put one in */ -static void *get_deserializer_from_store(OPENSSL_CTX *libctx, void *store, - void *data) -{ - struct deserializer_data_st *methdata = data; - void *method = NULL; - int id; - - if ((id = methdata->id) == 0) { - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - - id = ossl_namemap_name2num(namemap, methdata->names); - } - - if (store == NULL - && (store = get_deserializer_store(libctx)) == NULL) - return NULL; - - if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) - return NULL; - return method; -} - -static int put_deserializer_in_store(OPENSSL_CTX *libctx, void *store, - void *method, const OSSL_PROVIDER *prov, - int operation_id, const char *names, - const char *propdef, void *unused) -{ - OSSL_NAMEMAP *namemap; - int id; - - if ((namemap = ossl_namemap_stored(libctx)) == NULL - || (id = ossl_namemap_name2num(namemap, names)) == 0) - return 0; - - if (store == NULL && (store = get_deserializer_store(libctx)) == NULL) - return 0; - - return ossl_method_store_add(store, prov, id, propdef, method, - (int (*)(void *))OSSL_DESERIALIZER_up_ref, - (void (*)(void *))OSSL_DESERIALIZER_free); -} - -/* Create and populate a deserializer method */ -static void *deserializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef, - OSSL_PROVIDER *prov) -{ - OSSL_DESERIALIZER *deser = NULL; - const OSSL_DISPATCH *fns = algodef->implementation; - - if ((deser = ossl_deserializer_new()) == NULL) - return NULL; - deser->base.id = id; - deser->base.propdef = algodef->property_definition; - - for (; fns->function_id != 0; fns++) { - switch (fns->function_id) { - case OSSL_FUNC_DESERIALIZER_NEWCTX: - if (deser->newctx == NULL) - deser->newctx = OSSL_FUNC_deserializer_newctx(fns); - break; - case OSSL_FUNC_DESERIALIZER_FREECTX: - if (deser->freectx == NULL) - deser->freectx = OSSL_FUNC_deserializer_freectx(fns); - break; - case OSSL_FUNC_DESERIALIZER_GET_PARAMS: - if (deser->get_params == NULL) - deser->get_params = - OSSL_FUNC_deserializer_get_params(fns); - break; - case OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS: - if (deser->gettable_params == NULL) - deser->gettable_params = - OSSL_FUNC_deserializer_gettable_params(fns); - break; - case OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS: - if (deser->set_ctx_params == NULL) - deser->set_ctx_params = - OSSL_FUNC_deserializer_set_ctx_params(fns); - break; - case OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS: - if (deser->settable_ctx_params == NULL) - deser->settable_ctx_params = - OSSL_FUNC_deserializer_settable_ctx_params(fns); - break; - case OSSL_FUNC_DESERIALIZER_DESERIALIZE: - if (deser->deserialize == NULL) - deser->deserialize = OSSL_FUNC_deserializer_deserialize(fns); - break; - case OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT: - if (deser->export_object == NULL) - deser->export_object = OSSL_FUNC_deserializer_export_object(fns); - break; - } - } - /* - * Try to check that the method is sensible. - * If you have a constructor, you must have a destructor and vice versa. - * You must have at least one of the serializing driver functions. - */ - if (!((deser->newctx == NULL && deser->freectx == NULL) - || (deser->newctx != NULL && deser->freectx != NULL)) - || (deser->deserialize == NULL && deser->export_object == NULL)) { - OSSL_DESERIALIZER_free(deser); - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS); - return NULL; - } - - if (prov != NULL && !ossl_provider_up_ref(prov)) { - OSSL_DESERIALIZER_free(deser); - return NULL; - } - - deser->base.prov = prov; - return deser; -} - - -/* - * The core fetching functionality passes the names of the implementation. - * This function is responsible to getting an identity number for them, - * then call deserializer_from_dispatch() with that identity number. - */ -static void *construct_deserializer(const OSSL_ALGORITHM *algodef, - OSSL_PROVIDER *prov, void *unused) -{ - /* - * This function is only called if get_deserializer_from_store() returned - * NULL, so it's safe to say that of all the spots to create a new - * namemap entry, this is it. Should the name already exist there, we - * know that ossl_namemap_add() will return its corresponding number. - */ - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - const char *names = algodef->algorithm_names; - int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); - void *method = NULL; - - if (id != 0) - method = deserializer_from_dispatch(id, algodef, prov); - - return method; -} - -/* Intermediary function to avoid ugly casts, used below */ -static void destruct_deserializer(void *method, void *data) -{ - OSSL_DESERIALIZER_free(method); -} - -static int up_ref_deserializer(void *method) -{ - return OSSL_DESERIALIZER_up_ref(method); -} - -static void free_deserializer(void *method) -{ - OSSL_DESERIALIZER_free(method); -} - -/* Fetching support. Can fetch by numeric identity or by name */ -static OSSL_DESERIALIZER *inner_ossl_deserializer_fetch(OPENSSL_CTX *libctx, - int id, - const char *name, - const char *properties) -{ - OSSL_METHOD_STORE *store = get_deserializer_store(libctx); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - void *method = NULL; - - if (store == NULL || namemap == NULL) - return NULL; - - /* - * If we have been passed neither a name_id or a name, we have an - * internal programming error. - */ - if (!ossl_assert(id != 0 || name != NULL)) - return NULL; - - if (id == 0) - id = ossl_namemap_name2num(namemap, name); - - if (id == 0 - || !ossl_method_store_cache_get(store, id, properties, &method)) { - OSSL_METHOD_CONSTRUCT_METHOD mcm = { - alloc_tmp_deserializer_store, - dealloc_tmp_deserializer_store, - get_deserializer_from_store, - put_deserializer_in_store, - construct_deserializer, - destruct_deserializer - }; - struct deserializer_data_st mcmdata; - - mcmdata.libctx = libctx; - mcmdata.mcm = &mcm; - mcmdata.id = id; - mcmdata.names = name; - mcmdata.propquery = properties; - if ((method = ossl_method_construct(libctx, OSSL_OP_DESERIALIZER, - 0 /* !force_cache */, - &mcm, &mcmdata)) != NULL) { - /* - * If construction did create a method for us, we know that - * there is a correct name_id and meth_id, since those have - * already been calculated in get_deserializer_from_store() and - * put_deserializer_in_store() above. - */ - if (id == 0) - id = ossl_namemap_name2num(namemap, name); - ossl_method_store_cache_set(store, id, properties, method, - up_ref_deserializer, free_deserializer); - } - } - - return method; -} - -OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx, - const char *name, - const char *properties) -{ - return inner_ossl_deserializer_fetch(libctx, 0, name, properties); -} - -OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx, - int id, - const char *properties) -{ - return inner_ossl_deserializer_fetch(libctx, id, NULL, properties); -} - -/* - * Library of basic method functions - */ - -const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *deser) -{ - if (!ossl_assert(deser != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return deser->base.prov; -} - -const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *deser) -{ - if (!ossl_assert(deser != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return deser->base.propdef; -} - -int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *deser) -{ - if (!ossl_assert(deser != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return deser->base.id; -} - -int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *deser, const char *name) -{ - if (deser->base.prov != NULL) { - OPENSSL_CTX *libctx = ossl_provider_library_context(deser->base.prov); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - - return ossl_namemap_name2num(namemap, name) == deser->base.id; - } - return 0; -} - -struct deserializer_do_all_data_st { - void (*user_fn)(void *method, void *arg); - void *user_arg; -}; - -static void deserializer_do_one(OSSL_PROVIDER *provider, - const OSSL_ALGORITHM *algodef, - int no_store, void *vdata) -{ - struct deserializer_do_all_data_st *data = vdata; - OPENSSL_CTX *libctx = ossl_provider_library_context(provider); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - const char *names = algodef->algorithm_names; - int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); - void *method = NULL; - - if (id != 0) - method = - deserializer_from_dispatch(id, algodef, provider); - - if (method != NULL) { - data->user_fn(method, data->user_arg); - OSSL_DESERIALIZER_free(method); - } -} - -void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx, - void (*fn)(OSSL_DESERIALIZER *deser, - void *arg), - void *arg) -{ - struct deserializer_do_all_data_st data; - - data.user_fn = (void (*)(void *, void *))fn; - data.user_arg = arg; - ossl_algorithm_do_all(libctx, OSSL_OP_DESERIALIZER, NULL, - NULL, deserializer_do_one, NULL, - &data); -} - -void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *deser, - void (*fn)(const char *name, void *data), - void *data) -{ - if (deser == NULL) - return; - - if (deser->base.prov != NULL) { - OPENSSL_CTX *libctx = ossl_provider_library_context(deser->base.prov); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - - ossl_namemap_doall_names(namemap, deser->base.id, fn, data); - } -} - -const OSSL_PARAM * -OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser) -{ - if (deser != NULL && deser->gettable_params != NULL) - return deser->gettable_params(); - return NULL; -} - -int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER *deser, OSSL_PARAM params[]) -{ - if (deser != NULL && deser->get_params != NULL) - return deser->get_params(params); - return 0; -} - -const OSSL_PARAM * -OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *deser) -{ - if (deser != NULL && deser->settable_ctx_params != NULL) - return deser->settable_ctx_params(); - return NULL; -} - -/* - * Deserializer context support - */ - -/* - * |ser| value NULL is valid, and signifies that there is no deserializer. - * This is useful to provide fallback mechanisms. - * Functions that want to verify if there is a deserializer can do so with - * OSSL_DESERIALIZER_CTX_get_deserializer() - */ -OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void) -{ - OSSL_DESERIALIZER_CTX *ctx; - - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb; - return ctx; -} - -int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx, - const OSSL_PARAM params[]) -{ - size_t i; - size_t l; - - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (ctx->deser_insts == NULL) - return 1; - - l = (size_t)sk_OSSL_DESERIALIZER_INSTANCE_num(ctx->deser_insts); - for (i = 0; i < l; i++) { - OSSL_DESERIALIZER_INSTANCE *deser_inst = - sk_OSSL_DESERIALIZER_INSTANCE_value(ctx->deser_insts, i); - - if (deser_inst->deserctx == NULL - || deser_inst->deser->set_ctx_params == NULL) - continue; - if (!deser_inst->deser->set_ctx_params(deser_inst->deserctx, params)) - return 0; - } - return 1; -} - -static void -OSSL_DESERIALIZER_INSTANCE_free(OSSL_DESERIALIZER_INSTANCE *deser_inst) -{ - if (deser_inst != NULL) { - if (deser_inst->deser->freectx != NULL) - deser_inst->deser->freectx(deser_inst->deserctx); - deser_inst->deserctx = NULL; - OSSL_DESERIALIZER_free(deser_inst->deser); - deser_inst->deser = NULL; - OPENSSL_free(deser_inst); - deser_inst = NULL; - } -} - -void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx) -{ - if (ctx != NULL) { - if (ctx->cleanup != NULL) - ctx->cleanup(ctx->construct_data); - sk_OSSL_DESERIALIZER_INSTANCE_pop_free(ctx->deser_insts, - OSSL_DESERIALIZER_INSTANCE_free); - OSSL_DESERIALIZER_CTX_set_passphrase_ui(ctx, NULL, NULL); - OSSL_DESERIALIZER_CTX_set_passphrase(ctx, NULL, 0); - OPENSSL_free(ctx); - } -} diff --git a/crypto/serializer/deserializer_pkey.c b/crypto/serializer/deserializer_pkey.c deleted file mode 100644 index 44e7eb56ee..0000000000 --- a/crypto/serializer/deserializer_pkey.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "crypto/evp.h" -#include "serializer_local.h" - -int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx, - const unsigned char *kstr, - size_t klen) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - OPENSSL_clear_free(ctx->cached_passphrase, ctx->cached_passphrase_len); - ctx->cached_passphrase = NULL; - ctx->cached_passphrase_len = 0; - if (kstr != NULL) { - if (klen == 0) { - ctx->cached_passphrase = OPENSSL_zalloc(1); - ctx->cached_passphrase_len = 0; - } else { - ctx->cached_passphrase = OPENSSL_memdup(kstr, klen); - ctx->cached_passphrase_len = klen; - } - if (ctx->cached_passphrase == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - return 0; - } - } - ctx->flag_user_passphrase = 1; - return 1; -} - -static void deserializer_ctx_reset_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx) -{ - UI_destroy_method(ctx->allocated_ui_method); - ctx->allocated_ui_method = NULL; - ctx->ui_method = NULL; - ctx->ui_data = NULL; -} - -int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - deserializer_ctx_reset_passphrase_ui(ctx); - ctx->ui_method = ui_method; - ctx->ui_data = ui_data; - return 1; -} - -int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx, - pem_password_cb *cb, void *cbarg) -{ - UI_METHOD *ui_method = NULL; - - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - /* - * If |cb| is NULL, it means the caller wants to reset previous - * password callback info. Otherwise, we only set the new data - * if a new UI_METHOD could be created for this sort of callback. - */ - if (cb == NULL - || (ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) != NULL) { - deserializer_ctx_reset_passphrase_ui(ctx); - ctx->ui_method = ctx->allocated_ui_method = ui_method; - ctx->ui_data = cbarg; - ctx->passphrase_cb = ossl_deserializer_passphrase_in_cb; - return 1; - } - - return 0; -} - -/* - * Support for OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY: - * The construct data, and collecting keymgmt information for it - */ - -DEFINE_STACK_OF(EVP_KEYMGMT) - -struct deser_EVP_PKEY_data_st { - char *object_type; /* recorded object data type, may be NULL */ - void **object; /* Where the result should end up */ - STACK_OF(EVP_KEYMGMT) *keymgmts; /* The EVP_KEYMGMTs we handle */ -}; - -static int deser_construct_EVP_PKEY(OSSL_DESERIALIZER_INSTANCE *deser_inst, - const OSSL_PARAM *params, - void *construct_data) -{ - struct deser_EVP_PKEY_data_st *data = construct_data; - OSSL_DESERIALIZER *deser = - OSSL_DESERIALIZER_INSTANCE_deserializer(deser_inst); - void *deserctx = OSSL_DESERIALIZER_INSTANCE_deserializer_ctx(deser_inst); - size_t i, end_i; - /* - * |object_ref| points to a provider reference to an object, its exact - * contents entirely opaque to us, but may be passed to any provider - * function that expects this (such as OSSL_FUNC_keymgmt_load(). - * - * This pointer is considered volatile, i.e. whatever it points at - * is assumed to be freed as soon as this function returns. - */ - void *object_ref = NULL; - size_t object_ref_sz = 0; - const OSSL_PARAM *p; - - p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_DATA_TYPE); - if (p != NULL) { - char *object_type = NULL; - - if (!OSSL_PARAM_get_utf8_string(p, &object_type, 0)) - return 0; - OPENSSL_free(data->object_type); - data->object_type = object_type; - } - - /* - * For stuff that should end up in an EVP_PKEY, we only accept an object - * reference for the moment. This enforces that the key data itself - * remains with the provider. - */ - p = OSSL_PARAM_locate_const(params, OSSL_DESERIALIZER_PARAM_REFERENCE); - if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) - return 0; - object_ref = p->data; - object_ref_sz = p->data_size; - - /* We may have reached one of the goals, let's find out! */ - end_i = sk_EVP_KEYMGMT_num(data->keymgmts); - for (i = 0; end_i; i++) { - EVP_KEYMGMT *keymgmt = sk_EVP_KEYMGMT_value(data->keymgmts, i); - - /* - * There are two ways to find a matching KEYMGMT: - * - * 1. If the object data type (recorded in |data->object_type|) - * is defined, by checking it using EVP_KEYMGMT_is_a(). - * 2. If the object data type is NOT defined, by comparing the - * EVP_KEYMGMT and OSSL_DESERIALIZER method numbers. Since - * EVP_KEYMGMT and OSSL_DESERIALIZE operate with the same - * namemap, we know that the method numbers must match. - * - * This allows individual deserializers to specify variants of keys, - * such as a DER to RSA deserializer finding a RSA-PSS key, without - * having to deserialize the exact same DER blob into the exact same - * internal structure twice. This is, of course, entirely at the - * discretion of the deserializer implementations. - */ - if (data->object_type != NULL - ? EVP_KEYMGMT_is_a(keymgmt, data->object_type) - : EVP_KEYMGMT_number(keymgmt) == OSSL_DESERIALIZER_number(deser)) { - EVP_PKEY *pkey = NULL; - void *keydata = NULL; - const OSSL_PROVIDER *keymgmt_prov = - EVP_KEYMGMT_provider(keymgmt); - const OSSL_PROVIDER *deser_prov = - OSSL_DESERIALIZER_provider(deser); - - /* - * If the EVP_KEYMGMT and the OSSL_DESERIALIZER are from the - * same provider, we assume that the KEYMGMT has a key loading - * function that can handle the provider reference we hold. - * - * Otherwise, we export from the deserializer and import the - * result in the keymgmt. - */ - if (keymgmt_prov == deser_prov) { - keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz); - } else { - struct evp_keymgmt_util_try_import_data_st import_data; - - import_data.keymgmt = keymgmt; - import_data.keydata = NULL; - import_data.selection = OSSL_KEYMGMT_SELECT_ALL; - - /* - * No need to check for errors here, the value of - * |import_data.keydata| is as much an indicator. - */ - (void)deser->export_object(deserctx, object_ref, object_ref_sz, - &evp_keymgmt_util_try_import, - &import_data); - keydata = import_data.keydata; - import_data.keydata = NULL; - } - - if (keydata != NULL - && (pkey = - evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL) - evp_keymgmt_freedata(keymgmt, keydata); - - *data->object = pkey; - - break; - } - } - /* - * We successfully looked through, |*ctx->object| determines if we - * actually found something. - */ - return (*data->object != NULL); -} - -static void deser_clean_EVP_PKEY_construct_arg(void *construct_data) -{ - struct deser_EVP_PKEY_data_st *data = construct_data; - - if (data != NULL) { - sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free); - OPENSSL_free(data->object_type); - OPENSSL_free(data); - } -} - -DEFINE_STACK_OF_CSTRING() - -struct collected_data_st { - struct deser_EVP_PKEY_data_st *process_data; - STACK_OF(OPENSSL_CSTRING) *names; - - unsigned int error_occured:1; -}; - -static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) -{ - struct collected_data_st *data = arg; - - if (data->error_occured) - return; - - data->error_occured = 1; /* Assume the worst */ - - if (!EVP_KEYMGMT_up_ref(keymgmt) /* ref++ */) - return; - if (sk_EVP_KEYMGMT_push(data->process_data->keymgmts, keymgmt) <= 0) { - EVP_KEYMGMT_free(keymgmt); /* ref-- */ - return; - } - - data->error_occured = 0; /* All is good now */ -} - -static void collect_name(const char *name, void *arg) -{ - struct collected_data_st *data = arg; - - if (data->error_occured) - return; - - data->error_occured = 1; /* Assume the worst */ - - if (sk_OPENSSL_CSTRING_push(data->names, name) <= 0) - return; - - data->error_occured = 0; /* All is good now */ -} - -OSSL_DESERIALIZER_CTX * -OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, - const char *input_type, - OPENSSL_CTX *libctx, - const char *propquery) -{ - OSSL_DESERIALIZER_CTX *ctx = NULL; - struct collected_data_st *data = NULL; - size_t i, end_i; - - if ((ctx = OSSL_DESERIALIZER_CTX_new()) == NULL - || (data = OPENSSL_zalloc(sizeof(*data))) == NULL - || (data->process_data = - OPENSSL_zalloc(sizeof(*data->process_data))) == NULL - || (data->process_data->keymgmts - = sk_EVP_KEYMGMT_new_null()) == NULL - || (data->names = sk_OPENSSL_CSTRING_new_null()) == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - goto err; - } - data->process_data->object = (void **)pkey; - OSSL_DESERIALIZER_CTX_set_input_type(ctx, input_type); - - /* First, find all keymgmts to form goals */ - EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, data); - - if (data->error_occured) - goto err; - - /* - * Then, use the names of those keymgmts to find the first set of - * derializers. - */ - ERR_set_mark(); - end_i = sk_EVP_KEYMGMT_num(data->process_data->keymgmts); - for (i = 0; i < end_i; i++) { - EVP_KEYMGMT *keymgmt = - sk_EVP_KEYMGMT_value(data->process_data->keymgmts, i); - size_t j; - OSSL_DESERIALIZER *deser = NULL; - - EVP_KEYMGMT_names_do_all(keymgmt, collect_name, data); - - for (j = sk_OPENSSL_CSTRING_num(data->names); - j-- > 0 && deser == NULL;) { - const char *name = sk_OPENSSL_CSTRING_pop(data->names); - - ERR_set_mark(); - deser = OSSL_DESERIALIZER_fetch(libctx, name, propquery); - ERR_pop_to_mark(); - } - - /* - * The names in |data->names| aren't allocated for the stack, - * so we can simply clear it and let it be re-used. - */ - sk_OPENSSL_CSTRING_zero(data->names); - - /* - * If we found a matching serializer, try to add it to the context. - */ - if (deser != NULL) { - (void)OSSL_DESERIALIZER_CTX_add_deserializer(ctx, deser); - OSSL_DESERIALIZER_free(deser); - } - } - /* If we found no deserializers to match the keymgmts, we err */ - if (OSSL_DESERIALIZER_CTX_num_deserializers(ctx) == 0) { - ERR_clear_last_mark(); - goto err; - } - ERR_pop_to_mark(); - - /* Finally, collect extra deserializers based on what we already have */ - (void)OSSL_DESERIALIZER_CTX_add_extra(ctx, libctx, propquery); - - if (!OSSL_DESERIALIZER_CTX_set_construct(ctx, deser_construct_EVP_PKEY) - || !OSSL_DESERIALIZER_CTX_set_construct_data(ctx, data->process_data) - || !OSSL_DESERIALIZER_CTX_set_cleanup - (ctx, deser_clean_EVP_PKEY_construct_arg)) - goto err; - - data->process_data = NULL; - err: - deser_clean_EVP_PKEY_construct_arg(data->process_data); - sk_OPENSSL_CSTRING_free(data->names); - OPENSSL_free(data); - return ctx; -} diff --git a/crypto/serializer/serdes_pass.c b/crypto/serializer/serdes_pass.c deleted file mode 100644 index 75200955b5..0000000000 --- a/crypto/serializer/serdes_pass.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include "internal/cryptlib.h" -#include "serializer_local.h" - -/* Passphrase callbacks for any who need it */ - -/* - * First, define the generic passphrase function that supports both - * outgoing (with passphrase verify) and incoming (without passphrase - * verify) passphrase reading. - */ -static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len, - const OSSL_PARAM params[], void *arg, int verify, - const UI_METHOD *ui_method, void *ui_data, int errlib) -{ - const OSSL_PARAM *p; - const char *prompt_info = NULL; - char *prompt = NULL, *vpass = NULL; - int prompt_idx = -1, verify_idx = -1; - UI *ui = NULL; - int ret = 0; - - if (!ossl_assert(pass != NULL && pass_size != 0 && pass_len != NULL)) { - ERR_raise(errlib, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if ((p = OSSL_PARAM_locate_const(params, - OSSL_PASSPHRASE_PARAM_INFO)) != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - prompt_info = p->data; - } - - if ((ui = UI_new()) == NULL) { - ERR_raise(errlib, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (ui_method != NULL) { - UI_set_method(ui, ui_method); - if (ui_data != NULL) - UI_add_user_data(ui, ui_data); - } - - /* Get an application constructed prompt */ - prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); - if (prompt == NULL) { - ERR_raise(errlib, ERR_R_MALLOC_FAILURE); - goto end; - } - - prompt_idx = UI_add_input_string(ui, prompt, - UI_INPUT_FLAG_DEFAULT_PWD, - pass, 0, pass_size - 1) - 1; - if (prompt_idx < 0) { - ERR_raise(errlib, ERR_R_UI_LIB); - goto end; - } - - if (verify) { - /* Get a buffer for verification prompt */ - vpass = OPENSSL_zalloc(pass_size); - if (vpass == NULL) { - ERR_raise(errlib, ERR_R_MALLOC_FAILURE); - goto end; - } - verify_idx = UI_add_verify_string(ui, prompt, - UI_INPUT_FLAG_DEFAULT_PWD, - vpass, 0, pass_size - 1, - pass) - 1; - if (verify_idx < 0) { - ERR_raise(errlib, ERR_R_UI_LIB); - goto end; - } - } - - switch (UI_process(ui)) { - case -2: - ERR_raise(errlib, ERR_R_INTERRUPTED_OR_CANCELLED); - break; - case -1: - ERR_raise(errlib, ERR_R_UI_LIB); - break; - default: - *pass_len = (size_t)UI_get_result_length(ui, prompt_idx); - ret = 1; - break; - } - - end: - OPENSSL_free(vpass); - OPENSSL_free(prompt); - UI_free(ui); - return ret; -} - -/* - * Serializers typically want to get an outgoing passphrase, while - * deserializers typically want to get en incoming passphrase. - */ -int ossl_serializer_passphrase_out_cb(char *pass, size_t pass_size, - size_t *pass_len, - const OSSL_PARAM params[], void *arg) -{ - OSSL_SERIALIZER_CTX *ctx = arg; - - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return do_passphrase(pass, pass_size, pass_len, params, arg, 1, - ctx->ui_method, ctx->ui_data, - ERR_LIB_OSSL_SERIALIZER); -} - -int ossl_deserializer_passphrase_in_cb(char *pass, size_t pass_size, - size_t *pass_len, - const OSSL_PARAM params[], void *arg) -{ - OSSL_DESERIALIZER_CTX *ctx = arg; - - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (ctx->cached_passphrase != NULL) { - size_t len = ctx->cached_passphrase_len; - - if (len > pass_size) - len = pass_size; - memcpy(pass, ctx->cached_passphrase, len); - *pass_len = len; - return 1; - } else { - if ((ctx->cached_passphrase = OPENSSL_zalloc(pass_size)) == NULL) { - ERR_raise(ERR_LIB_OSSL_DESERIALIZER, ERR_R_MALLOC_FAILURE); - return 0; - } - } - if (do_passphrase(pass, pass_size, pass_len, params, arg, 0, - ctx->ui_method, ctx->ui_data, - ERR_LIB_OSSL_DESERIALIZER)) { - memcpy(ctx->cached_passphrase, pass, *pass_len); - ctx->cached_passphrase_len = *pass_len; - return 1; - } - return 0; -} diff --git a/crypto/serializer/serializer_err.c b/crypto/serializer/serializer_err.c deleted file mode 100644 index 2ea8b8bede..0000000000 --- a/crypto/serializer/serializer_err.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA OSSL_SERIALIZER_str_reasons[] = { - {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY), - "incorrect property query"}, - {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND), - "serializer not found"}, - {0, NULL} -}; - -#endif - -int ERR_load_OSSL_SERIALIZER_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OSSL_SERIALIZER_str_reasons[0].error) == NULL) - ERR_load_strings_const(OSSL_SERIALIZER_str_reasons); -#endif - return 1; -} diff --git a/crypto/serializer/serializer_lib.c b/crypto/serializer/serializer_lib.c deleted file mode 100644 index 932ef1e3ae..0000000000 --- a/crypto/serializer/serializer_lib.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "serializer_local.h" - -int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out) -{ - return ctx->do_output(ctx, out); -} - -#ifndef OPENSSL_NO_STDIO -static BIO *bio_from_file(FILE *fp) -{ - BIO *b; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_BUF_LIB); - return NULL; - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - return b; -} - -int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp) -{ - BIO *b = bio_from_file(fp); - int ret = 0; - - if (b != NULL) - ret = OSSL_SERIALIZER_to_bio(ctx, b); - - BIO_free(b); - return ret; -} -#endif diff --git a/crypto/serializer/serializer_local.h b/crypto/serializer/serializer_local.h deleted file mode 100644 index d139e402d7..0000000000 --- a/crypto/serializer/serializer_local.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "internal/refcount.h" - -struct ossl_serdes_base_st { - OSSL_PROVIDER *prov; - int id; - const char *propdef; - - CRYPTO_REF_COUNT refcnt; - CRYPTO_RWLOCK *lock; -}; - -struct ossl_serializer_st { - struct ossl_serdes_base_st base; - OSSL_FUNC_serializer_newctx_fn *newctx; - OSSL_FUNC_serializer_freectx_fn *freectx; - OSSL_FUNC_serializer_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_serializer_settable_ctx_params_fn *settable_ctx_params; - OSSL_FUNC_serializer_serialize_data_fn *serialize_data; - OSSL_FUNC_serializer_serialize_object_fn *serialize_object; -}; - -struct ossl_deserializer_st { - struct ossl_serdes_base_st base; - OSSL_FUNC_deserializer_newctx_fn *newctx; - OSSL_FUNC_deserializer_freectx_fn *freectx; - OSSL_FUNC_deserializer_get_params_fn *get_params; - OSSL_FUNC_deserializer_gettable_params_fn *gettable_params; - OSSL_FUNC_deserializer_set_ctx_params_fn *set_ctx_params; - OSSL_FUNC_deserializer_settable_ctx_params_fn *settable_ctx_params; - OSSL_FUNC_deserializer_deserialize_fn *deserialize; - OSSL_FUNC_deserializer_export_object_fn *export_object; -}; - -struct ossl_serializer_ctx_st { - OSSL_SERIALIZER *ser; - void *serctx; - - int selection; - - /*- - * Output / serializing data, used by OSSL_SERIALIZER_to_{bio,fp} - * - * |object| is the libcrypto object to handle. - * |do_output| performs the actual serialization. - * - * |do_output| must have intimate knowledge of |object|. - */ - const void *object; - int (*do_output)(OSSL_SERIALIZER_CTX *ctx, BIO *out); - - /* For any function that needs a passphrase reader */ - const UI_METHOD *ui_method; - void *ui_data; - /* - * if caller used OSSL_SERIALIZER_CTX_set_passphrase_cb(), we need - * intermediary storage. - */ - UI_METHOD *allocated_ui_method; -}; - -struct ossl_deserializer_instance_st { - OSSL_DESERIALIZER *deser; /* Never NULL */ - void *deserctx; /* Never NULL */ - const char *input_type; /* Never NULL */ -}; - -DEFINE_STACK_OF(OSSL_DESERIALIZER_INSTANCE) - -struct ossl_deserializer_ctx_st { - /* - * The caller may know the input type of the data they pass. If not, - * this will remain NULL and the deserializing functionality will start - * with trying to deserialize with any desserializer in |deser_insts|, - * regardless of their respective input type. - */ - const char *start_input_type; - - /* - * Deserializers that are components of any current deserialization path. - */ - STACK_OF(OSSL_DESERIALIZER_INSTANCE) *deser_insts; - - /* - * The constructors of a deserialization, and its caller argument. - */ - OSSL_DESERIALIZER_CONSTRUCT *construct; - OSSL_DESERIALIZER_CLEANUP *cleanup; - void *construct_data; - - /* For any function that needs a passphrase reader */ - OSSL_PASSPHRASE_CALLBACK *passphrase_cb; - const UI_METHOD *ui_method; - void *ui_data; - /* - * if caller used OSSL_SERIALIZER_CTX_set_pem_password_cb(), we need - * intermediary storage. - */ - UI_METHOD *allocated_ui_method; - /* - * Because the same input may pass through more than one deserializer, - * we cache any passphrase passed to us. The desrializing processor - * must clear this at the end of a run. - */ - unsigned char *cached_passphrase; - size_t cached_passphrase_len; - - /* - * Flag section. Keep these together - */ - - /* - * The passphrase was passed to us by the user. In that case, it - * should only be freed when freeing this context. - */ - unsigned int flag_user_passphrase:1; -}; - -/* Passphrase callbacks, found in serdes_pass.c */ - -/* - * Serializers typically want to get an outgoing passphrase, while - * deserializers typically want to get en incoming passphrase. - */ -OSSL_PASSPHRASE_CALLBACK ossl_serializer_passphrase_out_cb; -OSSL_PASSPHRASE_CALLBACK ossl_deserializer_passphrase_in_cb; diff --git a/crypto/serializer/serializer_meth.c b/crypto/serializer/serializer_meth.c deleted file mode 100644 index c2ff1c0dca..0000000000 --- a/crypto/serializer/serializer_meth.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "internal/core.h" -#include "internal/namemap.h" -#include "internal/property.h" -#include "internal/provider.h" -#include "crypto/serializer.h" -#include "serializer_local.h" - -/* - * Serializer can have multiple names, separated with colons in a name string - */ -#define NAME_SEPARATOR ':' - -/* Simple method structure constructor and destructor */ -static OSSL_SERIALIZER *ossl_serializer_new(void) -{ - OSSL_SERIALIZER *ser = NULL; - - if ((ser = OPENSSL_zalloc(sizeof(*ser))) == NULL - || (ser->base.lock = CRYPTO_THREAD_lock_new()) == NULL) { - OSSL_SERIALIZER_free(ser); - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ser->base.refcnt = 1; - - return ser; -} - -int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser) -{ - int ref = 0; - - CRYPTO_UP_REF(&ser->base.refcnt, &ref, ser->base.lock); - return 1; -} - -void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser) -{ - int ref = 0; - - if (ser == NULL) - return; - - CRYPTO_DOWN_REF(&ser->base.refcnt, &ref, ser->base.lock); - if (ref > 0) - return; - ossl_provider_free(ser->base.prov); - CRYPTO_THREAD_lock_free(ser->base.lock); - OPENSSL_free(ser); -} - -/* Permanent serializer method store, constructor and destructor */ -static void serializer_store_free(void *vstore) -{ - ossl_method_store_free(vstore); -} - -static void *serializer_store_new(OPENSSL_CTX *ctx) -{ - return ossl_method_store_new(ctx); -} - - -static const OPENSSL_CTX_METHOD serializer_store_method = { - serializer_store_new, - serializer_store_free, -}; - -/* Data to be passed through ossl_method_construct() */ -struct serializer_data_st { - OPENSSL_CTX *libctx; - OSSL_METHOD_CONSTRUCT_METHOD *mcm; - int id; /* For get_serializer_from_store() */ - const char *names; /* For get_serializer_from_store() */ - const char *propquery; /* For get_serializer_from_store() */ -}; - -/* - * Generic routines to fetch / create SERIALIZER methods with - * ossl_method_construct() - */ - -/* Temporary serializer method store, constructor and destructor */ -static void *alloc_tmp_serializer_store(OPENSSL_CTX *ctx) -{ - return ossl_method_store_new(ctx); -} - - static void dealloc_tmp_serializer_store(void *store) -{ - if (store != NULL) - ossl_method_store_free(store); -} - -/* Get the permanent serializer store */ -static OSSL_METHOD_STORE *get_serializer_store(OPENSSL_CTX *libctx) -{ - return openssl_ctx_get_data(libctx, OPENSSL_CTX_SERIALIZER_STORE_INDEX, - &serializer_store_method); -} - -/* Get serializer methods from a store, or put one in */ -static void *get_serializer_from_store(OPENSSL_CTX *libctx, void *store, - void *data) -{ - struct serializer_data_st *methdata = data; - void *method = NULL; - int id; - - if ((id = methdata->id) == 0) { - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - - id = ossl_namemap_name2num(namemap, methdata->names); - } - - if (store == NULL - && (store = get_serializer_store(libctx)) == NULL) - return NULL; - - if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) - return NULL; - return method; -} - -static int put_serializer_in_store(OPENSSL_CTX *libctx, void *store, - void *method, const OSSL_PROVIDER *prov, - int operation_id, const char *names, - const char *propdef, void *unused) -{ - OSSL_NAMEMAP *namemap; - int id; - - if ((namemap = ossl_namemap_stored(libctx)) == NULL - || (id = ossl_namemap_name2num(namemap, names)) == 0) - return 0; - - if (store == NULL && (store = get_serializer_store(libctx)) == NULL) - return 0; - - return ossl_method_store_add(store, prov, id, propdef, method, - (int (*)(void *))OSSL_SERIALIZER_up_ref, - (void (*)(void *))OSSL_SERIALIZER_free); -} - -/* Create and populate a serializer method */ -static void *serializer_from_dispatch(int id, const OSSL_ALGORITHM *algodef, - OSSL_PROVIDER *prov) -{ - OSSL_SERIALIZER *ser = NULL; - const OSSL_DISPATCH *fns = algodef->implementation; - - if ((ser = ossl_serializer_new()) == NULL) - return NULL; - ser->base.id = id; - ser->base.propdef = algodef->property_definition; - - for (; fns->function_id != 0; fns++) { - switch (fns->function_id) { - case OSSL_FUNC_SERIALIZER_NEWCTX: - if (ser->newctx == NULL) - ser->newctx = - OSSL_FUNC_serializer_newctx(fns); - break; - case OSSL_FUNC_SERIALIZER_FREECTX: - if (ser->freectx == NULL) - ser->freectx = - OSSL_FUNC_serializer_freectx(fns); - break; - case OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS: - if (ser->set_ctx_params == NULL) - ser->set_ctx_params = - OSSL_FUNC_serializer_set_ctx_params(fns); - break; - case OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS: - if (ser->settable_ctx_params == NULL) - ser->settable_ctx_params = - OSSL_FUNC_serializer_settable_ctx_params(fns); - break; - case OSSL_FUNC_SERIALIZER_SERIALIZE_DATA: - if (ser->serialize_data == NULL) - ser->serialize_data = - OSSL_FUNC_serializer_serialize_data(fns); - break; - case OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT: - if (ser->serialize_object == NULL) - ser->serialize_object = - OSSL_FUNC_serializer_serialize_object(fns); - break; - } - } - /* - * Try to check that the method is sensible. - * If you have a constructor, you must have a destructor and vice versa. - * You must have at least one of the serializing driver functions. - */ - if (!((ser->newctx == NULL && ser->freectx == NULL) - || (ser->newctx != NULL && ser->freectx != NULL)) - || (ser->serialize_data == NULL && ser->serialize_object == NULL)) { - OSSL_SERIALIZER_free(ser); - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_INVALID_PROVIDER_FUNCTIONS); - return NULL; - } - - if (prov != NULL && !ossl_provider_up_ref(prov)) { - OSSL_SERIALIZER_free(ser); - return NULL; - } - - ser->base.prov = prov; - return ser; -} - - -/* - * The core fetching functionality passes the names of the implementation. - * This function is responsible to getting an identity number for them, - * then call serializer_from_dispatch() with that identity number. - */ -static void *construct_serializer(const OSSL_ALGORITHM *algodef, - OSSL_PROVIDER *prov, void *unused) -{ - /* - * This function is only called if get_serializer_from_store() returned - * NULL, so it's safe to say that of all the spots to create a new - * namemap entry, this is it. Should the name already exist there, we - * know that ossl_namemap_add() will return its corresponding number. - */ - OPENSSL_CTX *libctx = ossl_provider_library_context(prov); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - const char *names = algodef->algorithm_names; - int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); - void *method = NULL; - - if (id != 0) - method = serializer_from_dispatch(id, algodef, prov); - - return method; -} - -/* Intermediary function to avoid ugly casts, used below */ -static void destruct_serializer(void *method, void *data) -{ - OSSL_SERIALIZER_free(method); -} - -static int up_ref_serializer(void *method) -{ - return OSSL_SERIALIZER_up_ref(method); -} - -static void free_serializer(void *method) -{ - OSSL_SERIALIZER_free(method); -} - -/* Fetching support. Can fetch by numeric identity or by name */ -static OSSL_SERIALIZER *inner_ossl_serializer_fetch(OPENSSL_CTX *libctx, - int id, const char *name, - const char *properties) -{ - OSSL_METHOD_STORE *store = get_serializer_store(libctx); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - void *method = NULL; - - if (store == NULL || namemap == NULL) - return NULL; - - /* - * If we have been passed neither a name_id or a name, we have an - * internal programming error. - */ - if (!ossl_assert(id != 0 || name != NULL)) - return NULL; - - if (id == 0) - id = ossl_namemap_name2num(namemap, name); - - if (id == 0 - || !ossl_method_store_cache_get(store, id, properties, &method)) { - OSSL_METHOD_CONSTRUCT_METHOD mcm = { - alloc_tmp_serializer_store, - dealloc_tmp_serializer_store, - get_serializer_from_store, - put_serializer_in_store, - construct_serializer, - destruct_serializer - }; - struct serializer_data_st mcmdata; - - mcmdata.libctx = libctx; - mcmdata.mcm = &mcm; - mcmdata.id = id; - mcmdata.names = name; - mcmdata.propquery = properties; - if ((method = ossl_method_construct(libctx, OSSL_OP_SERIALIZER, - 0 /* !force_cache */, - &mcm, &mcmdata)) != NULL) { - /* - * If construction did create a method for us, we know that - * there is a correct name_id and meth_id, since those have - * already been calculated in get_serializer_from_store() and - * put_serializer_in_store() above. - */ - if (id == 0) - id = ossl_namemap_name2num(namemap, name); - ossl_method_store_cache_set(store, id, properties, method, - up_ref_serializer, free_serializer); - } - } - - return method; -} - -OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *libctx, const char *name, - const char *properties) -{ - return inner_ossl_serializer_fetch(libctx, 0, name, properties); -} - -OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id, - const char *properties) -{ - return inner_ossl_serializer_fetch(libctx, id, NULL, properties); -} - -/* - * Library of basic method functions - */ - -const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER *ser) -{ - if (!ossl_assert(ser != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return ser->base.prov; -} - -const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser) -{ - if (!ossl_assert(ser != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return ser->base.propdef; -} - -int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser) -{ - if (!ossl_assert(ser != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return ser->base.id; -} - -int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser, const char *name) -{ - if (ser->base.prov != NULL) { - OPENSSL_CTX *libctx = ossl_provider_library_context(ser->base.prov); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - - return ossl_namemap_name2num(namemap, name) == ser->base.id; - } - return 0; -} - -struct serializer_do_all_data_st { - void (*user_fn)(void *method, void *arg); - void *user_arg; -}; - -static void serializer_do_one(OSSL_PROVIDER *provider, - const OSSL_ALGORITHM *algodef, - int no_store, void *vdata) -{ - struct serializer_do_all_data_st *data = vdata; - OPENSSL_CTX *libctx = ossl_provider_library_context(provider); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - const char *names = algodef->algorithm_names; - int id = ossl_namemap_add_names(namemap, 0, names, NAME_SEPARATOR); - void *method = NULL; - - if (id != 0) - method = - serializer_from_dispatch(id, algodef, provider); - - if (method != NULL) { - data->user_fn(method, data->user_arg); - OSSL_SERIALIZER_free(method); - } -} - -void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx, - void (*fn)(OSSL_SERIALIZER *ser, - void *arg), - void *arg) -{ - struct serializer_do_all_data_st data; - - data.user_fn = (void (*)(void *, void *))fn; - data.user_arg = arg; - - /* - * No pre- or post-condition for this call, as this only creates methods - * temporarly and then promptly destroys them. - */ - ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, NULL, - serializer_do_one, NULL, &data); -} - -void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser, - void (*fn)(const char *name, void *data), - void *data) -{ - if (ser == NULL) - return; - - if (ser->base.prov != NULL) { - OPENSSL_CTX *libctx = ossl_provider_library_context(ser->base.prov); - OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); - - ossl_namemap_doall_names(namemap, ser->base.id, fn, data); - } -} - -const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser) -{ - if (ser != NULL && ser->settable_ctx_params != NULL) - return ser->settable_ctx_params(); - return NULL; -} - -/* - * Serializer context support - */ - -/* - * |ser| value NULL is valid, and signifies that there is no serializer. - * This is useful to provide fallback mechanisms. - * Functions that want to verify if there is a serializer can do so with - * OSSL_SERIALIZER_CTX_get_serializer() - */ -OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser) -{ - OSSL_SERIALIZER_CTX *ctx; - - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ctx->ser = ser; - if (ser != NULL && ser->newctx != NULL) { - const OSSL_PROVIDER *prov = OSSL_SERIALIZER_provider(ser); - void *provctx = ossl_provider_ctx(prov); - - if (OSSL_SERIALIZER_up_ref(ser)) { - ctx->serctx = ser->newctx(provctx); - } else { - OSSL_SERIALIZER_free(ser); - OPENSSL_free(ctx); - ctx = NULL; - } - } - - return ctx; -} - -const OSSL_SERIALIZER * -OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return ctx->ser; -} - - -int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx, - const OSSL_PARAM params[]) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (ctx->ser != NULL && ctx->ser->set_ctx_params != NULL) - return ctx->ser->set_ctx_params(ctx->serctx, params); - return 0; -} - -void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx) -{ - if (ctx != NULL) { - if (ctx->ser != NULL && ctx->ser->freectx != NULL) - ctx->ser->freectx(ctx->serctx); - OSSL_SERIALIZER_free(ctx->ser); - UI_destroy_method(ctx->allocated_ui_method); - OPENSSL_free(ctx); - } -} diff --git a/crypto/serializer/serializer_pkey.c b/crypto/serializer/serializer_pkey.c deleted file mode 100644 index 6e24ed73f0..0000000000 --- a/crypto/serializer/serializer_pkey.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include -#include "internal/provider.h" -#include "internal/property.h" -#include "crypto/evp.h" -#include "serializer_local.h" - -DEFINE_STACK_OF_CSTRING() - -int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx, - const char *cipher_name, - const char *propquery) -{ - OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = - OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, - (void *)cipher_name, 0); - params[1] = - OSSL_PARAM_construct_utf8_string(OSSL_SERIALIZER_PARAM_PROPERTIES, - (void *)propquery, 0); - - return OSSL_SERIALIZER_CTX_set_params(ctx, params); -} - -int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx, - const unsigned char *kstr, - size_t klen) -{ - OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - params[0] = OSSL_PARAM_construct_octet_string(OSSL_SERIALIZER_PARAM_PASS, - (void *)kstr, klen); - - return OSSL_SERIALIZER_CTX_set_params(ctx, params); -} - -static void serializer_ctx_reset_passphrase_ui(OSSL_SERIALIZER_CTX *ctx) -{ - UI_destroy_method(ctx->allocated_ui_method); - ctx->allocated_ui_method = NULL; - ctx->ui_method = NULL; - ctx->ui_data = NULL; -} - -int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - serializer_ctx_reset_passphrase_ui(ctx); - ctx->ui_method = ui_method; - ctx->ui_data = ui_data; - return 1; -} - -int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx, - pem_password_cb *cb, void *cbarg) -{ - if (!ossl_assert(ctx != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - serializer_ctx_reset_passphrase_ui(ctx); - if (cb == NULL) - return 1; - ctx->ui_method = - ctx->allocated_ui_method = UI_UTIL_wrap_read_pem_callback(cb, 1); - ctx->ui_data = cbarg; - - return ctx->ui_method != NULL; -} - -/* - * Support for OSSL_SERIALIZER_CTX_new_by_TYPE: - * finding a suitable serializer - */ - -struct selected_serializer_st { - STACK_OF(OPENSSL_CSTRING) *names; - int error; -}; - -static void cache_serializers(const char *name, void *data) -{ - struct selected_serializer_st *d = data; - - if (sk_OPENSSL_CSTRING_push(d->names, name) <= 0) - d->error = 1; -} - -/* - * Support for OSSL_SERIALIZER_to_bio: - * writing callback for the OSSL_PARAM (the implementation doesn't have - * intimate knowledge of the provider side object) - */ - -struct serializer_write_data_st { - OSSL_SERIALIZER_CTX *ctx; - BIO *out; -}; - -static int serializer_write_cb(const OSSL_PARAM params[], void *arg) -{ - struct serializer_write_data_st *write_data = arg; - OSSL_SERIALIZER_CTX *ctx = write_data->ctx; - BIO *out = write_data->out; - - return ctx->ser->serialize_data(ctx->serctx, params, (OSSL_CORE_BIO *)out, - ossl_serializer_passphrase_out_cb, ctx); -} - -/* - * Support for OSSL_SERIALIZER_to_bio: - * Perform the actual output. - */ - -static int serializer_EVP_PKEY_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out) -{ - const EVP_PKEY *pkey = ctx->object; - void *keydata = pkey->keydata; - EVP_KEYMGMT *keymgmt = pkey->keymgmt; - - /* - * OSSL_SERIALIZER_CTX_new() creates a context, even when the - * serializer it's given is NULL. Callers can detect the lack - * of serializer with OSSL_SERIALIZER_CTX_get_serializer() and - * should take precautions, possibly call a fallback instead of - * OSSL_SERIALIZER_to_bio() / OSSL_SERIALIZER_to_fp(). If it's - * come this far, we return an error. - */ - if (ctx->ser == NULL) - return 0; - - if (ctx->ser->serialize_object == NULL) { - struct serializer_write_data_st write_data; - - write_data.ctx = ctx; - write_data.out = out; - - return evp_keymgmt_export(keymgmt, keydata, ctx->selection, - &serializer_write_cb, &write_data); - } - - return ctx->ser->serialize_object(ctx->serctx, keydata, - (OSSL_CORE_BIO *)out, - ossl_serializer_passphrase_out_cb, ctx); -} - -/* - * OSSL_SERIALIZER_CTX_new_by_EVP_PKEY() returns a ctx with no serializer if - * it couldn't find a suitable serializer. This allows a caller to detect if - * a suitable serializer was found, with OSSL_SERIALIZER_CTX_get_serializer(), - * and to use fallback methods if the result is NULL. - */ -OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, - const char *propquery) -{ - OSSL_SERIALIZER_CTX *ctx = NULL; - OSSL_SERIALIZER *ser = NULL; - EVP_KEYMGMT *keymgmt = pkey->keymgmt; - int selection = OSSL_KEYMGMT_SELECT_ALL; - - if (!ossl_assert(pkey != NULL && propquery != NULL)) { - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if (keymgmt != NULL) { - const OSSL_PROVIDER *desired_prov = EVP_KEYMGMT_provider(keymgmt); - OPENSSL_CTX *libctx = ossl_provider_library_context(desired_prov); - struct selected_serializer_st sel_data; - OSSL_SERIALIZER *first = NULL; - const char *name; - int i; - - /* - * Select the serializer in two steps. First, get the names of all of - * the serializers. Then determine which is the best one to use. - * This has to be broken because it isn't possible to fetch the - * serialisers inside EVP_KEYMGMT_names_do_all() due to locking - * order inversions with the store lock. - */ - sel_data.error = 0; - sel_data.names = sk_OPENSSL_CSTRING_new_null(); - if (sel_data.names == NULL) - return NULL; - EVP_KEYMGMT_names_do_all(keymgmt, cache_serializers, &sel_data); - /* - * Ignore memory allocation errors that are indicated in sel_data.error - * in case a suitable provider does get found regardless. - */ - - /* - * Serializers offer two functions, one that handles object data in - * the form of a OSSL_PARAM array, and one that directly handles a - * provider side object. The latter requires that the serializer - * is offered by the same provider that holds that object, but is - * more desirable because it usually provides faster serialization. - * - * When looking up possible serializers, we save the first that can - * handle an OSSL_PARAM array in |first| and use that if nothing - * better turns up. - */ - for (i = 0; i < sk_OPENSSL_CSTRING_num(sel_data.names); i++) { - name = sk_OPENSSL_CSTRING_value(sel_data.names, i); - ser = OSSL_SERIALIZER_fetch(libctx, name, propquery); - if (ser != NULL) { - if (OSSL_SERIALIZER_provider(ser) == desired_prov - && ser->serialize_object != NULL) { - OSSL_SERIALIZER_free(first); - break; - } - if (first == NULL && ser->serialize_data != NULL) - first = ser; - else - OSSL_SERIALIZER_free(ser); - ser = NULL; - } - } - sk_OPENSSL_CSTRING_free(sel_data.names); - if (ser == NULL) - ser = first; - - if (ser != NULL) { - OSSL_PROPERTY_LIST *check = NULL, *current_props = NULL; - - check = ossl_parse_query(libctx, "type=parameters"); - current_props = - ossl_parse_property(libctx, OSSL_SERIALIZER_properties(ser)); - if (ossl_property_match_count(check, current_props) > 0) - selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS; - ossl_property_free(current_props); - ossl_property_free(check); - } else { - if (sel_data.error) - ERR_raise(ERR_LIB_OSSL_SERIALIZER, ERR_R_MALLOC_FAILURE); - else - ERR_raise(ERR_LIB_OSSL_SERIALIZER, - OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND); - } - } - - ctx = OSSL_SERIALIZER_CTX_new(ser); /* refcnt(ser)++ */ - OSSL_SERIALIZER_free(ser); /* refcnt(ser)-- */ - - if (ctx != NULL) { - /* Setup for OSSL_SERIALIZE_to_bio() */ - ctx->selection = selection; - ctx->object = pkey; - ctx->do_output = serializer_EVP_PKEY_to_bio; - } - - return ctx; -} - diff --git a/crypto/sha/asm/sha1-586.pl b/crypto/sha/asm/sha1-586.pl index 8a33fd53ea..00350324a1 100644 --- a/crypto/sha/asm/sha1-586.pl +++ b/crypto/sha/asm/sha1-586.pl @@ -143,7 +143,7 @@ `ml 2>&1` =~ /Version ([0-9]+)\./ && $1>=10); # first version supporting AVX -$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ && +$ymm=1 if ($xmm && !$ymm && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/ && $2>=3.0); # first version supporting AVX $shaext=$xmm; ### set to zero if compiling for 1.0.1 diff --git a/crypto/sha/asm/sha1-mb-x86_64.pl b/crypto/sha/asm/sha1-mb-x86_64.pl index 16f6ddbd2a..67faba136d 100644 --- a/crypto/sha/asm/sha1-mb-x86_64.pl +++ b/crypto/sha/asm/sha1-mb-x86_64.pl @@ -72,7 +72,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl index 674b288f66..c66b8fca87 100755 --- a/crypto/sha/asm/sha1-x86_64.pl +++ b/crypto/sha/asm/sha1-x86_64.pl @@ -120,7 +120,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha256-586.pl b/crypto/sha/asm/sha256-586.pl index d3c0c44d3f..8e19cd875e 100644 --- a/crypto/sha/asm/sha256-586.pl +++ b/crypto/sha/asm/sha256-586.pl @@ -95,7 +95,7 @@ $avx = ($1>=10) + ($1>=11); } -if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) { +if ($xmm && !$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha256-mb-x86_64.pl b/crypto/sha/asm/sha256-mb-x86_64.pl index 681f505763..fa2ca86046 100644 --- a/crypto/sha/asm/sha256-mb-x86_64.pl +++ b/crypto/sha/asm/sha256-mb-x86_64.pl @@ -73,7 +73,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/sha/asm/sha512-x86_64.pl b/crypto/sha/asm/sha512-x86_64.pl index ec75abdd72..1bd0256954 100755 --- a/crypto/sha/asm/sha512-x86_64.pl +++ b/crypto/sha/asm/sha512-x86_64.pl @@ -136,7 +136,7 @@ $avx = ($1>=10) + ($1>=11); } -if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { +if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { $avx = ($2>=3.0) + ($2>3.0); } diff --git a/crypto/siphash/build.info b/crypto/siphash/build.info index 2dc7101a10..432b6f5ec3 100644 --- a/crypto/siphash/build.info +++ b/crypto/siphash/build.info @@ -1,4 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - siphash.c \ - siphash_ameth.c + siphash.c diff --git a/crypto/siphash/siphash_ameth.c b/crypto/siphash/siphash_ameth.c deleted file mode 100644 index 5aa4d88915..0000000000 --- a/crypto/siphash/siphash_ameth.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2007-2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/cryptlib.h" -#include -#include "crypto/asn1.h" -#include "crypto/siphash.h" -#include "siphash_local.h" -#include "crypto/evp.h" - -/* - * SIPHASH "ASN1" method. This is just here to indicate the maximum - * SIPHASH output length and to free up a SIPHASH key. - */ - -static int siphash_size(const EVP_PKEY *pkey) -{ - return SIPHASH_MAX_DIGEST_SIZE; -} - -static void siphash_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey); - - if (os != NULL) { - if (os->data != NULL) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int siphash_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - /* nothing (including ASN1_PKEY_CTRL_DEFAULT_MD_NID), is supported */ - return -2; -} - -static int siphash_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b)); -} - -static int siphash_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, - size_t len) -{ - ASN1_OCTET_STRING *os; - - if (pkey->pkey.ptr != NULL || len != SIPHASH_KEY_SIZE) - return 0; - - os = ASN1_OCTET_STRING_new(); - if (os == NULL) - return 0; - - if (!ASN1_OCTET_STRING_set(os, priv, len)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - - pkey->pkey.ptr = os; - return 1; -} - -static int siphash_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, - size_t *len) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - - if (priv == NULL) { - *len = SIPHASH_KEY_SIZE; - return 1; - } - - if (os == NULL || *len < SIPHASH_KEY_SIZE) - return 0; - - memcpy(priv, ASN1_STRING_get0_data(os), ASN1_STRING_length(os)); - *len = SIPHASH_KEY_SIZE; - - return 1; -} - -const EVP_PKEY_ASN1_METHOD siphash_asn1_meth = { - EVP_PKEY_SIPHASH, - EVP_PKEY_SIPHASH, - 0, - - "SIPHASH", - "OpenSSL SIPHASH method", - - 0, 0, siphash_pkey_public_cmp, 0, - - 0, 0, 0, - - siphash_size, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - - siphash_key_free, - siphash_pkey_ctrl, - NULL, - NULL, - - NULL, - NULL, - NULL, - - NULL, - NULL, - NULL, - - siphash_set_priv_key, - NULL, - siphash_get_priv_key, - NULL, -}; diff --git a/crypto/sm2/build.info b/crypto/sm2/build.info index be76d96d31..402a76cc5d 100644 --- a/crypto/sm2/build.info +++ b/crypto/sm2/build.info @@ -1,5 +1,5 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - sm2_sign.c sm2_crypt.c sm2_err.c sm2_pmeth.c + sm2_sign.c sm2_crypt.c sm2_err.c diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index c09e4c001b..6db87f6845 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -138,6 +138,9 @@ int sm2_encrypt(const EC_KEY *key, uint8_t *C3 = NULL; size_t field_size; const int C3_size = EVP_MD_size(digest); + EVP_MD *fetched_digest = NULL; + OSSL_LIB_CTX *libctx = ec_key_get_libctx(key); + const char *propq = ec_key_get0_propq(key); /* NULL these before any "goto done" */ ctext_struct.C2 = NULL; @@ -156,7 +159,7 @@ int sm2_encrypt(const EC_KEY *key, kG = EC_POINT_new(group); kP = EC_POINT_new(group); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (kG == NULL || kP == NULL || ctx == NULL) { SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE); goto done; @@ -211,7 +214,7 @@ int sm2_encrypt(const EC_KEY *key, /* X9.63 with no salt happens to match the KDF used in SM2 */ if (!ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, - digest)) { + digest, libctx, propq)) { SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB); goto done; } @@ -219,7 +222,12 @@ int sm2_encrypt(const EC_KEY *key, for (i = 0; i != msg_len; ++i) msg_mask[i] ^= msg[i]; - if (EVP_DigestInit(hash, digest) == 0 + fetched_digest = EVP_MD_fetch(libctx, EVP_MD_name(digest), propq); + if (fetched_digest == NULL) { + SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto done; + } + if (EVP_DigestInit(hash, fetched_digest) == 0 || EVP_DigestUpdate(hash, x2y2, field_size) == 0 || EVP_DigestUpdate(hash, msg, msg_len) == 0 || EVP_DigestUpdate(hash, x2y2 + field_size, field_size) == 0 @@ -254,6 +262,7 @@ int sm2_encrypt(const EC_KEY *key, rc = 1; done: + EVP_MD_free(fetched_digest); ASN1_OCTET_STRING_free(ctext_struct.C2); ASN1_OCTET_STRING_free(ctext_struct.C3); OPENSSL_free(msg_mask); @@ -288,6 +297,8 @@ int sm2_decrypt(const EC_KEY *key, const uint8_t *C3 = NULL; int msg_len = 0; EVP_MD_CTX *hash = NULL; + OSSL_LIB_CTX *libctx = ec_key_get_libctx(key); + const char *propq = ec_key_get0_propq(key); if (field_size == 0 || hash_size <= 0) goto done; @@ -310,7 +321,7 @@ int sm2_decrypt(const EC_KEY *key, C3 = sm2_ctext->C3->data; msg_len = sm2_ctext->C2->length; - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (ctx == NULL) { SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE); goto done; @@ -352,7 +363,7 @@ int sm2_decrypt(const EC_KEY *key, if (BN_bn2binpad(x2, x2y2, field_size) < 0 || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0 || !ecdh_KDF_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, - digest)) { + digest, libctx, propq)) { SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR); goto done; } diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c index 93ee9f7d7a..387b2f4cff 100644 --- a/crypto/sm2/sm2_err.c +++ b/crypto/sm2/sm2_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c deleted file mode 100644 index 45297f9bc6..0000000000 --- a/crypto/sm2/sm2_pmeth.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * ECDSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include "internal/cryptlib.h" -#include -#include -#include -#include "crypto/evp.h" -#include "crypto/sm2.h" -#include "crypto/sm2err.h" - -/* EC pkey context structure */ - -typedef struct { - /* message digest */ - const EVP_MD *md; - /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */ - uint8_t *id; - size_t id_len; - /* id_set indicates if the 'id' field is set (1) or not (0) */ - int id_set; -} SM2_PKEY_CTX; - -static int pkey_sm2_init(EVP_PKEY_CTX *ctx) -{ - SM2_PKEY_CTX *smctx; - - if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) { - SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - ctx->data = smctx; - return 1; -} - -static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx) -{ - SM2_PKEY_CTX *smctx = ctx->data; - - if (smctx != NULL) { - OPENSSL_free(smctx->id); - OPENSSL_free(smctx); - ctx->data = NULL; - } -} - -static int pkey_sm2_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) -{ - SM2_PKEY_CTX *dctx, *sctx; - - if (!pkey_sm2_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - if (sctx->id != NULL) { - dctx->id = OPENSSL_malloc(sctx->id_len); - if (dctx->id == NULL) { - SM2err(SM2_F_PKEY_SM2_COPY, ERR_R_MALLOC_FAILURE); - pkey_sm2_cleanup(dst); - return 0; - } - memcpy(dctx->id, sctx->id, sctx->id_len); - } - dctx->id_len = sctx->id_len; - dctx->id_set = sctx->id_set; - dctx->md = sctx->md; - - return 1; -} - -static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret; - unsigned int sltmp; - EC_KEY *ec = ctx->pkey->pkey.ec; - const int sig_sz = ECDSA_size(ctx->pkey->pkey.ec); - - if (sig_sz <= 0) { - return 0; - } - - if (sig == NULL) { - *siglen = (size_t)sig_sz; - return 1; - } - - if (*siglen < (size_t)sig_sz) { - SM2err(SM2_F_PKEY_SM2_SIGN, SM2_R_BUFFER_TOO_SMALL); - return 0; - } - - ret = sm2_sign(tbs, tbslen, sig, &sltmp, ec); - - if (ret <= 0) - return ret; - *siglen = (size_t)sltmp; - return 1; -} - -static int pkey_sm2_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - EC_KEY *ec = ctx->pkey->pkey.ec; - - return sm2_verify(tbs, tbslen, sig, siglen, ec); -} - -static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - EC_KEY *ec = ctx->pkey->pkey.ec; - SM2_PKEY_CTX *dctx = ctx->data; - const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md; - - if (out == NULL) { - if (!sm2_ciphertext_size(ec, md, inlen, outlen)) - return -1; - else - return 1; - } - - return sm2_encrypt(ec, md, in, inlen, out, outlen); -} - -static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - EC_KEY *ec = ctx->pkey->pkey.ec; - SM2_PKEY_CTX *dctx = ctx->data; - const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md; - - if (out == NULL) { - if (!sm2_plaintext_size(ec, md, inlen, outlen)) - return -1; - else - return 1; - } - - return sm2_decrypt(ec, md, in, inlen, out, outlen); -} - -static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - SM2_PKEY_CTX *smctx = ctx->data; - uint8_t *tmp_id; - - switch (type) { - case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: - /* - * This control could be removed, which would signal it being - * unsupported. However, that means that when the caller uses - * the correct curve, it may interpret the unsupported signal - * as an error, so it's better to accept the control, check the - * value and return a corresponding value. - */ - if (p1 != NID_sm2) { - SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE); - return 0; - } - return 1; - - case EVP_PKEY_CTRL_MD: - smctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = smctx->md; - return 1; - - case EVP_PKEY_CTRL_SET1_ID: - if (p1 > 0) { - tmp_id = OPENSSL_malloc(p1); - if (tmp_id == NULL) { - SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE); - return 0; - } - memcpy(tmp_id, p2, p1); - OPENSSL_free(smctx->id); - smctx->id = tmp_id; - } else { - /* set null-ID */ - OPENSSL_free(smctx->id); - smctx->id = NULL; - } - smctx->id_len = (size_t)p1; - smctx->id_set = 1; - return 1; - - case EVP_PKEY_CTRL_GET1_ID: - memcpy(p2, smctx->id, smctx->id_len); - return 1; - - case EVP_PKEY_CTRL_GET1_ID_LEN: - *(size_t *)p2 = smctx->id_len; - return 1; - - case EVP_PKEY_CTRL_DIGESTINIT: - /* nothing to be inited, this is to suppress the error... */ - return 1; - - default: - return -2; - } -} - -static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - uint8_t *hex_id; - long hex_len = 0; - int ret = 0; - - if (strcmp(type, "ec_paramgen_curve") == 0) { - int nid = NID_undef; - - if (((nid = EC_curve_nist2nid(value)) == NID_undef) - && ((nid = OBJ_sn2nid(value)) == NID_undef) - && ((nid = OBJ_ln2nid(value)) == NID_undef)) { - SM2err(SM2_F_PKEY_SM2_CTRL_STR, SM2_R_INVALID_CURVE); - return 0; - } - return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); - } else if (strcmp(type, "ec_param_enc") == 0) { - int param_enc; - - if (strcmp(value, "explicit") == 0) - param_enc = 0; - else if (strcmp(value, "named_curve") == 0) - param_enc = OPENSSL_EC_NAMED_CURVE; - else - return -2; - return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); - } else if (strcmp(type, "distid") == 0) { - return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, - (int)strlen(value), (void *)value); - } else if (strcmp(type, "hexdistid") == 0) { - hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len); - if (hex_id == NULL) { - SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT); - return 0; - } - ret = pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)hex_len, - (void *)hex_id); - OPENSSL_free(hex_id); - return ret; - } - - return -2; -} - -static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - uint8_t z[EVP_MAX_MD_SIZE]; - SM2_PKEY_CTX *smctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; - const EVP_MD *md = EVP_MD_CTX_md(mctx); - int mdlen = EVP_MD_size(md); - - if (!smctx->id_set) { - /* - * An ID value must be set. The specifications are not clear whether a - * NULL is allowed. We only allow it if set explicitly for maximum - * flexibility. - */ - SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET); - return 0; - } - - if (mdlen < 0) { - SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_INVALID_DIGEST); - return 0; - } - - /* get hashed prefix 'z' of tbs message */ - if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec)) - return 0; - - return EVP_DigestUpdate(mctx, z, (size_t)mdlen); -} - -static int pkey_sm2_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - EC_KEY *ec = NULL; - int ret; - - ec = EC_KEY_new_by_curve_name(NID_sm2); - if (ec == NULL) - return 0; - if (!ossl_assert(ret = EVP_PKEY_assign_EC_KEY(pkey, ec))) - EC_KEY_free(ec); - return ret; -} - -static int pkey_sm2_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - EC_KEY *ec = NULL; - - ec = EC_KEY_new_by_curve_name(NID_sm2); - if (ec == NULL) - return 0; - if (!ossl_assert(EVP_PKEY_assign_EC_KEY(pkey, ec))) { - EC_KEY_free(ec); - return 0; - } - /* Note: if error is returned, we count on caller to free pkey->pkey.ec */ - if (ctx->pkey != NULL - && !EVP_PKEY_copy_parameters(pkey, ctx->pkey)) - return 0; - - return EC_KEY_generate_key(ec); -} - -static const EVP_PKEY_METHOD sm2_pkey_meth = { - EVP_PKEY_SM2, - 0, - pkey_sm2_init, - pkey_sm2_copy, - pkey_sm2_cleanup, - - 0, - pkey_sm2_paramgen, - - 0, - pkey_sm2_keygen, - - 0, - pkey_sm2_sign, - - 0, - pkey_sm2_verify, - - 0, 0, - - 0, 0, 0, 0, - - 0, - pkey_sm2_encrypt, - - 0, - pkey_sm2_decrypt, - - 0, - 0, - pkey_sm2_ctrl, - pkey_sm2_ctrl_str, - - 0, 0, - - 0, 0, 0, - - pkey_sm2_digest_custom -}; - -const EVP_PKEY_METHOD *sm2_pkey_method(void) -{ - return &sm2_pkey_meth; -} diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c index 318e981802..d180a5ace7 100644 --- a/crypto/sm2/sm2_sign.c +++ b/crypto/sm2/sm2_sign.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * @@ -42,7 +42,7 @@ int sm2_compute_z_digest(uint8_t *out, uint8_t e_byte = 0; hash = EVP_MD_CTX_new(); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(ec_key_get_libctx(key)); if (hash == NULL || ctx == NULL) { SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE); goto done; @@ -146,6 +146,9 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, const int md_size = EVP_MD_size(digest); uint8_t *z = NULL; BIGNUM *e = NULL; + EVP_MD *fetched_digest = NULL; + OSSL_LIB_CTX *libctx = ec_key_get_libctx(key); + const char *propq = ec_key_get0_propq(key); if (md_size < 0) { SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST); @@ -158,12 +161,18 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, goto done; } - if (!sm2_compute_z_digest(z, digest, id, id_len, key)) { + fetched_digest = EVP_MD_fetch(libctx, EVP_MD_name(digest), propq); + if (fetched_digest == NULL) { + SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR); + goto done; + } + + if (!sm2_compute_z_digest(z, fetched_digest, id, id_len, key)) { /* SM2err already called */ goto done; } - if (!EVP_DigestInit(hash, digest) + if (!EVP_DigestInit(hash, fetched_digest) || !EVP_DigestUpdate(hash, z, md_size) || !EVP_DigestUpdate(hash, msg, msg_len) /* reuse z buffer to hold H(Z || M) */ @@ -177,6 +186,7 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest, SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR); done: + EVP_MD_free(fetched_digest); OPENSSL_free(z); EVP_MD_CTX_free(hash); return e; @@ -196,9 +206,10 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) BIGNUM *s = NULL; BIGNUM *x1 = NULL; BIGNUM *tmp = NULL; + OSSL_LIB_CTX *libctx = ec_key_get_libctx(key); kG = EC_POINT_new(group); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); if (kG == NULL || ctx == NULL) { SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE); goto done; @@ -227,7 +238,7 @@ static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e) } for (;;) { - if (!BN_priv_rand_range(k, order)) { + if (!BN_priv_rand_range_ex(k, order, ctx)) { SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR); goto done; } @@ -295,8 +306,9 @@ static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, BIGNUM *x1 = NULL; const BIGNUM *r = NULL; const BIGNUM *s = NULL; + OSSL_LIB_CTX *libctx = ec_key_get_libctx(key); - ctx = BN_CTX_new(); + ctx = BN_CTX_new_ex(libctx); pt = EC_POINT_new(group); if (ctx == NULL || pt == NULL) { SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE); @@ -406,8 +418,8 @@ int sm2_do_verify(const EC_KEY *key, return ret; } -int sm2_sign(const unsigned char *dgst, int dgstlen, - unsigned char *sig, unsigned int *siglen, EC_KEY *eckey) +int sm2_internal_sign(const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey) { BIGNUM *e = NULL; ECDSA_SIG *s = NULL; @@ -416,15 +428,19 @@ int sm2_sign(const unsigned char *dgst, int dgstlen, e = BN_bin2bn(dgst, dgstlen, NULL); if (e == NULL) { - SM2err(SM2_F_SM2_SIGN, ERR_R_BN_LIB); + SM2err(0, ERR_R_BN_LIB); goto done; } s = sm2_sig_gen(eckey, e); + if (s == NULL) { + SM2err(0, ERR_R_INTERNAL_ERROR); + goto done; + } sigleni = i2d_ECDSA_SIG(s, &sig); if (sigleni < 0) { - SM2err(SM2_F_SM2_SIGN, ERR_R_INTERNAL_ERROR); + SM2err(0, ERR_R_INTERNAL_ERROR); goto done; } *siglen = (unsigned int)sigleni; @@ -437,8 +453,8 @@ int sm2_sign(const unsigned char *dgst, int dgstlen, return ret; } -int sm2_verify(const unsigned char *dgst, int dgstlen, - const unsigned char *sig, int sig_len, EC_KEY *eckey) +int sm2_internal_verify(const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int sig_len, EC_KEY *eckey) { ECDSA_SIG *s = NULL; BIGNUM *e = NULL; @@ -449,23 +465,23 @@ int sm2_verify(const unsigned char *dgst, int dgstlen, s = ECDSA_SIG_new(); if (s == NULL) { - SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE); + SM2err(0, ERR_R_MALLOC_FAILURE); goto done; } if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) { - SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING); + SM2err(0, SM2_R_INVALID_ENCODING); goto done; } /* Ensure signature uses DER and doesn't have trailing garbage */ derlen = i2d_ECDSA_SIG(s, &der); if (derlen != sig_len || memcmp(sig, der, derlen) != 0) { - SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING); + SM2err(0, SM2_R_INVALID_ENCODING); goto done; } e = BN_bin2bn(dgst, dgstlen, NULL); if (e == NULL) { - SM2err(SM2_F_SM2_VERIFY, ERR_R_BN_LIB); + SM2err(0, ERR_R_BN_LIB); goto done; } diff --git a/crypto/sparse_array.c b/crypto/sparse_array.c index 9d444739f5..be4db2c620 100644 --- a/crypto/sparse_array.c +++ b/crypto/sparse_array.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -162,7 +162,7 @@ void *OPENSSL_SA_get(const OPENSSL_SA *sa, ossl_uintmax_t n) int level; void **p, *r = NULL; - if (sa == NULL) + if (sa == NULL || sa->nelem == 0) return NULL; if (n <= sa->top) { diff --git a/crypto/srp/srp_lib.c b/crypto/srp/srp_lib.c index 253aaf9a57..092cc159aa 100644 --- a/crypto/srp/srp_lib.c +++ b/crypto/srp/srp_lib.c @@ -21,7 +21,7 @@ /* calculate = SHA1(PAD(x) || PAD(y)) */ static BIGNUM *srp_Calc_xy(const BIGNUM *x, const BIGNUM *y, const BIGNUM *N, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char digest[SHA_DIGEST_LENGTH]; unsigned char *tmp = NULL; @@ -49,7 +49,8 @@ static BIGNUM *srp_Calc_xy(const BIGNUM *x, const BIGNUM *y, const BIGNUM *N, return res; } -static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g, OPENSSL_CTX *libctx, +static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g, + OSSL_LIB_CTX *libctx, const char *propq) { /* k = SHA1(N | PAD(g)) -- tls-srp RFC 5054 */ @@ -57,7 +58,7 @@ static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g, OPENSSL_CTX *libctx, } BIGNUM *SRP_Calc_u_ex(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { /* u = SHA1(PAD(A) || PAD(B) ) -- tls-srp RFC 5054 */ return srp_Calc_xy(A, B, N, libctx, propq); @@ -100,7 +101,7 @@ BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, } BIGNUM *SRP_Calc_B_ex(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, - const BIGNUM *v, OPENSSL_CTX *libctx, const char *propq) + const BIGNUM *v, OSSL_LIB_CTX *libctx, const char *propq) { BIGNUM *kv = NULL, *gb = NULL; BIGNUM *B = NULL, *k = NULL; @@ -138,7 +139,7 @@ BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, } BIGNUM *SRP_Calc_x_ex(const BIGNUM *s, const char *user, const char *pass, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char dig[SHA_DIGEST_LENGTH]; EVP_MD_CTX *ctxt; @@ -207,7 +208,7 @@ BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g) BIGNUM *SRP_Calc_client_key_ex(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, const BIGNUM *x, const BIGNUM *a, const BIGNUM *u, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL; BN_CTX *bn_ctx; diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c index f0ed6da6f6..b166e5fb8b 100644 --- a/crypto/srp/srp_vfy.c +++ b/crypto/srp/srp_vfy.c @@ -25,10 +25,6 @@ # define SRP_RANDOM_SALT_LEN 20 # define MAX_LEN 2500 -DEFINE_STACK_OF(SRP_user_pwd) -DEFINE_STACK_OF(SRP_gN_cache) -DEFINE_STACK_OF(SRP_gN) - /* * Note that SRP uses its own variant of base 64 encoding. A different base64 * alphabet is used and no padding '=' characters are added. Instead we pad to @@ -600,7 +596,7 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) */ char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt, char **verifier, const char *N, const char *g, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { int len; char *result = NULL, *vf = NULL; @@ -706,7 +702,7 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt, */ int SRP_create_verifier_BN_ex(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, const BIGNUM *N, - const BIGNUM *g, OPENSSL_CTX *libctx, + const BIGNUM *g, OSSL_LIB_CTX *libctx, const char *propq) { int result = 0; diff --git a/crypto/store/build.info b/crypto/store/build.info index 7d882f313e..43d9e544a0 100644 --- a/crypto/store/build.info +++ b/crypto/store/build.info @@ -1,4 +1,7 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - store_err.c store_init.c store_lib.c store_register.c store_strings.c \ - loader_file.c + store_err.c store_lib.c store_result.c store_strings.c store_meth.c + +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../../libcrypto]=store_init.c store_register.c +ENDIF diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c deleted file mode 100644 index 5ff93e33ab..0000000000 --- a/crypto/store/loader_file.c +++ /dev/null @@ -1,1654 +0,0 @@ -/* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* We need to use some engine deprecated APIs */ -#define OPENSSL_SUPPRESS_DEPRECATED - -#include "e_os.h" -#include -#include -#include -#include - -#include -#include /* For d2i_DSAPrivateKey */ -#include -#include -#include -#include "internal/pem_int.h" -#include /* For the PKCS8 stuff o.O */ -#include /* For d2i_RSAPrivateKey */ -#include -#include -#include -#include /* For the PKCS8 stuff o.O */ -#include "crypto/asn1.h" -#include "crypto/ctype.h" -#include "internal/o_dir.h" -#include "internal/cryptlib.h" -#include "crypto/store.h" -#include "crypto/evp.h" -#include "store_local.h" - -DEFINE_STACK_OF(X509) - -#ifdef _WIN32 -# define stat _stat -#endif - -#ifndef S_ISDIR -# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) -#endif - -/*- - * Password prompting - * ------------------ - */ - -static char *file_get_pass(const UI_METHOD *ui_method, char *pass, - size_t maxsize, const char *desc, const char *info, - void *data) -{ - UI *ui = UI_new(); - char *prompt = NULL; - - if (ui == NULL) { - OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (ui_method != NULL) - UI_set_method(ui, ui_method); - UI_add_user_data(ui, data); - - if ((prompt = UI_construct_prompt(ui, desc, info)) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_MALLOC_FAILURE); - pass = NULL; - } else if (!UI_add_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD, - pass, 0, maxsize - 1)) { - OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_UI_LIB); - pass = NULL; - } else { - switch (UI_process(ui)) { - case -2: - OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, - OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED); - pass = NULL; - break; - case -1: - OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_UI_LIB); - pass = NULL; - break; - default: - break; - } - } - - OPENSSL_free(prompt); - UI_free(ui); - return pass; -} - -struct pem_pass_data { - const UI_METHOD *ui_method; - void *data; - const char *prompt_desc; - const char *prompt_info; -}; - -static int file_fill_pem_pass_data(struct pem_pass_data *pass_data, - const char *desc, const char *info, - const UI_METHOD *ui_method, void *ui_data) -{ - if (pass_data == NULL) - return 0; - pass_data->ui_method = ui_method; - pass_data->data = ui_data; - pass_data->prompt_desc = desc; - pass_data->prompt_info = info; - return 1; -} - -/* This is used anywhere a pem_password_cb is needed */ -static int file_get_pem_pass(char *buf, int num, int w, void *data) -{ - struct pem_pass_data *pass_data = data; - char *pass = file_get_pass(pass_data->ui_method, buf, num, - pass_data->prompt_desc, pass_data->prompt_info, - pass_data->data); - - return pass == NULL ? 0 : strlen(pass); -} - -/*- - * The file scheme decoders - * ------------------------ - * - * Each possible data type has its own decoder, which either operates - * through a given PEM name, or attempts to decode to see if the blob - * it's given is decodable for its data type. The assumption is that - * only the correct data type will match the content. - */ - -/*- - * The try_decode function is called to check if the blob of data can - * be used by this handler, and if it can, decodes it into a supported - * OpenSSL type and returns a OSSL_STORE_INFO with the decoded data. - * Input: - * pem_name: If this blob comes from a PEM file, this holds - * the PEM name. If it comes from another type of - * file, this is NULL. - * pem_header: If this blob comes from a PEM file, this holds - * the PEM headers. If it comes from another type of - * file, this is NULL. - * blob: The blob of data to match with what this handler - * can use. - * len: The length of the blob. - * handler_ctx: For a handler marked repeatable, this pointer can - * be used to create a context for the handler. IT IS - * THE HANDLER'S RESPONSIBILITY TO CREATE AND DESTROY - * THIS CONTEXT APPROPRIATELY, i.e. create on first call - * and destroy when about to return NULL. - * matchcount: A pointer to an int to count matches for this data. - * Usually becomes 0 (no match) or 1 (match!), but may - * be higher in the (unlikely) event that the data matches - * more than one possibility. The int will always be - * zero when the function is called. - * ui_method: Application UI method for getting a password, pin - * or any other interactive data. - * ui_data: Application data to be passed to ui_method when - * it's called. - * libctx: The library context to be used if applicable - * propq: The property query string for any algorithm fetches - * Output: - * a OSSL_STORE_INFO - */ -typedef OSSL_STORE_INFO *(*file_try_decode_fn)(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **handler_ctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OPENSSL_CTX *libctx, - const char *propq); -/* - * The eof function should return 1 if there's no more data to be found - * with the handler_ctx, otherwise 0. This is only used when the handler is - * marked repeatable. - */ -typedef int (*file_eof_fn)(void *handler_ctx); -/* - * The destroy_ctx function is used to destroy the handler_ctx that was - * initiated by a repeatable try_decode function. This is only used when - * the handler is marked repeatable. - */ -typedef void (*file_destroy_ctx_fn)(void **handler_ctx); - -typedef struct file_handler_st { - const char *name; - file_try_decode_fn try_decode; - file_eof_fn eof; - file_destroy_ctx_fn destroy_ctx; - - /* flags */ - int repeatable; -} FILE_HANDLER; - -/* - * PKCS#12 decoder. It operates by decoding all of the blob content, - * extracting all the interesting data from it and storing them internally, - * then serving them one piece at a time. - */ -static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - STACK_OF(OSSL_STORE_INFO) *ctx = *pctx; - - if (ctx == NULL) { - /* Initial parsing */ - PKCS12 *p12; - - if (pem_name != NULL) - /* No match, there is no PEM PKCS12 tag */ - return NULL; - - if ((p12 = d2i_PKCS12(NULL, &blob, len)) != NULL) { - char *pass = NULL; - char tpass[PEM_BUFSIZE]; - EVP_PKEY *pkey = NULL; - X509 *cert = NULL; - STACK_OF(X509) *chain = NULL; - - *matchcount = 1; - - if (PKCS12_verify_mac(p12, "", 0) - || PKCS12_verify_mac(p12, NULL, 0)) { - pass = ""; - } else { - if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE, - "PKCS12 import pass phrase", uri, - ui_data)) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12, - OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR); - goto p12_end; - } - if (!PKCS12_verify_mac(p12, pass, strlen(pass))) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12, - OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC); - goto p12_end; - } - } - - if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) { - OSSL_STORE_INFO *osi_pkey = NULL; - OSSL_STORE_INFO *osi_cert = NULL; - OSSL_STORE_INFO *osi_ca = NULL; - int ok = 1; - - if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL) { - if (pkey != NULL) { - if ((osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL - /* clearing pkey here avoids case distinctions */ - && (pkey = NULL) == NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0) - osi_pkey = NULL; - else - ok = 0; - } - if (ok && cert != NULL) { - if ((osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL - /* clearing cert here avoids case distinctions */ - && (cert = NULL) == NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0) - osi_cert = NULL; - else - ok = 0; - } - while (ok && sk_X509_num(chain) > 0) { - X509 *ca = sk_X509_value(chain, 0); - - if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) != NULL - && sk_X509_shift(chain) != NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_ca) != 0) - osi_ca = NULL; - else - ok = 0; - } - } - EVP_PKEY_free(pkey); - X509_free(cert); - sk_X509_pop_free(chain, X509_free); - OSSL_STORE_INFO_free(osi_pkey); - OSSL_STORE_INFO_free(osi_cert); - OSSL_STORE_INFO_free(osi_ca); - if (!ok) { - sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free); - ctx = NULL; - } - *pctx = ctx; - } - } - p12_end: - PKCS12_free(p12); - if (ctx == NULL) - return NULL; - } - - *matchcount = 1; - store_info = sk_OSSL_STORE_INFO_shift(ctx); - return store_info; -} - -static int eof_PKCS12(void *ctx_) -{ - STACK_OF(OSSL_STORE_INFO) *ctx = ctx_; - - return ctx == NULL || sk_OSSL_STORE_INFO_num(ctx) == 0; -} - -static void destroy_ctx_PKCS12(void **pctx) -{ - STACK_OF(OSSL_STORE_INFO) *ctx = *pctx; - - sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free); - *pctx = NULL; -} - -static FILE_HANDLER PKCS12_handler = { - "PKCS12", - try_decode_PKCS12, - eof_PKCS12, - destroy_ctx_PKCS12, - 1 /* repeatable */ -}; - -/* - * Encrypted PKCS#8 decoder. It operates by just decrypting the given blob - * into a new blob, which is returned as an EMBEDDED STORE_INFO. The whole - * decoding process will then start over with the new blob. - */ -static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, - const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - X509_SIG *p8 = NULL; - char kbuf[PEM_BUFSIZE]; - char *pass = NULL; - const X509_ALGOR *dalg = NULL; - const ASN1_OCTET_STRING *doct = NULL; - OSSL_STORE_INFO *store_info = NULL; - BUF_MEM *mem = NULL; - unsigned char *new_data = NULL; - int new_data_len; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_PKCS8) != 0) - return NULL; - *matchcount = 1; - } - - if ((p8 = d2i_X509_SIG(NULL, &blob, len)) == NULL) - return NULL; - - *matchcount = 1; - - if ((mem = BUF_MEM_new()) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, - ERR_R_MALLOC_FAILURE); - goto nop8; - } - - if ((pass = file_get_pass(ui_method, kbuf, PEM_BUFSIZE, - "PKCS8 decrypt pass phrase", uri, - ui_data)) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, - OSSL_STORE_R_BAD_PASSWORD_READ); - goto nop8; - } - - X509_SIG_get0(p8, &dalg, &doct); - if (!PKCS12_pbe_crypt(dalg, pass, strlen(pass), doct->data, doct->length, - &new_data, &new_data_len, 0)) - goto nop8; - - mem->data = (char *)new_data; - mem->max = mem->length = (size_t)new_data_len; - X509_SIG_free(p8); - - store_info = ossl_store_info_new_EMBEDDED(PEM_STRING_PKCS8INF, mem); - if (store_info == NULL) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED, - ERR_R_MALLOC_FAILURE); - goto nop8; - } - - return store_info; - nop8: - X509_SIG_free(p8); - BUF_MEM_free(mem); - return NULL; -} - -static FILE_HANDLER PKCS8Encrypted_handler = { - "PKCS8Encrypted", - try_decode_PKCS8Encrypted -}; - -/* - * Private key decoder. Decodes all sorts of private keys, both PKCS#8 - * encoded ones and old style PEM ones (with the key type is encoded into - * the PEM name). - */ -int pem_check_suffix(const char *pem_str, const char *suffix); -static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - EVP_PKEY *pkey = NULL; - const EVP_PKEY_ASN1_METHOD *ameth = NULL; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf = - d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len); - - *matchcount = 1; - if (p8inf != NULL) - pkey = evp_pkcs82pkey_int(p8inf, libctx, propq); - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else { - int slen; - - if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0 - && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, - slen)) != NULL) { - *matchcount = 1; - pkey = d2i_PrivateKey_ex(ameth->pkey_id, NULL, &blob, len, - libctx, propq); - } - } - } else { - int i; -#ifndef OPENSSL_NO_ENGINE - ENGINE *curengine = ENGINE_get_first(); - - while (curengine != NULL) { - ENGINE_PKEY_ASN1_METHS_PTR asn1meths = - ENGINE_get_pkey_asn1_meths(curengine); - - if (asn1meths != NULL) { - const int *nids = NULL; - int nids_n = asn1meths(curengine, NULL, &nids, 0); - - for (i = 0; i < nids_n; i++) { - EVP_PKEY_ASN1_METHOD *ameth2 = NULL; - EVP_PKEY *tmp_pkey = NULL; - const unsigned char *tmp_blob = blob; - - if (!asn1meths(curengine, &ameth2, NULL, nids[i])) - continue; - if (ameth2 == NULL - || ameth2->pkey_flags & ASN1_PKEY_ALIAS) - continue; - - tmp_pkey = - d2i_PrivateKey_ex(ameth2->pkey_id, NULL, - &tmp_blob, len, libctx, propq); - if (tmp_pkey != NULL) { - if (pkey != NULL) - EVP_PKEY_free(tmp_pkey); - else - pkey = tmp_pkey; - (*matchcount)++; - } - } - } - curengine = ENGINE_get_next(curengine); - } -#endif - - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - EVP_PKEY *tmp_pkey = NULL; - const unsigned char *tmp_blob = blob; - - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_flags & ASN1_PKEY_ALIAS) - continue; - - tmp_pkey = d2i_PrivateKey_ex(ameth->pkey_id, NULL, &tmp_blob, len, - libctx, propq); - if (tmp_pkey != NULL) { - if (pkey != NULL) - EVP_PKEY_free(tmp_pkey); - else - pkey = tmp_pkey; - (*matchcount)++; - } - } - - if (*matchcount > 1) { - EVP_PKEY_free(pkey); - pkey = NULL; - } - } - if (pkey == NULL) - /* No match */ - return NULL; - - store_info = OSSL_STORE_INFO_new_PKEY(pkey); - if (store_info == NULL) - EVP_PKEY_free(pkey); - - return store_info; -} - -static FILE_HANDLER PrivateKey_handler = { - "PrivateKey", - try_decode_PrivateKey -}; - -/* - * Public key decoder. Only supports SubjectPublicKeyInfo formatted keys. - */ -static OSSL_STORE_INFO *try_decode_PUBKEY(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - EVP_PKEY *pkey = NULL; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_PUBLIC) != 0) - /* No match */ - return NULL; - *matchcount = 1; - } - - if ((pkey = d2i_PUBKEY(NULL, &blob, len)) != NULL) { - *matchcount = 1; - store_info = OSSL_STORE_INFO_new_PKEY(pkey); - } - - return store_info; -} - -static FILE_HANDLER PUBKEY_handler = { - "PUBKEY", - try_decode_PUBKEY -}; - -/* - * Key parameter decoder. - */ -static OSSL_STORE_INFO *try_decode_params(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - int slen = 0; - EVP_PKEY *pkey = NULL; - const EVP_PKEY_ASN1_METHOD *ameth = NULL; - int ok = 0; - - if (pem_name != NULL) { - if ((slen = pem_check_suffix(pem_name, "PARAMETERS")) == 0) - return NULL; - *matchcount = 1; - } - - if (slen > 0) { - if ((pkey = EVP_PKEY_new()) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB); - return NULL; - } - - - if (EVP_PKEY_set_type_str(pkey, pem_name, slen) - && (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL - && ameth->param_decode != NULL - && ameth->param_decode(pkey, &blob, len)) - ok = 1; - } else { - int i; - EVP_PKEY *tmp_pkey = NULL; - - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - const unsigned char *tmp_blob = blob; - - if (tmp_pkey == NULL && (tmp_pkey = EVP_PKEY_new()) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB); - break; - } - - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_flags & ASN1_PKEY_ALIAS) - continue; - - if (EVP_PKEY_set_type(tmp_pkey, ameth->pkey_id) - && (ameth = EVP_PKEY_get0_asn1(tmp_pkey)) != NULL - && ameth->param_decode != NULL - && ameth->param_decode(tmp_pkey, &tmp_blob, len)) { - if (pkey != NULL) - EVP_PKEY_free(tmp_pkey); - else - pkey = tmp_pkey; - tmp_pkey = NULL; - (*matchcount)++; - } - } - - EVP_PKEY_free(tmp_pkey); - if (*matchcount == 1) { - ok = 1; - } - } - - if (ok) - store_info = OSSL_STORE_INFO_new_PARAMS(pkey); - if (store_info == NULL) - EVP_PKEY_free(pkey); - - return store_info; -} - -static FILE_HANDLER params_handler = { - "params", - try_decode_params -}; - -/* - * X.509 certificate decoder. - */ -static OSSL_STORE_INFO *try_decode_X509Certificate(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, - const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - X509 *cert = NULL; - - /* - * In most cases, we can try to interpret the serialized data as a trusted - * cert (X509 + X509_AUX) and fall back to reading it as a normal cert - * (just X509), but if the PEM name specifically declares it as a trusted - * cert, then no fallback should be engaged. |ignore_trusted| tells if - * the fallback can be used (1) or not (0). - */ - int ignore_trusted = 1; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_X509_TRUSTED) == 0) - ignore_trusted = 0; - else if (strcmp(pem_name, PEM_STRING_X509_OLD) != 0 - && strcmp(pem_name, PEM_STRING_X509) != 0) - /* No match */ - return NULL; - *matchcount = 1; - } - - cert = X509_new_with_libctx(libctx, propq); - if (cert == NULL) - return NULL; - - if ((d2i_X509_AUX(&cert, &blob, len)) != NULL - || (ignore_trusted && (d2i_X509(&cert, &blob, len)) != NULL)) { - *matchcount = 1; - store_info = OSSL_STORE_INFO_new_CERT(cert); - } - - if (store_info == NULL) - X509_free(cert); - - return store_info; -} - -static FILE_HANDLER X509Certificate_handler = { - "X509Certificate", - try_decode_X509Certificate -}; - -/* - * X.509 CRL decoder. - */ -static OSSL_STORE_INFO *try_decode_X509CRL(const char *pem_name, - const char *pem_header, - const unsigned char *blob, - size_t len, void **pctx, - int *matchcount, - const UI_METHOD *ui_method, - void *ui_data, const char *uri, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_INFO *store_info = NULL; - X509_CRL *crl = NULL; - - if (pem_name != NULL) { - if (strcmp(pem_name, PEM_STRING_X509_CRL) != 0) - /* No match */ - return NULL; - *matchcount = 1; - } - - if ((crl = d2i_X509_CRL(NULL, &blob, len)) != NULL) { - *matchcount = 1; - store_info = OSSL_STORE_INFO_new_CRL(crl); - } - - if (store_info == NULL) - X509_CRL_free(crl); - - return store_info; -} - -static FILE_HANDLER X509CRL_handler = { - "X509CRL", - try_decode_X509CRL -}; - -/* - * To finish it all off, we collect all the handlers. - */ -static const FILE_HANDLER *file_handlers[] = { - &PKCS12_handler, - &PKCS8Encrypted_handler, - &X509Certificate_handler, - &X509CRL_handler, - ¶ms_handler, - &PUBKEY_handler, - &PrivateKey_handler, -}; - - -/*- - * The loader itself - * ----------------- - */ - -struct ossl_store_loader_ctx_st { - char *uri; /* The URI we currently try to load */ - enum { - is_raw = 0, - is_pem, - is_dir - } type; - int errcnt; -#define FILE_FLAG_SECMEM (1<<0) -#define FILE_FLAG_ATTACHED (1<<1) - unsigned int flags; - union { - struct { /* Used with is_raw and is_pem */ - BIO *file; - - /* - * The following are used when the handler is marked as - * repeatable - */ - const FILE_HANDLER *last_handler; - void *last_handler_ctx; - } file; - struct { /* Used with is_dir */ - OPENSSL_DIR_CTX *ctx; - int end_reached; - - /* - * When a search expression is given, these are filled in. - * |search_name| contains the file basename to look for. - * The string is exactly 8 characters long. - */ - char search_name[9]; - - /* - * The directory reading utility we have combines opening with - * reading the first name. To make sure we can detect the end - * at the right time, we read early and cache the name. - */ - const char *last_entry; - int last_errno; - } dir; - } _; - - /* Expected object type. May be unspecified */ - int expected_type; - OPENSSL_CTX *libctx; - char *propq; -}; - -static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx) -{ - if (ctx == NULL) - return; - - OPENSSL_free(ctx->propq); - OPENSSL_free(ctx->uri); - if (ctx->type != is_dir) { - if (ctx->_.file.last_handler != NULL) { - ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx); - ctx->_.file.last_handler_ctx = NULL; - ctx->_.file.last_handler = NULL; - } - } - OPENSSL_free(ctx); -} - -static int file_find_type(OSSL_STORE_LOADER_CTX *ctx) -{ - BIO *buff = NULL; - char peekbuf[4096] = { 0, }; - - if ((buff = BIO_new(BIO_f_buffer())) == NULL) - return 0; - - ctx->_.file.file = BIO_push(buff, ctx->_.file.file); - if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) { - peekbuf[sizeof(peekbuf) - 1] = '\0'; - if (strstr(peekbuf, "-----BEGIN ") != NULL) - ctx->type = is_pem; - } - return 1; -} - -static OSSL_STORE_LOADER_CTX *file_open_with_libctx - (const OSSL_STORE_LOADER *loader, const char *uri, - OPENSSL_CTX *libctx, const char *propq, - const UI_METHOD *ui_method, void *ui_data) -{ - OSSL_STORE_LOADER_CTX *ctx = NULL; - struct stat st; - struct { - const char *path; - unsigned int check_absolute:1; - } path_data[2]; - size_t path_data_n = 0, i; - const char *path; - - /* - * First step, just take the URI as is. - */ - path_data[path_data_n].check_absolute = 0; - path_data[path_data_n++].path = uri; - - /* - * Second step, if the URI appears to start with the 'file' scheme, - * extract the path and make that the second path to check. - * There's a special case if the URI also contains an authority, then - * the full URI shouldn't be used as a path anywhere. - */ - if (strncasecmp(uri, "file:", 5) == 0) { - const char *p = &uri[5]; - - if (strncmp(&uri[5], "//", 2) == 0) { - path_data_n--; /* Invalidate using the full URI */ - if (strncasecmp(&uri[7], "localhost/", 10) == 0) { - p = &uri[16]; - } else if (uri[7] == '/') { - p = &uri[7]; - } else { - OSSL_STOREerr(0, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED); - return NULL; - } - } - - path_data[path_data_n].check_absolute = 1; -#ifdef _WIN32 - /* Windows file: URIs with a drive letter start with a / */ - if (p[0] == '/' && p[2] == ':' && p[3] == '/') { - char c = ossl_tolower(p[1]); - - if (c >= 'a' && c <= 'z') { - p++; - /* We know it's absolute, so no need to check */ - path_data[path_data_n].check_absolute = 0; - } - } -#endif - path_data[path_data_n++].path = p; - } - - - for (i = 0, path = NULL; path == NULL && i < path_data_n; i++) { - /* - * If the scheme "file" was an explicit part of the URI, the path must - * be absolute. So says RFC 8089 - */ - if (path_data[i].check_absolute && path_data[i].path[0] != '/') { - OSSL_STOREerr(0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE); - ERR_add_error_data(1, path_data[i].path); - return NULL; - } - - if (stat(path_data[i].path, &st) < 0) { - ERR_raise_data(ERR_LIB_SYS, errno, - "calling stat(%s)", - path_data[i].path); - } else { - path = path_data[i].path; - } - } - if (path == NULL) { - return NULL; - } - - /* Successfully found a working path, clear possible collected errors */ - ERR_clear_error(); - - ctx = OPENSSL_zalloc(sizeof(*ctx)); - if (ctx == NULL) { - OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE); - return NULL; - } - ctx->uri = OPENSSL_strdup(uri); - if (ctx->uri == NULL) { - OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (S_ISDIR(st.st_mode)) { - ctx->type = is_dir; - ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, path); - ctx->_.dir.last_errno = errno; - if (ctx->_.dir.last_entry == NULL) { - if (ctx->_.dir.last_errno != 0) { - char errbuf[256]; - OSSL_STOREerr(0, ERR_R_SYS_LIB); - errno = ctx->_.dir.last_errno; - if (openssl_strerror_r(errno, errbuf, sizeof(errbuf))) - ERR_add_error_data(1, errbuf); - goto err; - } - ctx->_.dir.end_reached = 1; - } - } else if ((ctx->_.file.file = BIO_new_file(path, "rb")) == NULL - || !file_find_type(ctx)) { - BIO_free_all(ctx->_.file.file); - goto err; - } - if (propq != NULL) { - ctx->propq = OPENSSL_strdup(propq); - if (ctx->propq == NULL) { - OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE); - goto err; - } - } - ctx->libctx = libctx; - - return ctx; - err: - OSSL_STORE_LOADER_CTX_free(ctx); - return NULL; -} - -static OSSL_STORE_LOADER_CTX *file_open - (const OSSL_STORE_LOADER *loader, const char *uri, - const UI_METHOD *ui_method, void *ui_data) -{ - return file_open_with_libctx(loader, uri, NULL, NULL, ui_method, ui_data); -} - -static OSSL_STORE_LOADER_CTX *file_attach - (const OSSL_STORE_LOADER *loader, BIO *bp, - OPENSSL_CTX *libctx, const char *propq, - const UI_METHOD *ui_method, void *ui_data) -{ - OSSL_STORE_LOADER_CTX *ctx = NULL; - - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (propq != NULL) { - ctx->propq = OPENSSL_strdup(propq); - if (ctx->propq == NULL) { - OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE); - goto err; - } - } - ctx->libctx = libctx; - ctx->flags |= FILE_FLAG_ATTACHED; - ctx->_.file.file = bp; - if (!file_find_type(ctx)) { - /* Safety measure */ - ctx->_.file.file = NULL; - goto err; - } - return ctx; -err: - OSSL_STORE_LOADER_CTX_free(ctx); - return NULL; -} - -static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args) -{ - int ret = 1; - - switch (cmd) { - case OSSL_STORE_C_USE_SECMEM: - { - int on = *(va_arg(args, int *)); - - switch (on) { - case 0: - ctx->flags &= ~FILE_FLAG_SECMEM; - break; - case 1: - ctx->flags |= FILE_FLAG_SECMEM; - break; - default: - OSSL_STOREerr(0, ERR_R_PASSED_INVALID_ARGUMENT); - ret = 0; - break; - } - } - break; - default: - break; - } - - return ret; -} - -static int file_expect(OSSL_STORE_LOADER_CTX *ctx, int expected) -{ - ctx->expected_type = expected; - return 1; -} - -static int file_find(OSSL_STORE_LOADER_CTX *ctx, - const OSSL_STORE_SEARCH *search) -{ - /* - * If ctx == NULL, the library is looking to know if this loader supports - * the given search type. - */ - - if (OSSL_STORE_SEARCH_get_type(search) == OSSL_STORE_SEARCH_BY_NAME) { - unsigned long hash = 0; - - if (ctx == NULL) - return 1; - - if (ctx->type != is_dir) { - OSSL_STOREerr(OSSL_STORE_F_FILE_FIND, - OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES); - return 0; - } - - hash = X509_NAME_hash(OSSL_STORE_SEARCH_get0_name(search)); - BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name), - "%08lx", hash); - return 1; - } - - if (ctx != NULL) - OSSL_STOREerr(OSSL_STORE_F_FILE_FIND, - OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE); - return 0; -} - -static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx, - const char *pem_name, - const char *pem_header, - unsigned char *data, size_t len, - const UI_METHOD *ui_method, - void *ui_data, int *matchcount) -{ - OSSL_STORE_INFO *result = NULL; - BUF_MEM *new_mem = NULL; - char *new_pem_name = NULL; - int t = 0; - - again: - { - size_t i = 0; - void *handler_ctx = NULL; - const FILE_HANDLER **matching_handlers = - OPENSSL_zalloc(sizeof(*matching_handlers) - * OSSL_NELEM(file_handlers)); - - if (matching_handlers == NULL) { - OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD_TRY_DECODE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - *matchcount = 0; - for (i = 0; i < OSSL_NELEM(file_handlers); i++) { - const FILE_HANDLER *handler = file_handlers[i]; - int try_matchcount = 0; - void *tmp_handler_ctx = NULL; - OSSL_STORE_INFO *tmp_result = - handler->try_decode(pem_name, pem_header, data, len, - &tmp_handler_ctx, &try_matchcount, - ui_method, ui_data, ctx->uri, - ctx->libctx, ctx->propq); - - if (try_matchcount > 0) { - - matching_handlers[*matchcount] = handler; - - if (handler_ctx) - handler->destroy_ctx(&handler_ctx); - handler_ctx = tmp_handler_ctx; - - if ((*matchcount += try_matchcount) > 1) { - /* more than one match => ambiguous, kill any result */ - OSSL_STORE_INFO_free(result); - OSSL_STORE_INFO_free(tmp_result); - if (handler->destroy_ctx != NULL) - handler->destroy_ctx(&handler_ctx); - handler_ctx = NULL; - tmp_result = NULL; - result = NULL; - } - if (result == NULL) - result = tmp_result; - } - } - - if (*matchcount == 1 && matching_handlers[0]->repeatable) { - ctx->_.file.last_handler = matching_handlers[0]; - ctx->_.file.last_handler_ctx = handler_ctx; - } - - OPENSSL_free(matching_handlers); - } - - err: - OPENSSL_free(new_pem_name); - BUF_MEM_free(new_mem); - - if (result != NULL - && (t = OSSL_STORE_INFO_get_type(result)) == OSSL_STORE_INFO_EMBEDDED) { - pem_name = new_pem_name = - ossl_store_info_get0_EMBEDDED_pem_name(result); - new_mem = ossl_store_info_get0_EMBEDDED_buffer(result); - data = (unsigned char *)new_mem->data; - len = new_mem->length; - OPENSSL_free(result); - result = NULL; - goto again; - } - - if (result != NULL) - ERR_clear_error(); - - return result; -} - -static OSSL_STORE_INFO *file_load_try_repeat(OSSL_STORE_LOADER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data) -{ - OSSL_STORE_INFO *result = NULL; - int try_matchcount = 0; - - if (ctx->_.file.last_handler != NULL) { - result = - ctx->_.file.last_handler->try_decode(NULL, NULL, NULL, 0, - &ctx->_.file.last_handler_ctx, - &try_matchcount, - ui_method, ui_data, ctx->uri, - ctx->libctx, ctx->propq); - - if (result == NULL) { - ctx->_.file.last_handler->destroy_ctx(&ctx->_.file.last_handler_ctx); - ctx->_.file.last_handler_ctx = NULL; - ctx->_.file.last_handler = NULL; - } - } - return result; -} - -static void pem_free_flag(void *pem_data, int secure, size_t num) -{ - if (secure) - OPENSSL_secure_clear_free(pem_data, num); - else - OPENSSL_free(pem_data); -} -static int file_read_pem(BIO *bp, char **pem_name, char **pem_header, - unsigned char **data, long *len, - const UI_METHOD *ui_method, void *ui_data, - const char *uri, int secure) -{ - int i = secure - ? PEM_read_bio_ex(bp, pem_name, pem_header, data, len, - PEM_FLAG_SECURE | PEM_FLAG_EAY_COMPATIBLE) - : PEM_read_bio(bp, pem_name, pem_header, data, len); - - if (i <= 0) - return 0; - - /* - * 10 is the number of characters in "Proc-Type:", which - * PEM_get_EVP_CIPHER_INFO() requires to be present. - * If the PEM header has less characters than that, it's - * not worth spending cycles on it. - */ - if (strlen(*pem_header) > 10) { - EVP_CIPHER_INFO cipher; - struct pem_pass_data pass_data; - - if (!PEM_get_EVP_CIPHER_INFO(*pem_header, &cipher) - || !file_fill_pem_pass_data(&pass_data, "PEM pass phrase", uri, - ui_method, ui_data) - || !PEM_do_header(&cipher, *data, len, file_get_pem_pass, - &pass_data)) { - return 0; - } - } - return 1; -} - -static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount) -{ -#ifdef OPENSSL_NO_DSA - return NULL; -#else - OSSL_STORE_INFO *result = NULL; - int ispub = -1; - - { - unsigned int magic = 0, bitlen = 0; - int isdss = 0; - unsigned char peekbuf[16] = { 0, }; - const unsigned char *p = peekbuf; - - if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0) - return 0; - if (!ossl_do_blob_header(&p, sizeof(peekbuf), &magic, &bitlen, - &isdss, &ispub)) - return 0; - } - - (*matchcount)++; - - { - EVP_PKEY *tmp = ispub - ? b2i_PublicKey_bio(bp) - : b2i_PrivateKey_bio(bp); - - if (tmp == NULL - || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) { - EVP_PKEY_free(tmp); - return 0; - } - } - - return result; -#endif -} - -static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method, - void *ui_data, const char *uri, - int *matchcount) -{ -#if defined(OPENSSL_NO_DSA) || defined(OPENSSL_NO_RC4) - return NULL; -#else - OSSL_STORE_INFO *result = NULL; - - { - unsigned int saltlen = 0, keylen = 0; - unsigned char peekbuf[24] = { 0, }; - const unsigned char *p = peekbuf; - - if (BIO_buffer_peek(bp, peekbuf, sizeof(peekbuf)) <= 0) - return 0; - if (!ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &saltlen, &keylen)) - return 0; - } - - (*matchcount)++; - - { - EVP_PKEY *tmp = NULL; - struct pem_pass_data pass_data; - - if (!file_fill_pem_pass_data(&pass_data, "PVK pass phrase", uri, - ui_method, ui_data) - || (tmp = b2i_PVK_bio(bp, file_get_pem_pass, &pass_data)) == NULL - || (result = OSSL_STORE_INFO_new_PKEY(tmp)) == NULL) { - EVP_PKEY_free(tmp); - return 0; - } - } - - return result; -#endif -} - -static int file_read_asn1(BIO *bp, unsigned char **data, long *len) -{ - BUF_MEM *mem = NULL; - - if (asn1_d2i_read_bio(bp, &mem) < 0) - return 0; - - *data = (unsigned char *)mem->data; - *len = (long)mem->length; - OPENSSL_free(mem); - - return 1; -} - -static int ends_with_dirsep(const char *uri) -{ - if (*uri != '\0') - uri += strlen(uri) - 1; -#if defined(__VMS) - if (*uri == ']' || *uri == '>' || *uri == ':') - return 1; -#elif defined(_WIN32) - if (*uri == '\\') - return 1; -#endif - return *uri == '/'; -} - -static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name, - char **data) -{ - assert(name != NULL); - assert(data != NULL); - { - const char *pathsep = ends_with_dirsep(ctx->uri) ? "" : "/"; - long calculated_length = strlen(ctx->uri) + strlen(pathsep) - + strlen(name) + 1 /* \0 */; - - *data = OPENSSL_zalloc(calculated_length); - if (*data == NULL) { - OSSL_STOREerr(OSSL_STORE_F_FILE_NAME_TO_URI, ERR_R_MALLOC_FAILURE); - return 0; - } - - OPENSSL_strlcat(*data, ctx->uri, calculated_length); - OPENSSL_strlcat(*data, pathsep, calculated_length); - OPENSSL_strlcat(*data, name, calculated_length); - } - return 1; -} - -static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name) -{ - const char *p = NULL; - - /* If there are no search criteria, all names are accepted */ - if (ctx->_.dir.search_name[0] == '\0') - return 1; - - /* If the expected type isn't supported, no name is accepted */ - if (ctx->expected_type != 0 - && ctx->expected_type != OSSL_STORE_INFO_CERT - && ctx->expected_type != OSSL_STORE_INFO_CRL) - return 0; - - /* - * First, check the basename - */ - if (strncasecmp(name, ctx->_.dir.search_name, - sizeof(ctx->_.dir.search_name) - 1) != 0 - || name[sizeof(ctx->_.dir.search_name) - 1] != '.') - return 0; - p = &name[sizeof(ctx->_.dir.search_name)]; - - /* - * Then, if the expected type is a CRL, check that the extension starts - * with 'r' - */ - if (*p == 'r') { - p++; - if (ctx->expected_type != 0 - && ctx->expected_type != OSSL_STORE_INFO_CRL) - return 0; - } else if (ctx->expected_type == OSSL_STORE_INFO_CRL) { - return 0; - } - - /* - * Last, check that the rest of the extension is a decimal number, at - * least one digit long. - */ - if (!ossl_isdigit(*p)) - return 0; - while (ossl_isdigit(*p)) - p++; - -#ifdef __VMS - /* - * One extra step here, check for a possible generation number. - */ - if (*p == ';') - for (p++; *p != '\0'; p++) - if (!ossl_isdigit(*p)) - break; -#endif - - /* - * If we've reached the end of the string at this point, we've successfully - * found a fitting file name. - */ - return *p == '\0'; -} - -static int file_eof(OSSL_STORE_LOADER_CTX *ctx); -static int file_error(OSSL_STORE_LOADER_CTX *ctx); -static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data) -{ - OSSL_STORE_INFO *result = NULL; - - ctx->errcnt = 0; - ERR_clear_error(); - - if (ctx->type == is_dir) { - do { - char *newname = NULL; - - if (ctx->_.dir.last_entry == NULL) { - if (!ctx->_.dir.end_reached) { - char errbuf[256]; - assert(ctx->_.dir.last_errno != 0); - OSSL_STOREerr(0, ERR_R_SYS_LIB); - errno = ctx->_.dir.last_errno; - ctx->errcnt++; - if (openssl_strerror_r(errno, errbuf, sizeof(errbuf))) - ERR_add_error_data(1, errbuf); - } - return NULL; - } - - if (ctx->_.dir.last_entry[0] != '.' - && file_name_check(ctx, ctx->_.dir.last_entry) - && !file_name_to_uri(ctx, ctx->_.dir.last_entry, &newname)) - return NULL; - - /* - * On the first call (with a NULL context), OPENSSL_DIR_read() - * cares about the second argument. On the following calls, it - * only cares that it isn't NULL. Therefore, we can safely give - * it our URI here. - */ - ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, ctx->uri); - ctx->_.dir.last_errno = errno; - if (ctx->_.dir.last_entry == NULL && ctx->_.dir.last_errno == 0) - ctx->_.dir.end_reached = 1; - - if (newname != NULL - && (result = OSSL_STORE_INFO_new_NAME(newname)) == NULL) { - OPENSSL_free(newname); - OSSL_STOREerr(0, ERR_R_OSSL_STORE_LIB); - return NULL; - } - } while (result == NULL && !file_eof(ctx)); - } else { - int matchcount = -1; - - again: - result = file_load_try_repeat(ctx, ui_method, ui_data); - if (result != NULL) - return result; - - if (file_eof(ctx)) - return NULL; - - do { - char *pem_name = NULL; /* PEM record name */ - char *pem_header = NULL; /* PEM record header */ - unsigned char *data = NULL; /* DER encoded data */ - long len = 0; /* DER encoded data length */ - - matchcount = -1; - if (ctx->type == is_pem) { - if (!file_read_pem(ctx->_.file.file, &pem_name, &pem_header, - &data, &len, ui_method, ui_data, ctx->uri, - (ctx->flags & FILE_FLAG_SECMEM) != 0)) { - ctx->errcnt++; - goto endloop; - } - } else { - if ((result = file_try_read_msblob(ctx->_.file.file, - &matchcount)) != NULL - || (result = file_try_read_PVK(ctx->_.file.file, - ui_method, ui_data, ctx->uri, - &matchcount)) != NULL) - goto endloop; - - if (!file_read_asn1(ctx->_.file.file, &data, &len)) { - ctx->errcnt++; - goto endloop; - } - } - - result = file_load_try_decode(ctx, pem_name, pem_header, data, len, - ui_method, ui_data, &matchcount); - - if (result != NULL) - goto endloop; - - /* - * If a PEM name matches more than one handler, the handlers are - * badly coded. - */ - if (!ossl_assert(pem_name == NULL || matchcount <= 1)) { - ctx->errcnt++; - goto endloop; - } - - if (matchcount > 1) { - OSSL_STOREerr(0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE); - } else if (matchcount == 1) { - /* - * If there are other errors on the stack, they already show - * what the problem is. - */ - if (ERR_peek_error() == 0) { - OSSL_STOREerr(0, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE); - if (pem_name != NULL) - ERR_add_error_data(3, "PEM type is '", pem_name, "'"); - } - } - if (matchcount > 0) - ctx->errcnt++; - - endloop: - pem_free_flag(pem_name, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0); - pem_free_flag(pem_header, (ctx->flags & FILE_FLAG_SECMEM) != 0, 0); - pem_free_flag(data, (ctx->flags & FILE_FLAG_SECMEM) != 0, len); - } while (matchcount == 0 && !file_eof(ctx) && !file_error(ctx)); - - /* We bail out on ambiguity */ - if (matchcount > 1) { - OSSL_STORE_INFO_free(result); - return NULL; - } - - if (result != NULL - && ctx->expected_type != 0 - && ctx->expected_type != OSSL_STORE_INFO_get_type(result)) { - OSSL_STORE_INFO_free(result); - goto again; - } - } - - return result; -} - -static int file_error(OSSL_STORE_LOADER_CTX *ctx) -{ - return ctx->errcnt > 0; -} - -static int file_eof(OSSL_STORE_LOADER_CTX *ctx) -{ - if (ctx->type == is_dir) - return ctx->_.dir.end_reached; - - if (ctx->_.file.last_handler != NULL - && !ctx->_.file.last_handler->eof(ctx->_.file.last_handler_ctx)) - return 0; - return BIO_eof(ctx->_.file.file); -} - -static int file_close(OSSL_STORE_LOADER_CTX *ctx) -{ - if ((ctx->flags & FILE_FLAG_ATTACHED) == 0) { - if (ctx->type == is_dir) - OPENSSL_DIR_end(&ctx->_.dir.ctx); - else - BIO_free_all(ctx->_.file.file); - } else { - /* - * Because file_attach() called file_find_type(), we know that a - * BIO_f_buffer() has been pushed on top of the regular BIO. - */ - BIO *buff = ctx->_.file.file; - - /* Detach buff */ - (void)BIO_pop(ctx->_.file.file); - /* Safety measure */ - ctx->_.file.file = NULL; - - BIO_free(buff); - } - OSSL_STORE_LOADER_CTX_free(ctx); - return 1; -} - -static OSSL_STORE_LOADER file_loader = - { - "file", - NULL, - file_open, - file_attach, - file_ctrl, - file_expect, - file_find, - file_load, - file_eof, - file_error, - file_close, - file_open_with_libctx, - }; - -static void store_file_loader_deinit(void) -{ - ossl_store_unregister_loader_int(file_loader.scheme); -} - -int ossl_store_file_loader_init(void) -{ - int ret = ossl_store_register_loader_int(&file_loader); - - OPENSSL_atexit(store_file_loader_deinit); - return ret; -} diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c index 3abb50bb21..320934e6c6 100644 --- a/crypto/store/store_err.c +++ b/crypto/store/store_err.c @@ -32,8 +32,11 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CERTIFICATE), "not a certificate"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CRL), "not a crl"}, - {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_KEY), "not a key"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_NAME), "not a name"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_PRIVATE_KEY), + "not a private key"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_PUBLIC_KEY), + "not a public key"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_PARAMETERS), "not parameters"}, {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR), diff --git a/crypto/store/store_init.c b/crypto/store/store_init.c index e1b953fbf8..d308dc5d0b 100644 --- a/crypto/store/store_init.c +++ b/crypto/store/store_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,14 +14,13 @@ static CRYPTO_ONCE store_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(do_store_init) { - return OPENSSL_init_crypto(0, NULL) - && ossl_store_file_loader_init(); + return OPENSSL_init_crypto(0, NULL); } int ossl_store_init_once(void) { if (!RUN_ONCE(&store_init, do_store_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INIT_ONCE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return 0; } return 1; diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 2878358245..1ce61ea9da 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -7,39 +7,41 @@ * https://www.openssl.org/source/license.html */ -#include "e_os.h" #include #include #include + +/* We need to use some STORE deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include "e_os.h" + #include #include #include +#include +#include +#include #include #include "internal/thread_once.h" +#include "internal/cryptlib.h" +#include "internal/provider.h" #include "crypto/store.h" #include "store_local.h" -struct ossl_store_ctx_st { - const OSSL_STORE_LOADER *loader; - OSSL_STORE_LOADER_CTX *loader_ctx; - const UI_METHOD *ui_method; - void *ui_data; - OSSL_STORE_post_process_info_fn post_process; - void *post_process_data; - int expected_type; +static int ossl_store_close_it(OSSL_STORE_CTX *ctx); - /* 0 before the first STORE_load(), 1 otherwise */ - int loading; -}; - -OSSL_STORE_CTX *OSSL_STORE_open_with_libctx( - const char *uri, OPENSSL_CTX *libctx, const char *propq, - const UI_METHOD *ui_method, void *ui_data, - OSSL_STORE_post_process_info_fn post_process, void *post_process_data) +OSSL_STORE_CTX * +OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data) { const OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_LOADER *fetched_loader = NULL; OSSL_STORE_LOADER_CTX *loader_ctx = NULL; OSSL_STORE_CTX *ctx = NULL; + char *propq_copy = NULL; char scheme_copy[256], *p, *schemes[2]; size_t schemes_n = 0; size_t i; @@ -70,32 +72,77 @@ OSSL_STORE_CTX *OSSL_STORE_open_with_libctx( ERR_set_mark(); - /* Try each scheme until we find one that could open the URI */ + /* + * Try each scheme until we find one that could open the URI. + * + * For each scheme, we look for the engine implementation first, and + * failing that, we then try to fetch a provided implementation. + * This is consistent with how we handle legacy / engine implementations + * elsewhere. + */ for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { OSSL_TRACE1(STORE, "Looking up scheme %s\n", schemes[i]); +#ifndef OPENSSL_NO_DEPRECATED_3_0 if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) { - OSSL_TRACE1(STORE, "Found loader for scheme %s\n", schemes[i]); - if (loader->open_with_libctx != NULL) - loader_ctx = loader->open_with_libctx(loader, uri, libctx, propq, - ui_method, ui_data); + if (loader->open_ex != NULL) + loader_ctx = loader->open_ex(loader, uri, libctx, propq, + ui_method, ui_data); else loader_ctx = loader->open(loader, uri, ui_method, ui_data); - OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); + } +#endif + if (loader == NULL + && (fetched_loader = + OSSL_STORE_LOADER_fetch(schemes[i], libctx, propq)) != NULL) { + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_provider(fetched_loader); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); + + loader_ctx = fetched_loader->p_open(provctx, uri); + if (loader_ctx == NULL) { + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } else if (propq != NULL) { + OSSL_PARAM params[] = { + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, + NULL, 0), + OSSL_PARAM_END + }; + + params[0].data = (void *)propq; + if (!fetched_loader->p_set_ctx_params(loader_ctx, params)) { + (void)fetched_loader->p_close(loader_ctx); + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } + } + loader = fetched_loader; } } + if (loader != NULL) + OSSL_TRACE1(STORE, "Found loader for scheme %s\n", schemes[i]); + if (loader_ctx == NULL) goto err; - if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE); + OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); + + if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL) + || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); goto err; } + if (ui_method != NULL + && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); + goto err; + } + ctx->properties = propq_copy; + ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; - ctx->ui_method = ui_method; - ctx->ui_data = ui_data; ctx->post_process = post_process; ctx->post_process_data = post_process_data; @@ -111,13 +158,26 @@ OSSL_STORE_CTX *OSSL_STORE_open_with_libctx( err: ERR_clear_last_mark(); if (loader_ctx != NULL) { + /* + * Temporary structure so OSSL_STORE_close() can work even when + * |ctx| couldn't be allocated properly + */ + OSSL_STORE_CTX tmpctx = { NULL, }; + + tmpctx.fetched_loader = fetched_loader; + tmpctx.loader = loader; + tmpctx.loader_ctx = loader_ctx; + /* * We ignore a returned error because we will return NULL anyway in * this case, so if something goes wrong when closing, that'll simply * just add another entry on the error stack. */ - (void)loader->close(loader_ctx); + (void)ossl_store_close_it(&tmpctx); } + OSSL_STORE_LOADER_free(fetched_loader); + OPENSSL_free(propq_copy); + OPENSSL_free(ctx); return NULL; } @@ -126,10 +186,11 @@ OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, OSSL_STORE_post_process_info_fn post_process, void *post_process_data) { - return OSSL_STORE_open_with_libctx(uri, NULL, NULL, ui_method, ui_data, - post_process, post_process_data); + return OSSL_STORE_open_ex(uri, NULL, NULL, ui_method, ui_data, post_process, + post_process_data); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) { va_list args; @@ -144,39 +205,155 @@ int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) { - if (ctx->loader->ctrl != NULL) + if (ctx->fetched_loader != NULL) { + if (ctx->fetched_loader->p_set_ctx_params != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + switch (cmd) { + case OSSL_STORE_C_USE_SECMEM: + { + int on = *(va_arg(args, int *)); + + params[0] = OSSL_PARAM_construct_int("use_secmem", &on); + } + break; + default: + break; + } + + return ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, + params); + } + } else if (ctx->loader->ctrl != NULL) { return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); - return 0; + } + + /* + * If the fetched loader doesn't have a set_ctx_params or a ctrl, it's as + * if there was one that ignored our params, which usually returns 1. + */ + return 1; } +#endif int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) { + int ret = 1; + if (ctx->loading) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_EXPECT, - OSSL_STORE_R_LOADING_STARTED); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); return 0; } ctx->expected_type = expected_type; - if (ctx->loader->expect != NULL) - return ctx->loader->expect(ctx->loader_ctx, expected_type); - return 1; + if (ctx->fetched_loader != NULL + && ctx->fetched_loader->p_set_ctx_params != NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + params[0] = + OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expected_type); + ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, params); + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL + && ctx->loader->expect != NULL) { + ret = ctx->loader->expect(ctx->loader_ctx, expected_type); + } +#endif + return ret; } int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) { + int ret = 1; + if (ctx->loading) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, - OSSL_STORE_R_LOADING_STARTED); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); return 0; } - if (ctx->loader->find == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, - OSSL_STORE_R_UNSUPPORTED_OPERATION); + if (search == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); return 0; } - return ctx->loader->find(ctx->loader_ctx, search); + if (ctx->fetched_loader != NULL) { + OSSL_PARAM_BLD *bld; + OSSL_PARAM *params; + /* OSSL_STORE_SEARCH_BY_NAME, OSSL_STORE_SEARCH_BY_ISSUER_SERIAL*/ + void *name_der = NULL; + int name_der_sz; + /* OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */ + BIGNUM *number = NULL; + + if (ctx->fetched_loader->p_set_ctx_params == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); + return 0; + } + + if ((bld = OSSL_PARAM_BLD_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + return 0; + } + + ret = 0; /* Assume the worst */ + + switch (search->search_type) { + case OSSL_STORE_SEARCH_BY_NAME: + if ((name_der_sz = i2d_X509_NAME(search->name, + (unsigned char **)&name_der)) > 0 + && OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_STORE_PARAM_SUBJECT, + name_der, name_der_sz)) + ret = 1; + break; + case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: + if ((name_der_sz = i2d_X509_NAME(search->name, + (unsigned char **)&name_der)) > 0 + && (number = ASN1_INTEGER_to_BN(search->serial, NULL)) != NULL + && OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_STORE_PARAM_ISSUER, + name_der, name_der_sz) + && OSSL_PARAM_BLD_push_BN(bld, OSSL_STORE_PARAM_SERIAL, + number)) + ret = 1; + break; + case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: + if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_DIGEST, + EVP_MD_name(search->digest), 0) + && OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_STORE_PARAM_FINGERPRINT, + search->string, + search->stringlength)) + ret = 1; + break; + case OSSL_STORE_SEARCH_BY_ALIAS: + if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_ALIAS, + (char *)search->string, + search->stringlength)) + ret = 1; + break; + } + if (ret) { + params = OSSL_PARAM_BLD_to_param(bld); + ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, + params); + OSSL_PARAM_BLD_free_params(params); + } + OSSL_PARAM_BLD_free(bld); + OPENSSL_free(name_der); + BN_free(number); + } else { +#ifndef OPENSSL_NO_DEPRECATED_3_0 + /* legacy loader section */ + if (ctx->loader->find == NULL) { + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); + return 0; + } + ret = ctx->loader->find(ctx->loader_ctx, search); +#endif + } + + return ret; } OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) @@ -188,8 +365,42 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) if (OSSL_STORE_eof(ctx)) return NULL; - OSSL_TRACE(STORE, "Loading next object\n"); - v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data); + if (ctx->loader != NULL) + OSSL_TRACE(STORE, "Loading next object\n"); + + if (ctx->cached_info != NULL + && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { + sk_OSSL_STORE_INFO_free(ctx->cached_info); + ctx->cached_info = NULL; + } + + if (ctx->cached_info != NULL) { + v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); + } else { + if (ctx->fetched_loader != NULL) { + struct ossl_load_result_data_st load_data; + + load_data.v = NULL; + load_data.ctx = ctx; + + if (!ctx->fetched_loader->p_load(ctx->loader_ctx, + ossl_store_handle_load_result, + &load_data, + ossl_pw_passphrase_callback_dec, + &ctx->pwdata)) { + if (!OSSL_STORE_eof(ctx)) + ctx->error_flag = 1; + return NULL; + } + v = load_data.v; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + v = ctx->loader->load(ctx->loader_ctx, + ctx->pwdata._.ui_method.ui_method, + ctx->pwdata._.ui_method.ui_method_data); +#endif + } if (ctx->post_process != NULL && v != NULL) { v = ctx->post_process(v, ctx->post_process_data); @@ -206,13 +417,6 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) int returned_type = OSSL_STORE_INFO_get_type(v); if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { - /* - * Soft assert here so those who want to harsly weed out faulty - * loaders can do so using a debugging version of libcrypto. - */ - if (ctx->loader->expect != NULL) - assert(ctx->expected_type == returned_type); - if (ctx->expected_type != returned_type) { OSSL_STORE_INFO_free(v); goto again; @@ -229,25 +433,58 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) int OSSL_STORE_error(OSSL_STORE_CTX *ctx) { - return ctx->loader->error(ctx->loader_ctx); + int ret = 1; + + if (ctx->fetched_loader != NULL) + ret = ctx->error_flag; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + ret = ctx->loader->error(ctx->loader_ctx); +#endif + return ret; } int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) { - return ctx->loader->eof(ctx->loader_ctx); + int ret = 1; + + if (ctx->fetched_loader != NULL) + ret = ctx->loader->p_eof(ctx->loader_ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + ret = ctx->loader->eof(ctx->loader_ctx); +#endif + return ret; } -int OSSL_STORE_close(OSSL_STORE_CTX *ctx) +static int ossl_store_close_it(OSSL_STORE_CTX *ctx) { - int loader_ret; + int ret = 0; if (ctx == NULL) return 1; OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx); - loader_ret = ctx->loader->close(ctx->loader_ctx); + + if (ctx->fetched_loader != NULL) + ret = ctx->loader->p_close(ctx->loader_ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) + ret = ctx->loader->close(ctx->loader_ctx); +#endif + + sk_OSSL_STORE_INFO_pop_free(ctx->cached_info, OSSL_STORE_INFO_free); + OSSL_STORE_LOADER_free(ctx->fetched_loader); + OPENSSL_free(ctx->properties); + ossl_pw_clear_passphrase_data(&ctx->pwdata); + return ret; +} + +int OSSL_STORE_close(OSSL_STORE_CTX *ctx) +{ + int ret = ossl_store_close_it(ctx); OPENSSL_free(ctx); - return loader_ret; + return ret; } /* @@ -257,7 +494,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx) * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO * and will therefore be freed when the OSSL_STORE_INFO is freed. */ -static OSSL_STORE_INFO *store_info_new(int type, void *data) +OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data) { OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); @@ -271,11 +508,10 @@ static OSSL_STORE_INFO *store_info_new(int type, void *data) OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL); if (info == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -288,8 +524,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) { if (info->type != OSSL_STORE_INFO_NAME) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION, - ERR_R_PASSED_INVALID_ARGUMENT); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } @@ -299,41 +534,46 @@ int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) } OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); + return info; +} + +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey) +{ + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey); + + if (info == NULL) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) { - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl); + OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl); if (info == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return info; } @@ -345,6 +585,13 @@ int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) return info->type; } +void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info) +{ + if (info->type == type) + return info->_.data; + return NULL; +} + const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) { if (info->type == OSSL_STORE_INFO_NAME) @@ -358,12 +605,10 @@ char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) char *ret = OPENSSL_strdup(info->_.name.name); if (ret == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return ret; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, - OSSL_STORE_R_NOT_A_NAME); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); return NULL; } @@ -381,12 +626,10 @@ char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) ? info->_.name.desc : ""); if (ret == NULL) - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return ret; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, - OSSL_STORE_R_NOT_A_NAME); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); return NULL; } @@ -403,8 +646,24 @@ EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) EVP_PKEY_up_ref(info->_.params); return info->_.params; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS, - OSSL_STORE_R_NOT_PARAMETERS); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS); + return NULL; +} + +EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info) +{ + if (info->type == OSSL_STORE_INFO_PUBKEY) + return info->_.pubkey; + return NULL; +} + +EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info) +{ + if (info->type == OSSL_STORE_INFO_PUBKEY) { + EVP_PKEY_up_ref(info->_.pubkey); + return info->_.pubkey; + } + OSSL_STOREerr(0, OSSL_STORE_R_NOT_A_PUBLIC_KEY); return NULL; } @@ -421,8 +680,7 @@ EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) EVP_PKEY_up_ref(info->_.pkey); return info->_.pkey; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY, - OSSL_STORE_R_NOT_A_KEY); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY); return NULL; } @@ -439,8 +697,7 @@ X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) X509_up_ref(info->_.x509); return info->_.x509; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, - OSSL_STORE_R_NOT_A_CERTIFICATE); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE); return NULL; } @@ -457,8 +714,7 @@ X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) X509_CRL_up_ref(info->_.crl); return info->_.crl; } - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL, - OSSL_STORE_R_NOT_A_CRL); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL); return NULL; } @@ -469,10 +725,6 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) { if (info != NULL) { switch (info->type) { - case OSSL_STORE_INFO_EMBEDDED: - BUF_MEM_free(info->_.embedded.blob); - OPENSSL_free(info->_.embedded.pem_name); - break; case OSSL_STORE_INFO_NAME: OPENSSL_free(info->_.name.name); OPENSSL_free(info->_.name.desc); @@ -480,6 +732,9 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) case OSSL_STORE_INFO_PARAMS: EVP_PKEY_free(info->_.params); break; + case OSSL_STORE_INFO_PUBKEY: + EVP_PKEY_free(info->_.pubkey); + break; case OSSL_STORE_INFO_PKEY: EVP_PKEY_free(info->_.pkey); break; @@ -496,12 +751,55 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) { - OSSL_STORE_SEARCH tmp_search; - - if (ctx->loader->find == NULL) - return 0; - tmp_search.search_type = search_type; - return ctx->loader->find(NULL, &tmp_search); + int ret = 0; + + if (ctx->fetched_loader != NULL) { + void *provctx = + ossl_provider_ctx(OSSL_STORE_LOADER_provider(ctx->fetched_loader)); + const OSSL_PARAM *params; + const OSSL_PARAM *p_subject = NULL; + const OSSL_PARAM *p_issuer = NULL; + const OSSL_PARAM *p_serial = NULL; + const OSSL_PARAM *p_fingerprint = NULL; + const OSSL_PARAM *p_alias = NULL; + + if (ctx->fetched_loader->p_settable_ctx_params == NULL) + return 0; + + params = ctx->fetched_loader->p_settable_ctx_params(provctx); + p_subject = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); + p_issuer = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER); + p_serial = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL); + p_fingerprint = + OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT); + p_alias = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS); + + switch (search_type) { + case OSSL_STORE_SEARCH_BY_NAME: + ret = (p_subject != NULL); + break; + case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: + ret = (p_issuer != NULL && p_serial != NULL); + break; + case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: + ret = (p_fingerprint != NULL); + break; + case OSSL_STORE_SEARCH_BY_ALIAS: + ret = (p_alias != NULL); + break; + } + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->fetched_loader == NULL) { + OSSL_STORE_SEARCH tmp_search; + + if (ctx->loader->find == NULL) + return 0; + tmp_search.search_type = search_type; + ret = ctx->loader->find(NULL, &tmp_search); + } +#endif + return ret; } /* Search term constructors */ @@ -510,8 +808,7 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -526,8 +823,7 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -544,20 +840,17 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } if (digest != NULL && len != (size_t)EVP_MD_size(digest)) { - char buf1[20], buf2[20]; - - BIO_snprintf(buf1, sizeof(buf1), "%d", EVP_MD_size(digest)); - BIO_snprintf(buf2, sizeof(buf2), "%zu", len); - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, - OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST); - ERR_add_error_data(5, EVP_MD_name(digest), " size is ", buf1, - ", fingerprint size is ", buf2); + ERR_raise_data(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST, + "%s size is %d, fingerprint size is %zu", + EVP_MD_name(digest), EVP_MD_size(digest), len); + OPENSSL_free(search); + return NULL; } search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; @@ -572,8 +865,7 @@ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); if (search == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -623,71 +915,70 @@ const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) return criterion->digest; } -/* Internal functions */ -OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name, - BUF_MEM *embedded) -{ - OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL); - - if (info == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, - ERR_R_MALLOC_FAILURE); - return NULL; - } - - info->_.embedded.blob = embedded; - info->_.embedded.pem_name = - new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name); - - if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, - ERR_R_MALLOC_FAILURE); - OSSL_STORE_INFO_free(info); - info = NULL; - } - - return info; -} - -BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info) -{ - if (info->type == OSSL_STORE_INFO_EMBEDDED) - return info->_.embedded.blob; - return NULL; -} - -char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info) -{ - if (info->type == OSSL_STORE_INFO_EMBEDDED) - return info->_.embedded.pem_name; - return NULL; -} - OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, - OPENSSL_CTX *libctx, const char *propq, + OSSL_LIB_CTX *libctx, const char *propq, const UI_METHOD *ui_method, void *ui_data, OSSL_STORE_post_process_info_fn post_process, void *post_process_data) { - OSSL_STORE_CTX *ctx = NULL; const OSSL_STORE_LOADER *loader = NULL; + OSSL_STORE_LOADER *fetched_loader = NULL; OSSL_STORE_LOADER_CTX *loader_ctx = NULL; + OSSL_STORE_CTX *ctx = NULL; + + if (scheme == NULL) + scheme = "file"; + + OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) + loader_ctx = loader->attach(loader, bp, libctx, propq, + ui_method, ui_data); +#endif + if (loader == NULL + && (fetched_loader = + OSSL_STORE_LOADER_fetch(scheme, libctx, propq)) != NULL) { + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_provider(fetched_loader); + void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); + + if ((loader_ctx = + fetched_loader->p_attach(provctx, (OSSL_CORE_BIO *)bp)) == NULL) { + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } else if (propq != NULL) { + OSSL_PARAM params[] = { + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, + NULL, 0), + OSSL_PARAM_END + }; + + params[0].data = (void *)propq; + if (!fetched_loader->p_set_ctx_params(loader_ctx, params)) { + (void)fetched_loader->p_close(loader_ctx); + OSSL_STORE_LOADER_free(fetched_loader); + fetched_loader = NULL; + } + } + loader = fetched_loader; + } - if ((loader = - ossl_store_get0_loader_int(scheme != NULL ? scheme : "file")) == NULL - || (loader_ctx = loader->attach(loader, bp, libctx, propq, - ui_method, ui_data)) == NULL) + if (loader_ctx == NULL) return NULL; if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } + if (ui_method != NULL + && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { + OPENSSL_free(ctx); + return NULL; + } + ctx->fetched_loader = fetched_loader; ctx->loader = loader; ctx->loader_ctx = loader_ctx; - ctx->ui_method = ui_method; - ctx->ui_data = ui_data; ctx->post_process = post_process; ctx->post_process_data = post_process_data; diff --git a/crypto/store/store_local.h b/crypto/store/store_local.h index c9592c38ce..56a90a125b 100644 --- a/crypto/store/store_local.h +++ b/crypto/store/store_local.h @@ -7,13 +7,16 @@ * https://www.openssl.org/source/license.html */ +#include #include "internal/thread_once.h" +#include "internal/refcount.h" #include #include #include #include #include #include +#include "internal/passphrase.h" /*- * OSSL_STORE_INFO stuff @@ -25,42 +28,20 @@ struct ossl_store_info_st { union { void *data; /* used internally as generic pointer */ - struct { - BUF_MEM *blob; - char *pem_name; - } embedded; /* when type == OSSL_STORE_INFO_EMBEDDED */ - struct { char *name; char *desc; } name; /* when type == OSSL_STORE_INFO_NAME */ EVP_PKEY *params; /* when type == OSSL_STORE_INFO_PARAMS */ + EVP_PKEY *pubkey; /* when type == OSSL_STORE_INFO_PUBKEY */ EVP_PKEY *pkey; /* when type == OSSL_STORE_INFO_PKEY */ X509 *x509; /* when type == OSSL_STORE_INFO_CERT */ X509_CRL *crl; /* when type == OSSL_STORE_INFO_CRL */ } _; }; - DEFINE_STACK_OF(OSSL_STORE_INFO) -/* - * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file - * handlers. It should never reach a calling application or any engine. - * However, it can be used by a FILE_HANDLER's try_decode function to signal - * that it has decoded the incoming blob into a new blob, and that the - * attempted decoding should be immediately restarted with the new blob, using - * the new PEM name. - */ -/* - * Because this is an internal type, we don't make it public. - */ -#define OSSL_STORE_INFO_EMBEDDED -1 -OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name, - BUF_MEM *embedded); -BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info); -char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info); - /*- * OSSL_STORE_SEARCH stuff * ----------------------- @@ -99,6 +80,8 @@ OSSL_STORE_LOADER *ossl_store_unregister_loader_int(const char *scheme); /* loader stuff */ struct ossl_store_loader_st { +#ifndef OPENSSL_NO_DEPRECATED_3_0 + /* Legacy stuff */ const char *scheme; ENGINE *engine; OSSL_STORE_open_fn open; @@ -110,17 +93,94 @@ struct ossl_store_loader_st { OSSL_STORE_eof_fn eof; OSSL_STORE_error_fn error; OSSL_STORE_close_fn close; - OSSL_STORE_open_with_libctx_fn open_with_libctx; + OSSL_STORE_open_ex_fn open_ex; +#endif + + /* Provider stuff */ + OSSL_PROVIDER *prov; + int scheme_id; + const char *propdef; + + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; + + OSSL_FUNC_store_open_fn *p_open; + OSSL_FUNC_store_attach_fn *p_attach; + OSSL_FUNC_store_settable_ctx_params_fn *p_settable_ctx_params; + OSSL_FUNC_store_set_ctx_params_fn *p_set_ctx_params; + OSSL_FUNC_store_load_fn *p_load; + OSSL_FUNC_store_eof_fn *p_eof; + OSSL_FUNC_store_close_fn *p_close; + OSSL_FUNC_store_export_object_fn *p_export_object; }; DEFINE_LHASH_OF(OSSL_STORE_LOADER); const OSSL_STORE_LOADER *ossl_store_get0_loader_int(const char *scheme); void ossl_store_destroy_loaders_int(void); +#ifdef OPENSSL_NO_DEPRECATED_3_0 +/* struct ossl_store_loader_ctx_st is defined differently by each loader */ +typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; +#endif + +/*- + * OSSL_STORE_CTX stuff + * --------------------- + */ + +struct ossl_store_ctx_st { + const OSSL_STORE_LOADER *loader; /* legacy */ + OSSL_STORE_LOADER *fetched_loader; + OSSL_STORE_LOADER_CTX *loader_ctx; + OSSL_STORE_post_process_info_fn post_process; + void *post_process_data; + int expected_type; + + char *properties; + + /* 0 before the first STORE_load(), 1 otherwise */ + int loading; + /* 1 on load error, only valid for fetched loaders */ + int error_flag; + + /* + * Cache of stuff, to be able to return the contents of a PKCS#12 + * blob, one object at a time. + */ + STACK_OF(OSSL_STORE_INFO) *cached_info; + + struct ossl_passphrase_data_st pwdata; +}; + /*- * OSSL_STORE init stuff * --------------------- */ int ossl_store_init_once(void); -int ossl_store_file_loader_init(void); + +/*- + * 'file' scheme stuff + * ------------------- + */ + +OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp); +int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx); + +/*- + * Provider stuff + * ------------------- + */ +OSSL_STORE_LOADER *ossl_store_loader_fetch(OSSL_LIB_CTX *libctx, + const char *scheme, + const char *properties); +OSSL_STORE_LOADER *ossl_store_loader_fetch_by_number(OSSL_LIB_CTX *libctx, + int scheme_id, + const char *properties); + +/* Standard function to handle the result from OSSL_FUNC_store_load() */ +struct ossl_load_result_data_st { + OSSL_STORE_INFO *v; /* To be filled in */ + OSSL_STORE_CTX *ctx; +}; +OSSL_CALLBACK ossl_store_handle_load_result; diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c new file mode 100644 index 0000000000..166b885806 --- /dev/null +++ b/crypto/store/store_meth.c @@ -0,0 +1,425 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/core.h" +#include "internal/namemap.h" +#include "internal/property.h" +#include "internal/provider.h" +#include "store_local.h" + +int OSSL_STORE_LOADER_up_ref(OSSL_STORE_LOADER *loader) +{ + int ref = 0; + + if (loader->prov != NULL) + CRYPTO_UP_REF(&loader->refcnt, &ref, loader->lock); + return 1; +} + +void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader) +{ + if (loader != NULL && loader->prov != NULL) { + int i; + + CRYPTO_DOWN_REF(&loader->refcnt, &i, loader->lock); + if (i > 0) + return; + ossl_provider_free(loader->prov); + CRYPTO_THREAD_lock_free(loader->lock); + } + OPENSSL_free(loader); +} + +/* + * OSSL_STORE_LOADER_new() expects the scheme as a constant string, + * which we currently don't have, so we need an alternative allocator. + */ +static OSSL_STORE_LOADER *new_loader(OSSL_PROVIDER *prov) +{ + OSSL_STORE_LOADER *loader; + + if ((loader = OPENSSL_zalloc(sizeof(*loader))) == NULL + || (loader->lock = CRYPTO_THREAD_lock_new()) == NULL) { + OPENSSL_free(loader); + return NULL; + } + loader->prov = prov; + ossl_provider_up_ref(prov); + loader->refcnt = 1; + + return loader; +} + +static int up_ref_loader(void *method) +{ + return OSSL_STORE_LOADER_up_ref(method); +} + +static void free_loader(void *method) +{ + OSSL_STORE_LOADER_free(method); +} + +/* Permanent loader method store, constructor and destructor */ +static void loader_store_free(void *vstore) +{ + ossl_method_store_free(vstore); +} + +static void *loader_store_new(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + +static const OSSL_LIB_CTX_METHOD loader_store_method = { + loader_store_new, + loader_store_free, +}; + +/* Data to be passed through ossl_method_construct() */ +struct loader_data_st { + OSSL_LIB_CTX *libctx; + OSSL_METHOD_CONSTRUCT_METHOD *mcm; + int scheme_id; /* For get_loader_from_store() */ + const char *scheme; /* For get_loader_from_store() */ + const char *propquery; /* For get_loader_from_store() */ +}; + +/* + * Generic routines to fetch / create OSSL_STORE methods with + * ossl_method_construct() + */ + +/* Temporary loader method store, constructor and destructor */ +static void *alloc_tmp_loader_store(OSSL_LIB_CTX *ctx) +{ + return ossl_method_store_new(ctx); +} + + static void dealloc_tmp_loader_store(void *store) +{ + if (store != NULL) + ossl_method_store_free(store); +} + +/* Get the permanent loader store */ +static OSSL_METHOD_STORE *get_loader_store(OSSL_LIB_CTX *libctx) +{ + return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX, + &loader_store_method); +} + +/* Get loader methods from a store, or put one in */ +static void *get_loader_from_store(OSSL_LIB_CTX *libctx, void *store, + void *data) +{ + struct loader_data_st *methdata = data; + void *method = NULL; + int id; + + if ((id = methdata->scheme_id) == 0) { + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + id = ossl_namemap_name2num(namemap, methdata->scheme); + } + + if (store == NULL + && (store = get_loader_store(libctx)) == NULL) + return NULL; + + if (!ossl_method_store_fetch(store, id, methdata->propquery, &method)) + return NULL; + return method; +} + +static int put_loader_in_store(OSSL_LIB_CTX *libctx, void *store, + void *method, const OSSL_PROVIDER *prov, + int operation_id, const char *scheme, + const char *propdef, void *unused) +{ + OSSL_NAMEMAP *namemap; + int id; + + if ((namemap = ossl_namemap_stored(libctx)) == NULL + || (id = ossl_namemap_name2num(namemap, scheme)) == 0) + return 0; + + if (store == NULL && (store = get_loader_store(libctx)) == NULL) + return 0; + + return ossl_method_store_add(store, prov, id, propdef, method, + up_ref_loader, free_loader); +} + +static void *loader_from_dispatch(int scheme_id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) +{ + OSSL_STORE_LOADER *loader = NULL; + const OSSL_DISPATCH *fns = algodef->implementation; + + if ((loader = new_loader(prov)) == NULL) + return NULL; + loader->scheme_id = scheme_id; + loader->propdef = algodef->property_definition; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_STORE_OPEN: + if (loader->p_open == NULL) + loader->p_open = OSSL_FUNC_store_open(fns); + break; + case OSSL_FUNC_STORE_ATTACH: + if (loader->p_attach == NULL) + loader->p_attach = OSSL_FUNC_store_attach(fns); + break; + case OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS: + if (loader->p_settable_ctx_params == NULL) + loader->p_settable_ctx_params = + OSSL_FUNC_store_settable_ctx_params(fns); + break; + case OSSL_FUNC_STORE_SET_CTX_PARAMS: + if (loader->p_set_ctx_params == NULL) + loader->p_set_ctx_params = OSSL_FUNC_store_set_ctx_params(fns); + break; + case OSSL_FUNC_STORE_LOAD: + if (loader->p_load == NULL) + loader->p_load = OSSL_FUNC_store_load(fns); + break; + case OSSL_FUNC_STORE_EOF: + if (loader->p_eof == NULL) + loader->p_eof = OSSL_FUNC_store_eof(fns); + break; + case OSSL_FUNC_STORE_CLOSE: + if (loader->p_close == NULL) + loader->p_close = OSSL_FUNC_store_close(fns); + break; + case OSSL_FUNC_STORE_EXPORT_OBJECT: + if (loader->p_export_object == NULL) + loader->p_export_object = OSSL_FUNC_store_export_object(fns); + break; + } + } + + if ((loader->p_open == NULL && loader->p_attach == NULL) + || loader->p_load == NULL + || loader->p_eof == NULL + || loader->p_close == NULL) { + /* Only set_ctx_params is optionaal */ + OSSL_STORE_LOADER_free(loader); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE); + return NULL; + } + return loader; +} + +/* + * The core fetching functionality passes the scheme of the implementation. + * This function is responsible to getting an identity number for them, + * then call loader_from_dispatch() with that identity number. + */ +static void *construct_loader(const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov, void *unused) +{ + /* + * This function is only called if get_loader_from_store() returned + * NULL, so it's safe to say that of all the spots to create a new + * namemap entry, this is it. Should the scheme already exist there, we + * know that ossl_namemap_add() will return its corresponding number. + */ + OSSL_LIB_CTX *libctx = ossl_provider_libctx(prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *scheme = algodef->algorithm_names; + int id = ossl_namemap_add_name(namemap, 0, scheme); + void *method = NULL; + + if (id != 0) + method = loader_from_dispatch(id, algodef, prov); + + return method; +} + +/* Intermediary function to avoid ugly casts, used below */ +static void destruct_loader(void *method, void *data) +{ + OSSL_STORE_LOADER_free(method); +} + +/* Fetching support. Can fetch by numeric identity or by scheme */ +static OSSL_STORE_LOADER *inner_loader_fetch(OSSL_LIB_CTX *libctx, + int id, const char *scheme, + const char *properties) +{ + OSSL_METHOD_STORE *store = get_loader_store(libctx); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + void *method = NULL; + + if (store == NULL || namemap == NULL) + return NULL; + + /* + * If we have been passed neither a scheme_id or a scheme, we have an + * internal programming error. + */ + if (!ossl_assert(id != 0 || scheme != NULL)) + return NULL; + + if (id == 0) + id = ossl_namemap_name2num(namemap, scheme); + + if (id == 0 + || !ossl_method_store_cache_get(store, id, properties, &method)) { + OSSL_METHOD_CONSTRUCT_METHOD mcm = { + alloc_tmp_loader_store, + dealloc_tmp_loader_store, + get_loader_from_store, + put_loader_in_store, + construct_loader, + destruct_loader + }; + struct loader_data_st mcmdata; + + mcmdata.libctx = libctx; + mcmdata.mcm = &mcm; + mcmdata.scheme_id = id; + mcmdata.scheme = scheme; + mcmdata.propquery = properties; + if ((method = ossl_method_construct(libctx, OSSL_OP_STORE, + 0 /* !force_cache */, + &mcm, &mcmdata)) != NULL) { + /* + * If construction did create a method for us, we know that there + * is a correct scheme_id, since those have already been calculated + * in get_loader_from_store() and put_loader_in_store() above. + */ + if (id == 0) + id = ossl_namemap_name2num(namemap, scheme); + ossl_method_store_cache_set(store, id, properties, method, + up_ref_loader, free_loader); + } + } + + return method; +} + +OSSL_STORE_LOADER *OSSL_STORE_LOADER_fetch(const char *scheme, + OSSL_LIB_CTX *libctx, + const char *properties) +{ + return inner_loader_fetch(libctx, 0, scheme, properties); +} + +OSSL_STORE_LOADER *ossl_store_loader_fetch_by_number(OSSL_LIB_CTX *libctx, + int scheme_id, + const char *properties) +{ + return inner_loader_fetch(libctx, scheme_id, NULL, properties); +} + +/* + * Library of basic method functions + */ + +const OSSL_PROVIDER *OSSL_STORE_LOADER_provider(const OSSL_STORE_LOADER *loader) +{ + if (!ossl_assert(loader != NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return loader->prov; +} + +const char *OSSL_STORE_LOADER_properties(const OSSL_STORE_LOADER *loader) +{ + if (!ossl_assert(loader != NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return loader->propdef; +} + +int OSSL_STORE_LOADER_number(const OSSL_STORE_LOADER *loader) +{ + if (!ossl_assert(loader != NULL)) { + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return loader->scheme_id; +} + +int OSSL_STORE_LOADER_is_a(const OSSL_STORE_LOADER *loader, const char *name) +{ + if (loader->prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(loader->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + return ossl_namemap_name2num(namemap, name) == loader->scheme_id; + } + return 0; +} + +struct loader_do_all_data_st { + void (*user_fn)(void *method, void *arg); + void *user_arg; +}; + +static void loader_do_one(OSSL_PROVIDER *provider, + const OSSL_ALGORITHM *algodef, + int no_store, void *vdata) +{ + struct loader_do_all_data_st *data = vdata; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + const char *name = algodef->algorithm_names; + int id = ossl_namemap_add_name(namemap, 0, name); + void *method = NULL; + + if (id != 0) + method = + loader_from_dispatch(id, algodef, provider); + + if (method != NULL) { + data->user_fn(method, data->user_arg); + OSSL_STORE_LOADER_free(method); + } +} + +void OSSL_STORE_LOADER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(OSSL_STORE_LOADER *loader, + void *arg), + void *arg) +{ + struct loader_do_all_data_st data; + + data.user_fn = (void (*)(void *, void *))fn; + data.user_arg = arg; + ossl_algorithm_do_all(libctx, OSSL_OP_STORE, NULL, + NULL, loader_do_one, NULL, + &data); +} + +void OSSL_STORE_LOADER_names_do_all(const OSSL_STORE_LOADER *loader, + void (*fn)(const char *name, void *data), + void *data) +{ + if (loader == NULL) + return; + + if (loader->prov != NULL) { + OSSL_LIB_CTX *libctx = ossl_provider_libctx(loader->prov); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + + ossl_namemap_doall_names(namemap, loader->scheme_id, fn, data); + } +} diff --git a/crypto/store/store_register.c b/crypto/store/store_register.c index 4fbf459afa..f426a82ecc 100644 --- a/crypto/store/store_register.c +++ b/crypto/store/store_register.c @@ -39,13 +39,12 @@ OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme) * later on. */ if (scheme == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_LOADER_NEW, - OSSL_STORE_R_INVALID_SCHEME); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME); return NULL; } if ((res = OPENSSL_zalloc(sizeof(*res))) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_LOADER_NEW, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -71,6 +70,14 @@ int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, return 1; } +int OSSL_STORE_LOADER_set_open_ex + (OSSL_STORE_LOADER *loader, + OSSL_STORE_open_ex_fn open_ex_function) +{ + loader->open_ex = open_ex_function; + return 1; +} + int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader, OSSL_STORE_attach_fn attach_function) { @@ -127,11 +134,6 @@ int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, return 1; } -void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader) -{ - OPENSSL_free(loader); -} - /* * Functions for registering OSSL_STORE_LOADERs */ @@ -149,6 +151,14 @@ static int store_loader_cmp(const OSSL_STORE_LOADER *a, } static LHASH_OF(OSSL_STORE_LOADER) *loader_register = NULL; +static int ossl_store_register_init(void) +{ + if (loader_register == NULL) { + loader_register = lh_OSSL_STORE_LOADER_new(store_loader_hash, + store_loader_cmp); + } + return loader_register != NULL; +} int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) { @@ -168,33 +178,25 @@ int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) || strchr("+-.", *scheme) != NULL)) scheme++; if (*scheme != '\0') { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, - OSSL_STORE_R_INVALID_SCHEME); - ERR_add_error_data(2, "scheme=", loader->scheme); + ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME, + "scheme=%s", loader->scheme); return 0; } /* Check that functions we absolutely require are present */ if (loader->open == NULL || loader->load == NULL || loader->eof == NULL || loader->error == NULL || loader->close == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, - OSSL_STORE_R_LOADER_INCOMPLETE); + ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE); return 0; } if (!RUN_ONCE(®istry_init, do_registry_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return 0; } CRYPTO_THREAD_write_lock(registry_lock); - if (loader_register == NULL) { - loader_register = lh_OSSL_STORE_LOADER_new(store_loader_hash, - store_loader_cmp); - } - - if (loader_register != NULL + if (ossl_store_register_init() && (lh_OSSL_STORE_LOADER_insert(loader_register, loader) != NULL || lh_OSSL_STORE_LOADER_error(loader_register) == 0)) ok = 1; @@ -220,25 +222,23 @@ const OSSL_STORE_LOADER *ossl_store_get0_loader_int(const char *scheme) template.load = NULL; template.eof = NULL; template.close = NULL; - template.open_with_libctx = NULL; + template.open_ex = NULL; if (!ossl_store_init_once()) return NULL; if (!RUN_ONCE(®istry_init, do_registry_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } CRYPTO_THREAD_write_lock(registry_lock); - loader = lh_OSSL_STORE_LOADER_retrieve(loader_register, &template); - - if (loader == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, - OSSL_STORE_R_UNREGISTERED_SCHEME); - ERR_add_error_data(2, "scheme=", scheme); - } + if (!ossl_store_register_init()) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR); + else if ((loader = lh_OSSL_STORE_LOADER_retrieve(loader_register, + &template)) == NULL) + ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME, + "scheme=%s", scheme); CRYPTO_THREAD_unlock(registry_lock); @@ -257,19 +257,17 @@ OSSL_STORE_LOADER *ossl_store_unregister_loader_int(const char *scheme) template.close = NULL; if (!RUN_ONCE(®istry_init, do_registry_init)) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, - ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); return NULL; } CRYPTO_THREAD_write_lock(registry_lock); - loader = lh_OSSL_STORE_LOADER_delete(loader_register, &template); - - if (loader == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, - OSSL_STORE_R_UNREGISTERED_SCHEME); - ERR_add_error_data(2, "scheme=", scheme); - } + if (!ossl_store_register_init()) + ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR); + else if ((loader = lh_OSSL_STORE_LOADER_delete(loader_register, + &template)) == NULL) + ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME, + "scheme=%s", scheme); CRYPTO_THREAD_unlock(registry_lock); @@ -284,7 +282,6 @@ OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme) void ossl_store_destroy_loaders_int(void) { - assert(lh_OSSL_STORE_LOADER_num_items(loader_register) == 0); lh_OSSL_STORE_LOADER_free(loader_register); loader_register = NULL; CRYPTO_THREAD_lock_free(registry_lock); @@ -300,6 +297,7 @@ int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER *loader, void *do_arg), void *do_arg) { - lh_OSSL_STORE_LOADER_doall_void(loader_register, do_function, do_arg); + if (ossl_store_register_init()) + lh_OSSL_STORE_LOADER_doall_void(loader_register, do_function, do_arg); return 1; } diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c new file mode 100644 index 0000000000..5848761a5e --- /dev/null +++ b/crypto/store/store_result.c @@ -0,0 +1,600 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/provider.h" +#include "internal/passphrase.h" +#include "crypto/evp.h" +#include "crypto/x509.h" +#include "store_local.h" + +#ifndef OSSL_OBJECT_PKCS12 +/* + * The object abstraction doesn't know PKCS#12, but we want to indicate + * it anyway, so we create our own. Since the public macros use positive + * numbers, negative ones should be fine. They must never slip out from + * this translation unit anyway. + */ +# define OSSL_OBJECT_PKCS12 -1 +#endif + +/* + * ossl_store_handle_load_result() is initially written to be a companion + * to our 'file:' scheme provider implementation, but has been made generic + * to serve others as well. + * + * This result handler takes any object abstraction (see provider-object(7)) + * and does the best it can with it. If the object is passed by value (not + * by reference), the contents are currently expected to be DER encoded. + * If an object type is specified, that will be respected; otherwise, this + * handler will guess the contents, by trying the following in order: + * + * 1. Decode it into an EVP_PKEY, using OSSL_DECODER. + * 2. Decode it into an X.509 certificate, using d2i_X509 / d2i_X509_AUX. + * 3. Decode it into an X.509 CRL, using d2i_X509_CRL. + * 4. Decode it into a PKCS#12 structure, using d2i_PKCS12 (*). + * + * For the 'file:' scheme implementation, this is division of labor. Since + * the libcrypto <-> provider interface currently doesn't support certain + * structures as first class objects, they must be unpacked from DER here + * rather than in the provider. The current exception is asymmetric keys, + * which can reside within the provider boundary, most of all thanks to + * OSSL_FUNC_keymgmt_load(), which allows loading the key material by + * reference. + */ + +struct extracted_param_data_st { + int object_type; + const char *data_type; + const char *utf8_data; + const void *octet_data; + size_t octet_data_size; + const void *ref; + size_t ref_size; + const char *desc; +}; + +static int try_name(struct extracted_param_data_st *, OSSL_STORE_INFO **); +static int try_key(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_STORE_CTX *, const OSSL_PROVIDER *, + OSSL_LIB_CTX *, const char *); +static int try_cert(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_LIB_CTX *, const char *); +static int try_crl(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_LIB_CTX *, const char *); +static int try_pkcs12(struct extracted_param_data_st *, OSSL_STORE_INFO **, + OSSL_STORE_CTX *, OSSL_LIB_CTX *, const char *); + +#define SET_ERR_MARK() ERR_set_mark() +#define CLEAR_ERR_MARK() \ + do { \ + int err = ERR_peek_last_error(); \ + \ + if (ERR_GET_LIB(err) == ERR_LIB_ASN1 \ + && (ERR_GET_REASON(err) == ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE \ + || ERR_GET_REASON(err) == ASN1_R_NO_MATCHING_CHOICE_TYPE \ + || ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR)) \ + ERR_pop_to_mark(); \ + else \ + ERR_clear_last_mark(); \ + } while(0) +#define RESET_ERR_MARK() \ + do { \ + CLEAR_ERR_MARK(); \ + SET_ERR_MARK(); \ + } while(0) + +int ossl_store_handle_load_result(const OSSL_PARAM params[], void *arg) +{ + struct ossl_load_result_data_st *cbdata = arg; + OSSL_STORE_INFO **v = &cbdata->v; + OSSL_STORE_CTX *ctx = cbdata->ctx; + const OSSL_PROVIDER *provider = + OSSL_STORE_LOADER_provider(ctx->fetched_loader); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(provider); + const char *propq = ctx->properties; + const OSSL_PARAM *p; + struct extracted_param_data_st helper_data; + + memset(&helper_data, 0, sizeof(helper_data)); + helper_data.object_type = OSSL_OBJECT_UNKNOWN; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_TYPE)) != NULL + && !OSSL_PARAM_get_int(p, &helper_data.object_type)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p != NULL + && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.data_type)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA); + if (p != NULL + && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.octet_data, + &helper_data.octet_data_size) + && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.utf8_data)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE); + if (p != NULL && !OSSL_PARAM_get_octet_string_ptr(p, &helper_data.ref, + &helper_data.ref_size)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DESC); + if (p != NULL && !OSSL_PARAM_get_utf8_string_ptr(p, &helper_data.desc)) + return 0; + + /* + * The helper functions return 0 on actual errors, otherwise 1, even if + * they didn't fill out |*v|. + */ + SET_ERR_MARK(); + if (!try_name(&helper_data, v)) + goto err; + RESET_ERR_MARK(); + if (!try_key(&helper_data, v, ctx, provider, libctx, propq)) + goto err; + RESET_ERR_MARK(); + if (!try_cert(&helper_data, v, libctx, propq)) + goto err; + RESET_ERR_MARK(); + if (!try_crl(&helper_data, v, libctx, propq)) + goto err; + RESET_ERR_MARK(); + if (!try_pkcs12(&helper_data, v, ctx, libctx, propq)) + goto err; + CLEAR_ERR_MARK(); + + return (*v != NULL); + err: + return 0; +} + +static int try_name(struct extracted_param_data_st *data, OSSL_STORE_INFO **v) +{ + if (data->object_type == OSSL_OBJECT_NAME) { + char *newname = NULL, *newdesc = NULL; + + if (data->utf8_data == NULL) + return 0; + if ((newname = OPENSSL_strdup(data->utf8_data)) == NULL + || (data->desc != NULL + && (newdesc = OPENSSL_strdup(data->desc)) == NULL) + || (*v = OSSL_STORE_INFO_new_NAME(newname)) == NULL) { + OPENSSL_free(newname); + OPENSSL_free(newdesc); + return 0; + } + OSSL_STORE_INFO_set0_NAME_description(*v, newdesc); + } + return 1; +} + +/* + * For the rest of the object types, the provider code may not know what + * type of data it gave us, so we may need to figure that out on our own. + * Therefore, we do check for OSSL_OBJECT_UNKNOWN everywhere below, and + * only return 0 on error if the object type is known. + */ + +static EVP_PKEY *try_key_ref(struct extracted_param_data_st *data, + OSSL_STORE_CTX *ctx, + const OSSL_PROVIDER *provider, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pk = NULL; + EVP_KEYMGMT *keymgmt = NULL; + void *keydata = NULL; + + /* If we have an object reference, we must have a data type */ + if (data->data_type == NULL) + return 0; + + keymgmt = EVP_KEYMGMT_fetch(libctx, data->data_type, propq); + if (keymgmt != NULL) { + /* + * There are two possible cases + * + * 1. The keymgmt is from the same provider as the loader, + * so we can use evp_keymgmt_load() + * 2. The keymgmt is from another provider, then we must + * do the export/import dance. + */ + if (EVP_KEYMGMT_provider(keymgmt) == provider) { + keydata = evp_keymgmt_load(keymgmt, data->ref, data->ref_size); + } else { + struct evp_keymgmt_util_try_import_data_st import_data; + OSSL_FUNC_store_export_object_fn *export_object = + ctx->fetched_loader->p_export_object; + + import_data.keymgmt = keymgmt; + import_data.keydata = NULL; + import_data.selection = OSSL_KEYMGMT_SELECT_ALL; + + if (export_object != NULL) { + /* + * No need to check for errors here, the value of + * |import_data.keydata| is as much an indicator. + */ + (void)export_object(ctx->loader_ctx, + data->ref, data->ref_size, + &evp_keymgmt_util_try_import, + &import_data); + } + + keydata = import_data.keydata; + } + } + if (keydata != NULL) + pk = evp_keymgmt_util_make_pkey(keymgmt, keydata); + EVP_KEYMGMT_free(keymgmt); + + return pk; +} + +static EVP_PKEY *try_key_value(struct extracted_param_data_st *data, + OSSL_STORE_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pk = NULL; + OSSL_DECODER_CTX *decoderctx = NULL; + const unsigned char *pdata = data->octet_data; + size_t pdatalen = data->octet_data_size; + + decoderctx = + OSSL_DECODER_CTX_new_by_EVP_PKEY(&pk, "DER", NULL, libctx, propq); + (void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg); + + /* No error if this couldn't be decoded */ + (void)OSSL_DECODER_from_data(decoderctx, &pdata, &pdatalen); + + OSSL_DECODER_CTX_free(decoderctx); + + return pk; +} + +typedef OSSL_STORE_INFO *store_info_new_fn(EVP_PKEY *); + +static EVP_PKEY *try_key_value_legacy(struct extracted_param_data_st *data, + store_info_new_fn **store_info_new, + OSSL_STORE_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_PKEY *pk = NULL; + const unsigned char *der = data->octet_data, *derp; + long der_len = (long)data->octet_data_size; + + SET_ERR_MARK(); + /* Try PUBKEY first, that's a real easy target */ + derp = der; + pk = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, propq); + if (pk != NULL) + *store_info_new = OSSL_STORE_INFO_new_PUBKEY; + RESET_ERR_MARK(); + + /* Try private keys next */ + if (pk == NULL) { + unsigned char *new_der = NULL; + X509_SIG *p8 = NULL; + PKCS8_PRIV_KEY_INFO *p8info = NULL; + + /* See if it's an encrypted PKCS#8 and decrypt it */ + derp = der; + if ((p8 = d2i_X509_SIG(NULL, &derp, der_len)) != NULL) { + char pbuf[PEM_BUFSIZE]; + size_t plen = 0; + + if (!cb(pbuf, sizeof(pbuf), &plen, NULL, cbarg)) { + ERR_raise(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_BAD_PASSWORD_READ); + } else { + const X509_ALGOR *alg = NULL; + const ASN1_OCTET_STRING *oct = NULL; + int len = 0; + + X509_SIG_get0(p8, &alg, &oct); + + /* + * No need to check the returned value, |new_der| + * will be NULL on error anyway. + */ + PKCS12_pbe_crypt(alg, pbuf, plen, + oct->data, oct->length, + &new_der, &len, 0); + der_len = len; + der = new_der; + } + X509_SIG_free(p8); + } + RESET_ERR_MARK(); + + /* + * If the encrypted PKCS#8 couldn't be decrypted, + * |der| is NULL + */ + if (der != NULL) { + /* Try to unpack an unencrypted PKCS#8, that's easy */ + derp = der; + p8info = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, der_len); + RESET_ERR_MARK(); + if (p8info != NULL) { + pk = EVP_PKCS82PKEY_ex(p8info, libctx, propq); + PKCS8_PRIV_KEY_INFO_free(p8info); + } + } + + if (pk != NULL) + *store_info_new = OSSL_STORE_INFO_new_PKEY; + + OPENSSL_free(new_der); + der = data->octet_data; + der_len = (long)data->octet_data_size; + } + CLEAR_ERR_MARK(); + + return pk; +} + +static int try_key(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_STORE_CTX *ctx, const OSSL_PROVIDER *provider, + OSSL_LIB_CTX *libctx, const char *propq) +{ + store_info_new_fn *store_info_new = NULL; + + if (data->object_type == OSSL_OBJECT_UNKNOWN + || data->object_type == OSSL_OBJECT_PKEY) { + EVP_PKEY *pk = NULL; + + /* Prefer key by reference than key by value */ + if (data->object_type == OSSL_OBJECT_PKEY && data->ref != NULL) { + pk = try_key_ref(data, ctx, provider, libctx, propq); + + /* + * If for some reason we couldn't get a key, it's an error. + * It indicates that while decoders could make a key reference, + * the keymgmt somehow couldn't handle it, or doesn't have a + * OSSL_FUNC_keymgmt_load function. + */ + if (pk == NULL) + return 0; + } else if (data->octet_data != NULL) { + OSSL_PASSPHRASE_CALLBACK *cb = ossl_pw_passphrase_callback_dec; + void *cbarg = &ctx->pwdata; + + pk = try_key_value(data, ctx, cb, cbarg, libctx, propq); + + /* + * Desperate last maneuver, in case the decoders don't support + * the data we have, then we try on our own to at least get a + * legacy key. + * This is the same as der2key_decode() does, but in a limited + * way and within the walls of libcrypto. + * + * TODO Remove this when #legacy keys are gone + */ + if (pk == NULL) + pk = try_key_value_legacy(data, &store_info_new, ctx, + cb, cbarg, libctx, propq); + } + + if (pk != NULL) { + data->object_type = OSSL_OBJECT_PKEY; + + if (store_info_new == NULL) { + /* + * We determined the object type for OSSL_STORE_INFO, which + * makes an explicit difference between an EVP_PKEY with just + * (domain) parameters and an EVP_PKEY with actual key + * material. + * The logic is that an EVP_PKEY with actual key material + * always has the public half. + */ + if (evp_keymgmt_util_has(pk, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) + store_info_new = OSSL_STORE_INFO_new_PKEY; + else if (evp_keymgmt_util_has(pk, + OSSL_KEYMGMT_SELECT_PUBLIC_KEY)) + store_info_new = OSSL_STORE_INFO_new_PUBKEY; + else + store_info_new = OSSL_STORE_INFO_new_PARAMS; + } + *v = store_info_new(pk); + } + + if (*v == NULL) + EVP_PKEY_free(pk); + } + + return 1; +} + +static int try_cert(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_LIB_CTX *libctx, const char *propq) +{ + if (data->object_type == OSSL_OBJECT_UNKNOWN + || data->object_type == OSSL_OBJECT_CERT) { + X509 *cert; + + /* + * In most cases, we can try to interpret the serialized + * data as a trusted cert (X509 + X509_AUX) and fall back + * to reading it as a normal cert (just X509), but if + * |data_type| (the PEM name) specifically declares it as a + * trusted cert, then no fallback should be engaged. + * |ignore_trusted| tells if the fallback can be used (1) + * or not (0). + */ + int ignore_trusted = 1; + + /* If we have a data type, it should be a PEM name */ + if (data->data_type != NULL + && (strcasecmp(data->data_type, PEM_STRING_X509_TRUSTED) == 0)) + ignore_trusted = 0; + + cert = d2i_X509_AUX(NULL, (const unsigned char **)&data->octet_data, + data->octet_data_size); + if (cert == NULL && ignore_trusted) + cert = d2i_X509(NULL, (const unsigned char **)&data->octet_data, + data->octet_data_size); + + if (cert != NULL) + /* We determined the object type */ + data->object_type = OSSL_OBJECT_CERT; + + if (cert != NULL && !x509_set0_libctx(cert, libctx, propq)) { + X509_free(cert); + cert = NULL; + } + + if (cert != NULL) + *v = OSSL_STORE_INFO_new_CERT(cert); + if (*v == NULL) + X509_free(cert); + } + + return 1; +} + +static int try_crl(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_LIB_CTX *libctx, const char *propq) +{ + if (data->object_type == OSSL_OBJECT_UNKNOWN + || data->object_type == OSSL_OBJECT_CRL) { + X509_CRL *crl; + + crl = d2i_X509_CRL(NULL, (const unsigned char **)&data->octet_data, + data->octet_data_size); + if (crl != NULL) + /* We determined the object type */ + data->object_type = OSSL_OBJECT_CRL; + + if (crl != NULL && !x509_crl_set0_libctx(crl, libctx, propq)) { + X509_CRL_free(crl); + crl = NULL; + } + + if (crl != NULL) + *v = OSSL_STORE_INFO_new_CRL(crl); + if (*v == NULL) + X509_CRL_free(crl); + } + + return 1; +} + +static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, + OSSL_STORE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) +{ + /* There is no specific object type for PKCS12 */ + if (data->object_type == OSSL_OBJECT_UNKNOWN) { + /* Initial parsing */ + PKCS12 *p12; + + if ((p12 = d2i_PKCS12(NULL, (const unsigned char **)&data->octet_data, + data->octet_data_size)) != NULL) { + char *pass = NULL; + char tpass[PEM_BUFSIZE]; + size_t tpass_len; + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + STACK_OF(X509) *chain = NULL; + + data->object_type = OSSL_OBJECT_PKCS12; + + if (PKCS12_verify_mac(p12, "", 0) + || PKCS12_verify_mac(p12, NULL, 0)) { + pass = ""; + } else { + static char prompt_info[] = "PKCS12 import pass phrase"; + OSSL_PARAM pw_params[] = { + OSSL_PARAM_utf8_string(OSSL_PASSPHRASE_PARAM_INFO, + prompt_info, + sizeof(prompt_info) - 1), + OSSL_PARAM_END + }; + + if (!ossl_pw_get_passphrase(tpass, sizeof(tpass), &tpass_len, + pw_params, 0, &ctx->pwdata)) { + ERR_raise(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR); + goto p12_end; + } + pass = tpass; + if (!PKCS12_verify_mac(p12, pass, strlen(pass))) { + ERR_raise(ERR_LIB_OSSL_STORE, + OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC); + goto p12_end; + } + } + + if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) { + STACK_OF(OSSL_STORE_INFO) *infos = NULL; + OSSL_STORE_INFO *osi_pkey = NULL; + OSSL_STORE_INFO *osi_cert = NULL; + OSSL_STORE_INFO *osi_ca = NULL; + int ok = 1; + + if ((infos = sk_OSSL_STORE_INFO_new_null()) != NULL) { + if (pkey != NULL) { + if ((osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL + /* clearing pkey here avoids case distinctions */ + && (pkey = NULL) == NULL + && sk_OSSL_STORE_INFO_push(infos, osi_pkey) != 0) + osi_pkey = NULL; + else + ok = 0; + } + if (ok && cert != NULL) { + if ((osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL + /* clearing cert here avoids case distinctions */ + && (cert = NULL) == NULL + && sk_OSSL_STORE_INFO_push(infos, osi_cert) != 0) + osi_cert = NULL; + else + ok = 0; + } + while (ok && sk_X509_num(chain) > 0) { + X509 *ca = sk_X509_value(chain, 0); + + if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) != NULL + && sk_X509_shift(chain) != NULL + && sk_OSSL_STORE_INFO_push(infos, osi_ca) != 0) + osi_ca = NULL; + else + ok = 0; + } + } + EVP_PKEY_free(pkey); + X509_free(cert); + sk_X509_pop_free(chain, X509_free); + OSSL_STORE_INFO_free(osi_pkey); + OSSL_STORE_INFO_free(osi_cert); + OSSL_STORE_INFO_free(osi_ca); + if (!ok) { + sk_OSSL_STORE_INFO_pop_free(infos, OSSL_STORE_INFO_free); + infos = NULL; + } + ctx->cached_info = infos; + } + } + p12_end: + PKCS12_free(p12); + *v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); + } + + return 1; +} diff --git a/crypto/store/store_strings.c b/crypto/store/store_strings.c index 84cfdcfe6b..3d4a8ea730 100644 --- a/crypto/store/store_strings.c +++ b/crypto/store/store_strings.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,7 @@ static char *type_strings[] = { "Name", /* OSSL_STORE_INFO_NAME */ "Parameters", /* OSSL_STORE_INFO_PARAMS */ + "Public key", /* OSSL_STORE_INFO_PUBKEY */ "Pkey", /* OSSL_STORE_INFO_PKEY */ "Certificate", /* OSSL_STORE_INFO_CERT */ "CRL" /* OSSL_STORE_INFO_CRL */ diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 8b60251e77..a2735332b8 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -49,7 +49,11 @@ CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) } pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + #if defined(__TANDEM) && defined(_SPT_MODEL_) + pthread_mutexattr_setkind_np(&attr,MUTEX_RECURSIVE_NP); + #else + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + #endif if (pthread_mutex_init(lock, &attr) != 0) { pthread_mutexattr_destroy(&attr); @@ -191,8 +195,6 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) } # ifndef FIPS_MODULE -/* TODO(3.0): No fork protection in FIPS module yet! */ - # ifdef OPENSSL_SYS_UNIX static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT; diff --git a/crypto/trace.c b/crypto/trace.c old mode 100755 new mode 100644 diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c index 85bf8c1f80..017afb7c07 100644 --- a/crypto/ui/ui_lib.c +++ b/crypto/ui/ui_lib.c @@ -15,8 +15,6 @@ #include #include "ui_local.h" -DEFINE_STACK_OF(UI_STRING) - UI *UI_new(void) { return UI_new_method(NULL); @@ -356,22 +354,22 @@ int UI_dup_error_string(UI *ui, const char *text) 0, 0, NULL); } -char *UI_construct_prompt(UI *ui, const char *object_desc, +char *UI_construct_prompt(UI *ui, const char *phrase_desc, const char *object_name) { char *prompt = NULL; - if (ui->meth->ui_construct_prompt != NULL) - prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name); + if (ui != NULL && ui->meth != NULL && ui->meth->ui_construct_prompt != NULL) + prompt = ui->meth->ui_construct_prompt(ui, phrase_desc, object_name); else { char prompt1[] = "Enter "; char prompt2[] = " for "; char prompt3[] = ":"; int len = 0; - if (object_desc == NULL) + if (phrase_desc == NULL) return NULL; - len = sizeof(prompt1) - 1 + strlen(object_desc); + len = sizeof(prompt1) - 1 + strlen(phrase_desc); if (object_name != NULL) len += sizeof(prompt2) - 1 + strlen(object_name); len += sizeof(prompt3) - 1; @@ -381,7 +379,7 @@ char *UI_construct_prompt(UI *ui, const char *object_desc, return NULL; } OPENSSL_strlcpy(prompt, prompt1, len + 1); - OPENSSL_strlcat(prompt, object_desc, len + 1); + OPENSSL_strlcat(prompt, phrase_desc, len + 1); if (object_name != NULL) { OPENSSL_strlcat(prompt, prompt2, len + 1); OPENSSL_strlcat(prompt, object_name, len + 1); @@ -690,10 +688,8 @@ int UI_method_set_data_duplicator(UI_METHOD *method, int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor) (UI *ui, - const char - *object_desc, - const char - *object_name)) + const char *, + const char *)) { if (method != NULL) { method->ui_construct_prompt = prompt_constructor; diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index ff6e4cf03c..b67b6c5648 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -22,8 +22,6 @@ #include "crypto/x509.h" #include "x509_local.h" -DEFINE_STACK_OF(X509_OBJECT) - struct lookup_dir_hashes_st { unsigned long hash; int suffix; @@ -49,12 +47,9 @@ static void free_dir(X509_LOOKUP *lu); static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret); -static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, - X509_LOOKUP_TYPE type, - const X509_NAME *name, - X509_OBJECT *ret, - OPENSSL_CTX *libctx, - const char *propq); +static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq); static X509_LOOKUP_METHOD x509_dir_lookup = { "Load certs from files in a directory", new_dir, /* new_item */ @@ -66,8 +61,8 @@ static X509_LOOKUP_METHOD x509_dir_lookup = { NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ - get_cert_by_subject_with_libctx, /* get_by_subject_with_libctx */ - NULL, /* ctrl_with_libctx */ + get_cert_by_subject_ex, /* get_by_subject_ex */ + NULL, /* ctrl_ex */ }; X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) @@ -219,12 +214,9 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) return 1; } -static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, - X509_LOOKUP_TYPE type, - const X509_NAME *name, - X509_OBJECT *ret, - OPENSSL_CTX *libctx, - const char *propq) +static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) { BY_DIR *ctx; union { @@ -292,6 +284,7 @@ static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, } for (;;) { char c = '/'; + #ifdef OPENSSL_SYS_VMS c = ent->dir[strlen(ent->dir) - 1]; if (c != ':' && c != '>' && c != ']') { @@ -305,7 +298,7 @@ static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, } else { c = '\0'; } -#endif + if (c == '\0') { /* * This is special. When c == '\0', no directory separator @@ -313,7 +306,9 @@ static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, */ BIO_snprintf(b->data, b->max, "%s%08lx.%s%d", ent->dir, h, postfix, k); - } else { + } else +#endif + { BIO_snprintf(b->data, b->max, "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); } @@ -329,8 +324,8 @@ static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, #endif /* found one. */ if (type == X509_LU_X509) { - if ((X509_load_cert_file_with_libctx(xl, b->data, ent->dir_type, - libctx, propq)) == 0) + if ((X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx, + propq)) == 0) break; } else if (type == X509_LU_CRL) { if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) @@ -408,5 +403,5 @@ static int get_cert_by_subject_with_libctx(X509_LOOKUP *xl, static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret) { - return get_cert_by_subject_with_libctx(xl, type, name, ret, NULL, NULL); + return get_cert_by_subject_ex(xl, type, name, ret, NULL, NULL); } diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index d5e6dde4f8..16d2971731 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -17,13 +17,11 @@ #include #include "x509_local.h" -DEFINE_STACK_OF(X509_INFO) - static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); -static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, - const char *argc, long argl, char **ret, - OPENSSL_CTX *libctx, const char *propq); +static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret, OSSL_LIB_CTX *libctx, + const char *propq); static X509_LOOKUP_METHOD x509_file_lookup = { @@ -37,8 +35,8 @@ static X509_LOOKUP_METHOD x509_file_lookup = { NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ - NULL, /* get_by_subject_with_libctx */ - by_file_ctrl_with_libctx, /* ctrl_with_libctx */ + NULL, /* get_by_subject_ex */ + by_file_ctrl_ex, /* ctrl_ex */ }; X509_LOOKUP_METHOD *X509_LOOKUP_file(void) @@ -46,9 +44,9 @@ X509_LOOKUP_METHOD *X509_LOOKUP_file(void) return &x509_file_lookup; } -static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, - const char *argp, long argl, char **ret, - OPENSSL_CTX *libctx, const char *propq) +static int by_file_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **ret, OSSL_LIB_CTX *libctx, + const char *propq) { int ok = 0; const char *file; @@ -58,12 +56,11 @@ static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, if (argl == X509_FILETYPE_DEFAULT) { file = ossl_safe_getenv(X509_get_default_cert_file_env()); if (file) - ok = (X509_load_cert_crl_file_with_libctx(ctx, file, - X509_FILETYPE_PEM, - libctx, propq) != 0); + ok = (X509_load_cert_crl_file_ex(ctx, file, X509_FILETYPE_PEM, + libctx, propq) != 0); else - ok = (X509_load_cert_crl_file_with_libctx( + ok = (X509_load_cert_crl_file_ex( ctx, X509_get_default_cert_file(), X509_FILETYPE_PEM, libctx, propq) != 0); @@ -72,12 +69,11 @@ static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, } } else { if (argl == X509_FILETYPE_PEM) - ok = (X509_load_cert_crl_file_with_libctx(ctx, argp, - X509_FILETYPE_PEM, - libctx, propq) != 0); + ok = (X509_load_cert_crl_file_ex(ctx, argp, X509_FILETYPE_PEM, + libctx, propq) != 0); else - ok = (X509_load_cert_file_with_libctx(ctx, argp, (int)argl, - libctx, propq) != 0); + ok = (X509_load_cert_file_ex(ctx, argp, (int)argl, libctx, + propq) != 0); } break; } @@ -87,11 +83,11 @@ static int by_file_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **ret) { - return by_file_ctrl_with_libctx(ctx, cmd, argp, argl, ret, NULL, NULL); + return by_file_ctrl_ex(ctx, cmd, argp, argl, ret, NULL, NULL); } -int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type, - OPENSSL_CTX *libctx, const char *propq) +int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; BIO *in = NULL; @@ -109,7 +105,7 @@ int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type X509err(0, X509_R_BAD_X509_FILETYPE); goto err; } - x = X509_new_with_libctx(libctx, propq); + x = X509_new_ex(libctx, propq); if (x == NULL) { X509err(0, ERR_R_MALLOC_FAILURE); goto err; @@ -155,7 +151,7 @@ int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) { - return X509_load_cert_file_with_libctx(ctx, file, type, NULL, NULL); + return X509_load_cert_file_ex(ctx, file, type, NULL, NULL); } int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) @@ -215,9 +211,8 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) return ret; } -int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file, - int type, OPENSSL_CTX *libctx, - const char *propq) +int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(X509_INFO) *inf; X509_INFO *itmp; @@ -225,13 +220,13 @@ int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file, int i, count = 0; if (type != X509_FILETYPE_PEM) - return X509_load_cert_file_with_libctx(ctx, file, type, libctx, propq); + return X509_load_cert_file_ex(ctx, file, type, libctx, propq); in = BIO_new_file(file, "r"); if (!in) { X509err(0, ERR_R_SYS_LIB); return 0; } - inf = PEM_X509_INFO_read_bio_with_libctx(in, NULL, NULL, "", libctx, propq); + inf = PEM_X509_INFO_read_bio_ex(in, NULL, NULL, "", libctx, propq); BIO_free(in); if (!inf) { X509err(0, ERR_R_PEM_LIB); @@ -259,6 +254,6 @@ int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file, int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) { - return X509_load_cert_crl_file_with_libctx(ctx, file, type, NULL, NULL); + return X509_load_cert_crl_file_ex(ctx, file, type, NULL, NULL); } diff --git a/crypto/x509/by_store.c b/crypto/x509/by_store.c index debb76150d..29d9700ab1 100644 --- a/crypto/x509/by_store.c +++ b/crypto/x509/by_store.c @@ -12,19 +12,16 @@ #include "crypto/x509.h" #include "x509_local.h" -DEFINE_STACK_OF_STRING() - /* Generic object loader, given expected type and criterion */ static int cache_objects(X509_LOOKUP *lctx, const char *uri, const OSSL_STORE_SEARCH *criterion, - int depth, OPENSSL_CTX *libctx, const char *propq) + int depth, OSSL_LIB_CTX *libctx, const char *propq) { int ok = 0; OSSL_STORE_CTX *ctx = NULL; X509_STORE *xstore = X509_LOOKUP_get_store(lctx); - if ((ctx = OSSL_STORE_open_with_libctx(uri, libctx, propq, - NULL, NULL, NULL, NULL)) == NULL) + if ((ctx = OSSL_STORE_open_ex(uri, libctx, propq, NULL, NULL, NULL, NULL)) == NULL) return 0; /* @@ -107,10 +104,9 @@ static void by_store_free(X509_LOOKUP *ctx) sk_OPENSSL_STRING_pop_free(uris, free_uri); } -static int by_store_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, - const char *argp, long argl, - char **retp, - OPENSSL_CTX *libctx, const char *propq) +static int by_store_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **retp, OSSL_LIB_CTX *libctx, + const char *propq) { switch (cmd) { case X509_L_ADD_STORE: @@ -140,12 +136,12 @@ static int by_store_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, static int by_store_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, char **retp) { - return by_store_ctrl_with_libctx(ctx, cmd, argp, argl, retp, NULL, NULL); + return by_store_ctrl_ex(ctx, cmd, argp, argl, retp, NULL, NULL); } static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const OSSL_STORE_SEARCH *criterion, X509_OBJECT *ret, - OPENSSL_CTX *libctx, const char *propq) + OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx); int i; @@ -161,9 +157,9 @@ static int by_store(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, return ok; } -static int by_store_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret, - OPENSSL_CTX *libctx, const char *propq) +static int by_store_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) { OSSL_STORE_SEARCH *criterion = OSSL_STORE_SEARCH_by_name((X509_NAME *)name); /* won't modify it */ @@ -218,7 +214,7 @@ static int by_store_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, static int by_store_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret) { - return by_store_subject_with_libctx(ctx, type, name, ret, NULL, NULL); + return by_store_subject_ex(ctx, type, name, ret, NULL, NULL); } /* @@ -238,8 +234,8 @@ static X509_LOOKUP_METHOD x509_store_lookup = { NULL, /* get_by_issuer_serial */ NULL, /* get_by_fingerprint */ NULL, /* get_by_alias */ - by_store_subject_with_libctx, - by_store_ctrl_with_libctx + by_store_subject_ex, + by_store_ctrl_ex }; X509_LOOKUP_METHOD *X509_LOOKUP_store(void) diff --git a/crypto/x509/pcy_cache.c b/crypto/x509/pcy_cache.c index 61423bf2c2..608ccfeb1c 100644 --- a/crypto/x509/pcy_cache.c +++ b/crypto/x509/pcy_cache.c @@ -14,8 +14,6 @@ #include "pcy_local.h" -DEFINE_STACK_OF(POLICYINFO) - static int policy_data_cmp(const X509_POLICY_DATA *const *a, const X509_POLICY_DATA *const *b); static int policy_cache_set_int(long *out, ASN1_INTEGER *value); diff --git a/crypto/x509/pcy_data.c b/crypto/x509/pcy_data.c index 6b509cf457..9499f94dff 100644 --- a/crypto/x509/pcy_data.c +++ b/crypto/x509/pcy_data.c @@ -13,9 +13,6 @@ #include "pcy_local.h" -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF(POLICYQUALINFO) - /* Policy Node routines */ void policy_data_free(X509_POLICY_DATA *data) diff --git a/crypto/x509/pcy_lib.c b/crypto/x509/pcy_lib.c index 23baa2db1b..c4740a0a30 100644 --- a/crypto/x509/pcy_lib.c +++ b/crypto/x509/pcy_lib.c @@ -13,8 +13,6 @@ #include "pcy_local.h" -DEFINE_STACK_OF(X509_POLICY_NODE) - /* accessor functions */ /* X509_POLICY_TREE stuff */ diff --git a/crypto/x509/pcy_map.c b/crypto/x509/pcy_map.c index 0dec624525..a1210ef37f 100644 --- a/crypto/x509/pcy_map.c +++ b/crypto/x509/pcy_map.c @@ -14,9 +14,6 @@ #include "pcy_local.h" -DEFINE_STACK_OF(POLICY_MAPPING) -DEFINE_STACK_OF(ASN1_OBJECT) - /* * Set policy mapping entries in cache. Note: this modifies the passed * POLICY_MAPPINGS structure diff --git a/crypto/x509/pcy_node.c b/crypto/x509/pcy_node.c index baa4fa8d32..d2b43814bd 100644 --- a/crypto/x509/pcy_node.c +++ b/crypto/x509/pcy_node.c @@ -14,9 +14,6 @@ #include "pcy_local.h" -DEFINE_STACK_OF(X509_POLICY_NODE) -DEFINE_STACK_OF(ASN1_OBJECT) - static int node_cmp(const X509_POLICY_NODE *const *a, const X509_POLICY_NODE *const *b) { diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c index 30879197f8..3ee30745d2 100644 --- a/crypto/x509/pcy_tree.c +++ b/crypto/x509/pcy_tree.c @@ -14,10 +14,6 @@ #include "pcy_local.h" -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_POLICY_NODE) - static void expected_print(BIO *channel, X509_POLICY_LEVEL *lev, X509_POLICY_NODE *node, int indent) diff --git a/crypto/x509/t_crl.c b/crypto/x509/t_crl.c index 0824bb6def..44be2f237b 100644 --- a/crypto/x509/t_crl.c +++ b/crypto/x509/t_crl.c @@ -15,8 +15,6 @@ #include #include -DEFINE_STACK_OF(X509_REVOKED) - #ifndef OPENSSL_NO_STDIO int X509_CRL_print_fp(FILE *fp, X509_CRL *x) { diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c index e1ee12de95..abcca0a8f5 100644 --- a/crypto/x509/t_req.c +++ b/crypto/x509/t_req.c @@ -17,8 +17,6 @@ #include #include -DEFINE_STACK_OF(X509_EXTENSION) - #ifndef OPENSSL_NO_STDIO int X509_REQ_print_fp(FILE *fp, X509_REQ *x) { diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c index 199f88857b..2d0ccd8a68 100644 --- a/crypto/x509/t_x509.c +++ b/crypto/x509/t_x509.c @@ -17,9 +17,6 @@ #include "crypto/asn1.h" #include "crypto/x509.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(ASN1_OBJECT) - #ifndef OPENSSL_NO_STDIO int X509_print_fp(FILE *fp, X509 *x) { @@ -200,9 +197,10 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } } - if (!(cflag & X509_FLAG_NO_EXTENSIONS)) - X509V3_extensions_print(bp, "X509v3 extensions", - X509_get0_extensions(x), cflag, 8); + if (!(cflag & X509_FLAG_NO_EXTENSIONS) + && !X509V3_extensions_print(bp, "X509v3 extensions", + X509_get0_extensions(x), cflag, 8)) + goto err; if (!(cflag & X509_FLAG_NO_SIGDUMP)) { const X509_ALGOR *sig_alg; @@ -415,7 +413,8 @@ int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags) if (X509_cmp_current_time(X509_get0_notAfter(cert)) < 0) if (BIO_printf(bio, " no more valid\n") <= 0) return 0; - return X509_print_ex(bio, cert, flags, ~(neg_cflags)); + return X509_print_ex(bio, cert, flags, + ~neg_cflags & ~X509_FLAG_EXTENSIONS_ONLY_KID); } static int print_certs(BIO *bio, const STACK_OF(X509) *certs) @@ -427,8 +426,15 @@ static int print_certs(BIO *bio, const STACK_OF(X509) *certs) for (i = 0; i < sk_X509_num(certs); i++) { X509 *cert = sk_X509_value(certs, i); - if (cert != NULL && !x509_print_ex_brief(bio, cert, 0)) - return 0; + + if (cert != NULL) { + if (!x509_print_ex_brief(bio, cert, 0)) + return 0; + if (!X509V3_extensions_print(bio, NULL, + X509_get0_extensions(cert), + X509_FLAG_EXTENSIONS_ONLY_KID, 8)) + return 0; + } } return 1; } diff --git a/crypto/x509/v3_addr.c b/crypto/x509/v3_addr.c index d965d74553..7d4e99be5a 100644 --- a/crypto/x509/v3_addr.c +++ b/crypto/x509/v3_addr.c @@ -26,11 +26,6 @@ #ifndef OPENSSL_NO_RFC3779 -DEFINE_STACK_OF(IPAddressOrRange) -DEFINE_STACK_OF(IPAddressFamily) -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(X509) - /* * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. */ @@ -1262,7 +1257,7 @@ static int addr_validate_path_internal(X509_STORE_CTX *ctx, || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, fc->ipAddressChoice->u.addressesOrRanges, length_from_afi(X509v3_addr_get_afi(fc)))) - sk_IPAddressFamily_set(child, j, fp); + (void)sk_IPAddressFamily_set(child, j, fp); else validation_err(X509_V_ERR_UNNESTED_RESOURCE); } diff --git a/crypto/x509/v3_admis.c b/crypto/x509/v3_admis.c index 2fbb11bdaf..0dfd088eb4 100644 --- a/crypto/x509/v3_admis.c +++ b/crypto/x509/v3_admis.c @@ -20,11 +20,6 @@ #include "v3_admis.h" #include "ext_dat.h" -DEFINE_STACK_OF(ADMISSIONS) -DEFINE_STACK_OF(PROFESSION_INFO) -DEFINE_STACK_OF(ASN1_STRING) -DEFINE_STACK_OF(ASN1_OBJECT) - ASN1_SEQUENCE(NAMING_AUTHORITY) = { ASN1_OPT(NAMING_AUTHORITY, namingAuthorityId, ASN1_OBJECT), ASN1_OPT(NAMING_AUTHORITY, namingAuthorityUrl, ASN1_IA5STRING), diff --git a/crypto/x509/v3_akey.c b/crypto/x509/v3_akey.c index 65019a5a12..a3061c9a8f 100644 --- a/crypto/x509/v3_akey.c +++ b/crypto/x509/v3_akey.c @@ -15,9 +15,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(GENERAL_NAME) - static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, AUTHORITY_KEYID *akeyid, STACK_OF(CONF_VALUE) diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c index dd45546f6c..caa2f23220 100644 --- a/crypto/x509/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -14,9 +14,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(GENERAL_NAME) - static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c index 0fc7641386..93b345a0b8 100644 --- a/crypto/x509/v3_asid.c +++ b/crypto/x509/v3_asid.c @@ -56,10 +56,6 @@ IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) -DEFINE_STACK_OF(ASIdOrRange) -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(X509) - /* * i2r method for an ASIdentifierChoice. */ diff --git a/crypto/x509/v3_bcons.c b/crypto/x509/v3_bcons.c index 01d38473a3..7a06a9d0ff 100644 --- a/crypto/x509/v3_bcons.c +++ b/crypto/x509/v3_bcons.c @@ -16,8 +16,6 @@ #include "ext_dat.h" #include "x509_local.h" -DEFINE_STACK_OF(CONF_VALUE) - static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, BASIC_CONSTRAINTS *bcons, STACK_OF(CONF_VALUE) diff --git a/crypto/x509/v3_bitst.c b/crypto/x509/v3_bitst.c index 02d40863a6..21511603c2 100644 --- a/crypto/x509/v3_bitst.c +++ b/crypto/x509/v3_bitst.c @@ -13,8 +13,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) - static BIT_STRING_BITNAME ns_cert_type_table[] = { {0, "SSL Client", "client"}, {1, "SSL Server", "server"}, diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c index 88e29f9cc4..918e96e709 100644 --- a/crypto/x509/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -17,9 +17,6 @@ #include "crypto/x509.h" #include -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(X509_EXTENSION) - static int v3_check_critical(const char **value); static int v3_check_generic(const char **value); static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c index 6b507f40d7..9a227e4058 100644 --- a/crypto/x509/v3_cpols.c +++ b/crypto/x509/v3_cpols.c @@ -18,11 +18,6 @@ #include "pcy_local.h" #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(POLICYINFO) -DEFINE_STACK_OF(POLICYQUALINFO) -DEFINE_STACK_OF(ASN1_INTEGER) - /* Certificate policies extension support: this one is a bit complex... */ static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c index b54346d036..81ea31b16f 100644 --- a/crypto/x509/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -18,11 +18,6 @@ #include "ext_dat.h" #include "x509_local.h" -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(DIST_POINT) -DEFINE_STACK_OF(X509_NAME_ENTRY) - static void *v2i_crld(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, @@ -485,30 +480,31 @@ static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, return 1; } +/* Append any nameRelativeToCRLIssuer in dpn to iname, set in dpn->dpname */ int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname) { int i; STACK_OF(X509_NAME_ENTRY) *frag; X509_NAME_ENTRY *ne; - if (!dpn || (dpn->type != 1)) + + if (dpn == NULL || dpn->type != 1) return 1; frag = dpn->name.relativename; + X509_NAME_free(dpn->dpname); /* just in case it was already set */ dpn->dpname = X509_NAME_dup(iname); - if (!dpn->dpname) + if (dpn->dpname == NULL) return 0; for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { ne = sk_X509_NAME_ENTRY_value(frag, i); - if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) + goto err; } /* generate cached encoding of name */ - if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - return 1; + if (i2d_X509_NAME(dpn->dpname, NULL) >= 0) + return 1; + + err: + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; } diff --git a/crypto/x509/v3_extku.c b/crypto/x509/v3_extku.c index 7769bc9931..b9a1447b82 100644 --- a/crypto/x509/v3_extku.c +++ b/crypto/x509/v3_extku.c @@ -14,9 +14,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF(CONF_VALUE) - static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); diff --git a/crypto/x509/v3_info.c b/crypto/x509/v3_info.c index 489daa7199..3711b51e18 100644 --- a/crypto/x509/v3_info.c +++ b/crypto/x509/v3_info.c @@ -15,9 +15,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(ACCESS_DESCRIPTION) -DEFINE_STACK_OF(CONF_VALUE) - static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, STACK_OF(CONF_VALUE) diff --git a/crypto/x509/v3_ist.c b/crypto/x509/v3_ist.c index ceb127f637..6db4f19913 100644 --- a/crypto/x509/v3_ist.c +++ b/crypto/x509/v3_ist.c @@ -15,8 +15,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) - /* * Issuer Sign Tool (1.2.643.100.112) The name of the tool used to signs the subject (ASN1_SEQUENCE) * This extention is required to obtain the status of a qualified certificate at Russian Federation. diff --git a/crypto/x509/v3_lib.c b/crypto/x509/v3_lib.c index b1e32bb419..1069a9f24a 100644 --- a/crypto/x509/v3_lib.c +++ b/crypto/x509/v3_lib.c @@ -16,9 +16,6 @@ #include "ext_dat.h" -DEFINE_STACK_OF(X509V3_EXT_METHOD) -DEFINE_STACK_OF(X509_EXTENSION) - static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; static int ext_cmp(const X509V3_EXT_METHOD *const *a, diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c index 4543ec2e11..6af8edecdb 100644 --- a/crypto/x509/v3_ncons.c +++ b/crypto/x509/v3_ncons.c @@ -17,12 +17,9 @@ #include #include "crypto/x509.h" +#include "crypto/punycode.h" #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(GENERAL_SUBTREE) - static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); @@ -38,6 +35,7 @@ static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); static int nc_dn(const X509_NAME *sub, const X509_NAME *nm); static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_email_eai(ASN1_UTF8STRING *sub, ASN1_IA5STRING *eml); static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base); @@ -459,6 +457,14 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) { GENERAL_SUBTREE *sub; int i, r, match = 0; + /* + * We need to compare not gen->type field but an "effective" type because + * the otherName field may contain EAI email address treated specially + * according to RFC 8398, section 6 + */ + int effective_type = ((gen->type == GEN_OTHERNAME) && + (OBJ_obj2nid(gen->d.otherName->type_id) == + NID_id_on_SmtpUTF8Mailbox)) ? GEN_EMAIL : gen->type; /* * Permitted subtrees: if any subtrees exist of matching the type at @@ -467,7 +473,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); - if (gen->type != sub->base->type) + if (effective_type != sub->base->type) continue; if (!nc_minmax_valid(sub)) return X509_V_ERR_SUBTREE_MINMAX; @@ -490,7 +496,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); - if (gen->type != sub->base->type) + if (effective_type != sub->base->type) continue; if (!nc_minmax_valid(sub)) return X509_V_ERR_SUBTREE_MINMAX; @@ -509,7 +515,14 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) { - switch (base->type) { + switch (gen->type) { + case GEN_OTHERNAME: + /* + * We are here only when we have SmtpUTF8 name, + * so we match the value of othername with base->d.rfc822Name + */ + return nc_email_eai(gen->d.otherName->value->value.utf8string, + base->d.rfc822Name); case GEN_DIRNAME: return nc_dn(gen->d.directoryName, base->d.directoryName); @@ -577,13 +590,59 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) } +/* + * This function implements comparison between ASCII/U-label in eml + * and A-label in base according to RFC 8398, section 6. + * Convert base to U-label and ASCII-parts of domain names, for base + * Octet-to-octet comparison of `eml` and `base` hostname parts + * (ASCII-parts should be compared in case-insensitive manner) + */ +static int nc_email_eai(ASN1_UTF8STRING *eml, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; + const char *emlat = strrchr(emlptr, '@'); + + char ulabel[256]; + size_t size = sizeof(ulabel) - 1; + + if (emlat == NULL) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + memset(ulabel, 0, sizeof(ulabel)); + /* Special case: initial '.' is RHS match */ + if (*baseptr == '.') { + ulabel[0] = '.'; + size -= 1; + if (ossl_a2ulabel(baseptr, ulabel + 1, &size) <= 0) + return X509_V_ERR_UNSPECIFIED; + + if ((size_t)eml->length > size + 1) { + emlptr += eml->length - (size + 1); + if (ia5casecmp(ulabel, emlptr) == 0) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + emlptr = emlat + 1; + if (ossl_a2ulabel(baseptr, ulabel, &size) <= 0) + return X509_V_ERR_UNSPECIFIED; + /* Just have hostname left to match: case insensitive */ + if (ia5casecmp(ulabel, emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} + static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) { const char *baseptr = (char *)base->data; const char *emlptr = (char *)eml->data; - const char *baseat = strchr(baseptr, '@'); - const char *emlat = strchr(emlptr, '@'); + const char *baseat = strrchr(baseptr, '@'); + const char *emlat = strrchr(emlptr, '@'); if (!emlat) return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; /* Special case: initial '.' is RHS match */ diff --git a/crypto/x509/v3_pci.c b/crypto/x509/v3_pci.c index 714733684b..febb07f7d4 100644 --- a/crypto/x509/v3_pci.c +++ b/crypto/x509/v3_pci.c @@ -49,8 +49,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) - static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, BIO *out, int indent); static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, diff --git a/crypto/x509/v3_pcons.c b/crypto/x509/v3_pcons.c index 88a9497504..e61a14e254 100644 --- a/crypto/x509/v3_pcons.c +++ b/crypto/x509/v3_pcons.c @@ -15,8 +15,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(CONF_VALUE) - static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *bcons, STACK_OF(CONF_VALUE) *extlist); diff --git a/crypto/x509/v3_pmaps.c b/crypto/x509/v3_pmaps.c index 23aefb196c..a2b95c48e4 100644 --- a/crypto/x509/v3_pmaps.c +++ b/crypto/x509/v3_pmaps.c @@ -14,9 +14,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(POLICY_MAPPING) -DEFINE_STACK_OF(CONF_VALUE) - static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD diff --git a/crypto/x509/v3_prn.c b/crypto/x509/v3_prn.c index aa902204f0..1e4516a713 100644 --- a/crypto/x509/v3_prn.c +++ b/crypto/x509/v3_prn.c @@ -14,9 +14,6 @@ #include #include -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(X509_EXTENSION) - /* Extension printing routines */ static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen, @@ -156,10 +153,15 @@ int X509V3_extensions_print(BIO *bp, const char *title, for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + obj = X509_EXTENSION_get_object(ex); + if ((flag & X509_FLAG_EXTENSIONS_ONLY_KID) != 0 + && OBJ_obj2nid(obj) != NID_subject_key_identifier + && OBJ_obj2nid(obj) != NID_authority_key_identifier) + continue; if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) return 0; - obj = X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bp, obj); j = X509_EXTENSION_get_critical(ex); if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index 9e0190a038..fd512419f0 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -16,11 +16,6 @@ #include "internal/tsan_assist.h" #include "x509_local.h" -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(DIST_POINT) -DEFINE_STACK_OF(X509_PURPOSE) -DEFINE_STACK_OF(ASN1_OBJECT) - static int check_ssl_ca(const X509 *x); static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); @@ -288,6 +283,7 @@ int X509_supported_extension(X509_EXTENSION *ex) NID_sbgp_ipAddrBlock, /* 290 */ NID_sbgp_autonomousSysNum, /* 291 */ #endif + NID_id_pkix_OCSP_noCheck, /* 369 */ NID_policy_constraints, /* 401 */ NID_proxyCertInfo, /* 663 */ NID_name_constraints, /* 666 */ @@ -305,34 +301,49 @@ int X509_supported_extension(X509_EXTENSION *ex) return 0; } -static int setup_dp(X509 *x, DIST_POINT *dp) +/* return 1 on success, 0 if x is invalid, -1 on (internal) error */ +static int setup_dp(const X509 *x, DIST_POINT *dp) { const X509_NAME *iname = NULL; int i; - if (dp->reasons) { + if (dp->distpoint == NULL && sk_GENERAL_NAME_num(dp->CRLissuer) <= 0) { + X509err(0, X509_R_INVALID_DISTPOINT); + return 0; + } + if (dp->reasons != NULL) { if (dp->reasons->length > 0) dp->dp_reasons = dp->reasons->data[0]; if (dp->reasons->length > 1) dp->dp_reasons |= (dp->reasons->data[1] << 8); dp->dp_reasons &= CRLDP_ALL_REASONS; - } else + } else { dp->dp_reasons = CRLDP_ALL_REASONS; - if (!dp->distpoint || (dp->distpoint->type != 1)) + } + if (dp->distpoint == NULL || dp->distpoint->type != 1) return 1; + + /* handle name fragment given by nameRelativeToCRLIssuer */ + /* + * Note that the below way of determining iname is not really compliant + * with https://tools.ietf.org/html/rfc5280#section-4.2.1.13 + * According to it, sk_GENERAL_NAME_num(dp->CRLissuer) MUST be <= 1 + * and any CRLissuer could be of type different to GEN_DIRNAME. + */ for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { iname = gen->d.directoryName; break; } } - if (!iname) + if (iname == NULL) iname = X509_get_issuer_name(x); - - return DIST_POINT_set_dpname(dp->distpoint, iname); + return DIST_POINT_set_dpname(dp->distpoint, iname) ? 1 : -1; } +/* return 1 on success, 0 if x is invalid, -1 on (internal) error */ static int setup_crldp(X509 *x) { int i; @@ -340,9 +351,12 @@ static int setup_crldp(X509 *x) x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &i, NULL); if (x->crldp == NULL && i != -1) return 0; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { - if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) - return 0; + int res = setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); + + if (res < 1) + return res; } return 1; } @@ -373,6 +387,7 @@ static int check_sig_alg_match(const EVP_PKEY *pkey, const X509 *subject) /* * Cache info on various X.509v3 extensions and further derived information, * e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields. + * X509_SIG_INFO_VALID is set in x->flags if x->siginf was filled successfully. * Set EXFLAG_INVALID and return 0 in case the certificate is invalid. */ int x509v3_cache_extensions(X509 *x) @@ -382,8 +397,8 @@ int x509v3_cache_extensions(X509 *x) ASN1_BIT_STRING *usage; ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; - X509_EXTENSION *ex; int i; + int res; #ifdef tsan_ld_acq /* fast lock-free check, see end of the function for details. */ @@ -396,31 +411,36 @@ int x509v3_cache_extensions(X509 *x) CRYPTO_THREAD_unlock(x->lock); return (x->ex_flags & EXFLAG_INVALID) == 0; } + ERR_set_mark(); + /* Cache the SHA1 digest of the cert */ if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL)) - x->ex_flags |= EXFLAG_INVALID; + /* + * Note that the cert is marked invalid also on internal malloc failure + * or on failure of EVP_MD_fetch(), potentially called by X509_digest(). + */ + x->ex_flags |= EXFLAG_INVALID; /* V1 should mean no extensions ... */ if (X509_get_version(x) == 0) x->ex_flags |= EXFLAG_V1; /* Handle basic constraints */ + x->ex_pathlen = -1; if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &i, NULL)) != NULL) { if (bs->ca) x->ex_flags |= EXFLAG_CA; if (bs->pathlen != NULL) { + /* + * the error case !bs->ca is checked by check_chain() + * in case ctx->param->flags & X509_V_FLAG_X509_STRICT + */ if (bs->pathlen->type == V_ASN1_NEG_INTEGER) { + X509err(0, X509V3_R_NEGATIVE_PATHLEN); x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; } else { x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); - if (!bs->ca && x->ex_pathlen != 0) { - x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; - } } - } else { - x->ex_pathlen = -1; } BASIC_CONSTRAINTS_free(bs); x->ex_flags |= EXFLAG_BCONS; @@ -435,9 +455,9 @@ int x509v3_cache_extensions(X509 *x) || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { x->ex_flags |= EXFLAG_INVALID; } - if (pci->pcPathLengthConstraint) { + if (pci->pcPathLengthConstraint != NULL) x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); - } else + else x->ex_pcpathlen = -1; PROXY_CERT_INFO_EXTENSION_free(pci); x->ex_flags |= EXFLAG_PROXY; @@ -445,7 +465,7 @@ int x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_INVALID; } - /* Handle (basic and extended) key usage */ + /* Handle (basic) key usage */ if ((usage = X509_get_ext_d2i(x, NID_key_usage, &i, NULL)) != NULL) { x->ex_kusage = 0; if (usage->length > 0) { @@ -455,9 +475,16 @@ int x509v3_cache_extensions(X509 *x) } x->ex_flags |= EXFLAG_KUSAGE; ASN1_BIT_STRING_free(usage); + /* Check for empty key usage according to RFC 5280 section 4.2.1.3 */ + if (x->ex_kusage == 0) { + X509err(0, X509V3_R_EMPTY_KEY_USAGE); + x->ex_flags |= EXFLAG_INVALID; + } } else if (i != -1) { x->ex_flags |= EXFLAG_INVALID; } + + /* Handle extended key usage */ x->ex_xkusage = 0; if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &i, NULL)) != NULL) { x->ex_flags |= EXFLAG_XKUSAGE; @@ -492,6 +519,7 @@ int x509v3_cache_extensions(X509 *x) x->ex_xkusage |= XKU_ANYEKU; break; default: + /* ignore unknown extended key usage */ break; } } @@ -516,6 +544,7 @@ int x509v3_cache_extensions(X509 *x) x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &i, NULL); if (x->skid == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &i, NULL); if (x->akid == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; @@ -537,8 +566,13 @@ int x509v3_cache_extensions(X509 *x) x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); if (x->nc == NULL && i != -1) x->ex_flags |= EXFLAG_INVALID; - if (!setup_crldp(x)) + + /* Handle CRL distribution point entries */ + res = setup_crldp(x); + if (res == 0) x->ex_flags |= EXFLAG_INVALID; + else if (res < 0) + goto err; #ifndef OPENSSL_NO_RFC3779 x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL); @@ -549,9 +583,10 @@ int x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_INVALID; #endif for (i = 0; i < X509_get_ext_count(x); i++) { - ex = X509_get_ext(x, i); - if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) - == NID_freshest_crl) + X509_EXTENSION *ex = X509_get_ext(x, i); + int nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (nid == NID_freshest_crl) x->ex_flags |= EXFLAG_FRESHEST; if (!X509_EXTENSION_get_critical(ex)) continue; @@ -559,9 +594,26 @@ int x509v3_cache_extensions(X509 *x) x->ex_flags |= EXFLAG_CRITICAL; break; } + switch (nid) { + case NID_basic_constraints: + x->ex_flags |= EXFLAG_BCONS_CRITICAL; + break; + case NID_authority_key_identifier: + x->ex_flags |= EXFLAG_AKID_CRITICAL; + break; + case NID_subject_key_identifier: + x->ex_flags |= EXFLAG_SKID_CRITICAL; + break; + case NID_subject_alt_name: + x->ex_flags |= EXFLAG_SAN_CRITICAL; + break; + default: + break; + } } - x509_init_sig_info(x); + /* Set x->siginf, ignoring errors due to unsupported algos */ + (void)x509_init_sig_info(x); x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */ #ifdef tsan_st_rel @@ -572,9 +624,17 @@ int x509v3_cache_extensions(X509 *x) * all stores are visible on all processors. Hence the release fence. */ #endif - CRYPTO_THREAD_unlock(x->lock); + ERR_pop_to_mark(); + if ((x->ex_flags & EXFLAG_INVALID) == 0) { + CRYPTO_THREAD_unlock(x->lock); + return 1; + } + X509err(0, X509V3_R_INVALID_CERTIFICATE); - return (x->ex_flags & EXFLAG_INVALID) == 0; + err: + x->ex_flags |= EXFLAG_SET; /* indicate that cert has been processed */ + CRYPTO_THREAD_unlock(x->lock); + return 0; } /*- diff --git a/crypto/x509/v3_sxnet.c b/crypto/x509/v3_sxnet.c index d90073754e..b7623b1051 100644 --- a/crypto/x509/v3_sxnet.c +++ b/crypto/x509/v3_sxnet.c @@ -15,9 +15,6 @@ #include #include "ext_dat.h" -DEFINE_STACK_OF(SXNETID) -DEFINE_STACK_OF(CONF_VALUE) - /* Support for Thawte strong extranet extension */ #define SXNET_TEST diff --git a/crypto/x509/v3_tlsf.c b/crypto/x509/v3_tlsf.c index 81ce333a34..bc0a463dec 100644 --- a/crypto/x509/v3_tlsf.c +++ b/crypto/x509/v3_tlsf.c @@ -16,9 +16,6 @@ #include "ext_dat.h" #include "x509_local.h" -DEFINE_STACK_OF(ASN1_INTEGER) -DEFINE_STACK_OF(CONF_VALUE) - static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, TLS_FEATURE *tls_feature, STACK_OF(CONF_VALUE) *ext_list); diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c index acb0e35a42..001c5f2296 100644 --- a/crypto/x509/v3_utl.c +++ b/crypto/x509/v3_utl.c @@ -21,12 +21,6 @@ #include "ext_dat.h" #include "x509_local.h" -DEFINE_STACK_OF(CONF_VALUE) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(ACCESS_DESCRIPTION) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF_STRING() - static char *strip_spaces(char *name); static int sk_strcmp(const char *const *a, const char *const *b); static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name, @@ -878,8 +872,22 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen, ASN1_STRING *cstr; gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != check_type) - continue; + if ((gen->type == GEN_OTHERNAME) && (check_type == GEN_EMAIL)) { + if (OBJ_obj2nid(gen->d.otherName->type_id) == + NID_id_on_SmtpUTF8Mailbox) { + san_present = 1; + cstr = gen->d.otherName->value->value.utf8string; + + /* Positive on success, negative on error! */ + if ((rv = do_check_string(cstr, 0, equal, flags, + chk, chklen, peername)) != 0) + break; + } else + continue; + } else { + if ((gen->type != check_type) && (gen->type != GEN_OTHERNAME)) + continue; + } san_present = 1; if (check_type == GEN_EMAIL) cstr = gen->d.rfc822Name; @@ -978,7 +986,12 @@ int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) char *ipaddr_to_asc(unsigned char *p, int len) { + /* + * 40 is enough space for the longest IPv6 address + nul terminator byte + * XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX\0 + */ char buf[40], *out; + int i = 0, remain = 0, bytes = 0; switch (len) { case 4: /* IPv4 */ @@ -986,11 +999,14 @@ char *ipaddr_to_asc(unsigned char *p, int len) break; /* TODO possibly combine with static i2r_address() in v3_addr.c */ case 16: /* IPv6 */ - for (out = buf; out < buf + 8 * 3; out += 3) { - BIO_snprintf(out, 3 + 1, "%X:", p[0] << 8 | p[1]); + for (out = buf, i = 8, remain = sizeof(buf); + i-- > 0 && bytes >= 0; + remain -= bytes, out += bytes) { + const char *template = (i > 0 ? "%X:" : "%X"); + + bytes = BIO_snprintf(out, remain, template, p[0] << 8 | p[1]); p += 2; } - out[-1] = '\0'; break; default: BIO_snprintf(buf, sizeof(buf), "", len); diff --git a/crypto/x509/v3err.c b/crypto/x509/v3err.c index 4c62e59db9..5124908089 100644 --- a/crypto/x509/v3err.c +++ b/crypto/x509/v3err.c @@ -24,6 +24,7 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { "distpoint already set"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EMPTY_KEY_USAGE), "empty key usage"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CREATING_EXTENSION), @@ -51,6 +52,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_ASRANGE), "invalid asrange"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_CERTIFICATE), + "invalid certificate"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EXTENSION_STRING), "invalid extension string"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_INHERITANCE), @@ -84,6 +87,8 @@ static const ERR_STRING_DATA X509V3_str_reasons[] = { {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_MISSING_VALUE), "missing value"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), "need organization and numbers"}, + {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEGATIVE_PATHLEN), + "negative pathlen"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_CONFIG_DATABASE), "no config database"}, {ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_ISSUER_CERTIFICATE), diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c index ce003615ec..6966d12c20 100644 --- a/crypto/x509/x509_att.c +++ b/crypto/x509/x509_att.c @@ -17,9 +17,6 @@ #include #include "x509_local.h" -DEFINE_STACK_OF(X509_ATTRIBUTE) -DEFINE_STACK_OF(ASN1_TYPE) - int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) { return sk_X509_ATTRIBUTE_num(x); @@ -152,7 +149,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) return ret; } -void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, +void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x, const ASN1_OBJECT *obj, int lastpos, int type) { int i; diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 25f72e057e..e74c842fdc 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -16,8 +16,6 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(X509) - int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) { int i; @@ -30,8 +28,8 @@ int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) ai = &a->cert_info; bi = &b->cert_info; i = ASN1_INTEGER_cmp(&ai->serialNumber, &bi->serialNumber); - if (i) - return i; + if (i != 0) + return i < 0 ? -1 : 1; return X509_NAME_cmp(ai->issuer, bi->issuer); } @@ -83,7 +81,9 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { - return memcmp(a->sha1_hash, b->sha1_hash, 20); + int rv = memcmp(a->sha1_hash, b->sha1_hash, 20); + + return rv < 0 ? -1 : rv > 0; } X509_NAME *X509_get_issuer_name(const X509 *a) @@ -149,18 +149,74 @@ int X509_cmp(const X509 *a, const X509 *b) return -2; rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); - if (rv) - return rv; + if (rv != 0) + return rv < 0 ? -1 : 1; /* Check for match against stored encoding too */ if (!a->cert_info.enc.modified && !b->cert_info.enc.modified) { if (a->cert_info.enc.len < b->cert_info.enc.len) return -1; if (a->cert_info.enc.len > b->cert_info.enc.len) return 1; - return memcmp(a->cert_info.enc.enc, b->cert_info.enc.enc, - a->cert_info.enc.len); + rv = memcmp(a->cert_info.enc.enc, + b->cert_info.enc.enc, a->cert_info.enc.len); } - return rv; + return rv < 0 ? -1 : rv > 0; +} + +int X509_add_cert_new(STACK_OF(X509) **sk, X509 *cert, int flags) +{ + if (*sk == NULL + && (*sk = sk_X509_new_null()) == NULL) { + X509err(0, ERR_R_MALLOC_FAILURE); + return 0; + } + return X509_add_cert(*sk, cert, flags); +} + +int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags) +{ + if (sk == NULL) { + X509err(0, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((flags & X509_ADD_FLAG_NO_DUP) != 0) { + /* + * not using sk_X509_set_cmp_func() and sk_X509_find() + * because this re-orders the certs on the stack + */ + int i; + + for (i = 0; i < sk_X509_num(sk); i++) { + if (X509_cmp(sk_X509_value(sk, i), cert) == 0) + return 1; + } + } + if ((flags & X509_ADD_FLAG_NO_SS) != 0 && X509_self_signed(cert, 0)) + return 1; + if (!sk_X509_insert(sk, cert, + (flags & X509_ADD_FLAG_PREPEND) != 0 ? 0 : -1)) { + X509err(0, ERR_R_MALLOC_FAILURE); + return 0; + } + if ((flags & X509_ADD_FLAG_UP_REF) != 0) + (void)X509_up_ref(cert); + return 1; +} + +int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags) +/* compiler would allow 'const' for the list of certs, yet they are up-ref'ed */ +{ + int n = sk_X509_num(certs); /* certs may be NULL */ + int i; + + for (i = 0; i < n; i++) { + int j = (flags & X509_ADD_FLAG_PREPEND) == 0 ? i : n - 1 - i; + /* if prepend, add certs in reverse order to keep original order */ + + if (!X509_add_cert(sk, sk_X509_value(certs, j), flags)) + return 0; + } + return 1; } int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) @@ -186,12 +242,10 @@ int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) } ret = a->canon_enclen - b->canon_enclen; + if (ret == 0 && a->canon_enclen != 0) + ret = memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); - if (ret != 0 || a->canon_enclen == 0) - return ret; - - return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); - + return ret < 0 ? -1 : ret > 0; } unsigned long X509_NAME_hash(const X509_NAME *x) @@ -354,9 +408,9 @@ static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; - } else + } else { return X509_V_ERR_SUITE_B_INVALID_CURVE; - + } return X509_V_OK; } @@ -374,9 +428,9 @@ int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, if (x == NULL) { x = sk_X509_value(chain, 0); i = 1; - } else + } else { i = 0; - + } pk = X509_get0_pubkey(x); /* @@ -477,7 +531,7 @@ STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) return ret; err: while (i-- > 0) - X509_free (sk_X509_value(ret, i)); + X509_free(sk_X509_value(ret, i)); sk_X509_free(ret); return NULL; } diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c index 512c7ae13e..4c2bc4defa 100644 --- a/crypto/x509/x509_d2.c +++ b/crypto/x509/x509_d2.c @@ -12,17 +12,15 @@ #include #include -int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx, - OPENSSL_CTX *libctx, - const char *propq) +int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, + const char *propq) { X509_LOOKUP *lookup; lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); if (lookup == NULL) return 0; - X509_LOOKUP_load_file_with_libctx(lookup, NULL, X509_FILETYPE_DEFAULT, - libctx, propq); + X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, libctx, propq); lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); if (lookup == NULL) @@ -32,7 +30,7 @@ int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx, lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store()); if (lookup == NULL) return 0; - X509_LOOKUP_add_store_with_libctx(lookup, NULL, libctx, propq); + X509_LOOKUP_add_store_ex(lookup, NULL, libctx, propq); /* clear any errors */ ERR_clear_error(); @@ -41,18 +39,18 @@ int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx, } int X509_STORE_set_default_paths(X509_STORE *ctx) { - return X509_STORE_set_default_paths_with_libctx(ctx, NULL, NULL); + return X509_STORE_set_default_paths_ex(ctx, NULL, NULL); } -int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file, - OPENSSL_CTX *libctx, const char *propq) +int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, + OSSL_LIB_CTX *libctx, const char *propq) { X509_LOOKUP *lookup; if (file == NULL || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file())) == NULL - || X509_LOOKUP_load_file_with_libctx(lookup, file, X509_FILETYPE_PEM, - libctx, propq) == 0) + || X509_LOOKUP_load_file_ex(lookup, file, X509_FILETYPE_PEM, libctx, + propq) == 0) return 0; return 1; @@ -60,7 +58,7 @@ int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file, int X509_STORE_load_file(X509_STORE *ctx, const char *file) { - return X509_STORE_load_file_with_libctx(ctx, file, NULL, NULL); + return X509_STORE_load_file_ex(ctx, file, NULL, NULL); } int X509_STORE_load_path(X509_STORE *ctx, const char *path) @@ -75,14 +73,14 @@ int X509_STORE_load_path(X509_STORE *ctx, const char *path) return 1; } -int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *uri, - OPENSSL_CTX *libctx, const char *propq) +int X509_STORE_load_store_ex(X509_STORE *ctx, const char *uri, + OSSL_LIB_CTX *libctx, const char *propq) { X509_LOOKUP *lookup; if (uri == NULL || (lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_store())) == NULL - || X509_LOOKUP_add_store_with_libctx(lookup, uri, libctx, propq) == 0) + || X509_LOOKUP_add_store_ex(lookup, uri, libctx, propq) == 0) return 0; return 1; @@ -90,17 +88,16 @@ int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *uri, int X509_STORE_load_store(X509_STORE *ctx, const char *uri) { - return X509_STORE_load_store_with_libctx(ctx, uri, NULL, NULL); + return X509_STORE_load_store_ex(ctx, uri, NULL, NULL); } -int X509_STORE_load_locations_with_libctx(X509_STORE *ctx, const char *file, - const char *path, - OPENSSL_CTX *libctx, const char *propq) +int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, + const char *path, OSSL_LIB_CTX *libctx, + const char *propq) { if (file == NULL && path == NULL) return 0; - if (file != NULL && !X509_STORE_load_file_with_libctx(ctx, file, - libctx, propq)) + if (file != NULL && !X509_STORE_load_file_ex(ctx, file, libctx, propq)) return 0; if (path != NULL && !X509_STORE_load_path(ctx, path)) return 0; @@ -110,5 +107,5 @@ int X509_STORE_load_locations_with_libctx(X509_STORE *ctx, const char *file, int X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path) { - return X509_STORE_load_locations_with_libctx(ctx, file, path, NULL, NULL); + return X509_STORE_load_locations_ex(ctx, file, path, NULL, NULL); } diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c index 450f2a7930..330fed3406 100644 --- a/crypto/x509/x509_err.c +++ b/crypto/x509/x509_err.c @@ -27,10 +27,15 @@ static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE), "crl verify failure"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_GETTING_MD_BY_NID), + "error getting md by nid"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_USING_SIGINF_SET), + "error using siginf set"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "idp mismatch"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_ATTRIBUTES), "invalid attributes"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "invalid directory"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DISTPOINT), "invalid distpoint"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME), "invalid field name"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "invalid trust"}, @@ -66,6 +71,8 @@ static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_NID), "unknown nid"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_SIGID_ALGS), + "unknown sigid algs"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_TRUST_ID), "unknown trust id"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, diff --git a/crypto/x509/x509_local.h b/crypto/x509/x509_local.h index 6a2137129c..1467aca1ff 100644 --- a/crypto/x509/x509_local.h +++ b/crypto/x509/x509_local.h @@ -90,12 +90,11 @@ struct x509_lookup_method_st { X509_OBJECT *ret); int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const char *str, int len, X509_OBJECT *ret); - int (*get_by_subject_with_libctx) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret, - OPENSSL_CTX *libctx, const char *propq); - int (*ctrl_with_libctx) (X509_LOOKUP *ctx, int cmd, - const char *argc, long argl, char **ret, - OPENSSL_CTX *libctx, const char *propq); + int (*get_by_subject_ex) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq); + int (*ctrl_ex) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret, OSSL_LIB_CTX *libctx, const char *propq); }; /* This is the functions plus an instance of the local variables. */ diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index e66cfb1825..e591f16938 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -15,11 +15,6 @@ #include #include "x509_local.h" -DEFINE_STACK_OF(X509_LOOKUP) -DEFINE_STACK_OF(X509_OBJECT) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(X509) - X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) { X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(*ret)); @@ -76,15 +71,13 @@ int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) return 1; } -int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret, - OPENSSL_CTX *libctx, const char *propq) +int X509_LOOKUP_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret, OSSL_LIB_CTX *libctx, const char *propq) { if (ctx->method == NULL) return -1; - if (ctx->method->ctrl_with_libctx != NULL) - return ctx->method->ctrl_with_libctx(ctx, cmd, argc, argl, ret, - libctx, propq); + if (ctx->method->ctrl_ex != NULL) + return ctx->method->ctrl_ex(ctx, cmd, argc, argl, ret, libctx, propq); if (ctx->method->ctrl != NULL) return ctx->method->ctrl(ctx, cmd, argc, argl, ret); return 1; @@ -93,21 +86,21 @@ int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc, int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret) { - return X509_LOOKUP_ctrl_with_libctx(ctx, cmd, argc, argl, ret, NULL, NULL); + return X509_LOOKUP_ctrl_ex(ctx, cmd, argc, argl, ret, NULL, NULL); } -int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret, - OPENSSL_CTX *libctx, const char *propq) +int X509_LOOKUP_by_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq) { if (ctx->skip || ctx->method == NULL || (ctx->method->get_by_subject == NULL - && ctx->method->get_by_subject_with_libctx == NULL)) + && ctx->method->get_by_subject_ex == NULL)) return 0; - if (ctx->method->get_by_subject_with_libctx != NULL) - return ctx->method->get_by_subject_with_libctx(ctx, type, name, ret, - libctx, propq); + if (ctx->method->get_by_subject_ex != NULL) + return ctx->method->get_by_subject_ex(ctx, type, name, ret, libctx, + propq); else return ctx->method->get_by_subject(ctx, type, name, ret); } @@ -115,7 +108,7 @@ int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret) { - return X509_LOOKUP_by_subject_with_libctx(ctx, type, name, ret, NULL, NULL); + return X509_LOOKUP_by_subject_ex(ctx, type, name, ret, NULL, NULL); } int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, @@ -335,8 +328,8 @@ int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, if (tmp == NULL || type == X509_LU_CRL) { for (i = 0; i < sk_X509_LOOKUP_num(store->get_cert_methods); i++) { lu = sk_X509_LOOKUP_value(store->get_cert_methods, i); - j = X509_LOOKUP_by_subject_with_libctx(lu, type, name, &stmp, - vs->libctx, vs->propq); + j = X509_LOOKUP_by_subject_ex(lu, type, name, &stmp, vs->libctx, + vs->propq); if (j) { tmp = &stmp; break; @@ -578,14 +571,9 @@ STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *store) for (i = 0; i < sk_X509_OBJECT_num(objs); i++) { X509 *cert = X509_OBJECT_get0_X509(sk_X509_OBJECT_value(objs, i)); - if (cert != NULL) { - if (!X509_up_ref(cert)) - goto err; - if (!sk_X509_push(sk, cert)) { - X509_free(cert); - goto err; - } - } + if (cert != NULL + && !X509_add_cert(sk, cert, X509_ADD_FLAG_UP_REF)) + goto err; } X509_STORE_unlock(store); return sk; @@ -638,14 +626,8 @@ STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, for (i = 0; i < cnt; i++, idx++) { obj = sk_X509_OBJECT_value(store->objs, idx); x = obj->data.x509; - if (!X509_up_ref(x)) { - X509_STORE_unlock(store); - sk_X509_pop_free(sk, X509_free); - return NULL; - } - if (!sk_X509_push(sk, x)) { + if (!X509_add_cert(sk, x, X509_ADD_FLAG_UP_REF)) { X509_STORE_unlock(store); - X509_free(x); sk_X509_pop_free(sk, X509_free); return NULL; } diff --git a/crypto/x509/x509_obj.c b/crypto/x509/x509_obj.c index c1e893bf13..0acfaa3589 100644 --- a/crypto/x509/x509_obj.c +++ b/crypto/x509/x509_obj.c @@ -13,8 +13,7 @@ #include #include #include "crypto/x509.h" - -DEFINE_STACK_OF(X509_NAME_ENTRY) +#include "crypto/ctype.h" /* * Limit to ensure we don't overflow: much greater than @@ -28,6 +27,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) const X509_NAME_ENTRY *ne; int i; int n, lold, l, l1, l2, num, j, type; + int prev_set = -1; const char *s; char *p; unsigned char *q; @@ -109,14 +109,11 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) if (!gs_doit[j & 3]) continue; l2++; -#ifndef CHARSET_EBCDIC - if ((q[j] < ' ') || (q[j] > '~')) - l2 += 3; -#else - if ((os_toascii[q[j]] < os_toascii[' ']) || - (os_toascii[q[j]] > os_toascii['~'])) + if (q[j] == '/' || q[j] == '+') + l2++; /* char needs to be escaped */ + else if ((ossl_toascii(q[j]) < ossl_toascii(' ')) || + (ossl_toascii(q[j]) > ossl_toascii('~'))) l2 += 3; -#endif } lold = l; @@ -133,7 +130,7 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) break; } else p = &(buf[lold]); - *(p++) = '/'; + *(p++) = prev_set == ne->set ? '+' : '/'; memcpy(p, s, (unsigned int)l1); p += l1; *(p++) = '='; @@ -152,8 +149,11 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; - } else + } else { + if (n == '/' || n == '+') + *(p++) = '\\'; *(p++) = n; + } #else n = os_toascii[q[j]]; if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { @@ -161,11 +161,15 @@ char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len) *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; - } else + } else { + if (n == os_toascii['/'] || n == os_toascii['+']) + *(p++) = '\\'; *(p++) = q[j]; + } #endif } *p = '\0'; + prev_set = ne->set; } if (b != NULL) { p = b->data; diff --git a/crypto/x509/x509_r2x.c b/crypto/x509/x509_r2x.c index a284bf72ca..a03ba24926 100644 --- a/crypto/x509/x509_r2x.c +++ b/crypto/x509/x509_r2x.c @@ -17,8 +17,6 @@ #include #include -DEFINE_STACK_OF(X509_ATTRIBUTE) - X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) { X509 *ret = NULL; diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c index 46cabc4b42..79e4c03ca3 100644 --- a/crypto/x509/x509_set.c +++ b/crypto/x509/x509_set.c @@ -192,60 +192,85 @@ int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags); } -static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, - const ASN1_STRING *sig) +/* Modify *siginf according to alg and sig. Return 1 on success, else 0. */ +static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, + const ASN1_STRING *sig) { int pknid, mdnid; const EVP_MD *md; + const EVP_PKEY_ASN1_METHOD *ameth; siginf->mdnid = NID_undef; siginf->pknid = NID_undef; siginf->secbits = -1; siginf->flags = 0; if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid) - || pknid == NID_undef) - return; + || pknid == NID_undef) { + X509err(0, X509_R_UNKNOWN_SIGID_ALGS); + return 0; + } + siginf->mdnid = mdnid; siginf->pknid = pknid; - if (mdnid == NID_undef) { + + switch (mdnid) { + case NID_undef: /* If we have one, use a custom handler for this algorithm */ - const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid); + ameth = EVP_PKEY_asn1_find(NULL, pknid); if (ameth == NULL || ameth->siginf_set == NULL - || ameth->siginf_set(siginf, alg, sig) == 0) - return; - siginf->flags |= X509_SIG_INFO_VALID; - return; - } - siginf->flags |= X509_SIG_INFO_VALID; - siginf->mdnid = mdnid; - md = EVP_get_digestbynid(mdnid); - if (md == NULL) - return; - /* Security bits: half number of bits in digest */ - siginf->secbits = EVP_MD_size(md) * 4; - /* - * SHA1 and MD5 are known to be broken. Reduce security bits so that - * they're no longer accepted at security level 1. The real values don't - * really matter as long as they're lower than 80, which is our security - * level 1. - * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for SHA1 at - * 2^63.4 - * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf - * puts a chosen-prefix attack for MD5 at 2^39. - */ - if (mdnid == NID_sha1) + || !ameth->siginf_set(siginf, alg, sig)) { + X509err(0, X509_R_ERROR_USING_SIGINF_SET); + return 0; + } + break; + /* + * SHA1 and MD5 are known to be broken. Reduce security bits so that + * they're no longer accepted at security level 1. + * The real values don't really matter as long as they're lower than 80, + * which is our security level 1. + */ + case NID_sha1: + /* + * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack + * for SHA1 at2^63.4 + */ siginf->secbits = 63; - else if (mdnid == NID_md5) + break; + case NID_md5: + /* + * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf + * puts a chosen-prefix attack for MD5 at 2^39. + */ siginf->secbits = 39; + break; + case NID_id_GostR3411_94: + /* + * There is a collision attack on GOST R 34.11-94 at 2^105, see + * https://link.springer.com/chapter/10.1007%2F978-3-540-85174-5_10 + */ + siginf->secbits = 105; + break; + default: + /* Security bits: half number of bits in digest */ + if ((md = EVP_get_digestbynid(mdnid)) == NULL) { + X509err(0, X509_R_ERROR_GETTING_MD_BY_NID); + return 0; + } + siginf->secbits = EVP_MD_size(md) * 4; + break; + } switch (mdnid) { - case NID_sha1: - case NID_sha256: - case NID_sha384: - case NID_sha512: + case NID_sha1: + case NID_sha256: + case NID_sha384: + case NID_sha512: siginf->flags |= X509_SIG_INFO_TLS; } + siginf->flags |= X509_SIG_INFO_VALID; + return 1; } -void x509_init_sig_info(X509 *x) +/* Returns 1 on success, 0 on failure */ +int x509_init_sig_info(X509 *x) { - x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature); + return x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature); } diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index ebd45b68b0..10718c347d 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -12,9 +12,6 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(X509_TRUST) -DEFINE_STACK_OF(ASN1_OBJECT) - static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); static void trtable_free(X509_TRUST *p); diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c index 63d8d95f3f..0c7ae1ed79 100644 --- a/crypto/x509/x509_txt.c +++ b/crypto/x509/x509_txt.c @@ -69,8 +69,8 @@ const char *X509_verify_cert_error_string(long n) return "certificate chain too long"; case X509_V_ERR_CERT_REVOKED: return "certificate revoked"; - case X509_V_ERR_INVALID_CA: - return "invalid CA certificate"; + case X509_V_ERR_NO_ISSUER_PUBLIC_KEY: + return "issuer certificate doesn't have a public key"; case X509_V_ERR_PATH_LENGTH_EXCEEDED: return "path length constraint exceeded"; case X509_V_ERR_INVALID_PURPOSE: @@ -174,12 +174,44 @@ const char *X509_verify_cert_error_string(long n) return "OCSP verification failed"; case X509_V_ERR_OCSP_CERT_UNKNOWN: return "OCSP unknown cert"; - case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH: - return "subject signature algorithm and issuer public key algorithm mismatch"; - case X509_V_ERR_NO_ISSUER_PUBLIC_KEY: - return "issuer certificate doesn't have a public key"; case X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM: return "Cannot find certificate signature algorithm"; + case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH: + return "subject signature algorithm and issuer public key algorithm mismatch"; + case X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY: + return "cert info siganature and signature algorithm mismatch"; + case X509_V_ERR_INVALID_CA: + return "invalid CA certificate"; + case X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA: + return "Path length invalid for non-CA cert"; + case X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN: + return "Path length given without key usage keyCertSign"; + case X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA: + return "Key usage keyCertSign invalid for non-CA cert"; + case X509_V_ERR_ISSUER_NAME_EMPTY: + return "Issuer name empty"; + case X509_V_ERR_SUBJECT_NAME_EMPTY: + return "Subject name empty"; + case X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER: + return "Missing Authority Key Identifier"; + case X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER: + return "Missing Subject Key Identifier"; + case X509_V_ERR_EMPTY_SUBJECT_ALT_NAME: + return "Empty Subject Alternative Name extension"; + case X509_V_ERR_CA_BCONS_NOT_CRITICAL: + return "Basic Constraints of CA cert not marked critical"; + case X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL: + return "Subject empty and Subject Alt Name extension not critical"; + case X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL: + return "Authority Key Identifier marked critical"; + case X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL: + return "Subject Key Identifier marked critical"; + case X509_V_ERR_CA_CERT_MISSING_KEY_USAGE: + return "CA cert does not include key usage extension"; + case X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3: + return "Using cert extension requires at least X509v3"; + case X509_V_ERR_EC_KEY_EXPLICIT_PARAMS: + return "Certificate public key has explicit ECC parameters"; default: /* Printing an error number into a static buffer is not thread-safe */ diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c index f059667263..96ba940aa4 100644 --- a/crypto/x509/x509_v3.c +++ b/crypto/x509/x509_v3.c @@ -17,8 +17,6 @@ #include #include "x509_local.h" -DEFINE_STACK_OF(X509_EXTENSION) - int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) { if (x == NULL) diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 012f932ee5..1b24e0156a 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -25,13 +25,6 @@ #include "crypto/x509.h" #include "x509_local.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_REVOKED) -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(X509_CRL) -DEFINE_STACK_OF(DIST_POINT) -DEFINE_STACK_OF_STRING() - /* CRL score values */ /* No unhandled critical extensions */ @@ -76,7 +69,7 @@ static int dane_verify(X509_STORE_CTX *ctx); static int null_callback(int ok, X509_STORE_CTX *e); static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); -static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_chain(X509_STORE_CTX *ctx); static int check_name_constraints(X509_STORE_CTX *ctx); static int check_id(X509_STORE_CTX *ctx); static int check_trust(X509_STORE_CTX *ctx, int num_untrusted); @@ -87,6 +80,7 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); static int check_dane_issuer(X509_STORE_CTX *ctx, int depth); static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert); +static int check_curve(X509 *cert); static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, unsigned int *preasons, X509_CRL *crl, X509 *x); @@ -228,7 +222,7 @@ static int verify_chain(X509_STORE_CTX *ctx) * instantiate chain public key parameters. */ if ((ok = build_chain(ctx)) == 0 || - (ok = check_chain_extensions(ctx)) == 0 || + (ok = check_chain(ctx)) == 0 || (ok = check_auth_level(ctx)) == 0 || (ok = check_id(ctx)) == 0 || 1) X509_get_pubkey_parameters(NULL, ctx->chain); @@ -285,24 +279,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx) return -1; } - if (!X509_up_ref(ctx->cert)) { - X509err(X509_F_X509_VERIFY_CERT, ERR_R_INTERNAL_ERROR); - ctx->error = X509_V_ERR_UNSPECIFIED; - return -1; - } - - /* - * first we make sure the chain we are going to build is present and that - * the first entry is in place - */ - if ((ctx->chain = sk_X509_new_null()) == NULL - || !sk_X509_push(ctx->chain, ctx->cert)) { - X509_free(ctx->cert); - X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + if (!X509_add_cert_new(&ctx->chain, ctx->cert, X509_ADD_FLAG_UP_REF)) { ctx->error = X509_V_ERR_OUT_OF_MEM; return -1; } - ctx->num_untrusted = 1; /* If the peer's public key is too weak, we can stop early. */ @@ -395,18 +375,8 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) { x = sk_X509_value(ctx->other_ctx, i); if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) { - if (!X509_up_ref(x)) { - sk_X509_pop_free(sk, X509_free); - X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_INTERNAL_ERROR); - ctx->error = X509_V_ERR_UNSPECIFIED; - return NULL; - } - if (sk == NULL) - sk = sk_X509_new_null(); - if (sk == NULL || !sk_X509_push(sk, x)) { - X509_free(x); + if (!X509_add_cert_new(&sk, x, X509_ADD_FLAG_UP_REF)) { sk_X509_pop_free(sk, X509_free); - X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; return NULL; } @@ -471,7 +441,7 @@ static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth, * purpose */ -static int check_chain_extensions(X509_STORE_CTX *ctx) +static int check_chain(X509_STORE_CTX *ctx) { int i, must_be_ca, plen = 0; X509 *x; @@ -503,6 +473,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) for (i = 0; i < num; i++) { int ret; + x = sk_X509_value(ctx->chain, i); if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) && (x->ex_flags & EXFLAG_CRITICAL)) { @@ -543,12 +514,86 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) ret = 1; break; } - if ((x->ex_flags & EXFLAG_CA) == 0 - && x->ex_pathlen != -1 - && (ctx->param->flags & X509_V_FLAG_X509_STRICT)) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - ret = 0; + if (num > 1) { + /* Check for presence of explicit elliptic curve parameters */ + ret = check_curve(x); + if (ret < 0) + ctx->error = X509_V_ERR_UNSPECIFIED; + else if (ret == 0) + ctx->error = X509_V_ERR_EC_KEY_EXPLICIT_PARAMS; } + /* + * Do the following set of checks only if strict checking is requrested + * and not for self-issued (including self-signed) EE (non-CA) certs + * because RFC 5280 does not apply to them according RFC 6818 section 2. + */ + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) != 0 + && num > 1) { /* + * this should imply + * !(i == 0 && (x->ex_flags & EXFLAG_CA) == 0 + * && (x->ex_flags & EXFLAG_SI) != 0) + */ + /* Check Basic Constraints according to RFC 5280 section 4.2.1.9 */ + if (x->ex_pathlen != -1) { + if ((x->ex_flags & EXFLAG_CA) == 0) + ctx->error = X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA; + if ((x->ex_kusage & KU_KEY_CERT_SIGN) == 0) + ctx->error = X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN; + } + if ((x->ex_flags & EXFLAG_CA) != 0 + && (x->ex_flags & EXFLAG_BCONS) != 0 + && (x->ex_flags & EXFLAG_BCONS_CRITICAL) == 0) + ctx->error = X509_V_ERR_CA_BCONS_NOT_CRITICAL; + /* Check Key Usage according to RFC 5280 section 4.2.1.3 */ + if ((x->ex_flags & EXFLAG_CA) != 0) { + if ((x->ex_flags & EXFLAG_KUSAGE) == 0) + ctx->error = X509_V_ERR_CA_CERT_MISSING_KEY_USAGE; + } else { + if ((x->ex_kusage & KU_KEY_CERT_SIGN) != 0) + ctx->error = X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA; + } + /* Check issuer is non-empty acc. to RFC 5280 section 4.1.2.4 */ + if (X509_NAME_entry_count(X509_get_issuer_name(x)) == 0) + ctx->error = X509_V_ERR_ISSUER_NAME_EMPTY; + /* Check subject is non-empty acc. to RFC 5280 section 4.1.2.6 */ + if (((x->ex_flags & EXFLAG_CA) != 0 + || (x->ex_kusage & KU_CRL_SIGN) != 0 + || x->altname == NULL + ) && X509_NAME_entry_count(X509_get_subject_name(x)) == 0) + ctx->error = X509_V_ERR_SUBJECT_NAME_EMPTY; + if (X509_NAME_entry_count(X509_get_subject_name(x)) == 0 + && x->altname != NULL + && (x->ex_flags & EXFLAG_SAN_CRITICAL) == 0) + ctx->error = X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL; + /* Check SAN is non-empty according to RFC 5280 section 4.2.1.6 */ + if (x->altname != NULL && sk_GENERAL_NAME_num(x->altname) <= 0) + ctx->error = X509_V_ERR_EMPTY_SUBJECT_ALT_NAME; + /* TODO add more checks on SAN entries */ + /* Check sig alg consistency acc. to RFC 5280 section 4.1.1.2 */ + if (X509_ALGOR_cmp(&x->sig_alg, &x->cert_info.signature) != 0) + ctx->error = X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY; + if (x->akid != NULL && (x->ex_flags & EXFLAG_AKID_CRITICAL) != 0) + ctx->error = X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL; + if (x->skid != NULL && (x->ex_flags & EXFLAG_SKID_CRITICAL) != 0) + ctx->error = X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL; + if (X509_get_version(x) >= 2) { /* at least X.509v3 */ + /* Check AKID presence acc. to RFC 5280 section 4.2.1.1 */ + if (i + 1 < num /* + * this means not last cert in chain, + * taken as "generated by conforming CAs" + */ + && (x->akid == NULL || x->akid->keyid == NULL)) + ctx->error = X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER; + /* Check SKID presence acc. to RFC 5280 section 4.2.1.2 */ + if ((x->ex_flags & EXFLAG_CA) != 0 && x->skid == NULL) + ctx->error = X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER; + } else { + if (sk_X509_EXTENSION_num(X509_get0_extensions(x)) > 0) + ctx->error = X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3; + } + } + if (ctx->error != X509_V_OK) + ret = 0; if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK)) return 0; /* check_purpose() makes the callback as needed */ @@ -1647,7 +1692,7 @@ static int check_policy(X509_STORE_CTX *ctx) ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, ctx->param->policies, ctx->param->flags); if (ctx->bare_ta_signed) - sk_X509_pop(ctx->chain); + (void)sk_X509_pop(ctx->chain); if (ret == X509_PCY_TREE_INTERNAL) { X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); @@ -1759,9 +1804,15 @@ static int internal_verify(X509_STORE_CTX *ctx) xs = xi; goto check_cert_time; } - if (n <= 0) - return verify_cb_cert(ctx, xi, 0, - X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); + if (n <= 0) { + if (!verify_cb_cert(ctx, xi, 0, + X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE)) + return 0; + + xs = xi; + goto check_cert_time; + } + n--; ctx->error_depth = n; xs = sk_X509_value(ctx->chain, n); @@ -2271,8 +2322,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, return 1; } -X509_STORE_CTX *X509_STORE_CTX_new_with_libctx(OPENSSL_CTX *libctx, - const char *propq) +X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509_STORE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); @@ -2296,7 +2346,7 @@ X509_STORE_CTX *X509_STORE_CTX_new_with_libctx(OPENSSL_CTX *libctx, X509_STORE_CTX *X509_STORE_CTX_new(void) { - return X509_STORE_CTX_new_with_libctx(NULL, NULL); + return X509_STORE_CTX_new_ex(NULL, NULL); } @@ -3053,13 +3103,10 @@ static int build_chain(X509_STORE_CTX *ctx) ctx->error = X509_V_ERR_OUT_OF_MEM; return 0; } - for (i = 0; i < sk_X509_num(dane->certs); ++i) { - if (!sk_X509_push(sktmp, sk_X509_value(dane->certs, i))) { - sk_X509_free(sktmp); - X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } + if (!X509_add_certs(sktmp, dane->certs, X509_ADD_FLAG_DEFAULT)) { + sk_X509_free(sktmp); + ctx->error = X509_V_ERR_OUT_OF_MEM; + return 0; } } @@ -3181,6 +3228,7 @@ static int build_chain(X509_STORE_CTX *ctx) } self_signed = X509_self_signed(x, 0); if (self_signed < 0) { + sk_X509_free(sktmp); ctx->error = X509_V_ERR_UNSPECIFIED; return 0; } @@ -3399,6 +3447,32 @@ static int check_key_level(X509_STORE_CTX *ctx, X509 *cert) return EVP_PKEY_security_bits(pkey) >= minbits_table[level - 1]; } +/* + * Check whether the public key of ``cert`` does not use explicit params + * for an elliptic curve. + * + * Returns 1 on success, 0 if check fails, -1 for other errors. + */ +static int check_curve(X509 *cert) +{ +#ifndef OPENSSL_NO_EC + EVP_PKEY *pkey = X509_get0_pubkey(cert); + + /* Unsupported or malformed key */ + if (pkey == NULL) + return -1; + + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + int ret; + + ret = EC_KEY_decoded_from_explicit_params(EVP_PKEY_get0_EC_KEY(pkey)); + return ret < 0 ? ret : !ret; + } +#endif + + return 1; +} + /* * Check whether the signature digest algorithm of ``cert`` meets the security * level of ``ctx``. Should not be checked for trust anchors (whether diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index f87dfd0726..a429d5a5ae 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -18,10 +18,6 @@ #include "x509_local.h" -DEFINE_STACK_OF(ASN1_OBJECT) -DEFINE_STACK_OF(X509_VERIFY_PARAM) -DEFINE_STACK_OF_STRING() - /* X509_VERIFY_PARAM functions */ #define SET_HOST 0 diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c index d5b3778035..22143da65e 100644 --- a/crypto/x509/x509cset.c +++ b/crypto/x509/x509cset.c @@ -16,8 +16,6 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(X509_REVOKED) - int X509_CRL_set_version(X509_CRL *x, long version) { if (x == NULL) diff --git a/crypto/x509/x509name.c b/crypto/x509/x509name.c index 7e2704fb68..b00e5f5b38 100644 --- a/crypto/x509/x509name.c +++ b/crypto/x509/x509name.c @@ -16,8 +16,6 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(X509_NAME_ENTRY) - int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, char *buf, int len) { diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index b06828f718..20b048c4a3 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -23,84 +23,31 @@ #include #include #include -#include "crypto/asn1.h" +#include "internal/asn1.h" +#include "crypto/pkcs7.h" #include "crypto/x509.h" -static void clean_id_ctx(EVP_MD_CTX *ctx) -{ - EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx); - - EVP_PKEY_CTX_free(pctx); - EVP_MD_CTX_free(ctx); -} - -static EVP_MD_CTX *make_id_ctx(EVP_PKEY *r, ASN1_OCTET_STRING *id, - OPENSSL_CTX *libctx, const char *propq) -{ - EVP_MD_CTX *ctx = NULL; - EVP_PKEY_CTX *pctx = NULL; - - if ((ctx = EVP_MD_CTX_new()) == NULL - || (pctx = EVP_PKEY_CTX_new_from_pkey(libctx, r, propq)) == NULL) { - X509err(0, ERR_R_MALLOC_FAILURE); - goto error; - } - -#ifndef OPENSSL_NO_EC - if (id != NULL) { - if (EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) { - X509err(0, ERR_R_MALLOC_FAILURE); - goto error; - } - } -#endif - - EVP_MD_CTX_set_pkey_ctx(ctx, pctx); - - return ctx; - error: - EVP_PKEY_CTX_free(pctx); - EVP_MD_CTX_free(ctx); - return NULL; -} - int X509_verify(X509 *a, EVP_PKEY *r) { - int rv = 0; - EVP_MD_CTX *ctx = NULL; - ASN1_OCTET_STRING *id = NULL; - if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature)) return 0; - id = a->distinguishing_id; - if ((ctx = make_id_ctx(r, id, a->libctx, a->propq)) != NULL) { - rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, - &a->signature, &a->cert_info, ctx); - clean_id_ctx(ctx); - } - return rv; + return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, + &a->signature, &a->cert_info, + a->distinguishing_id, r, a->libctx, a->propq); } -int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx, - const char *propq) +int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx, + const char *propq) { - int rv = 0; - EVP_MD_CTX *ctx = NULL; - ASN1_OCTET_STRING *id = NULL; - - id = a->distinguishing_id; - if ((ctx = make_id_ctx(r, id, libctx, propq)) != NULL) { - rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg, - a->signature, &a->req_info, ctx); - clean_id_ctx(ctx); - } - return rv; + return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg, + a->signature, &a->req_info, a->distinguishing_id, + r, libctx, propq); } int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) { - return X509_REQ_verify_with_libctx(a, r, NULL, NULL); + return X509_REQ_verify_ex(a, r, NULL, NULL); } int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) @@ -125,7 +72,6 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) &x->sig_alg, &x->signature, &x->cert_info, ctx); } -#if !defined(OPENSSL_NO_SOCK) static ASN1_VALUE *simple_get_asn1(const char *url, BIO *bio, BIO *rbio, int timeout, const ASN1_ITEM *it) { @@ -141,7 +87,6 @@ X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) return (X509 *)simple_get_asn1(url, bio, rbio, timeout, ASN1_ITEM_rptr(X509)); } -#endif int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { @@ -171,13 +116,11 @@ int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) &x->crl, ctx); } -#if !defined(OPENSSL_NO_SOCK) X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) { return (X509_CRL *)simple_get_asn1(url, bio, rbio, timeout, ASN1_ITEM_rptr(X509_CRL)); } -#endif int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { @@ -232,7 +175,12 @@ int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl) #ifndef OPENSSL_NO_STDIO PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) { - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); + PKCS7 *ret; + + ret = ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); + if (ret != NULL && p7 != NULL) + pkcs7_resolve_libctx(ret); + return ret; } int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7) @@ -243,7 +191,12 @@ int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7) PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) { - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); + PKCS7 *ret; + + ret = ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); + if (ret != NULL && p7 != NULL) + pkcs7_resolve_libctx(ret); + return ret; } int i2d_PKCS7_bio(BIO *bp, const PKCS7 *p7) @@ -449,8 +402,8 @@ int X509_digest(const X509 *cert, const EVP_MD *md, unsigned char *data, memcpy(data, cert->sha1_hash, sizeof(cert->sha1_hash)); return 1; } - return (asn1_item_digest_with_libctx(ASN1_ITEM_rptr(X509), md, (char *)cert, - data, len, cert->libctx, cert->propq)); + return (asn1_item_digest_ex(ASN1_ITEM_rptr(X509), md, (char *)cert, data, + len, cert->libctx, cert->propq)); } /* calculate cert digest using the same hash algorithm as in its signature */ @@ -602,7 +555,7 @@ EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a); } -EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OPENSSL_CTX *libctx, +EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq) { BIO *b; @@ -666,7 +619,7 @@ EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a); } -EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OPENSSL_CTX *libctx, +EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq) { BUF_MEM *b = NULL; diff --git a/crypto/x509/x_attrib.c b/crypto/x509/x_attrib.c index fca6df5067..5c5e608173 100644 --- a/crypto/x509/x_attrib.c +++ b/crypto/x509/x_attrib.c @@ -14,8 +14,6 @@ #include #include "x509_local.h" -DEFINE_STACK_OF(ASN1_TYPE) - /*- * X509_ATTRIBUTE: this has the following form: * diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c index 1690dd8963..17c9305f5c 100644 --- a/crypto/x509/x_crl.c +++ b/crypto/x509/x_crl.c @@ -15,11 +15,6 @@ #include #include "x509_local.h" -DEFINE_STACK_OF(GENERAL_NAME) -DEFINE_STACK_OF(GENERAL_NAMES) -DEFINE_STACK_OF(X509_REVOKED) -DEFINE_STACK_OF(X509_EXTENSION) - static int X509_REVOKED_cmp(const X509_REVOKED *const *a, const X509_REVOKED *const *b); static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); @@ -494,3 +489,12 @@ void *X509_CRL_get_meth_data(X509_CRL *crl) { return crl->meth_data; } + +int x509_crl_set0_libctx(X509_CRL *x, OSSL_LIB_CTX *libctx, const char *propq) +{ + if (x != NULL) { + x->libctx = libctx; + x->propq = propq; + } + return 1; +} diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c index 2db9aa34ca..a85b10f1cf 100644 --- a/crypto/x509/x_name.c +++ b/crypto/x509/x_name.c @@ -16,9 +16,6 @@ #include "crypto/asn1.h" #include "x509_local.h" -DEFINE_STACK_OF(X509_NAME_ENTRY) -DEFINE_STACK_OF(ASN1_VALUE) - /* * Maximum length of X509_NAME: much larger than anything we should * ever see in practice. @@ -189,7 +186,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, entry->set = i; if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) goto err; - sk_X509_NAME_ENTRY_set(entries, j, NULL); + (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); } } ret = x509_name_canon(nm.x); diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index c73ea7a4ed..7d39254685 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -22,12 +22,17 @@ #include "crypto/x509.h" #include #include -#include +#include +#include "internal/provider.h" struct X509_pubkey_st { X509_ALGOR *algor; ASN1_BIT_STRING *public_key; EVP_PKEY *pkey; + + /* extra data for the callback, used by d2i_PUBKEY_ex */ + OSSL_LIB_CTX *libctx; + const char *propq; }; static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key); @@ -36,12 +41,12 @@ static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key); static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) { + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + if (operation == ASN1_OP_FREE_POST) { - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; EVP_PKEY_free(pubkey->pkey); } else if (operation == ASN1_OP_D2I_POST) { /* Attempt to decode public key and cache in pubkey structure. */ - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; EVP_PKEY_free(pubkey->pkey); pubkey->pkey = NULL; /* @@ -50,8 +55,10 @@ static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, * will return an appropriate error. */ ERR_set_mark(); - if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1) + if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1) { + ERR_clear_last_mark(); return 0; + } ERR_pop_to_mark(); } return 1; @@ -91,21 +98,25 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); goto error; } - } else if (pkey->keymgmt != NULL) { - BIO *bmem = BIO_new(BIO_s_mem()); - const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ; - OSSL_SERIALIZER_CTX *sctx = - OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pkey, serprop); - - if (OSSL_SERIALIZER_to_bio(sctx, bmem)) { - const unsigned char *der = NULL; - long derlen = BIO_get_mem_data(bmem, (char **)&der); - - pk = d2i_X509_PUBKEY(NULL, &der, derlen); + } else if (evp_pkey_is_provided(pkey)) { + const OSSL_PROVIDER *pkprov = EVP_KEYMGMT_provider(pkey->keymgmt); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(pkprov); + unsigned char *der = NULL; + size_t derlen = 0; + int selection = (OSSL_KEYMGMT_SELECT_PUBLIC_KEY + | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS); + OSSL_ENCODER_CTX *ectx = + OSSL_ENCODER_CTX_new_by_EVP_PKEY(pkey, "DER", selection, + libctx, NULL); + + if (OSSL_ENCODER_to_data(ectx, &der, &derlen)) { + const unsigned char *pder = der; + + pk = d2i_X509_PUBKEY(NULL, &pder, (long)derlen); } - OSSL_SERIALIZER_CTX_free(sctx); - BIO_free(bmem); + OSSL_ENCODER_CTX_free(ectx); + OPENSSL_free(der); } if (pk == NULL) @@ -120,7 +131,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) /* * pk->pkey is NULL when using the legacy routine, but is non-NULL when - * going through the serializer, and for all intents and purposes, it's + * going through the encoder, and for all intents and purposes, it's * a perfect copy of |pkey|, just not the same instance. In that case, * we could simply return early, right here. * However, in the interest of being cautious leaning on paranoia, some @@ -171,10 +182,8 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key) * future we could have different return codes for decode * errors and fatal errors such as malloc failure. */ - if (!pkey->ameth->pub_decode(pkey, key)) { - X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR); + if (!pkey->ameth->pub_decode(pkey, key)) goto error; - } } else { X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED); goto error; @@ -228,32 +237,57 @@ EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) } /* - * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or - * decode as X509_PUBKEY + * Now three pseudo ASN1 routines that take an EVP_PKEY structure and encode + * or decode as X509_PUBKEY */ -EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) +EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length, + OSSL_LIB_CTX *libctx, const char *propq) { - X509_PUBKEY *xpk; - EVP_PKEY *pktmp; + X509_PUBKEY *xpk, *xpk2 = NULL, **pxpk = NULL; + EVP_PKEY *pktmp = NULL; const unsigned char *q; q = *pp; - xpk = d2i_X509_PUBKEY(NULL, &q, length); + + /* + * If libctx or propq are non-NULL, we take advantage of the reuse + * feature. It's not generally recommended, but is safe enough for + * newly created structures. + */ + if (libctx != NULL || propq != NULL) { + xpk2 = OPENSSL_zalloc(sizeof(*xpk2)); + if (xpk2 == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + xpk2->libctx = libctx; + xpk2->propq = propq; + pxpk = &xpk2; + } + xpk = d2i_X509_PUBKEY(pxpk, &q, length); if (xpk == NULL) - return NULL; + goto end; pktmp = X509_PUBKEY_get(xpk); X509_PUBKEY_free(xpk); + xpk2 = NULL; /* We know that xpk == xpk2 */ if (pktmp == NULL) - return NULL; + goto end; *pp = q; if (a != NULL) { EVP_PKEY_free(*a); *a = pktmp; } + end: + X509_PUBKEY_free(xpk2); return pktmp; } +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) +{ + return d2i_PUBKEY_ex(a, pp, length, NULL, NULL); +} + int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) { int ret = -1; @@ -274,16 +308,18 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) } X509_PUBKEY_free(xpk); } else if (a->keymgmt != NULL) { - const char *serprop = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ; - OSSL_SERIALIZER_CTX *ctx = - OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(a, serprop); + const OSSL_PROVIDER *pkprov = EVP_KEYMGMT_provider(a->keymgmt); + OSSL_LIB_CTX *libctx = ossl_provider_libctx(pkprov); + int selection = (OSSL_KEYMGMT_SELECT_PUBLIC_KEY + | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS); + OSSL_ENCODER_CTX *ctx = + OSSL_ENCODER_CTX_new_by_EVP_PKEY(a, "DER", selection, libctx, NULL); BIO *out = BIO_new(BIO_s_mem()); BUF_MEM *buf = NULL; - if (ctx != NULL + if (OSSL_ENCODER_CTX_get_num_encoders(ctx) != 0 && out != NULL - && OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL - && OSSL_SERIALIZER_to_bio(ctx, out) + && OSSL_ENCODER_to_bio(ctx, out) && BIO_get_mem_ptr(out, &buf) > 0) { ret = buf->length; @@ -299,7 +335,7 @@ int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) } } BIO_free(out); - OSSL_SERIALIZER_CTX_free(ctx); + OSSL_ENCODER_CTX_free(ctx); } return ret; @@ -493,3 +529,13 @@ int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b) return -2; return EVP_PKEY_eq(pA, pB); } + +int X509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq, + const X509_PUBKEY *key) +{ + if (plibctx) + *plibctx = key->libctx; + if (ppropq) + *ppropq = key->propq; + return 1; +} diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c index 10b82df559..e821ffdb78 100644 --- a/crypto/x509/x_req.c +++ b/crypto/x509/x_req.c @@ -13,8 +13,6 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(X509_ATTRIBUTE) - /*- * X509_REQ_INFO is handled in an unusual way to get round * invalid encodings. Some broken certificate requests don't @@ -50,7 +48,6 @@ static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) { -#ifndef OPENSSL_NO_SM2 X509_REQ *ret = (X509_REQ *)*pval; switch (operation) { @@ -65,7 +62,6 @@ static int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, ASN1_OCTET_STRING_free(ret->distinguishing_id); break; } -#endif return 1; } diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index 9358c46a7f..13b816fcde 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -15,10 +15,6 @@ #include #include "crypto/x509.h" -#ifndef OPENSSL_NO_RFC3779 -DEFINE_STACK_OF(IPAddressFamily) -#endif - ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), ASN1_EMBED(X509_CINF, serialNumber, ASN1_INTEGER), @@ -133,15 +129,26 @@ int i2d_X509(const X509 *a, unsigned char **out) return ASN1_item_i2d((const ASN1_VALUE *)a, out, (X509_it())); } -X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq) +/* + * This should only be used if the X509 object was embedded inside another + * asn1 object and it needs a libctx to operate. + * Use X509_new_ex() instead if possible. + */ +int x509_set0_libctx(X509 *x, OSSL_LIB_CTX *libctx, const char *propq) +{ + if (x != NULL) { + x->libctx = libctx; + x->propq = propq; + } + return 1; +} + +X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509 *cert = NULL; cert = (X509 *)ASN1_item_new((X509_it())); - if (cert != NULL) { - cert->libctx = libctx; - cert->propq = propq; - } + (void)x509_set0_libctx(cert, libctx, propq); return cert; } diff --git a/crypto/x509/x_x509a.c b/crypto/x509/x_x509a.c index f0dc9d6535..ef93db26d8 100644 --- a/crypto/x509/x_x509a.c +++ b/crypto/x509/x_x509a.c @@ -14,8 +14,6 @@ #include #include "crypto/x509.h" -DEFINE_STACK_OF(ASN1_OBJECT) - /* * X509_CERT_AUX routines. These are used to encode additional user * modifiable data about a certificate. This data is appended to the X509 diff --git a/e_os.h b/e_os.h index c035568464..979be9b2b1 100644 --- a/e_os.h +++ b/e_os.h @@ -295,6 +295,64 @@ struct servent *getservbyname(const char *name, const char *proto); # endif /* end vxworks */ +/* ----------------------------- HP NonStop -------------------------------- */ +/* Required to support platform variant without getpid() and pid_t. */ +# ifdef __TANDEM +# include +# include +# define getservbyname(name,proto) getservbyname((char*)name,proto) +# define gethostbyname(name) gethostbyname((char*)name) +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# ifdef NO_GETPID +inline int nssgetpid(); +# ifndef NSSGETPID_MACRO +# define NSSGETPID_MACRO +# include +# include + inline int nssgetpid() + { + short phandle[10]={0}; + union pseudo_pid { + struct { + short cpu; + short pin; + } cpu_pin ; + int ppid; + } ppid = { 0 }; + PROCESSHANDLE_GETMINE_(phandle); + PROCESSHANDLE_DECOMPOSE_(phandle, &ppid.cpu_pin.cpu, &ppid.cpu_pin.pin); + return ppid.ppid; + } +# define getpid(a) nssgetpid(a) +# endif /* NSSGETPID_MACRO */ +# endif /* NO_GETPID */ +/*# define setsockopt(a,b,c,d,f) setsockopt(a,b,c,(char*)d,f)*/ +/*# define getsockopt(a,b,c,d,f) getsockopt(a,b,c,(char*)d,f)*/ +/*# define connect(a,b,c) connect(a,(struct sockaddr *)b,c)*/ +/*# define bind(a,b,c) bind(a,(struct sockaddr *)b,c)*/ +/*# define sendto(a,b,c,d,e,f) sendto(a,(char*)b,c,d,(struct sockaddr *)e,f)*/ +# if defined(OPENSSL_THREADS) && !defined(_PUT_MODEL_) + /* + * HPNS SPT threads + */ +# define SPT_THREAD_SIGNAL 1 +# define SPT_THREAD_AWARE 1 +# include +# undef close +# define close spt_close +/* +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# define closesocket(s) close(s) +# define readsocket(s,b,n) read((s),(char*)(b),(n)) +# define writesocket(s,b,n) write((s),(char*)(b),(n) +*/ +# define accept(a,b,c) accept(a,(struct sockaddr *)b,c) +# define recvfrom(a,b,c,d,e,f) recvfrom(a,b,(socklen_t)c,d,e,f) +# endif +# endif + # ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION # define CRYPTO_memcmp memcmp # endif diff --git a/import_openssl.sh b/import_openssl.sh index 6833df3f6a..52536765e3 100755 --- a/import_openssl.sh +++ b/import_openssl.sh @@ -260,8 +260,11 @@ function generate_build_config_headers() { make include/openssl/opensslv.h make include/crypto/bn_conf.h make include/crypto/dso_conf.h - make providers/common/include/prov/der_ec.h providers/common/include/prov/der_dsa.h providers/common/include/prov/der_rsa.h providers/common/include/prov/der_digests.h providers/common/include/prov/der_wrap.h - make providers/common/der/der_digests_gen.c providers/common/der/der_ec_gen.c providers/common/der/der_dsa_gen.c providers/common/der/der_rsa_gen.c providers/common/der/der_wrap_gen.c + make providers/common/include/prov/der_ec.h providers/common/include/prov/der_ecx.h providers/common/include/prov/der_sm2.h providers/common/include/prov/der_dsa.h providers/common/include/prov/der_rsa.h providers/common/include/prov/der_digests.h providers/common/include/prov/der_wrap.h + make providers/common/der/der_digests_gen.c providers/common/der/der_ecx_gen.c providers/common/der/der_ec_gen.c providers/common/der/der_dsa_gen.c providers/common/der/der_rsa_gen.c providers/common/der/der_sm2_gen.c providers/common/der/der_wrap_gen.c + + make include/openssl/asn1.h include/openssl/asn1t.h include/openssl/bio.h include/openssl/cmp.h include/openssl/cms.h include/openssl/conf.h include/openssl/configuration.h include/openssl/crmf.h include/openssl/crypto.h include/openssl/ct.h include/openssl/err.h include/openssl/ess.h include/openssl/fipskey.h include/openssl/ocsp.h include/openssl/opensslv.h include/openssl/pkcs12.h include/openssl/pkcs7.h include/openssl/safestack.h include/openssl/srp.h include/openssl/ssl.h include/openssl/ui.h include/openssl/x509.h include/openssl/x509_vfy.h include/openssl/x509v3.h + rm -f apps/CA.pl.bak openssl/opensslconf.h.bak mv -f include/crypto/bn_conf.h include/crypto/bn_conf-$outname.h @@ -627,22 +630,6 @@ function import() { gen_asm_x86_64 crypto/ec/asm/x25519-x86_64.pl - # Setup android.testssl directory - mkdir android.testssl - cat test/testssl | \ - sed 's#../util/shlib_wrap.sh ./ssltest#adb shell /system/bin/ssltest#' | \ - sed 's#../util/shlib_wrap.sh ../apps/openssl#adb shell /system/bin/openssl#' | \ - sed 's#adb shell /system/bin/openssl no-dh#[ `adb shell /system/bin/openssl no-dh` = no-dh ]#' | \ - sed 's#adb shell /system/bin/openssl no-rsa#[ `adb shell /system/bin/openssl no-rsa` = no-dh ]#' | \ - sed 's#../apps/server2.pem#/sdcard/android.testssl/server2.pem#' | \ - cat > \ - android.testssl/testssl - chmod +x android.testssl/testssl - cat test/Uss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/Uss.cnf - cat test/CAss.cnf | sed 's#./.rnd#/sdcard/android.testssl/.rnd#' >> android.testssl/CAss.cnf - cp apps/server2.pem android.testssl/ - cp ../patches/testssl.sh android.testssl/ - cd .. generate_config_mk Crypto-config-target.mk CRYPTO target diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index d3683649bc..0d5d2116de 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + /* Internal ASN1 structures and functions: not for application use */ /* ASN1 public key method structure */ @@ -49,9 +51,10 @@ struct evp_pkey_asn1_method_st { const unsigned char **pder, int derlen); int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder); /* Custom ASN1 signature verification */ - int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); - int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data, + const X509_ALGOR *a, const ASN1_BIT_STRING *sig, + EVP_PKEY *pkey); + int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, const void *data, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); int (*siginf_set) (X509_SIG_INFO *siginf, const X509_ALGOR *alg, @@ -73,19 +76,18 @@ struct evp_pkey_asn1_method_st { /* Exports and imports to / from providers */ size_t (*dirty_cnt) (const EVP_PKEY *pk); int (*export_to) (const EVP_PKEY *pk, void *to_keydata, - EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx, + EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx, const char *propq); OSSL_CALLBACK *import_from; - int (*priv_decode_with_libctx) (EVP_PKEY *pk, + int (*priv_decode_ex) (EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf, - OPENSSL_CTX *libctx, + OSSL_LIB_CTX *libctx, const char *propq); } /* EVP_PKEY_ASN1_METHOD */ ; DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD) -extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5]; @@ -95,12 +97,9 @@ extern const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ed448_asn1_meth; extern const EVP_PKEY_ASN1_METHOD sm2_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD poly1305_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2]; extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD siphash_asn1_meth; /* * These are used internally in the ASN1_OBJECT to keep track of whether the @@ -128,4 +127,14 @@ struct asn1_pctx_st { unsigned long str_flags; } /* ASN1_PCTX */ ; -int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); +/* ASN1 type functions */ + +int asn1_type_set_octetstring_int(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int asn1_type_get_octetstring_int(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +int x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md); +const EVP_MD *x509_algor_get_md(X509_ALGOR *alg); +X509_ALGOR *x509_algor_mgf1_decode(X509_ALGOR *alg); +int x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md); diff --git a/include/crypto/asn1_dsa.h b/include/crypto/asn1_dsa.h index caf0349968..df6ca0fe9c 100644 --- a/include/crypto/asn1_dsa.h +++ b/include/crypto/asn1_dsa.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,9 +15,9 @@ int encode_der_length(WPACKET *pkt, size_t cont_len); int encode_der_integer(WPACKET *pkt, const BIGNUM *n); int encode_der_dsa_sig(WPACKET *pkt, const BIGNUM *r, const BIGNUM *s); -int decode_der_length(PACKET *pkt, PACKET *subpkt); -int decode_der_integer(PACKET *pkt, BIGNUM *n); -size_t decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, - size_t len); +int ossl_decode_der_length(PACKET *pkt, PACKET *subpkt); +int ossl_decode_der_integer(PACKET *pkt, BIGNUM *n); +size_t ossl_decode_der_dsa_sig(BIGNUM *r, BIGNUM *s, const unsigned char **ppin, + size_t len); #endif diff --git a/include/crypto/bn.h b/include/crypto/bn.h index f2cb30de0a..4060541886 100644 --- a/include/crypto/bn.h +++ b/include/crypto/bn.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -110,7 +110,7 @@ int bn_rsa_fips186_4_derive_prime(BIGNUM *Y, BIGNUM *X, const BIGNUM *Xin, const BIGNUM *r1, const BIGNUM *r2, int nlen, const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb); -OPENSSL_CTX *bn_get_lib_ctx(BN_CTX *ctx); +OSSL_LIB_CTX *bn_get_libctx(BN_CTX *ctx); extern const BIGNUM bn_inv_sqrt_2; diff --git a/include/crypto/decoder.h b/include/crypto/decoder.h new file mode 100644 index 0000000000..f19e8bf841 --- /dev/null +++ b/include/crypto/decoder.h @@ -0,0 +1,40 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_CRYPTO_DECODER_H +# define OSSL_CRYPTO_DECODER_H + +# include + +OSSL_DECODER *ossl_decoder_fetch_by_number(OSSL_LIB_CTX *libctx, + int id, + const char *properties); + +/* + * These are specially made for the 'file:' provider-native loader, which + * uses this to install a DER to anything decoder, which doesn't do much + * except read a DER blob and pass it on as a provider object abstraction + * (provider-object(7)). + */ +void *ossl_decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov); + +OSSL_DECODER_INSTANCE * +ossl_decoder_instance_new(OSSL_DECODER *decoder, void *decoderctx); +void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst); +int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_INSTANCE *di); + +int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, + EVP_PKEY **pkey, const char *keytype, + OSSL_LIB_CTX *libctx, + const char *propquery); + +#endif + diff --git a/include/crypto/dh.h b/include/crypto/dh.h index 22847dd1e0..cd7e1e4a89 100644 --- a/include/crypto/dh.h +++ b/include/crypto/dh.h @@ -11,8 +11,8 @@ #include #include "internal/ffc.h" -DH *dh_new_by_nid_with_libctx(OPENSSL_CTX *libctx, int nid); -DH *dh_new_with_libctx(OPENSSL_CTX *libctx); +DH *dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid); +DH *dh_new_ex(OSSL_LIB_CTX *libctx); int dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits, BN_GENCB *cb); @@ -35,3 +35,9 @@ const DH_METHOD *dh_get_method(const DH *dh); int dh_buf2key(DH *key, const unsigned char *buf, size_t len); size_t dh_key2buf(const DH *dh, unsigned char **pbuf, size_t size, int alloc); + +int dh_KDF_X9_42_asn1(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const char *cek_alg, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md, + OSSL_LIB_CTX *libctx, const char *propq); diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h index 59c94a1740..759fa4cce4 100644 --- a/include/crypto/dsa.h +++ b/include/crypto/dsa.h @@ -14,14 +14,13 @@ #define DSA_PARAMGEN_TYPE_FIPS_186_4 0 /* Use FIPS186-4 standard */ #define DSA_PARAMGEN_TYPE_FIPS_186_2 1 /* Use legacy FIPS186-2 standard */ -DSA *dsa_new_with_ctx(OPENSSL_CTX *libctx); +DSA *dsa_new_with_ctx(OSSL_LIB_CTX *libctx); int dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits, BN_GENCB *cb); int dsa_sign_int(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa); -const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len); FFC_PARAMS *dsa_get0_params(DSA *dsa); int dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]); diff --git a/include/crypto/ec.h b/include/crypto/ec.h index a771cfd706..ffd5f19071 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -47,23 +47,28 @@ __owur int ec_group_do_inverse_ord(const EC_GROUP *group, BIGNUM *res, int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, const unsigned char *sinfo, size_t sinfolen, - const EVP_MD *md); + const EVP_MD *md, OSSL_LIB_CTX *libctx, const char *propq); -int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test); int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx); int ec_key_private_check(const EC_KEY *eckey); int ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx); -OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *eckey); +OSSL_LIB_CTX *ec_key_get_libctx(const EC_KEY *eckey); const char *ec_key_get0_propq(const EC_KEY *eckey); const char *ec_curve_nid2name(int nid); int ec_curve_name2nid(const char *name); -const unsigned char *ecdsa_algorithmidentifier_encoding(int md_nid, size_t *len); /* Backend support */ +int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *bnctx, unsigned char **genbuf); +int ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); int ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[], int include_private); -int ec_key_domparams_fromdata(EC_KEY *ecx, const OSSL_PARAM params[]); int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode); +int ec_encoding_name2id(const char *name); + +int evp_pkey_ctx_set_ec_param_enc_prov(EVP_PKEY_CTX *ctx, int param_enc); # endif /* OPENSSL_NO_EC */ #endif diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 54ce5f2b7c..4771df5fb6 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -61,7 +61,8 @@ typedef enum { : EVP_PKEY_ED448))) struct ecx_key_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; + char *propq; unsigned int haspubkey:1; unsigned char pubkey[MAX_KEYLEN]; unsigned char *privkey; @@ -74,7 +75,8 @@ struct ecx_key_st { typedef struct ecx_key_st ECX_KEY; size_t ecx_key_length(ECX_KEY_TYPE type); -ECX_KEY *ecx_key_new(OPENSSL_CTX *libctx, ECX_KEY_TYPE type, int haspubkey); +ECX_KEY *ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, + const char *propq); unsigned char *ecx_key_allocate_privkey(ECX_KEY *key); void ecx_key_free(ECX_KEY *key); int ecx_key_up_ref(ECX_KEY *key); @@ -84,35 +86,40 @@ int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], void X25519_public_from_private(uint8_t out_public_value[32], const uint8_t private_key[32]); -int ED25519_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[32], - const uint8_t private_key[32]); +int ED25519_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[32], + const uint8_t private_key[32], const char *propq); int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[32], const uint8_t private_key[32], - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int ED25519_verify(const uint8_t *message, size_t message_len, const uint8_t signature[64], const uint8_t public_key[32], - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); -int ED448_public_from_private(OPENSSL_CTX *ctx, uint8_t out_public_key[57], - const uint8_t private_key[57]); -int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message, +int ED448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57], + const uint8_t private_key[57], const char *propq); +int ED448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message, size_t message_len, const uint8_t public_key[57], const uint8_t private_key[57], const uint8_t *context, - size_t context_len); + size_t context_len, const char *propq); -int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len, +int ED448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len, const uint8_t signature[114], const uint8_t public_key[57], - const uint8_t *context, size_t context_len); + const uint8_t *context, size_t context_len, const char *propq); int X448(uint8_t out_shared_key[56], const uint8_t private_key[56], const uint8_t peer_public_value[56]); void X448_public_from_private(uint8_t out_public_value[56], const uint8_t private_key[56]); + /* Backend support */ int ecx_public_from_private(ECX_KEY *key); int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], int include_private); +ECX_KEY *evp_pkey_get1_X25519(EVP_PKEY *pkey); +ECX_KEY *evp_pkey_get1_X448(EVP_PKEY *pkey); +ECX_KEY *evp_pkey_get1_ED25519(EVP_PKEY *pkey); +ECX_KEY *evp_pkey_get1_ED448(EVP_PKEY *pkey); # endif /* OPENSSL_NO_EC */ #endif diff --git a/include/crypto/serializer.h b/include/crypto/encoder.h similarity index 53% rename from include/crypto/serializer.h rename to include/crypto/encoder.h index 84d6b54de7..a04ba93d54 100644 --- a/include/crypto/serializer.h +++ b/include/crypto/encoder.h @@ -9,7 +9,5 @@ #include -OSSL_SERIALIZER *ossl_serializer_fetch_by_number(OPENSSL_CTX *libctx, int id, - const char *properties); -OSSL_DESERIALIZER *ossl_deserializer_fetch_by_number(OPENSSL_CTX *libctx, int id, - const char *properties); +OSSL_ENCODER *ossl_encoder_fetch_by_number(OSSL_LIB_CTX *libctx, int id, + const char *properties); diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 2e85b56266..6eac2a0b63 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -18,6 +18,22 @@ */ #define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX 0x0400 +/* + * An EVP_PKEY can have the following support states: + * + * Supports legacy implementations only: + * + * engine != NULL || keytype == NULL + * + * Supports provided implementations: + * + * engine == NULL && keytype != NULL + */ +#define evp_pkey_ctx_is_legacy(ctx) \ + ((ctx)->engine != NULL || (ctx)->keytype == NULL) +#define evp_pkey_ctx_is_provided(ctx) \ + (!evp_pkey_ctx_is_legacy(ctx)) + struct evp_pkey_ctx_st { /* Actual operation */ int operation; @@ -26,7 +42,7 @@ struct evp_pkey_ctx_st { * Library context, property query, keytype and keymgmt associated with * this context */ - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; const char *propquery; const char *keytype; EVP_KEYMGMT *keymgmt; @@ -50,8 +66,27 @@ struct evp_pkey_ctx_st { EVP_ASYM_CIPHER *cipher; void *ciphprovctx; } ciph; + struct { + EVP_KEM *kem; + void *kemprovctx; + } encap; } op; + /* + * Cached parameters. Inits of operations that depend on these should + * call evp_pkey_ctx_use_delayed_data() when the operation has been set + * up properly. + */ + struct { + /* Distinguishing Identifier, ISO/IEC 15946-3, FIPS 196 */ + char *dist_id_name; /* The name used with EVP_PKEY_CTX_ctrl_str() */ + void *dist_id; /* The distinguishing ID itself */ + size_t dist_id_len; /* The length of the distinguishing ID */ + + /* Indicators of what has been set. Keep them together! */ + unsigned int dist_id_set : 1; + } cached_parameters; + /* Application specific data, usually used by the callback */ void *app_data; /* Keygen callback */ @@ -62,6 +97,8 @@ struct evp_pkey_ctx_st { /* Legacy fields below */ + /* EVP_PKEY identity */ + int legacy_keytype; /* Method associated with this operation */ const EVP_PKEY_METHOD *pmeth; /* Engine that implements this method or NULL if builtin */ @@ -74,6 +111,13 @@ struct evp_pkey_ctx_st { void *data; /* Indicator if digest_custom needs to be called */ unsigned int flag_call_digest_custom:1; + /* + * Used to support taking custody of memory in the case of a provider being + * used with the deprecated EVP_PKEY_CTX_set_rsa_keygen_pubexp() API. This + * member should NOT be used for any other purpose and should be removed + * when said deprecated API is excised completely. + */ + BIGNUM *rsa_pubexp; } /* EVP_PKEY_CTX */ ; #define EVP_PKEY_FLAG_DYNAMIC 1 @@ -131,24 +175,16 @@ DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD) void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); -const EVP_PKEY_METHOD *cmac_pkey_method(void); const EVP_PKEY_METHOD *dh_pkey_method(void); const EVP_PKEY_METHOD *dhx_pkey_method(void); const EVP_PKEY_METHOD *dsa_pkey_method(void); const EVP_PKEY_METHOD *ec_pkey_method(void); -const EVP_PKEY_METHOD *sm2_pkey_method(void); const EVP_PKEY_METHOD *ecx25519_pkey_method(void); const EVP_PKEY_METHOD *ecx448_pkey_method(void); const EVP_PKEY_METHOD *ed25519_pkey_method(void); const EVP_PKEY_METHOD *ed448_pkey_method(void); -const EVP_PKEY_METHOD *hmac_pkey_method(void); -const EVP_PKEY_METHOD *rsa_pkey_method(void); -const EVP_PKEY_METHOD *rsa_pss_pkey_method(void); -const EVP_PKEY_METHOD *scrypt_pkey_method(void); -const EVP_PKEY_METHOD *tls1_prf_pkey_method(void); -const EVP_PKEY_METHOD *hkdf_pkey_method(void); -const EVP_PKEY_METHOD *poly1305_pkey_method(void); -const EVP_PKEY_METHOD *siphash_pkey_method(void); +const EVP_PKEY_METHOD *ossl_rsa_pkey_method(void); +const EVP_PKEY_METHOD *ossl_rsa_pss_pkey_method(void); struct evp_mac_st { OSSL_PROVIDER *prov; @@ -314,7 +350,7 @@ static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns {\ while(inl>=EVP_MAXCHUNK) {\ int num = EVP_CIPHER_CTX_num(ctx);\ - cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num); \ + cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, ctx->iv, &num); \ EVP_CIPHER_CTX_set_num(ctx, num);\ inl-=EVP_MAXCHUNK;\ in +=EVP_MAXCHUNK;\ @@ -322,7 +358,7 @@ static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns }\ if (inl) {\ int num = EVP_CIPHER_CTX_num(ctx);\ - cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num); \ + cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, ctx->iv, &num); \ EVP_CIPHER_CTX_set_num(ctx, num);\ }\ return 1;\ @@ -333,13 +369,13 @@ static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const uns {\ while(inl>=EVP_MAXCHUNK) \ {\ - cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), EVP_CIPHER_CTX_encrypting(ctx));\ + cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, ctx->iv, EVP_CIPHER_CTX_encrypting(ctx));\ inl-=EVP_MAXCHUNK;\ in +=EVP_MAXCHUNK;\ out+=EVP_MAXCHUNK;\ }\ if (inl)\ - cprefix##_cbc_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), EVP_CIPHER_CTX_encrypting(ctx));\ + cprefix##_cbc_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, ctx->iv, EVP_CIPHER_CTX_encrypting(ctx));\ return 1;\ } @@ -356,7 +392,7 @@ static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, ((cbits == 1) \ && !EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS) \ ? chunk*8 : chunk), \ - &EVP_C_DATA(kstruct, ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx),\ + &EVP_C_DATA(kstruct, ctx)->ksched, ctx->iv,\ &num, EVP_CIPHER_CTX_encrypting(ctx));\ EVP_CIPHER_CTX_set_num(ctx, num);\ inl -= chunk;\ @@ -501,6 +537,18 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \ cipher##_init_key, NULL, NULL, NULL, NULL) +typedef struct { + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned int iv_len; + unsigned int tag_len; +} evp_cipher_aead_asn1_params; + +int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *params); + +int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *params); + /* * An EVP_PKEY can have the following states: * @@ -569,6 +617,7 @@ struct evp_pkey_st { # endif /* == Common attributes == */ + /* If these are modified, so must evp_pkey_downgrade() */ CRYPTO_REF_COUNT references; CRYPTO_RWLOCK *lock; STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ @@ -642,14 +691,19 @@ struct evp_pkey_st { ((ctx)->operation == EVP_PKEY_OP_PARAMGEN \ || (ctx)->operation == EVP_PKEY_OP_KEYGEN) +#define EVP_PKEY_CTX_IS_KEM_OP(ctx) \ + ((ctx)->operation == EVP_PKEY_OP_ENCAPSULATE \ + || (ctx)->operation == EVP_PKEY_OP_DECAPSULATE) + void openssl_add_all_ciphers_int(void); void openssl_add_all_digests_int(void); void evp_cleanup_int(void); void evp_app_cleanup_int(void); -void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx, +void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, EVP_KEYMGMT **keymgmt, const char *propquery); #ifndef FIPS_MODULE +int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src); int evp_pkey_downgrade(EVP_PKEY *pk); void evp_pkey_free_legacy(EVP_PKEY *x); #endif @@ -672,6 +726,8 @@ int evp_keymgmt_util_assign_pkey(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt, void *keydata); EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata); +int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection, + OSSL_CALLBACK *export_cb, void *export_cbarg); void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); size_t evp_keymgmt_util_find_operation_cache_index(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt); @@ -697,18 +753,13 @@ void *evp_keymgmt_newdata(const EVP_KEYMGMT *keymgmt); void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keyddata); int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata, OSSL_PARAM params[]); -const OSSL_PARAM *evp_keymgmt_gettable_params(const EVP_KEYMGMT *keymgmt); int evp_keymgmt_set_params(const EVP_KEYMGMT *keymgmt, void *keydata, const OSSL_PARAM params[]); -const OSSL_PARAM *evp_keymgmt_settable_params(const EVP_KEYMGMT *keymgmt); - void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection); int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx, void *template); int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx, const OSSL_PARAM params[]); -const OSSL_PARAM * -evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt); void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx, OSSL_CALLBACK *cb, void *cbarg); void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx); @@ -750,8 +801,15 @@ void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags); /* Use the SRP base64 alphabet instead of the standard one */ #define EVP_ENCODE_CTX_USE_SRP_ALPHABET 2 -const EVP_CIPHER *evp_get_cipherbyname_ex(OPENSSL_CTX *libctx, const char *name); -const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name); +const EVP_CIPHER *evp_get_cipherbyname_ex(OSSL_LIB_CTX *libctx, + const char *name); +const EVP_MD *evp_get_digestbyname_ex(OSSL_LIB_CTX *libctx, + const char *name); + +int pkcs5_pbkdf2_hmac_ex(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out, + OSSL_LIB_CTX *libctx, const char *propq); #ifndef FIPS_MODULE /* @@ -769,6 +827,18 @@ const EVP_MD *evp_get_digestbyname_ex(OPENSSL_CTX *libctx, const char *name); int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); -EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx, - const char *propq); +EVP_MD_CTX *evp_md_ctx_new_ex(EVP_PKEY *pkey, const ASN1_OCTET_STRING *id, + OSSL_LIB_CTX *libctx, const char *propq); +int evp_pkey_name2type(const char *name); + +int evp_pkey_ctx_set1_id_prov(EVP_PKEY_CTX *ctx, const void *id, int len); +int evp_pkey_ctx_get1_id_prov(EVP_PKEY_CTX *ctx, void *id); +int evp_pkey_ctx_get1_id_len_prov(EVP_PKEY_CTX *ctx, size_t *id_len); + +int evp_pkey_ctx_use_cached_data(EVP_PKEY_CTX *ctx); #endif /* !defined(FIPS_MODULE) */ +void evp_method_store_flush(OSSL_LIB_CTX *libctx); +int evp_set_default_properties_int(OSSL_LIB_CTX *libctx, const char *propq, + int loadconfig); + +void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force); diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h new file mode 100644 index 0000000000..60e01e5c39 --- /dev/null +++ b/include/crypto/pkcs7.h @@ -0,0 +1,10 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +void pkcs7_resolve_libctx(PKCS7 *p7); diff --git a/include/crypto/punycode.h b/include/crypto/punycode.h new file mode 100644 index 0000000000..ab31494060 --- /dev/null +++ b/include/crypto/punycode.h @@ -0,0 +1,24 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_CRYPTO_PUNYCODE_H +# define OSSL_CRYPTO_PUNYCODE_H + + +int ossl_punycode_decode ( + const char *pEncoded, + const size_t enc_len, + unsigned int *pDecoded, + unsigned int *pout_length +); + +int ossl_a2ulabel(const char *in, char *out, size_t *outlen); + +int ossl_a2ucompare(const char *a, const char *u); +#endif diff --git a/include/crypto/rand.h b/include/crypto/rand.h index c5eef81462..a437565fe8 100644 --- a/include/crypto/rand.h +++ b/include/crypto/rand.h @@ -88,4 +88,9 @@ void rand_pool_cleanup(void); */ void rand_pool_keep_random_devices_open(int keep); +/* + * Configuration + */ +void ossl_random_add_conf_module(void); + #endif diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 9469ec9233..1ee1991f57 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -19,79 +19,83 @@ typedef struct rsa_pss_params_30_st { int algorithm_nid; /* Currently always NID_mgf1 */ int hash_algorithm_nid; } mask_gen; - unsigned int salt_len; - unsigned int trailer_field; + int salt_len; + int trailer_field; } RSA_PSS_PARAMS_30; -RSA_PSS_PARAMS_30 *rsa_get0_pss_params_30(RSA *r); -int rsa_pss_params_30_set_defaults(RSA_PSS_PARAMS_30 *rsa_pss_params); -int rsa_pss_params_30_copy(RSA_PSS_PARAMS_30 *to, - const RSA_PSS_PARAMS_30 *from); -int rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params); -int rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int hashalg_nid); -int rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int maskgenalg_nid); -int rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, - int maskgenhashalg_nid); -int rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, - int saltlen); -int rsa_pss_params_30_set_trailerfield(RSA_PSS_PARAMS_30 *rsa_pss_params, - int trailerfield); -int rsa_pss_params_30_hashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params); -int rsa_pss_params_30_maskgenalg(const RSA_PSS_PARAMS_30 *rsa_pss_params); -int rsa_pss_params_30_maskgenhashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params); -int rsa_pss_params_30_saltlen(const RSA_PSS_PARAMS_30 *rsa_pss_params); -int rsa_pss_params_30_trailerfield(const RSA_PSS_PARAMS_30 *rsa_pss_params); - -const char *rsa_mgf_nid2name(int mgf); -int rsa_oaeppss_md2nid(const EVP_MD *md); -const char *rsa_oaeppss_nid2name(int md); - -RSA *rsa_new_with_ctx(OPENSSL_CTX *libctx); -OPENSSL_CTX *rsa_get0_libctx(RSA *r); - -int rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, - const STACK_OF(BIGNUM) *exps, - const STACK_OF(BIGNUM) *coeffs); -int rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, - STACK_OF(BIGNUM_const) *exps, - STACK_OF(BIGNUM_const) *coeffs); - -int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); -int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]); -int rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, const char *propq, - OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); -int rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, - const OSSL_PARAM params[], OPENSSL_CTX *libctx); - -int rsa_padding_check_PKCS1_type_2_TLS(OPENSSL_CTX *ctx, unsigned char *to, - size_t tlen, const unsigned char *from, - size_t flen, int client_version, - int alt_version); -int rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(OPENSSL_CTX *libctx, - unsigned char *to, int tlen, - const unsigned char *from, - int flen, - const unsigned char *param, - int plen, const EVP_MD *md, - const EVP_MD *mgf1md); - -int rsa_validate_public(const RSA *key); -int rsa_validate_private(const RSA *key); -int rsa_validate_pairwise(const RSA *key); +RSA_PSS_PARAMS_30 *ossl_rsa_get0_pss_params_30(RSA *r); +int ossl_rsa_pss_params_30_set_defaults(RSA_PSS_PARAMS_30 *rsa_pss_params); +int ossl_rsa_pss_params_30_copy(RSA_PSS_PARAMS_30 *to, + const RSA_PSS_PARAMS_30 *from); +int ossl_rsa_pss_params_30_is_unrestricted(const RSA_PSS_PARAMS_30 *rsa_pss_params); +int ossl_rsa_pss_params_30_set_hashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int hashalg_nid); +int ossl_rsa_pss_params_30_set_maskgenalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int maskgenalg_nid); +int ossl_rsa_pss_params_30_set_maskgenhashalg(RSA_PSS_PARAMS_30 *rsa_pss_params, + int maskgenhashalg_nid); +int ossl_rsa_pss_params_30_set_saltlen(RSA_PSS_PARAMS_30 *rsa_pss_params, + int saltlen); +int ossl_rsa_pss_params_30_set_trailerfield(RSA_PSS_PARAMS_30 *rsa_pss_params, + int trailerfield); +int ossl_rsa_pss_params_30_hashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params); +int ossl_rsa_pss_params_30_maskgenalg(const RSA_PSS_PARAMS_30 *rsa_pss_params); +int ossl_rsa_pss_params_30_maskgenhashalg(const RSA_PSS_PARAMS_30 *rsa_pss_params); +int ossl_rsa_pss_params_30_saltlen(const RSA_PSS_PARAMS_30 *rsa_pss_params); +int ossl_rsa_pss_params_30_trailerfield(const RSA_PSS_PARAMS_30 *rsa_pss_params); + +const char *ossl_rsa_mgf_nid2name(int mgf); +int ossl_rsa_oaeppss_md2nid(const EVP_MD *md); +const char *ossl_rsa_oaeppss_nid2name(int md); + +RSA *ossl_rsa_new_with_ctx(OSSL_LIB_CTX *libctx); +OSSL_LIB_CTX *ossl_rsa_get0_libctx(RSA *r); + +int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes, + const STACK_OF(BIGNUM) *exps, + const STACK_OF(BIGNUM) *coeffs); +int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes, + STACK_OF(BIGNUM_const) *exps, + STACK_OF(BIGNUM_const) *coeffs); + +int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); +int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]); +int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, + OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); +int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, + const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx); + +int ossl_rsa_padding_check_PKCS1_type_2_TLS(OSSL_LIB_CTX *ctx, unsigned char *to, + size_t tlen, + const unsigned char *from, + size_t flen, int client_version, + int alt_version); +int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx, + unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); + +int ossl_rsa_validate_public(const RSA *key); +int ossl_rsa_validate_private(const RSA *key); +int ossl_rsa_validate_pairwise(const RSA *key); int int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, size_t siglen, RSA *rsa); -const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len); -const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len); +const unsigned char *ossl_rsa_digestinfo_encoding(int md_nid, size_t *len); -extern const char *rsa_mp_factor_names[]; -extern const char *rsa_mp_exp_names[]; -extern const char *rsa_mp_coeff_names[]; +extern const char *ossl_rsa_mp_factor_names[]; +extern const char *ossl_rsa_mp_exp_names[]; +extern const char *ossl_rsa_mp_coeff_names[]; + +ASN1_STRING *ossl_rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx); +int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + const X509_ALGOR *sigalg, EVP_PKEY *pkey); # if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]); diff --git a/include/crypto/siv.h b/include/crypto/siv.h index fd39be00db..52560e704e 100644 --- a/include/crypto/siv.h +++ b/include/crypto/siv.h @@ -13,10 +13,10 @@ typedef struct siv128_context SIV128_CONTEXT; SIV128_CONTEXT *CRYPTO_siv128_new(const unsigned char *key, int klen, EVP_CIPHER *cbc, EVP_CIPHER *ctr, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, const EVP_CIPHER *cbc, const EVP_CIPHER *ctr, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src); int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad, size_t len); diff --git a/include/crypto/sm2.h b/include/crypto/sm2.h index 4a65ce4332..fe87c84bba 100644 --- a/include/crypto/sm2.h +++ b/include/crypto/sm2.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * @@ -45,14 +45,14 @@ int sm2_do_verify(const EC_KEY *key, /* * SM2 signature generation. */ -int sm2_sign(const unsigned char *dgst, int dgstlen, - unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); +int sm2_internal_sign(const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); /* * SM2 signature verification. */ -int sm2_verify(const unsigned char *dgst, int dgstlen, - const unsigned char *sig, int siglen, EC_KEY *eckey); +int sm2_internal_verify(const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); /* * SM2 encryption @@ -74,5 +74,6 @@ int sm2_decrypt(const EC_KEY *key, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len); +const unsigned char *sm2_algorithmidentifier_encoding(int md_nid, size_t *len); # endif /* OPENSSL_NO_SM2 */ #endif diff --git a/include/crypto/sm2err.h b/include/crypto/sm2err.h index d0b04baf71..bbbb0cfecf 100644 --- a/include/crypto/sm2err.h +++ b/include/crypto/sm2err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,8 +8,8 @@ * https://www.openssl.org/source/license.html */ -#ifndef OSSL_CRYPTO_SM2ERR_H -# define OSSL_CRYPTO_SM2ERR_H +#ifndef OPENSSL_SM2ERR_H +# define OPENSSL_SM2ERR_H # include # include @@ -39,6 +39,8 @@ int ERR_load_SM2_strings(void); # define SM2_F_SM2_COMPUTE_Z_DIGEST 0 # define SM2_F_SM2_DECRYPT 0 # define SM2_F_SM2_ENCRYPT 0 +# define SM2_F_SM2_INTERNAL_SIGN 0 +# define SM2_F_SM2_INTERNAL_VERIFY 0 # define SM2_F_SM2_PLAINTEXT_SIZE 0 # define SM2_F_SM2_SIGN 0 # define SM2_F_SM2_SIG_GEN 0 diff --git a/include/crypto/x509.h b/include/crypto/x509.h index 71a67df650..6fa5d22dc6 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -8,6 +8,8 @@ */ #include "internal/refcount.h" +#include +#include /* Internal X509 structures and functions: not for application use */ @@ -112,6 +114,9 @@ struct X509_crl_st { const X509_CRL_METHOD *meth; void *meth_data; CRYPTO_RWLOCK *lock; + + OSSL_LIB_CTX *libctx; + const char *propq; }; struct x509_revoked_st { @@ -190,7 +195,7 @@ struct x509_st { /* Set on live certificates for authentication purposes */ ASN1_OCTET_STRING *distinguishing_id; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; const char *propq; } /* X509 */ ; @@ -266,7 +271,7 @@ struct x509_store_ctx_st { /* X509_STORE_CTX */ /* signed via bare TA public key, rather than CA certificate */ int bare_ta_signed; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; }; @@ -299,10 +304,17 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc); int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm); int x509_print_ex_brief(BIO *bio, X509 *cert, unsigned long neg_cflags); int x509v3_cache_extensions(X509 *x); +int x509_init_sig_info(X509 *x); +int x509_check_issued_int(X509 *issuer, X509 *subject, OSSL_LIB_CTX *libctx, + const char *propq); -void x509_init_sig_info(X509 *x); +int x509_set0_libctx(X509 *x, OSSL_LIB_CTX *libctx, const char *propq); +int x509_crl_set0_libctx(X509_CRL *x, OSSL_LIB_CTX *libctx, const char *propq); +int x509_init_sig_info(X509 *x); +int asn1_item_digest_ex(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_add_cert_new(STACK_OF(X509) **sk, X509 *cert, int flags); -int asn1_item_digest_with_libctx(const ASN1_ITEM *it, const EVP_MD *type, - void *data, unsigned char *md, - unsigned int *len, OPENSSL_CTX *libctx, - const char *propq); +int X509_PUBKEY_get0_libctx(OSSL_LIB_CTX **plibctx, const char **ppropq, + const X509_PUBKEY *key); diff --git a/include/internal/asn1.h b/include/internal/asn1.h new file mode 100644 index 0000000000..8448786919 --- /dev/null +++ b/include/internal/asn1.h @@ -0,0 +1,15 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_ASN1_H +# define OSSL_INTERNAL_ASN1_H + +int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); + +#endif diff --git a/include/internal/core.h b/include/internal/core.h index 8823b3c744..8499f35794 100644 --- a/include/internal/core.h +++ b/include/internal/core.h @@ -28,13 +28,13 @@ */ typedef struct ossl_method_construct_method_st { /* Create store */ - void *(*alloc_tmp_store)(OPENSSL_CTX *ctx); + void *(*alloc_tmp_store)(OSSL_LIB_CTX *ctx); /* Remove a store */ void (*dealloc_tmp_store)(void *store); /* Get an already existing method from a store */ - void *(*get)(OPENSSL_CTX *libctx, void *store, void *data); + void *(*get)(OSSL_LIB_CTX *libctx, void *store, void *data); /* Store a method in a store */ - int (*put)(OPENSSL_CTX *libctx, void *store, void *method, + int (*put)(OSSL_LIB_CTX *libctx, void *store, void *method, const OSSL_PROVIDER *prov, int operation_id, const char *name, const char *propdef, void *data); /* Construct a new method */ @@ -44,11 +44,11 @@ typedef struct ossl_method_construct_method_st { void (*destruct)(void *method, void *data); } OSSL_METHOD_CONSTRUCT_METHOD; -void *ossl_method_construct(OPENSSL_CTX *ctx, int operation_id, +void *ossl_method_construct(OSSL_LIB_CTX *ctx, int operation_id, int force_cache, OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data); -void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, +void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, OSSL_PROVIDER *provider, int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result), diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index d0dd6fe2b5..e070618547 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -91,8 +91,8 @@ void OPENSSL_cpuid_setup(void); extern unsigned int OPENSSL_ia32cap_P[]; #endif void OPENSSL_showfatal(const char *fmta, ...); -int do_ex_data_init(OPENSSL_CTX *ctx); -void crypto_cleanup_all_ex_data_int(OPENSSL_CTX *ctx); +int do_ex_data_init(OSSL_LIB_CTX *ctx); +void crypto_cleanup_all_ex_data_int(OSSL_LIB_CTX *ctx); int openssl_init_fork_handlers(void); int openssl_get_fork_id(void); @@ -138,61 +138,62 @@ typedef struct ossl_ex_data_global_st { } OSSL_EX_DATA_GLOBAL; -/* OPENSSL_CTX */ - -# define OPENSSL_CTX_PROVIDER_STORE_RUN_ONCE_INDEX 0 -# define OPENSSL_CTX_DEFAULT_METHOD_STORE_RUN_ONCE_INDEX 1 -# define OPENSSL_CTX_METHOD_STORE_RUN_ONCE_INDEX 2 -# define OPENSSL_CTX_MAX_RUN_ONCE 3 - -# define OPENSSL_CTX_EVP_METHOD_STORE_INDEX 0 -# define OPENSSL_CTX_PROVIDER_STORE_INDEX 1 -# define OPENSSL_CTX_PROPERTY_DEFN_INDEX 2 -# define OPENSSL_CTX_PROPERTY_STRING_INDEX 3 -# define OPENSSL_CTX_NAMEMAP_INDEX 4 -# define OPENSSL_CTX_DRBG_INDEX 5 -# define OPENSSL_CTX_DRBG_NONCE_INDEX 6 -# define OPENSSL_CTX_RAND_CRNGT_INDEX 7 -# define OPENSSL_CTX_THREAD_EVENT_HANDLER_INDEX 8 -# define OPENSSL_CTX_FIPS_PROV_INDEX 9 -# define OPENSSL_CTX_SERIALIZER_STORE_INDEX 10 -# define OPENSSL_CTX_DESERIALIZER_STORE_INDEX 11 -# define OPENSSL_CTX_SELF_TEST_CB_INDEX 12 -# define OPENSSL_CTX_BIO_PROV_INDEX 13 -# define OPENSSL_CTX_GLOBAL_PROPERTIES 14 -# define OPENSSL_CTX_MAX_INDEXES 15 - -typedef struct openssl_ctx_method { - void *(*new_func)(OPENSSL_CTX *ctx); +/* OSSL_LIB_CTX */ + +# define OSSL_LIB_CTX_PROVIDER_STORE_RUN_ONCE_INDEX 0 +# define OSSL_LIB_CTX_DEFAULT_METHOD_STORE_RUN_ONCE_INDEX 1 +# define OSSL_LIB_CTX_METHOD_STORE_RUN_ONCE_INDEX 2 +# define OSSL_LIB_CTX_MAX_RUN_ONCE 3 + +# define OSSL_LIB_CTX_EVP_METHOD_STORE_INDEX 0 +# define OSSL_LIB_CTX_PROVIDER_STORE_INDEX 1 +# define OSSL_LIB_CTX_PROPERTY_DEFN_INDEX 2 +# define OSSL_LIB_CTX_PROPERTY_STRING_INDEX 3 +# define OSSL_LIB_CTX_NAMEMAP_INDEX 4 +# define OSSL_LIB_CTX_DRBG_INDEX 5 +# define OSSL_LIB_CTX_DRBG_NONCE_INDEX 6 +# define OSSL_LIB_CTX_RAND_CRNGT_INDEX 7 +# define OSSL_LIB_CTX_THREAD_EVENT_HANDLER_INDEX 8 +# define OSSL_LIB_CTX_FIPS_PROV_INDEX 9 +# define OSSL_LIB_CTX_ENCODER_STORE_INDEX 10 +# define OSSL_LIB_CTX_DECODER_STORE_INDEX 11 +# define OSSL_LIB_CTX_SELF_TEST_CB_INDEX 12 +# define OSSL_LIB_CTX_BIO_PROV_INDEX 13 +# define OSSL_LIB_CTX_GLOBAL_PROPERTIES 14 +# define OSSL_LIB_CTX_STORE_LOADER_STORE_INDEX 15 +# define OSSL_LIB_CTX_MAX_INDEXES 16 + +typedef struct ossl_lib_ctx_method { + void *(*new_func)(OSSL_LIB_CTX *ctx); void (*free_func)(void *); -} OPENSSL_CTX_METHOD; +} OSSL_LIB_CTX_METHOD; -OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx); -int openssl_ctx_is_default(OPENSSL_CTX *ctx); -int openssl_ctx_is_global_default(OPENSSL_CTX *ctx); +OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx); +int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx); +int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx); /* Functions to retrieve pointers to data by index */ -void *openssl_ctx_get_data(OPENSSL_CTX *, int /* index */, - const OPENSSL_CTX_METHOD * ctx); +void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *, int /* index */, + const OSSL_LIB_CTX_METHOD * ctx); -void openssl_ctx_default_deinit(void); -OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx); -typedef int (openssl_ctx_run_once_fn)(OPENSSL_CTX *ctx); -typedef void (openssl_ctx_onfree_fn)(OPENSSL_CTX *ctx); +void ossl_lib_ctx_default_deinit(void); +OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx); +typedef int (ossl_lib_ctx_run_once_fn)(OSSL_LIB_CTX *ctx); +typedef void (ossl_lib_ctx_onfree_fn)(OSSL_LIB_CTX *ctx); -int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx, - openssl_ctx_run_once_fn run_once_fn); -int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn); +int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, + ossl_lib_ctx_run_once_fn run_once_fn); +int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn); -OPENSSL_CTX *crypto_ex_data_get_openssl_ctx(const CRYPTO_EX_DATA *ad); -int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj, +OSSL_LIB_CTX *crypto_ex_data_get_ossl_lib_ctx(const CRYPTO_EX_DATA *ad); +int crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, CRYPTO_EX_DATA *ad); -int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, +int crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx); +int crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx); /* Function for simple binary search */ @@ -214,6 +215,10 @@ static ossl_inline void ossl_sleep(unsigned long millis) ts.tv_sec = (long int) (millis / 1000); ts.tv_nsec = (long int) (millis % 1000) * 1000000ul; nanosleep(&ts, NULL); +# elif defined(__TANDEM) && !defined(_REENTRANT) +# include + /* HPNS does not support usleep for non threaded apps */ + PROCESS_DELAY_(millis * 1000); # else usleep(millis * 1000); # endif diff --git a/include/internal/der.h b/include/internal/der.h index ce667dc869..a3e56d0dce 100644 --- a/include/internal/der.h +++ b/include/internal/der.h @@ -69,19 +69,20 @@ /* This can be used for all items that don't have a context */ #define DER_NO_CONTEXT -1 -int DER_w_precompiled(WPACKET *pkt, int tag, - const unsigned char *precompiled, size_t precompiled_n); +int ossl_DER_w_precompiled(WPACKET *pkt, int tag, + const unsigned char *precompiled, + size_t precompiled_n); -int DER_w_boolean(WPACKET *pkt, int tag, int b); -int DER_w_ulong(WPACKET *pkt, int tag, unsigned long v); -int DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v); -int DER_w_null(WPACKET *pkt, int tag); -int DER_w_octet_string(WPACKET *pkt, int tag, - const unsigned char *data, size_t data_n); -int DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value); +int ossl_DER_w_boolean(WPACKET *pkt, int tag, int b); +int ossl_DER_w_ulong(WPACKET *pkt, int tag, unsigned long v); +int ossl_DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v); +int ossl_DER_w_null(WPACKET *pkt, int tag); +int ossl_DER_w_octet_string(WPACKET *pkt, int tag, + const unsigned char *data, size_t data_n); +int ossl_DER_w_octet_string_uint32(WPACKET *pkt, int tag, uint32_t value); /* * All constructors for constructed elements have a begin and a end function */ -int DER_w_begin_sequence(WPACKET *pkt, int tag); -int DER_w_end_sequence(WPACKET *pkt, int tag); +int ossl_DER_w_begin_sequence(WPACKET *pkt, int tag); +int ossl_DER_w_end_sequence(WPACKET *pkt, int tag); diff --git a/include/internal/endian.h b/include/internal/endian.h index f581c14b24..b4e486da3a 100644 --- a/include/internal/endian.h +++ b/include/internal/endian.h @@ -10,13 +10,41 @@ #ifndef OSSL_INTERNAL_ENDIAN_H # define OSSL_INTERNAL_ENDIAN_H -# define DECLARE_IS_ENDIAN \ +/* + * IS_LITTLE_ENDIAN and IS_BIG_ENDIAN can be used to detect the endiannes + * at compile time. To use it, DECLARE_IS_ENDIAN must be used to declare + * a variable. + * + * L_ENDIAN and B_ENDIAN can be used at preprocessor time. They can be set + * in the configarion using the lib_cppflags variable. If neither is + * set, it will fall back to code works with either endianness. + */ + +# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) +# define DECLARE_IS_ENDIAN const int ossl_is_little_endian = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define IS_LITTLE_ENDIAN (ossl_is_little_endian) +# define IS_BIG_ENDIAN (!ossl_is_little_endian) +# if defined(L_ENDIAN) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) +# error "L_ENDIAN defined on a big endian machine" +# endif +# if defined(B_ENDIAN) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# error "B_ENDIAN defined on a little endian machine" +# endif +# if !defined(L_ENDIAN) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define L_ENDIAN +# endif +# if !defined(B_ENDIAN) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) +# define B_ENDIAN +# endif +# else +# define DECLARE_IS_ENDIAN \ const union { \ long one; \ char little; \ } ossl_is_endian = { 1 } -# define IS_LITTLE_ENDIAN (ossl_is_endian.little != 0) -# define IS_BIG_ENDIAN (ossl_is_endian.little == 0) +# define IS_LITTLE_ENDIAN (ossl_is_endian.little != 0) +# define IS_BIG_ENDIAN (ossl_is_endian.little == 0) +# endif #endif diff --git a/include/internal/ffc.h b/include/internal/ffc.h index b352b8d345..3e5d98f8e1 100644 --- a/include/internal/ffc.h +++ b/include/internal/ffc.h @@ -27,7 +27,7 @@ /* * The mode used by functions that share code for both generation and - * verification. See ffc_params_FIPS186_4_gen_verify(). + * verification. See ossl_ffc_params_FIPS186_4_gen_verify(). */ #define FFC_PARAM_MODE_VERIFY 0 #define FFC_PARAM_MODE_GENERATE 1 @@ -39,10 +39,11 @@ #define FFC_PARAM_RET_STATUS_UNVERIFIABLE_G 2 /* Validation flags */ -# define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 -# define FFC_PARAM_FLAG_VALIDATE_G 0x02 +# define FFC_PARAM_FLAG_VALIDATE_PQ 0x01 +# define FFC_PARAM_FLAG_VALIDATE_G 0x02 # define FFC_PARAM_FLAG_VALIDATE_ALL \ (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G) +#define FFC_PARAM_FLAG_VALIDATE_LEGACY 0x04 /* * NB: These values must align with the equivalently named macros in @@ -112,77 +113,86 @@ typedef struct ffc_params_st { const char *mdprops; } FFC_PARAMS; -void ffc_params_init(FFC_PARAMS *params); -void ffc_params_cleanup(FFC_PARAMS *params); -void ffc_params_set0_pqg(FFC_PARAMS *params, BIGNUM *p, BIGNUM *q, BIGNUM *g); -void ffc_params_get0_pqg(const FFC_PARAMS *params, const BIGNUM **p, - const BIGNUM **q, const BIGNUM **g); -void ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j); -int ffc_params_set_seed(FFC_PARAMS *params, - const unsigned char *seed, size_t seedlen); -void ffc_params_set_gindex(FFC_PARAMS *params, int index); -void ffc_params_set_pcounter(FFC_PARAMS *params, int index); -void ffc_params_set_h(FFC_PARAMS *params, int index); -void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags); -int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props); - -int ffc_params_set_validate_params(FFC_PARAMS *params, - const unsigned char *seed, size_t seedlen, - int counter); -void ffc_params_get_validate_params(const FFC_PARAMS *params, - unsigned char **seed, size_t *seedlen, - int *pcounter); - -int ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src); -int ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q); +void ossl_ffc_params_init(FFC_PARAMS *params); +void ossl_ffc_params_cleanup(FFC_PARAMS *params); +void ossl_ffc_params_set0_pqg(FFC_PARAMS *params, BIGNUM *p, BIGNUM *q, + BIGNUM *g); +void ossl_ffc_params_get0_pqg(const FFC_PARAMS *params, const BIGNUM **p, + const BIGNUM **q, const BIGNUM **g); +void ossl_ffc_params_set0_j(FFC_PARAMS *d, BIGNUM *j); +int ossl_ffc_params_set_seed(FFC_PARAMS *params, + const unsigned char *seed, size_t seedlen); +void ossl_ffc_params_set_gindex(FFC_PARAMS *params, int index); +void ossl_ffc_params_set_pcounter(FFC_PARAMS *params, int index); +void ossl_ffc_params_set_h(FFC_PARAMS *params, int index); +void ossl_ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags); +void ossl_ffc_params_enable_flags(FFC_PARAMS *params, unsigned int flags, + int enable); +int ossl_ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props); + +int ossl_ffc_params_set_validate_params(FFC_PARAMS *params, + const unsigned char *seed, + size_t seedlen, int counter); +void ossl_ffc_params_get_validate_params(const FFC_PARAMS *params, + unsigned char **seed, size_t *seedlen, + int *pcounter); + +int ossl_ffc_params_copy(FFC_PARAMS *dst, const FFC_PARAMS *src); +int ossl_ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q); #ifndef FIPS_MODULE -int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent); +int ossl_ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent); #endif /* FIPS_MODULE */ -int ffc_params_FIPS186_4_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int type, size_t L, size_t N, - int *res, BN_GENCB *cb); -int ffc_params_FIPS186_2_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int type, size_t L, size_t N, - int *res, BN_GENCB *cb); - -int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int mode, int type, size_t L, size_t N, - int *res, BN_GENCB *cb); -int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params, - int mode, int type, size_t L, size_t N, - int *res, BN_GENCB *cb); - -int ffc_params_simple_validate(OPENSSL_CTX *libctx, FFC_PARAMS *params, int type); -int ffc_params_FIPS186_4_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, - int type, int *res, BN_GENCB *cb); -int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params, - int type, int *res, BN_GENCB *cb); - -int ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params, - int N, int s, BIGNUM *priv); - -int ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, - const BIGNUM *p, const BIGNUM *q, - const BIGNUM *g, BIGNUM *tmp, int *ret); - -int ffc_validate_public_key(const FFC_PARAMS *params, const BIGNUM *pub_key, - int *ret); -int ffc_validate_public_key_partial(const FFC_PARAMS *params, - const BIGNUM *pub_key, int *ret); -int ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv_key, - int *ret); - -int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[]); -int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]); -int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name); -int ffc_named_group_to_uid(const char *name); -const char *ffc_named_group_from_uid(int nid); -int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name); -const char *ffc_params_flags_to_name(int flags); -int ffc_params_flags_from_name(const char *name); +int ossl_ffc_params_FIPS186_4_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb); +int ossl_ffc_params_FIPS186_2_generate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type, size_t L, size_t N, + int *res, BN_GENCB *cb); + +int ossl_ffc_params_FIPS186_4_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb); +int ossl_ffc_params_FIPS186_2_gen_verify(OSSL_LIB_CTX *libctx, + FFC_PARAMS *params, int mode, int type, + size_t L, size_t N, int *res, + BN_GENCB *cb); + +int ossl_ffc_params_simple_validate(OSSL_LIB_CTX *libctx, FFC_PARAMS *params, + int type); +int ossl_ffc_params_FIPS186_4_validate(OSSL_LIB_CTX *libctx, + const FFC_PARAMS *params, + int type, int *res, BN_GENCB *cb); +int ossl_ffc_params_FIPS186_2_validate(OSSL_LIB_CTX *libctx, + const FFC_PARAMS *params, + int type, int *res, BN_GENCB *cb); + +int ossl_ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params, + int N, int s, BIGNUM *priv); + +int ossl_ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont, + const BIGNUM *p, const BIGNUM *q, + const BIGNUM *g, BIGNUM *tmp, + int *ret); + +int ossl_ffc_validate_public_key(const FFC_PARAMS *params, + const BIGNUM *pub_key, int *ret); +int ossl_ffc_validate_public_key_partial(const FFC_PARAMS *params, + const BIGNUM *pub_key, int *ret); +int ossl_ffc_validate_private_key(const BIGNUM *upper, const BIGNUM *priv_key, + int *ret); + +int ossl_ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[]); +int ossl_ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]); +int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name); +int ossl_ffc_named_group_to_uid(const char *name); +const char *ossl_ffc_named_group_from_uid(int nid); +int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name); +const char *ossl_ffc_params_flags_to_name(int flags); +int ossl_ffc_params_flags_from_name(const char *name); #endif /* OSSL_INTERNAL_FFC_H */ diff --git a/include/internal/ktls.h b/include/internal/ktls.h index 9212bb4343..fd439b5718 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -20,9 +20,9 @@ # endif #endif -#ifndef OPENSSL_NO_KTLS -# ifndef HEADER_INTERNAL_KTLS -# define HEADER_INTERNAL_KTLS +#ifndef HEADER_INTERNAL_KTLS +# define HEADER_INTERNAL_KTLS +# ifndef OPENSSL_NO_KTLS # if defined(__FreeBSD__) # include @@ -30,12 +30,22 @@ # include # include # include -# include +# include "openssl/ssl3.h" + +# ifndef TCP_RXTLS_ENABLE +# define OPENSSL_NO_KTLS_RX +# endif +# define OPENSSL_KTLS_AES_GCM_128 +# define OPENSSL_KTLS_AES_GCM_256 +# define OPENSSL_KTLS_TLS13 /* * Only used by the tests in sslapitest.c. */ # define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 +# define TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE 8 + +typedef struct tls_enable ktls_crypto_info_t; /* * FreeBSD does not require any additional steps to enable KTLS before @@ -49,18 +59,24 @@ static ossl_inline int ktls_enable(int fd) /* * The TCP_TXTLS_ENABLE socket option marks the outgoing socket buffer * as using TLS. If successful, then data sent using this socket will - * be encrypted and encapsulated in TLS records using the tls_en. + * be encrypted and encapsulated in TLS records using the tls_en * provided here. + * + * The TCP_RXTLS_ENABLE socket option marks the incoming socket buffer + * as using TLS. If successful, then data received for this socket will + * be authenticated and decrypted using the tls_en provided here. */ -static ossl_inline int ktls_start(int fd, - void *tls_en, - size_t len, int is_tx) +static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *tls_en, int is_tx) { if (is_tx) return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, - tls_en, len) ? 0 : 1; - else - return 0; + tls_en, sizeof(*tls_en)) ? 0 : 1; +# ifndef OPENSSL_NO_KTLS_RX + return setsockopt(fd, IPPROTO_TCP, TCP_RXTLS_ENABLE, tls_en, + sizeof(*tls_en)) ? 0 : 1; +# else + return 0; +# endif } /* @@ -96,11 +112,79 @@ static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, return sendmsg(fd, &msg, 0); } +# ifdef OPENSSL_NO_KTLS_RX + static ossl_inline int ktls_read_record(int fd, void *data, size_t length) { return -1; } +# else /* !defined(OPENSSL_NO_KTLS_RX) */ + +/* + * Receive a TLS record using the tls_en provided in ktls_start. The + * kernel strips any explicit IV and authentication tag, but provides + * the TLS record header via a control message. If there is an error + * with the TLS record such as an invalid header, invalid padding, or + * authentication failure recvmsg() will fail with an error. + */ +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + struct msghdr msg = { 0 }; + int cmsg_len = sizeof(struct tls_get_record); + struct tls_get_record *tgr; + struct cmsghdr *cmsg; + char buf[CMSG_SPACE(cmsg_len)]; + struct iovec msg_iov; /* Vector of data to send/receive into */ + int ret; + unsigned char *p = data; + const size_t prepend_length = SSL3_RT_HEADER_LENGTH; + + if (length <= prepend_length) { + errno = EINVAL; + return -1; + } + + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + + msg_iov.iov_base = p + prepend_length; + msg_iov.iov_len = length - prepend_length; + msg.msg_iov = &msg_iov; + msg.msg_iovlen = 1; + + ret = recvmsg(fd, &msg, 0); + if (ret <= 0) + return ret; + + if ((msg.msg_flags & (MSG_EOR | MSG_CTRUNC)) != MSG_EOR) { + errno = EMSGSIZE; + return -1; + } + + if (msg.msg_controllen == 0) { + errno = EBADMSG; + return -1; + } + + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg->cmsg_level != IPPROTO_TCP || cmsg->cmsg_type != TLS_GET_RECORD + || cmsg->cmsg_len != CMSG_LEN(cmsg_len)) { + errno = EBADMSG; + return -1; + } + + tgr = (struct tls_get_record *)CMSG_DATA(cmsg); + p[0] = tgr->tls_type; + p[1] = tgr->tls_vmajor; + p[2] = tgr->tls_vminor; + *(uint16_t *)(p + 3) = htons(ret); + + return ret + prepend_length; +} + +# endif /* OPENSSL_NO_KTLS_RX */ + /* * KTLS enables the sendfile system call to send data from a file over * TLS. @@ -119,6 +203,7 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, } return sbytes; } + # endif /* __FreeBSD__ */ # if defined(OPENSSL_SYS_LINUX) @@ -173,6 +258,9 @@ struct tls_crypto_info_all { }; size_t tls_crypto_info_len; }; + +typedef struct tls_crypto_info_all ktls_crypto_info_t; + /* * When successful, this socket option doesn't change the behaviour of the * TCP socket, except changing the TCP setsockopt handler to enable the @@ -192,11 +280,11 @@ static ossl_inline int ktls_enable(int fd) * If successful, then data received using this socket will be decrypted, * authenticated and decapsulated using the crypto_info provided here. */ -static ossl_inline int ktls_start(int fd, void *crypto_info, - size_t len, int is_tx) +static ossl_inline int ktls_start(int fd, ktls_crypto_info_t *crypto_info, + int is_tx) { return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, - crypto_info, len) ? 0 : 1; + crypto_info, crypto_info->tls_crypto_info_len) ? 0 : 1; } /* @@ -310,130 +398,6 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length) # endif /* OPENSSL_NO_KTLS_RX */ -/* Function to check supported ciphers in Linux */ -static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c, - const EVP_CIPHER_CTX *dd) -{ - /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */ - switch (EVP_CIPHER_nid(c)) - { -# ifdef OPENSSL_KTLS_AES_CCM_128 - case NID_aes_128_ccm: - if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) - return 0; -# endif -# ifdef OPENSSL_KTLS_AES_GCM_128 - case NID_aes_128_gcm: -# endif -# ifdef OPENSSL_KTLS_AES_GCM_256 - case NID_aes_256_gcm: -# endif - return 1; - default: - return 0; - } -} - -/* Function to configure kernel TLS structure */ -static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_version, - EVP_CIPHER_CTX *dd, void *rl_sequence, - struct tls_crypto_info_all *crypto_info, - unsigned char **rec_seq, unsigned char *iv, - unsigned char *key) -{ - unsigned char geniv[12]; - unsigned char *iiv = iv; - - if (tls_version == TLS1_2_VERSION && - EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { - EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, - EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, - geniv); - iiv = geniv; - } - - memset(crypto_info, 0, sizeof(*crypto_info)); - switch (EVP_CIPHER_nid(c)) - { -# ifdef OPENSSL_KTLS_AES_GCM_128 - case NID_aes_128_gcm: - crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; - crypto_info->gcm128.info.version = tls_version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); - memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_128_IV_SIZE); - memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); - memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c)); - memcpy(crypto_info->gcm128.rec_seq, rl_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->gcm128.rec_seq; - return 1; -# endif -# ifdef OPENSSL_KTLS_AES_GCM_256 - case NID_aes_256_gcm: - crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; - crypto_info->gcm256.info.version = tls_version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); - memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_256_IV_SIZE); - memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); - memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c)); - memcpy(crypto_info->gcm256.rec_seq, rl_sequence, - TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->gcm256.rec_seq; - return 1; -# endif -# ifdef OPENSSL_KTLS_AES_CCM_128 - case NID_aes_128_ccm: - crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; - crypto_info->ccm128.info.version = tls_version; - crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); - memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_CCM_128_IV_SIZE); - memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); - memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c)); - memcpy(crypto_info->ccm128.rec_seq, rl_sequence, - TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); - if (rec_seq != NULL) - *rec_seq = crypto_info->ccm128.rec_seq; - return 1; -# endif - default: - return 0; - } - -} - # endif /* OPENSSL_SYS_LINUX */ -# endif /* HEADER_INTERNAL_KTLS */ -#else /* defined(OPENSSL_NO_KTLS) */ -/* Dummy functions here */ -static ossl_inline int ktls_enable(int fd) -{ - return 0; -} - -static ossl_inline int ktls_start(int fd, void *crypto_info, - size_t len, int is_tx) -{ - return 0; -} - -static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, - const void *data, size_t length) -{ - return -1; -} - -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - return -1; -} - -static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) -{ - return -1; -} -#endif +# endif /* OPENSSL_NO_KTLS */ +#endif /* HEADER_INTERNAL_KTLS */ diff --git a/include/internal/namemap.h b/include/internal/namemap.h index d33f4b0d4e..685ccb41c1 100644 --- a/include/internal/namemap.h +++ b/include/internal/namemap.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,7 +11,7 @@ typedef struct ossl_namemap_st OSSL_NAMEMAP; -OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx); +OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx); OSSL_NAMEMAP *ossl_namemap_new(void); void ossl_namemap_free(OSSL_NAMEMAP *namemap); diff --git a/include/internal/passphrase.h b/include/internal/passphrase.h new file mode 100644 index 0000000000..9077907d52 --- /dev/null +++ b/include/internal/passphrase.h @@ -0,0 +1,120 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_PASSPHRASE_H +# define OSSL_INTERNAL_PASSPHRASE_H + +/* + * This is a passphrase reader bridge with bells and whistles. + * + * On one hand, an API may wish to offer all sorts of passphrase callback + * possibilities to users, or may have to do so for historical reasons. + * On the other hand, that same API may have demands from other interfaces, + * notably from the libcrypto <-> provider interface, which uses + * OSSL_PASSPHRASE_CALLBACK consistently. + * + * The structure and functions below are the fundaments for bridging one + * passphrase callback form to another. + * + * In addition, extra features are included (this may be a growing list): + * + * - password caching. This is to be used by APIs where it's likely + * that the same passphrase may be asked for more than once, but the + * user shouldn't get prompted more than once. For example, this is + * useful for OSSL_DECODER, which may have to use a passphrase while + * trying to find out what input it has. + */ + +/* + * Structure to hold whatever the calling user may specify. This structure + * is intended to be integrated into API specific structures or to be used + * as a local on-stack variable type. Therefore, no functions to allocate + * or freed it on the heap is offered. + */ +struct ossl_passphrase_data_st { + enum { + is_expl_passphrase = 1, /* Explicit passphrase given by user */ + is_pem_password, /* pem_password_cb given by user */ + is_ossl_passphrase, /* OSSL_PASSPHRASE_CALLBACK given by user */ + is_ui_method /* UI_METHOD given by user */ + } type; + union { + struct { + char *passphrase_copy; + size_t passphrase_len; + } expl_passphrase; + + struct { + pem_password_cb *password_cb; + void *password_cbarg; + } pem_password; + + struct { + OSSL_PASSPHRASE_CALLBACK *passphrase_cb; + void *passphrase_cbarg; + } ossl_passphrase; + + struct { + const UI_METHOD *ui_method; + void *ui_method_data; + } ui_method; + } _; + + /*- + * Flags section + */ + + /* Set to indicate that caching should be done */ + unsigned int flag_cache_passphrase:1; + + /*- + * Misc section: caches and other + */ + + char *cached_passphrase; + size_t cached_passphrase_len; +}; + +/* Structure manipulation */ + +void ossl_pw_clear_passphrase_data(struct ossl_passphrase_data_st *data); +void ossl_pw_clear_passphrase_cache(struct ossl_passphrase_data_st *data); + +int ossl_pw_set_passphrase(struct ossl_passphrase_data_st *data, + const unsigned char *passphrase, + size_t passphrase_len); +int ossl_pw_set_pem_password_cb(struct ossl_passphrase_data_st *data, + pem_password_cb *cb, void *cbarg); +int ossl_pw_set_ossl_passphrase_cb(struct ossl_passphrase_data_st *data, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg); +int ossl_pw_set_ui_method(struct ossl_passphrase_data_st *data, + const UI_METHOD *ui_method, void *ui_data); + +int ossl_pw_enable_passphrase_caching(struct ossl_passphrase_data_st *data); +int ossl_pw_disable_passphrase_caching(struct ossl_passphrase_data_st *data); + +/* Central function for direct calls */ + +int ossl_pw_get_passphrase(char *pass, size_t pass_size, size_t *pass_len, + const OSSL_PARAM params[], int verify, + struct ossl_passphrase_data_st *data); + +/* Callback functions */ + +/* + * All of these callback expect that the callback argument is a + * struct ossl_passphrase_data_st + */ + +pem_password_cb ossl_pw_pem_password; +/* One callback for encoding (verification prompt) and one for decoding */ +OSSL_PASSPHRASE_CALLBACK ossl_pw_passphrase_callback_enc; +OSSL_PASSPHRASE_CALLBACK ossl_pw_passphrase_callback_dec; + +#endif diff --git a/crypto/include/internal/pem_int.h b/include/internal/pem.h similarity index 75% rename from crypto/include/internal/pem_int.h rename to include/internal/pem.h index c8f90528c3..b6a10241f3 100644 --- a/crypto/include/internal/pem_int.h +++ b/include/internal/pem.h @@ -7,17 +7,25 @@ * https://www.openssl.org/source/license.html */ -#ifndef HEADER_PEM_INT_H -# define HEADER_PEM_INT_H +#ifndef OSSL_INTERNAL_PEM_H +# define OSSL_INTERNAL_PEM_H # include +# ifndef OPENSSL_NO_DSA /* Found in crypto/pem/pvkfmt.c */ int ossl_do_blob_header(const unsigned char **in, unsigned int length, unsigned int *pmagic, unsigned int *pbitlen, int *pisdss, int *pispub); +# ifndef OPENSSL_NO_RC4 int ossl_do_PVK_header(const unsigned char **in, unsigned int length, int skip_magic, unsigned int *psaltlen, unsigned int *pkeylen); +# endif + +EVP_PKEY *ossl_b2i(const unsigned char **in, unsigned int length, int *ispub); +EVP_PKEY *ossl_b2i_bio(BIO *in, int *ispub); + +# endif #endif diff --git a/include/internal/property.h b/include/internal/property.h index d8ff3582eb..f2682a1fed 100644 --- a/include/internal/property.h +++ b/include/internal/property.h @@ -17,23 +17,23 @@ typedef struct ossl_method_store_st OSSL_METHOD_STORE; typedef struct ossl_property_list_st OSSL_PROPERTY_LIST; /* Initialisation */ -int ossl_property_parse_init(OPENSSL_CTX *ctx); +int ossl_property_parse_init(OSSL_LIB_CTX *ctx); /* Property definition parser */ -OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn); +OSSL_PROPERTY_LIST *ossl_parse_property(OSSL_LIB_CTX *ctx, const char *defn); /* Property query parser */ -OSSL_PROPERTY_LIST *ossl_parse_query(OPENSSL_CTX *ctx, const char *s); +OSSL_PROPERTY_LIST *ossl_parse_query(OSSL_LIB_CTX *ctx, const char *s); /* Property checker of query vs definition */ int ossl_property_match_count(const OSSL_PROPERTY_LIST *query, const OSSL_PROPERTY_LIST *defn); -int ossl_property_is_enabled(OPENSSL_CTX *ctx, const char *property_name, +int ossl_property_is_enabled(OSSL_LIB_CTX *ctx, const char *property_name, const OSSL_PROPERTY_LIST *prop_list); /* Free a parsed property list */ void ossl_property_free(OSSL_PROPERTY_LIST *p); /* Implementation store functions */ -OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx); +OSSL_METHOD_STORE *ossl_method_store_new(OSSL_LIB_CTX *ctx); void ossl_method_store_free(OSSL_METHOD_STORE *store); int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov, int nid, const char *properties, void *method, @@ -45,7 +45,8 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store, int nid, const char *prop_query, void **method); /* Get the global properties associate with the specified library context */ -OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OPENSSL_CTX *ctx); +OSSL_PROPERTY_LIST **ossl_ctx_global_properties(OSSL_LIB_CTX *ctx, + int loadconfig); /* property query cache functions */ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, int nid, @@ -54,7 +55,8 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, int nid, const char *prop_query, void *result, int (*method_up_ref)(void *), void (*method_destruct)(void *)); -void ossl_method_store_flush_cache(OSSL_METHOD_STORE *store); + +void ossl_method_store_flush_cache(OSSL_METHOD_STORE *store, int all); /* Merge two property queries together */ OSSL_PROPERTY_LIST *ossl_property_merge(const OSSL_PROPERTY_LIST *a, diff --git a/include/internal/provider.h b/include/internal/provider.h index dcd57708ba..ab36c93b32 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -27,9 +27,9 @@ extern "C" { */ /* Provider Object finder, constructor and destructor */ -OSSL_PROVIDER *ossl_provider_find(OPENSSL_CTX *libctx, const char *name, +OSSL_PROVIDER *ossl_provider_find(OSSL_LIB_CTX *libctx, const char *name, int noconfig); -OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name, +OSSL_PROVIDER *ossl_provider_new(OSSL_LIB_CTX *libctx, const char *name, OSSL_provider_init_fn *init_function, int noconfig); int ossl_provider_up_ref(OSSL_PROVIDER *prov); @@ -41,6 +41,9 @@ int ossl_provider_set_module_path(OSSL_PROVIDER *prov, const char *module_path); int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name, const char *value); +/* Disable fallback loading */ +int ossl_provider_disable_fallback_loading(OSSL_LIB_CTX *libctx); + /* * Activate the Provider * If the Provider is a module, the module will be loaded @@ -54,7 +57,7 @@ int ossl_provider_available(OSSL_PROVIDER *prov); void *ossl_provider_ctx(const OSSL_PROVIDER *prov); /* Iterate over all loaded providers */ -int ossl_provider_forall_loaded(OPENSSL_CTX *, +int ossl_provider_forall_loaded(OSSL_LIB_CTX *, int (*cb)(OSSL_PROVIDER *provider, void *cbdata), void *cbdata); @@ -65,7 +68,7 @@ const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov); const char *ossl_provider_module_name(const OSSL_PROVIDER *prov); const char *ossl_provider_module_path(const OSSL_PROVIDER *prov); void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov); -OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov); +OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov); /* Thin wrappers around calls to the provider */ void ossl_provider_teardown(const OSSL_PROVIDER *prov); @@ -75,6 +78,7 @@ int ossl_provider_get_capabilities(const OSSL_PROVIDER *prov, const char *capability, OSSL_CALLBACK *cb, void *arg); +int ossl_provider_self_test(const OSSL_PROVIDER *prov); const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, int operation_id, int *no_cache); diff --git a/include/internal/sockets.h b/include/internal/sockets.h index 6d17363d9b..e86ae8a09e 100644 --- a/include/internal/sockets.h +++ b/include/internal/sockets.h @@ -145,6 +145,17 @@ struct servent *PASCAL getservbyname(const char *, const char *); # define closesocket(s) close(s) # define readsocket(s,b,n) read((s),(b),(n)) # define writesocket(s,b,n) write((s),(char *)(b),(n)) +# elif defined(OPENSSL_SYS_TANDEM) +# if defined(OPENSSL_TANDEM_FLOSS) +# include +# define readsocket(s,b,n) floss_read((s),(b),(n)) +# define writesocket(s,b,n) floss_write((s),(b),(n)) +# else +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(b),(n)) +# endif +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# define closesocket(s) close(s) # else # define ioctlsocket(a,b,c) ioctl(a,b,c) # define closesocket(s) close(s) diff --git a/include/internal/thread_once.h b/include/internal/thread_once.h index cbc9cc1e6d..d16c924998 100644 --- a/include/internal/thread_once.h +++ b/include/internal/thread_once.h @@ -12,7 +12,7 @@ /* * Initialisation of global data should never happen via "RUN_ONCE" inside the * FIPS module. Global data should instead always be associated with a specific - * OPENSSL_CTX object. In this way data will get cleaned up correctly when the + * OSSL_LIB_CTX object. In this way data will get cleaned up correctly when the * module gets unloaded. */ #if !defined(FIPS_MODULE) || defined(ALLOW_RUN_ONCE_IN_FIPS) diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index c9917492d5..3a30894735 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/asn1.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_ASN1_H # define OPENSSL_ASN1_H # pragma once @@ -121,7 +126,33 @@ extern "C" { # define SMIME_STREAM 0x1000 /* Stacks for types not otherwise defined in this header */ -DEFINE_OR_DECLARE_STACK_OF(X509_ALGOR) +SKM_DEFINE_STACK_OF_INTERNAL(X509_ALGOR, X509_ALGOR, X509_ALGOR) +#define sk_X509_ALGOR_num(sk) OPENSSL_sk_num(ossl_check_const_X509_ALGOR_sk_type(sk)) +#define sk_X509_ALGOR_value(sk, idx) ((X509_ALGOR *)OPENSSL_sk_value(ossl_check_const_X509_ALGOR_sk_type(sk), (idx))) +#define sk_X509_ALGOR_new(cmp) ((STACK_OF(X509_ALGOR) *)OPENSSL_sk_new(ossl_check_X509_ALGOR_compfunc_type(cmp))) +#define sk_X509_ALGOR_new_null() ((STACK_OF(X509_ALGOR) *)OPENSSL_sk_new_null()) +#define sk_X509_ALGOR_new_reserve(cmp, n) ((STACK_OF(X509_ALGOR) *)OPENSSL_sk_new_reserve(ossl_check_X509_ALGOR_compfunc_type(cmp), (n))) +#define sk_X509_ALGOR_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_ALGOR_sk_type(sk), (n)) +#define sk_X509_ALGOR_free(sk) OPENSSL_sk_free(ossl_check_X509_ALGOR_sk_type(sk)) +#define sk_X509_ALGOR_zero(sk) OPENSSL_sk_zero(ossl_check_X509_ALGOR_sk_type(sk)) +#define sk_X509_ALGOR_delete(sk, i) ((X509_ALGOR *)OPENSSL_sk_delete(ossl_check_X509_ALGOR_sk_type(sk), (i))) +#define sk_X509_ALGOR_delete_ptr(sk, ptr) ((X509_ALGOR *)OPENSSL_sk_delete_ptr(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_type(ptr))) +#define sk_X509_ALGOR_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_type(ptr)) +#define sk_X509_ALGOR_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_type(ptr)) +#define sk_X509_ALGOR_pop(sk) ((X509_ALGOR *)OPENSSL_sk_pop(ossl_check_X509_ALGOR_sk_type(sk))) +#define sk_X509_ALGOR_shift(sk) ((X509_ALGOR *)OPENSSL_sk_shift(ossl_check_X509_ALGOR_sk_type(sk))) +#define sk_X509_ALGOR_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_ALGOR_sk_type(sk),ossl_check_X509_ALGOR_freefunc_type(freefunc)) +#define sk_X509_ALGOR_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_type(ptr), (idx)) +#define sk_X509_ALGOR_set(sk, idx, ptr) ((X509_ALGOR *)OPENSSL_sk_set(ossl_check_X509_ALGOR_sk_type(sk), (idx), ossl_check_X509_ALGOR_type(ptr))) +#define sk_X509_ALGOR_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_type(ptr)) +#define sk_X509_ALGOR_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_type(ptr)) +#define sk_X509_ALGOR_sort(sk) OPENSSL_sk_sort(ossl_check_X509_ALGOR_sk_type(sk)) +#define sk_X509_ALGOR_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_ALGOR_sk_type(sk)) +#define sk_X509_ALGOR_dup(sk) ((STACK_OF(X509_ALGOR) *)OPENSSL_sk_dup(ossl_check_const_X509_ALGOR_sk_type(sk))) +#define sk_X509_ALGOR_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_ALGOR) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_copyfunc_type(copyfunc), ossl_check_X509_ALGOR_freefunc_type(freefunc))) +#define sk_X509_ALGOR_set_cmp_func(sk, cmp) ((sk_X509_ALGOR_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_ALGOR_sk_type(sk), ossl_check_X509_ALGOR_compfunc_type(cmp))) + + # define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ /* @@ -196,7 +227,32 @@ struct asn1_string_table_st { unsigned long flags; }; -DEFINE_OR_DECLARE_STACK_OF(ASN1_STRING_TABLE) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_STRING_TABLE, ASN1_STRING_TABLE, ASN1_STRING_TABLE) +#define sk_ASN1_STRING_TABLE_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_STRING_TABLE_sk_type(sk)) +#define sk_ASN1_STRING_TABLE_value(sk, idx) ((ASN1_STRING_TABLE *)OPENSSL_sk_value(ossl_check_const_ASN1_STRING_TABLE_sk_type(sk), (idx))) +#define sk_ASN1_STRING_TABLE_new(cmp) ((STACK_OF(ASN1_STRING_TABLE) *)OPENSSL_sk_new(ossl_check_ASN1_STRING_TABLE_compfunc_type(cmp))) +#define sk_ASN1_STRING_TABLE_new_null() ((STACK_OF(ASN1_STRING_TABLE) *)OPENSSL_sk_new_null()) +#define sk_ASN1_STRING_TABLE_new_reserve(cmp, n) ((STACK_OF(ASN1_STRING_TABLE) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_STRING_TABLE_compfunc_type(cmp), (n))) +#define sk_ASN1_STRING_TABLE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_STRING_TABLE_sk_type(sk), (n)) +#define sk_ASN1_STRING_TABLE_free(sk) OPENSSL_sk_free(ossl_check_ASN1_STRING_TABLE_sk_type(sk)) +#define sk_ASN1_STRING_TABLE_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_STRING_TABLE_sk_type(sk)) +#define sk_ASN1_STRING_TABLE_delete(sk, i) ((ASN1_STRING_TABLE *)OPENSSL_sk_delete(ossl_check_ASN1_STRING_TABLE_sk_type(sk), (i))) +#define sk_ASN1_STRING_TABLE_delete_ptr(sk, ptr) ((ASN1_STRING_TABLE *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_type(ptr))) +#define sk_ASN1_STRING_TABLE_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_type(ptr)) +#define sk_ASN1_STRING_TABLE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_type(ptr)) +#define sk_ASN1_STRING_TABLE_pop(sk) ((ASN1_STRING_TABLE *)OPENSSL_sk_pop(ossl_check_ASN1_STRING_TABLE_sk_type(sk))) +#define sk_ASN1_STRING_TABLE_shift(sk) ((ASN1_STRING_TABLE *)OPENSSL_sk_shift(ossl_check_ASN1_STRING_TABLE_sk_type(sk))) +#define sk_ASN1_STRING_TABLE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_STRING_TABLE_sk_type(sk),ossl_check_ASN1_STRING_TABLE_freefunc_type(freefunc)) +#define sk_ASN1_STRING_TABLE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_type(ptr), (idx)) +#define sk_ASN1_STRING_TABLE_set(sk, idx, ptr) ((ASN1_STRING_TABLE *)OPENSSL_sk_set(ossl_check_ASN1_STRING_TABLE_sk_type(sk), (idx), ossl_check_ASN1_STRING_TABLE_type(ptr))) +#define sk_ASN1_STRING_TABLE_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_type(ptr)) +#define sk_ASN1_STRING_TABLE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_type(ptr)) +#define sk_ASN1_STRING_TABLE_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_STRING_TABLE_sk_type(sk)) +#define sk_ASN1_STRING_TABLE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_STRING_TABLE_sk_type(sk)) +#define sk_ASN1_STRING_TABLE_dup(sk) ((STACK_OF(ASN1_STRING_TABLE) *)OPENSSL_sk_dup(ossl_check_const_ASN1_STRING_TABLE_sk_type(sk))) +#define sk_ASN1_STRING_TABLE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_STRING_TABLE) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_copyfunc_type(copyfunc), ossl_check_ASN1_STRING_TABLE_freefunc_type(freefunc))) +#define sk_ASN1_STRING_TABLE_set_cmp_func(sk, cmp) ((sk_ASN1_STRING_TABLE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_STRING_TABLE_sk_type(sk), ossl_check_ASN1_STRING_TABLE_compfunc_type(cmp))) + /* size limits: this stuff is taken straight from RFC2459 */ @@ -219,45 +275,76 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; /* Declare ASN1 functions: the implement macro in in asn1t.h */ -# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) - -# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ - DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) - -# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ - DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ - DECLARE_ASN1_ENCODE_FUNCTIONS_name(type, name) - -# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ - DECLARE_ASN1_ENCODE_FUNCTIONS_only(type, name) \ - DECLARE_ASN1_ITEM(itname) +/* + * The mysterious 'extern' that's passed to some macros is innocuous, + * and is there to quiet pre-C99 compilers that may complain about empty + * arguments in macro calls. + */ +# define DECLARE_ASN1_FUNCTIONS_attr(attr, type) \ + DECLARE_ASN1_FUNCTIONS_name_attr(attr, type, type) +# define DECLARE_ASN1_FUNCTIONS(type) \ + DECLARE_ASN1_FUNCTIONS_attr(extern, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_attr(attr, type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(attr, type, type) +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_attr(extern, type) + +# define DECLARE_ASN1_FUNCTIONS_name_attr(attr, type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(attr, type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_name_attr(attr, type, name) +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_FUNCTIONS_name_attr(extern, type, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_attr(attr, type, itname, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(attr, type, name) \ + DECLARE_ASN1_ITEM_attr(attr, itname) +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_attr(extern, type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_name_attr(attr, type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_attr(attr, type, name, name) # define DECLARE_ASN1_ENCODE_FUNCTIONS_name(type, name) \ - DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) - -# define DECLARE_ASN1_ENCODE_FUNCTIONS_only(type, name) \ - type *d2i_##name(type **a, const unsigned char **in, long len); \ - int i2d_##name(const type *a, unsigned char **out); - -# define DECLARE_ASN1_NDEF_FUNCTION(name) \ - int i2d_##name##_NDEF(const name *a, unsigned char **out); - -# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ - type *name##_new(void); \ - void name##_free(type *a); - -# define DECLARE_ASN1_DUP_FUNCTION(type) \ - DECLARE_ASN1_DUP_FUNCTION_name(type, type) - -# define DECLARE_ASN1_DUP_FUNCTION_name(type, name) \ - type *name##_dup(const type *a); - -# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ - DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) - -# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ - int fname##_print_ctx(BIO *out, const stname *x, int indent, \ - const ASN1_PCTX *pctx); + DECLARE_ASN1_ENCODE_FUNCTIONS_name_attr(extern, type, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(attr, type, name) \ + attr type *d2i_##name(type **a, const unsigned char **in, long len); \ + attr int i2d_##name(const type *a, unsigned char **out); +# define DECLARE_ASN1_ENCODE_FUNCTIONS_only(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(extern, type, name) + +# define DECLARE_ASN1_NDEF_FUNCTION_attr(attr, name) \ + attr int i2d_##name##_NDEF(const name *a, unsigned char **out); +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + DECLARE_ASN1_NDEF_FUNCTION_attr(extern, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(attr, type, name) \ + attr type *name##_new(void); \ + attr void name##_free(type *a); +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(extern, type, name) + +# define DECLARE_ASN1_DUP_FUNCTION_attr(attr, type) \ + DECLARE_ASN1_DUP_FUNCTION_name_attr(attr, type, type) +# define DECLARE_ASN1_DUP_FUNCTION(type) \ + DECLARE_ASN1_DUP_FUNCTION_attr(extern, type) + +# define DECLARE_ASN1_DUP_FUNCTION_name_attr(attr, type, name) \ + attr type *name##_dup(const type *a); +# define DECLARE_ASN1_DUP_FUNCTION_name(type, name) \ + DECLARE_ASN1_DUP_FUNCTION_name_attr(extern, type, name) + +# define DECLARE_ASN1_PRINT_FUNCTION_attr(attr, stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname_attr(attr, stname, stname) +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_attr(extern, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname_attr(attr, stname, fname) \ + attr int fname##_print_ctx(BIO *out, const stname *x, int indent, \ + const ASN1_PCTX *pctx); +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname_attr(extern, stname, fname) # define D2I_OF(type) type *(*)(type **,const unsigned char **,long) # define I2D_OF(type) int (*)(const type *,unsigned char **) @@ -333,8 +420,10 @@ typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); # define ASN1_ITEM_rptr(ref) (ref##_it()) -# define DECLARE_ASN1_ITEM(name) \ - const ASN1_ITEM * name##_it(void); +# define DECLARE_ASN1_ITEM_attr(attr, name) \ + attr const ASN1_ITEM * name##_it(void); +# define DECLARE_ASN1_ITEM(name) \ + DECLARE_ASN1_ITEM_attr(extern, name) /* Parameters used by ASN1_STRING_print_ex() */ @@ -452,7 +541,32 @@ struct asn1_type_st { } value; }; -DEFINE_OR_DECLARE_STACK_OF(ASN1_TYPE) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_TYPE, ASN1_TYPE, ASN1_TYPE) +#define sk_ASN1_TYPE_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_TYPE_sk_type(sk)) +#define sk_ASN1_TYPE_value(sk, idx) ((ASN1_TYPE *)OPENSSL_sk_value(ossl_check_const_ASN1_TYPE_sk_type(sk), (idx))) +#define sk_ASN1_TYPE_new(cmp) ((STACK_OF(ASN1_TYPE) *)OPENSSL_sk_new(ossl_check_ASN1_TYPE_compfunc_type(cmp))) +#define sk_ASN1_TYPE_new_null() ((STACK_OF(ASN1_TYPE) *)OPENSSL_sk_new_null()) +#define sk_ASN1_TYPE_new_reserve(cmp, n) ((STACK_OF(ASN1_TYPE) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_TYPE_compfunc_type(cmp), (n))) +#define sk_ASN1_TYPE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_TYPE_sk_type(sk), (n)) +#define sk_ASN1_TYPE_free(sk) OPENSSL_sk_free(ossl_check_ASN1_TYPE_sk_type(sk)) +#define sk_ASN1_TYPE_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_TYPE_sk_type(sk)) +#define sk_ASN1_TYPE_delete(sk, i) ((ASN1_TYPE *)OPENSSL_sk_delete(ossl_check_ASN1_TYPE_sk_type(sk), (i))) +#define sk_ASN1_TYPE_delete_ptr(sk, ptr) ((ASN1_TYPE *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_type(ptr))) +#define sk_ASN1_TYPE_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_type(ptr)) +#define sk_ASN1_TYPE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_type(ptr)) +#define sk_ASN1_TYPE_pop(sk) ((ASN1_TYPE *)OPENSSL_sk_pop(ossl_check_ASN1_TYPE_sk_type(sk))) +#define sk_ASN1_TYPE_shift(sk) ((ASN1_TYPE *)OPENSSL_sk_shift(ossl_check_ASN1_TYPE_sk_type(sk))) +#define sk_ASN1_TYPE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_TYPE_sk_type(sk),ossl_check_ASN1_TYPE_freefunc_type(freefunc)) +#define sk_ASN1_TYPE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_type(ptr), (idx)) +#define sk_ASN1_TYPE_set(sk, idx, ptr) ((ASN1_TYPE *)OPENSSL_sk_set(ossl_check_ASN1_TYPE_sk_type(sk), (idx), ossl_check_ASN1_TYPE_type(ptr))) +#define sk_ASN1_TYPE_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_type(ptr)) +#define sk_ASN1_TYPE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_type(ptr)) +#define sk_ASN1_TYPE_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_TYPE_sk_type(sk)) +#define sk_ASN1_TYPE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_TYPE_sk_type(sk)) +#define sk_ASN1_TYPE_dup(sk) ((STACK_OF(ASN1_TYPE) *)OPENSSL_sk_dup(ossl_check_const_ASN1_TYPE_sk_type(sk))) +#define sk_ASN1_TYPE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_TYPE) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_copyfunc_type(copyfunc), ossl_check_ASN1_TYPE_freefunc_type(freefunc))) +#define sk_ASN1_TYPE_set_cmp_func(sk, cmp) ((sk_ASN1_TYPE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_TYPE_sk_type(sk), ossl_check_ASN1_TYPE_compfunc_type(cmp))) + typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; @@ -506,7 +620,32 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t); void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t); -DEFINE_OR_DECLARE_STACK_OF(ASN1_OBJECT) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_OBJECT, ASN1_OBJECT, ASN1_OBJECT) +#define sk_ASN1_OBJECT_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_OBJECT_sk_type(sk)) +#define sk_ASN1_OBJECT_value(sk, idx) ((ASN1_OBJECT *)OPENSSL_sk_value(ossl_check_const_ASN1_OBJECT_sk_type(sk), (idx))) +#define sk_ASN1_OBJECT_new(cmp) ((STACK_OF(ASN1_OBJECT) *)OPENSSL_sk_new(ossl_check_ASN1_OBJECT_compfunc_type(cmp))) +#define sk_ASN1_OBJECT_new_null() ((STACK_OF(ASN1_OBJECT) *)OPENSSL_sk_new_null()) +#define sk_ASN1_OBJECT_new_reserve(cmp, n) ((STACK_OF(ASN1_OBJECT) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_OBJECT_compfunc_type(cmp), (n))) +#define sk_ASN1_OBJECT_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_OBJECT_sk_type(sk), (n)) +#define sk_ASN1_OBJECT_free(sk) OPENSSL_sk_free(ossl_check_ASN1_OBJECT_sk_type(sk)) +#define sk_ASN1_OBJECT_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_OBJECT_sk_type(sk)) +#define sk_ASN1_OBJECT_delete(sk, i) ((ASN1_OBJECT *)OPENSSL_sk_delete(ossl_check_ASN1_OBJECT_sk_type(sk), (i))) +#define sk_ASN1_OBJECT_delete_ptr(sk, ptr) ((ASN1_OBJECT *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_type(ptr))) +#define sk_ASN1_OBJECT_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_type(ptr)) +#define sk_ASN1_OBJECT_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_type(ptr)) +#define sk_ASN1_OBJECT_pop(sk) ((ASN1_OBJECT *)OPENSSL_sk_pop(ossl_check_ASN1_OBJECT_sk_type(sk))) +#define sk_ASN1_OBJECT_shift(sk) ((ASN1_OBJECT *)OPENSSL_sk_shift(ossl_check_ASN1_OBJECT_sk_type(sk))) +#define sk_ASN1_OBJECT_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_OBJECT_sk_type(sk),ossl_check_ASN1_OBJECT_freefunc_type(freefunc)) +#define sk_ASN1_OBJECT_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_type(ptr), (idx)) +#define sk_ASN1_OBJECT_set(sk, idx, ptr) ((ASN1_OBJECT *)OPENSSL_sk_set(ossl_check_ASN1_OBJECT_sk_type(sk), (idx), ossl_check_ASN1_OBJECT_type(ptr))) +#define sk_ASN1_OBJECT_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_type(ptr)) +#define sk_ASN1_OBJECT_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_type(ptr)) +#define sk_ASN1_OBJECT_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_OBJECT_sk_type(sk)) +#define sk_ASN1_OBJECT_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_OBJECT_sk_type(sk)) +#define sk_ASN1_OBJECT_dup(sk) ((STACK_OF(ASN1_OBJECT) *)OPENSSL_sk_dup(ossl_check_const_ASN1_OBJECT_sk_type(sk))) +#define sk_ASN1_OBJECT_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_OBJECT) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_copyfunc_type(copyfunc), ossl_check_ASN1_OBJECT_freefunc_type(freefunc))) +#define sk_ASN1_OBJECT_set_cmp_func(sk, cmp) ((sk_ASN1_OBJECT_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_OBJECT_sk_type(sk), ossl_check_ASN1_OBJECT_compfunc_type(cmp))) + DECLARE_ASN1_FUNCTIONS(ASN1_OBJECT) @@ -524,7 +663,7 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); int ASN1_STRING_length(const ASN1_STRING *x); -void ASN1_STRING_length_set(ASN1_STRING *x, int n); +DEPRECATEDIN_3_0(void ASN1_STRING_length_set(ASN1_STRING *x, int n)) int ASN1_STRING_type(const ASN1_STRING *x); DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)) const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); @@ -542,7 +681,33 @@ int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl); int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, BIT_STRING_BITNAME *tbl); -DEFINE_OR_DECLARE_STACK_OF(ASN1_INTEGER) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_INTEGER, ASN1_INTEGER, ASN1_INTEGER) +#define sk_ASN1_INTEGER_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_INTEGER_sk_type(sk)) +#define sk_ASN1_INTEGER_value(sk, idx) ((ASN1_INTEGER *)OPENSSL_sk_value(ossl_check_const_ASN1_INTEGER_sk_type(sk), (idx))) +#define sk_ASN1_INTEGER_new(cmp) ((STACK_OF(ASN1_INTEGER) *)OPENSSL_sk_new(ossl_check_ASN1_INTEGER_compfunc_type(cmp))) +#define sk_ASN1_INTEGER_new_null() ((STACK_OF(ASN1_INTEGER) *)OPENSSL_sk_new_null()) +#define sk_ASN1_INTEGER_new_reserve(cmp, n) ((STACK_OF(ASN1_INTEGER) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_INTEGER_compfunc_type(cmp), (n))) +#define sk_ASN1_INTEGER_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_INTEGER_sk_type(sk), (n)) +#define sk_ASN1_INTEGER_free(sk) OPENSSL_sk_free(ossl_check_ASN1_INTEGER_sk_type(sk)) +#define sk_ASN1_INTEGER_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_INTEGER_sk_type(sk)) +#define sk_ASN1_INTEGER_delete(sk, i) ((ASN1_INTEGER *)OPENSSL_sk_delete(ossl_check_ASN1_INTEGER_sk_type(sk), (i))) +#define sk_ASN1_INTEGER_delete_ptr(sk, ptr) ((ASN1_INTEGER *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_type(ptr))) +#define sk_ASN1_INTEGER_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_type(ptr)) +#define sk_ASN1_INTEGER_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_type(ptr)) +#define sk_ASN1_INTEGER_pop(sk) ((ASN1_INTEGER *)OPENSSL_sk_pop(ossl_check_ASN1_INTEGER_sk_type(sk))) +#define sk_ASN1_INTEGER_shift(sk) ((ASN1_INTEGER *)OPENSSL_sk_shift(ossl_check_ASN1_INTEGER_sk_type(sk))) +#define sk_ASN1_INTEGER_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_INTEGER_sk_type(sk),ossl_check_ASN1_INTEGER_freefunc_type(freefunc)) +#define sk_ASN1_INTEGER_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_type(ptr), (idx)) +#define sk_ASN1_INTEGER_set(sk, idx, ptr) ((ASN1_INTEGER *)OPENSSL_sk_set(ossl_check_ASN1_INTEGER_sk_type(sk), (idx), ossl_check_ASN1_INTEGER_type(ptr))) +#define sk_ASN1_INTEGER_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_type(ptr)) +#define sk_ASN1_INTEGER_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_type(ptr)) +#define sk_ASN1_INTEGER_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_INTEGER_sk_type(sk)) +#define sk_ASN1_INTEGER_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_INTEGER_sk_type(sk)) +#define sk_ASN1_INTEGER_dup(sk) ((STACK_OF(ASN1_INTEGER) *)OPENSSL_sk_dup(ossl_check_const_ASN1_INTEGER_sk_type(sk))) +#define sk_ASN1_INTEGER_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_INTEGER) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_copyfunc_type(copyfunc), ossl_check_ASN1_INTEGER_freefunc_type(freefunc))) +#define sk_ASN1_INTEGER_set_cmp_func(sk, cmp) ((sk_ASN1_INTEGER_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_INTEGER_sk_type(sk), ossl_check_ASN1_INTEGER_compfunc_type(cmp))) + + DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, @@ -577,7 +742,32 @@ int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len); -DEFINE_OR_DECLARE_STACK_OF(ASN1_UTF8STRING) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_UTF8STRING, ASN1_UTF8STRING, ASN1_UTF8STRING) +#define sk_ASN1_UTF8STRING_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_UTF8STRING_sk_type(sk)) +#define sk_ASN1_UTF8STRING_value(sk, idx) ((ASN1_UTF8STRING *)OPENSSL_sk_value(ossl_check_const_ASN1_UTF8STRING_sk_type(sk), (idx))) +#define sk_ASN1_UTF8STRING_new(cmp) ((STACK_OF(ASN1_UTF8STRING) *)OPENSSL_sk_new(ossl_check_ASN1_UTF8STRING_compfunc_type(cmp))) +#define sk_ASN1_UTF8STRING_new_null() ((STACK_OF(ASN1_UTF8STRING) *)OPENSSL_sk_new_null()) +#define sk_ASN1_UTF8STRING_new_reserve(cmp, n) ((STACK_OF(ASN1_UTF8STRING) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_UTF8STRING_compfunc_type(cmp), (n))) +#define sk_ASN1_UTF8STRING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_UTF8STRING_sk_type(sk), (n)) +#define sk_ASN1_UTF8STRING_free(sk) OPENSSL_sk_free(ossl_check_ASN1_UTF8STRING_sk_type(sk)) +#define sk_ASN1_UTF8STRING_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_UTF8STRING_sk_type(sk)) +#define sk_ASN1_UTF8STRING_delete(sk, i) ((ASN1_UTF8STRING *)OPENSSL_sk_delete(ossl_check_ASN1_UTF8STRING_sk_type(sk), (i))) +#define sk_ASN1_UTF8STRING_delete_ptr(sk, ptr) ((ASN1_UTF8STRING *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_type(ptr))) +#define sk_ASN1_UTF8STRING_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_type(ptr)) +#define sk_ASN1_UTF8STRING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_type(ptr)) +#define sk_ASN1_UTF8STRING_pop(sk) ((ASN1_UTF8STRING *)OPENSSL_sk_pop(ossl_check_ASN1_UTF8STRING_sk_type(sk))) +#define sk_ASN1_UTF8STRING_shift(sk) ((ASN1_UTF8STRING *)OPENSSL_sk_shift(ossl_check_ASN1_UTF8STRING_sk_type(sk))) +#define sk_ASN1_UTF8STRING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_UTF8STRING_sk_type(sk),ossl_check_ASN1_UTF8STRING_freefunc_type(freefunc)) +#define sk_ASN1_UTF8STRING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_type(ptr), (idx)) +#define sk_ASN1_UTF8STRING_set(sk, idx, ptr) ((ASN1_UTF8STRING *)OPENSSL_sk_set(ossl_check_ASN1_UTF8STRING_sk_type(sk), (idx), ossl_check_ASN1_UTF8STRING_type(ptr))) +#define sk_ASN1_UTF8STRING_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_type(ptr)) +#define sk_ASN1_UTF8STRING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_type(ptr)) +#define sk_ASN1_UTF8STRING_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_UTF8STRING_sk_type(sk)) +#define sk_ASN1_UTF8STRING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_UTF8STRING_sk_type(sk)) +#define sk_ASN1_UTF8STRING_dup(sk) ((STACK_OF(ASN1_UTF8STRING) *)OPENSSL_sk_dup(ossl_check_const_ASN1_UTF8STRING_sk_type(sk))) +#define sk_ASN1_UTF8STRING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_UTF8STRING) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_copyfunc_type(copyfunc), ossl_check_ASN1_UTF8STRING_freefunc_type(freefunc))) +#define sk_ASN1_UTF8STRING_set_cmp_func(sk, cmp) ((sk_ASN1_UTF8STRING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_UTF8STRING_sk_type(sk), ossl_check_ASN1_UTF8STRING_compfunc_type(cmp))) + DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) @@ -588,7 +778,32 @@ DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) int UTF8_getc(const unsigned char *str, int len, unsigned long *val); int UTF8_putc(unsigned char *str, int len, unsigned long value); -DEFINE_OR_DECLARE_STACK_OF(ASN1_GENERALSTRING) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_GENERALSTRING, ASN1_GENERALSTRING, ASN1_GENERALSTRING) +#define sk_ASN1_GENERALSTRING_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_GENERALSTRING_sk_type(sk)) +#define sk_ASN1_GENERALSTRING_value(sk, idx) ((ASN1_GENERALSTRING *)OPENSSL_sk_value(ossl_check_const_ASN1_GENERALSTRING_sk_type(sk), (idx))) +#define sk_ASN1_GENERALSTRING_new(cmp) ((STACK_OF(ASN1_GENERALSTRING) *)OPENSSL_sk_new(ossl_check_ASN1_GENERALSTRING_compfunc_type(cmp))) +#define sk_ASN1_GENERALSTRING_new_null() ((STACK_OF(ASN1_GENERALSTRING) *)OPENSSL_sk_new_null()) +#define sk_ASN1_GENERALSTRING_new_reserve(cmp, n) ((STACK_OF(ASN1_GENERALSTRING) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_GENERALSTRING_compfunc_type(cmp), (n))) +#define sk_ASN1_GENERALSTRING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_GENERALSTRING_sk_type(sk), (n)) +#define sk_ASN1_GENERALSTRING_free(sk) OPENSSL_sk_free(ossl_check_ASN1_GENERALSTRING_sk_type(sk)) +#define sk_ASN1_GENERALSTRING_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_GENERALSTRING_sk_type(sk)) +#define sk_ASN1_GENERALSTRING_delete(sk, i) ((ASN1_GENERALSTRING *)OPENSSL_sk_delete(ossl_check_ASN1_GENERALSTRING_sk_type(sk), (i))) +#define sk_ASN1_GENERALSTRING_delete_ptr(sk, ptr) ((ASN1_GENERALSTRING *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_type(ptr))) +#define sk_ASN1_GENERALSTRING_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_type(ptr)) +#define sk_ASN1_GENERALSTRING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_type(ptr)) +#define sk_ASN1_GENERALSTRING_pop(sk) ((ASN1_GENERALSTRING *)OPENSSL_sk_pop(ossl_check_ASN1_GENERALSTRING_sk_type(sk))) +#define sk_ASN1_GENERALSTRING_shift(sk) ((ASN1_GENERALSTRING *)OPENSSL_sk_shift(ossl_check_ASN1_GENERALSTRING_sk_type(sk))) +#define sk_ASN1_GENERALSTRING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_GENERALSTRING_sk_type(sk),ossl_check_ASN1_GENERALSTRING_freefunc_type(freefunc)) +#define sk_ASN1_GENERALSTRING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_type(ptr), (idx)) +#define sk_ASN1_GENERALSTRING_set(sk, idx, ptr) ((ASN1_GENERALSTRING *)OPENSSL_sk_set(ossl_check_ASN1_GENERALSTRING_sk_type(sk), (idx), ossl_check_ASN1_GENERALSTRING_type(ptr))) +#define sk_ASN1_GENERALSTRING_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_type(ptr)) +#define sk_ASN1_GENERALSTRING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_type(ptr)) +#define sk_ASN1_GENERALSTRING_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_GENERALSTRING_sk_type(sk)) +#define sk_ASN1_GENERALSTRING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_GENERALSTRING_sk_type(sk)) +#define sk_ASN1_GENERALSTRING_dup(sk) ((STACK_OF(ASN1_GENERALSTRING) *)OPENSSL_sk_dup(ossl_check_const_ASN1_GENERALSTRING_sk_type(sk))) +#define sk_ASN1_GENERALSTRING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_GENERALSTRING) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_copyfunc_type(copyfunc), ossl_check_ASN1_GENERALSTRING_freefunc_type(freefunc))) +#define sk_ASN1_GENERALSTRING_set_cmp_func(sk, cmp) ((sk_ASN1_GENERALSTRING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_GENERALSTRING_sk_type(sk), ossl_check_ASN1_GENERALSTRING_compfunc_type(cmp))) + DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) @@ -678,6 +893,15 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x); CHECKED_PTR_OF(const type, x))) void *ASN1_item_dup(const ASN1_ITEM *it, const void *x); +int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, const ASN1_OCTET_STRING *id, + EVP_PKEY *pkey, const EVP_MD *md, OSSL_LIB_CTX *libctx, + const char *propq); +int ASN1_item_verify_ex(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + const ASN1_OCTET_STRING *id, EVP_PKEY *pkey, + OSSL_LIB_CTX *libctx, const char *propq); /* ASN1 alloc/free macros for when a type is only used internally */ @@ -845,7 +1069,13 @@ int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, int ctype_nid, int econt_nid, STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, BIO **bcont, const ASN1_ITEM *it, + ASN1_VALUE **x); int SMIME_crlf_copy(BIO *in, BIO *out, int flags); int SMIME_text(BIO *in, BIO *out); diff --git a/include/openssl/asn1.h.in b/include/openssl/asn1.h.in new file mode 100644 index 0000000000..27476a215f --- /dev/null +++ b/include/openssl/asn1.h.in @@ -0,0 +1,940 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_ASN1_H +# define OPENSSL_ASN1_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_ASN1_H +# endif + +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG /*compat*/ V_ASN1_PRIMITIVE_TAG + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_UNDEF -1 +/* ASN.1 tag values */ +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 + +/* + * NB the constants below are used internally by ASN1_INTEGER + * and ASN1_ENUMERATED to indicate the sign. They are *not* on + * the wire tag values. + */ + +# define V_ASN1_NEG 0x100 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) + +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + +/* Stacks for types not otherwise defined in this header */ +{- + generate_stack_macros("X509_ALGOR"); +-} + + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* String is embedded and only content should be freed */ +# define ASN1_STRING_FLAG_EMBED 0x080 +/* String should be parsed in RFC 5280's time format */ +# define ASN1_STRING_FLAG_X509_TIME 0x100 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +/* + * A zero passed to ASN1_STRING_TABLE_new_add for the flags is interpreted + * as "don't change" and STABLE_FLAGS_MALLOC is always set. By setting + * STABLE_FLAGS_MALLOC only we can clear the existing value. Use the alias + * STABLE_FLAGS_CLEAR to reflect this. + */ +# define STABLE_FLAGS_CLEAR STABLE_FLAGS_MALLOC +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +}; + +{- + generate_stack_macros("ASN1_STRING_TABLE"); +-} + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +/* + * The mysterious 'extern' that's passed to some macros is innocuous, + * and is there to quiet pre-C99 compilers that may complain about empty + * arguments in macro calls. + */ + +# define DECLARE_ASN1_FUNCTIONS_attr(attr, type) \ + DECLARE_ASN1_FUNCTIONS_name_attr(attr, type, type) +# define DECLARE_ASN1_FUNCTIONS(type) \ + DECLARE_ASN1_FUNCTIONS_attr(extern, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_attr(attr, type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(attr, type, type) +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_attr(extern, type) + +# define DECLARE_ASN1_FUNCTIONS_name_attr(attr, type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(attr, type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_name_attr(attr, type, name) +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_FUNCTIONS_name_attr(extern, type, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_attr(attr, type, itname, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(attr, type, name) \ + DECLARE_ASN1_ITEM_attr(attr, itname) +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_attr(extern, type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_name_attr(attr, type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_attr(attr, type, name, name) +# define DECLARE_ASN1_ENCODE_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_name_attr(extern, type, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(attr, type, name) \ + attr type *d2i_##name(type **a, const unsigned char **in, long len); \ + attr int i2d_##name(const type *a, unsigned char **out); +# define DECLARE_ASN1_ENCODE_FUNCTIONS_only(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_only_attr(extern, type, name) + +# define DECLARE_ASN1_NDEF_FUNCTION_attr(attr, name) \ + attr int i2d_##name##_NDEF(const name *a, unsigned char **out); +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + DECLARE_ASN1_NDEF_FUNCTION_attr(extern, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(attr, type, name) \ + attr type *name##_new(void); \ + attr void name##_free(type *a); +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name_attr(extern, type, name) + +# define DECLARE_ASN1_DUP_FUNCTION_attr(attr, type) \ + DECLARE_ASN1_DUP_FUNCTION_name_attr(attr, type, type) +# define DECLARE_ASN1_DUP_FUNCTION(type) \ + DECLARE_ASN1_DUP_FUNCTION_attr(extern, type) + +# define DECLARE_ASN1_DUP_FUNCTION_name_attr(attr, type, name) \ + attr type *name##_dup(const type *a); +# define DECLARE_ASN1_DUP_FUNCTION_name(type, name) \ + DECLARE_ASN1_DUP_FUNCTION_name_attr(extern, type, name) + +# define DECLARE_ASN1_PRINT_FUNCTION_attr(attr, stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname_attr(attr, stname, stname) +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_attr(extern, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname_attr(attr, stname, fname) \ + attr int fname##_print_ctx(BIO *out, const stname *x, int indent, \ + const ASN1_PCTX *pctx); +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname_attr(extern, stname, fname) + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(const type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +typedef void *d2i_of_void(void **, const unsigned char **, long); +typedef int i2d_of_void(const void *, unsigned char **); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM_attr(attr, name) \ + attr const ASN1_ITEM * name##_it(void); +# define DECLARE_ASN1_ITEM(name) \ + DECLARE_ASN1_ITEM_attr(extern, name) + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * This flag specifies that RC2254 escaping shall be performed. + */ +#define ASN1_STRFLGS_ESC_2254 0x400 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + + +struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +}; + +{- + generate_stack_macros("ASN1_TYPE"); +-} + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_name(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_name(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +DECLARE_ASN1_ALLOC_FUNCTIONS_name(ASN1_TYPE, ASN1_TYPE) +DECLARE_ASN1_ENCODE_FUNCTIONS(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(const ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t); +void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t); + +{- + generate_stack_macros("ASN1_OBJECT"); +-} + +DECLARE_ASN1_FUNCTIONS(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +DECLARE_ASN1_DUP_FUNCTION(ASN1_STRING) +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +DEPRECATEDIN_3_0(void ASN1_STRING_length_set(ASN1_STRING *x, int n)) +int ASN1_STRING_type(const ASN1_STRING *x); +DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)) +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, + const unsigned char *flags, int flags_len); + +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value, + BIT_STRING_BITNAME *tbl); + +{- + generate_stack_macros("ASN1_INTEGER"); +-} + + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +DECLARE_ASN1_DUP_FUNCTION(ASN1_INTEGER) +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +DECLARE_ASN1_DUP_FUNCTION(ASN1_OCTET_STRING) +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +{- + generate_stack_macros("ASN1_UTF8STRING"); +-} + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +{- + generate_stack_macros("ASN1_GENERALSTRING"); +-} + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_DUP_FUNCTION(ASN1_TIME) +DECLARE_ASN1_DUP_FUNCTION(ASN1_UTCTIME) +DECLARE_ASN1_DUP_FUNCTION(ASN1_GENERALIZEDTIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(const ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); +int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str); +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm); +int ASN1_TIME_normalize(ASN1_TIME *s); +int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t); +int ASN1_TIME_compare(const ASN1_TIME *a, const ASN1_TIME *b); + +int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type); +int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r); +int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a); +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a); +int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r); + + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +unsigned long ASN1_tag2bit(int tag); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, const void *x); +int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, const ASN1_OCTET_STRING *id, + EVP_PKEY *pkey, const EVP_MD *md, OSSL_LIB_CTX *libctx, + const char *propq); +int ASN1_item_verify_ex(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + const ASN1_OCTET_STRING *id, EVP_PKEY *pkey, + OSSL_LIB_CTX *libctx, const char *propq); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_STDIO +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, const void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, const void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in); + +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, const void *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, const void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags); +int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int off); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +const char *ASN1_tag2str(int tag); + +/* Used to load and write Netscape format cert */ + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it); + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(const ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(const ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); +void ASN1_add_stable_module(void); + +ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf); +int ASN1_str2mask(const char *str, unsigned long *pmask); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, const ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx)); +void ASN1_SCTX_free(ASN1_SCTX *p); +const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p); +const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p); +unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p); +void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data); +void *ASN1_SCTX_get_app_data(ASN1_SCTX *p); + +const BIO_METHOD *BIO_f_asn1(void); + +/* cannot constify val because of CMS_stream() */ +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +/* cannot constify val because of CMS_dataFinal() */ +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +int SMIME_write_ASN1_ex(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it, + OSSL_LIB_CTX *libctx, const char *propq); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1_ex(BIO *bio, BIO **bcont, const ASN1_ITEM *it, + ASN1_VALUE **x); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +const ASN1_ITEM *ASN1_ITEM_lookup(const char *name); +const ASN1_ITEM *ASN1_ITEM_get(size_t i); + +/* Legacy compatibility */ +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) +# define DECLARE_ASN1_FUNCTIONS_const(type) DECLARE_ASN1_FUNCTIONS(type) +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name) +# define I2D_OF_const(type) I2D_OF(type) +# define ASN1_dup_of_const(type,i2d,d2i,x) ASN1_dup_of(type,i2d,d2i,x) +# define ASN1_i2d_fp_of_const(type,i2d,out,x) ASN1_i2d_fp_of(type,i2d,out,x) +# define ASN1_i2d_bio_of_const(type,i2d,out,x) ASN1_i2d_bio_of(type,i2d,out,x) + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/asn1err.h b/include/openssl/asn1err.h index 3247e0f445..a29722e868 100644 --- a/include/openssl/asn1err.h +++ b/include/openssl/asn1err.h @@ -59,7 +59,6 @@ int ERR_load_ASN1_strings(void); # define ASN1_F_ASN1_ITEM_I2D_BIO 0 # define ASN1_F_ASN1_ITEM_I2D_FP 0 # define ASN1_F_ASN1_ITEM_PACK 0 -# define ASN1_F_ASN1_ITEM_SIGN 0 # define ASN1_F_ASN1_ITEM_SIGN_CTX 0 # define ASN1_F_ASN1_ITEM_UNPACK 0 # define ASN1_F_ASN1_ITEM_VERIFY 0 @@ -83,6 +82,7 @@ int ERR_load_ASN1_strings(void); # define ASN1_F_ASN1_TIME_ADJ 0 # define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 0 # define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 0 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING_INT 0 # define ASN1_F_ASN1_UTCTIME_ADJ 0 # define ASN1_F_ASN1_VERIFY 0 # define ASN1_F_B64_READ_ASN1 0 @@ -244,6 +244,7 @@ int ERR_load_ASN1_strings(void); # define ASN1_R_TYPE_NOT_PRIMITIVE 195 # define ASN1_R_UNEXPECTED_EOC 159 # define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_DIGEST 229 # define ASN1_R_UNKNOWN_FORMAT 160 # define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 # define ASN1_R_UNKNOWN_OBJECT_TYPE 162 diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h index 286db9e2eb..77b6ab041b 100644 --- a/include/openssl/asn1t.h +++ b/include/openssl/asn1t.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/asn1t.h.in + * * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_ASN1T_H # define OPENSSL_ASN1T_H # pragma once @@ -880,7 +885,33 @@ DECLARE_ASN1_ITEM(LONG) DECLARE_ASN1_ITEM(ZLONG) # endif -DEFINE_OR_DECLARE_STACK_OF(ASN1_VALUE) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_VALUE, ASN1_VALUE, ASN1_VALUE) +#define sk_ASN1_VALUE_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_VALUE_sk_type(sk)) +#define sk_ASN1_VALUE_value(sk, idx) ((ASN1_VALUE *)OPENSSL_sk_value(ossl_check_const_ASN1_VALUE_sk_type(sk), (idx))) +#define sk_ASN1_VALUE_new(cmp) ((STACK_OF(ASN1_VALUE) *)OPENSSL_sk_new(ossl_check_ASN1_VALUE_compfunc_type(cmp))) +#define sk_ASN1_VALUE_new_null() ((STACK_OF(ASN1_VALUE) *)OPENSSL_sk_new_null()) +#define sk_ASN1_VALUE_new_reserve(cmp, n) ((STACK_OF(ASN1_VALUE) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_VALUE_compfunc_type(cmp), (n))) +#define sk_ASN1_VALUE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_VALUE_sk_type(sk), (n)) +#define sk_ASN1_VALUE_free(sk) OPENSSL_sk_free(ossl_check_ASN1_VALUE_sk_type(sk)) +#define sk_ASN1_VALUE_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_VALUE_sk_type(sk)) +#define sk_ASN1_VALUE_delete(sk, i) ((ASN1_VALUE *)OPENSSL_sk_delete(ossl_check_ASN1_VALUE_sk_type(sk), (i))) +#define sk_ASN1_VALUE_delete_ptr(sk, ptr) ((ASN1_VALUE *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_type(ptr))) +#define sk_ASN1_VALUE_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_type(ptr)) +#define sk_ASN1_VALUE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_type(ptr)) +#define sk_ASN1_VALUE_pop(sk) ((ASN1_VALUE *)OPENSSL_sk_pop(ossl_check_ASN1_VALUE_sk_type(sk))) +#define sk_ASN1_VALUE_shift(sk) ((ASN1_VALUE *)OPENSSL_sk_shift(ossl_check_ASN1_VALUE_sk_type(sk))) +#define sk_ASN1_VALUE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_VALUE_sk_type(sk),ossl_check_ASN1_VALUE_freefunc_type(freefunc)) +#define sk_ASN1_VALUE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_type(ptr), (idx)) +#define sk_ASN1_VALUE_set(sk, idx, ptr) ((ASN1_VALUE *)OPENSSL_sk_set(ossl_check_ASN1_VALUE_sk_type(sk), (idx), ossl_check_ASN1_VALUE_type(ptr))) +#define sk_ASN1_VALUE_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_type(ptr)) +#define sk_ASN1_VALUE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_type(ptr)) +#define sk_ASN1_VALUE_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_VALUE_sk_type(sk)) +#define sk_ASN1_VALUE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_VALUE_sk_type(sk)) +#define sk_ASN1_VALUE_dup(sk) ((STACK_OF(ASN1_VALUE) *)OPENSSL_sk_dup(ossl_check_const_ASN1_VALUE_sk_type(sk))) +#define sk_ASN1_VALUE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_VALUE) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_copyfunc_type(copyfunc), ossl_check_ASN1_VALUE_freefunc_type(freefunc))) +#define sk_ASN1_VALUE_set_cmp_func(sk, cmp) ((sk_ASN1_VALUE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_VALUE_sk_type(sk), ossl_check_ASN1_VALUE_compfunc_type(cmp))) + + /* Functions used internally by the ASN1 code */ diff --git a/include/openssl/asn1t.h.in b/include/openssl/asn1t.h.in new file mode 100644 index 0000000000..1eebd1f85a --- /dev/null +++ b/include/openssl/asn1t.h.in @@ -0,0 +1,914 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_ASN1T_H +# define OPENSSL_ASN1T_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_ASN1T_H +# endif + +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)((iptr)())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define static_ASN1_ITEM_start(itname) \ + static ASN1_ITEM_start(itname) + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0, NULL}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_const_cb(tname, const_cb) \ + static const ASN1_AUX tname##_aux = \ + {NULL, ASN1_AFLG_CONST_CB, 0, 0, NULL, 0, const_cb}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_cb_const_cb(tname, cb, const_cb) \ + static const ASN1_AUX tname##_aux = \ + {NULL, ASN1_AFLG_CONST_CB, 0, 0, cb, 0, const_cb}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0, NULL}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc), NULL}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) +# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #tname \ + ASN1_ITEM_end(tname) +# define static_ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0, NULL}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + static_ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | (ex), tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | (ex), tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } + +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) +/* Embedded simple type */ +# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) +# define ASN1_OPT_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) +# define ASN1_IMP_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_IMP_OPT_EMBED(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_EMBED) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) +# define ASN1_EXP_OPT_EMBED(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_EMBED) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + adb_cb,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ + const char *field_name; /* Field name */ + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + int (*adb_cb)(long *psel); /* Application callback */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT (ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT) + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT (ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT) + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* Field is embedded and not a pointer */ +# define ASN1_TFLG_EMBED (0x1 << 12) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ + const char *sname; /* Structure name */ +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, const ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(const ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, const ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + * For the operations ASN1_OP_I2D_PRE, ASN1_OP_I2D_POST, ASN1_OP_PRINT_PRE, and + * ASN1_OP_PRINT_POST, meanwhile a variant of the callback with const parameter + * 'in' is provided to make clear statically that its input is not modified. If + * and only if this variant is in use the flag ASN1_AFLG_CONST_CB must be set. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); +typedef int ASN1_aux_const_cb(int operation, const ASN1_VALUE **in, + const ASN1_ITEM *it, void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ + ASN1_aux_const_cb *asn1_const_cb; /* for ASN1_OP_I2D_ and ASN1_OP_PRINT_ */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 +/* Use the new asn1_const_cb */ +# define ASN1_AFLG_CONST_CB 8 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((const ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \ + static stname *d2i_##stname(stname **a, \ + const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \ + ASN1_ITEM_rptr(stname)); \ + } \ + static int i2d_##stname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((const ASN1_VALUE *)a, out, \ + ASN1_ITEM_rptr(stname)); \ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(const stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, const stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (const ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(INT32) +DECLARE_ASN1_ITEM(ZINT32) +DECLARE_ASN1_ITEM(UINT32) +DECLARE_ASN1_ITEM(ZUINT32) +DECLARE_ASN1_ITEM(INT64) +DECLARE_ASN1_ITEM(ZINT64) +DECLARE_ASN1_ITEM(UINT64) +DECLARE_ASN1_ITEM(ZUINT64) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +/* + * LONG and ZLONG are strongly discouraged for use as stored data, as the + * underlying C type (long) differs in size depending on the architecture. + * They are designed with 32-bit longs in mind. + */ +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) +# endif + +{- + generate_stack_macros("ASN1_VALUE"); +-} + + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); + +/* Legacy compatibility */ +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) IMPLEMENT_ASN1_FUNCTIONS(name) +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/bio.h b/include/openssl/bio.h index 88e57e70a8..15108affd8 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/bio.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,7 @@ * https://www.openssl.org/source/license.html */ + #ifndef OPENSSL_BIO_H # define OPENSSL_BIO_H # pragma once @@ -287,7 +291,33 @@ int BIO_method_type(const BIO *b); typedef int BIO_info_cb(BIO *, int, int); typedef BIO_info_cb bio_info_cb; /* backward compatibility */ -DEFINE_OR_DECLARE_STACK_OF(BIO) +SKM_DEFINE_STACK_OF_INTERNAL(BIO, BIO, BIO) +#define sk_BIO_num(sk) OPENSSL_sk_num(ossl_check_const_BIO_sk_type(sk)) +#define sk_BIO_value(sk, idx) ((BIO *)OPENSSL_sk_value(ossl_check_const_BIO_sk_type(sk), (idx))) +#define sk_BIO_new(cmp) ((STACK_OF(BIO) *)OPENSSL_sk_new(ossl_check_BIO_compfunc_type(cmp))) +#define sk_BIO_new_null() ((STACK_OF(BIO) *)OPENSSL_sk_new_null()) +#define sk_BIO_new_reserve(cmp, n) ((STACK_OF(BIO) *)OPENSSL_sk_new_reserve(ossl_check_BIO_compfunc_type(cmp), (n))) +#define sk_BIO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_BIO_sk_type(sk), (n)) +#define sk_BIO_free(sk) OPENSSL_sk_free(ossl_check_BIO_sk_type(sk)) +#define sk_BIO_zero(sk) OPENSSL_sk_zero(ossl_check_BIO_sk_type(sk)) +#define sk_BIO_delete(sk, i) ((BIO *)OPENSSL_sk_delete(ossl_check_BIO_sk_type(sk), (i))) +#define sk_BIO_delete_ptr(sk, ptr) ((BIO *)OPENSSL_sk_delete_ptr(ossl_check_BIO_sk_type(sk), ossl_check_BIO_type(ptr))) +#define sk_BIO_push(sk, ptr) OPENSSL_sk_push(ossl_check_BIO_sk_type(sk), ossl_check_BIO_type(ptr)) +#define sk_BIO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_BIO_sk_type(sk), ossl_check_BIO_type(ptr)) +#define sk_BIO_pop(sk) ((BIO *)OPENSSL_sk_pop(ossl_check_BIO_sk_type(sk))) +#define sk_BIO_shift(sk) ((BIO *)OPENSSL_sk_shift(ossl_check_BIO_sk_type(sk))) +#define sk_BIO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_BIO_sk_type(sk),ossl_check_BIO_freefunc_type(freefunc)) +#define sk_BIO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_BIO_sk_type(sk), ossl_check_BIO_type(ptr), (idx)) +#define sk_BIO_set(sk, idx, ptr) ((BIO *)OPENSSL_sk_set(ossl_check_BIO_sk_type(sk), (idx), ossl_check_BIO_type(ptr))) +#define sk_BIO_find(sk, ptr) OPENSSL_sk_find(ossl_check_BIO_sk_type(sk), ossl_check_BIO_type(ptr)) +#define sk_BIO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_BIO_sk_type(sk), ossl_check_BIO_type(ptr)) +#define sk_BIO_sort(sk) OPENSSL_sk_sort(ossl_check_BIO_sk_type(sk)) +#define sk_BIO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_BIO_sk_type(sk)) +#define sk_BIO_dup(sk) ((STACK_OF(BIO) *)OPENSSL_sk_dup(ossl_check_const_BIO_sk_type(sk))) +#define sk_BIO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(BIO) *)OPENSSL_sk_deep_copy(ossl_check_const_BIO_sk_type(sk), ossl_check_BIO_copyfunc_type(copyfunc), ossl_check_BIO_freefunc_type(freefunc))) +#define sk_BIO_set_cmp_func(sk, cmp) ((sk_BIO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_BIO_sk_type(sk), ossl_check_BIO_compfunc_type(cmp))) + + /* Prefix and suffix callback in ASN1 BIO */ typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in new file mode 100644 index 0000000000..d7380d47e9 --- /dev/null +++ b/include/openssl/bio.h.in @@ -0,0 +1,851 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_BIO_H +# define OPENSSL_BIO_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_BIO_H +# endif + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* There are the classes of BIOs */ +# define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM ( 1|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_FILE ( 2|BIO_TYPE_SOURCE_SINK) + +# define BIO_TYPE_FD ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_SOCKET ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_NULL ( 6|BIO_TYPE_SOURCE_SINK) +# define BIO_TYPE_SSL ( 7|BIO_TYPE_FILTER) +# define BIO_TYPE_MD ( 8|BIO_TYPE_FILTER) +# define BIO_TYPE_BUFFER ( 9|BIO_TYPE_FILTER) +# define BIO_TYPE_CIPHER (10|BIO_TYPE_FILTER) +# define BIO_TYPE_BASE64 (11|BIO_TYPE_FILTER) +# define BIO_TYPE_CONNECT (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ACCEPT (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) + +# define BIO_TYPE_NBIO_TEST (16|BIO_TYPE_FILTER)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|BIO_TYPE_FILTER) +# define BIO_TYPE_BIO (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|BIO_TYPE_FILTER) +# define BIO_TYPE_DGRAM (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# define BIO_TYPE_ASN1 (22|BIO_TYPE_FILTER) +# define BIO_TYPE_COMP (23|BIO_TYPE_FILTER) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR) +# endif +# define BIO_TYPE_CORE_TO_PROV (25|BIO_TYPE_FILTER) + +#define BIO_TYPE_START 128 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_PEEK 29/* BIO_f_buffer special */ +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ +# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +/* Deliberately outside of OPENSSL_NO_SCTP - used in bss_dgram.c */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +# define BIO_CTRL_DGRAM_SET_PEEK_MODE 71 + +/* + * internal BIO: + * # define BIO_CTRL_SET_KTLS_SEND 72 + * # define BIO_CTRL_SET_KTLS_SEND_CTRL_MSG 74 + * # define BIO_CTRL_CLEAR_KTLS_CTRL_MSG 75 + */ + +# define BIO_CTRL_GET_KTLS_SEND 73 +# define BIO_CTRL_GET_KTLS_RECV 76 + +# define BIO_CTRL_DGRAM_SCTP_WAIT_FOR_DRY 77 +# define BIO_CTRL_DGRAM_SCTP_MSG_WAITING 78 + +/* BIO_f_prefix controls */ +# define BIO_CTRL_SET_PREFIX 79 +# define BIO_CTRL_SET_INDENT 80 +# define BIO_CTRL_GET_INDENT 81 + +# ifndef OPENSSL_NO_KTLS +# define BIO_get_ktls_send(b) \ + BIO_ctrl(b, BIO_CTRL_GET_KTLS_SEND, 0, NULL) +# define BIO_get_ktls_recv(b) \ + BIO_ctrl(b, BIO_CTRL_GET_KTLS_RECV, 0, NULL) +# else +# define BIO_get_ktls_send(b) (0) +# define BIO_get_ktls_recv(b) (0) +# endif + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef OPENSSL_NO_DEPRECATED_3_0 +/* This #define was replaced by an internal constant and should not be used. */ +# define BIO_FLAGS_UPLINK 0 +# endif + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: + * BIO_FLAGS_MEM_RDONLY means we shouldn't free up or change the data in any way; + * BIO_FLAGS_NONCLEAR_RST means we shouldn't clear data on reset. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 +# define BIO_FLAGS_NONCLEAR_RST 0x400 +# define BIO_FLAGS_IN_EOF 0x800 + +typedef union bio_addr_st BIO_ADDR; +typedef struct bio_addrinfo_st BIO_ADDRINFO; + +int BIO_get_new_index(void); +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi, + long argl, long ret); +typedef long (*BIO_callback_fn_ex)(BIO *b, int oper, const char *argp, + size_t len, int argi, + long argl, int ret, size_t *processed); +BIO_callback_fn BIO_get_callback(const BIO *b); +void BIO_set_callback(BIO *b, BIO_callback_fn callback); + +BIO_callback_fn_ex BIO_get_callback_ex(const BIO *b); +void BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex callback); + +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +typedef struct bio_method_st BIO_METHOD; + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef int BIO_info_cb(BIO *, int, int); +typedef BIO_info_cb bio_info_cb; /* backward compatibility */ + +{- + generate_stack_macros("BIO"); +-} + + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +typedef void (*BIO_dgram_sctp_notification_handler_fn) (BIO *b, + void *context, + void *buf); +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +/* # define BIO_C_SET_PROXY_PARAM 103 */ +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +/* # define BIO_C_GET_PROXY_PARAM 121 */ +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_C_SET_CONNECT_MODE 155 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +# ifndef OPENSSL_NO_SOCK +/* IP families we support, for BIO_s_connect() and BIO_s_accept() */ +/* Note: the underlying operating system may not support some of them */ +# define BIO_FAMILY_IPV4 4 +# define BIO_FAMILY_IPV6 6 +# define BIO_FAMILY_IPANY 256 + +/* BIO_s_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0, \ + (char *)(name)) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1, \ + (char *)(port)) +# define BIO_set_conn_address(b,addr) BIO_ctrl(b,BIO_C_SET_CONNECT,2, \ + (char *)(addr)) +# define BIO_set_conn_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f) +# define BIO_get_conn_hostname(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)) +# define BIO_get_conn_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)) +# define BIO_get_conn_address(b) ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)) +# define BIO_get_conn_ip_family(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) +# define BIO_set_conn_mode(b,n) BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_name(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0, \ + (char *)(name)) +# define BIO_set_accept_port(b,port) BIO_ctrl(b,BIO_C_SET_ACCEPT,1, \ + (char *)(port)) +# define BIO_get_accept_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)) +# define BIO_get_accept_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1)) +# define BIO_get_peer_name(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2)) +# define BIO_get_peer_port(b) ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3)) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,3, \ + (char *)(bio)) +# define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f) +# define BIO_get_accept_ip_family(b) BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL) + +/* Aliases kept for backward compatibility */ +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR BIO_SOCK_REUSEADDR +# define BIO_BIND_REUSEADDR_IF_UNUSED BIO_SOCK_REUSEADDR +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# endif /* OPENSSL_NO_SOCK */ + +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)(c)) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)(fp)) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)(fpp)) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)(name)) +# endif +# define BIO_write_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)(ssl)) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)(sslp)) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)(md)) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)(pp)) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)(bm)) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0, \ + (char *)(pp)) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) +# define BIO_buffer_peek(b,s,l) BIO_ctrl(b,BIO_CTRL_PEEK,(l),(s)) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)(peer)) +# define BIO_ctrl_set_connected(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, 0, (char *)(peer)) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)(peer)) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +/* ctrl macros for BIO_f_prefix */ +# define BIO_set_prefix(b,p) BIO_ctrl((b), BIO_CTRL_SET_PREFIX, 0, (void *)(p)) +# define BIO_set_indent(b,i) BIO_ctrl((b), BIO_CTRL_SET_INDENT, (i), NULL) +# define BIO_get_indent(b) BIO_ctrl((b), BIO_CTRL_GET_INDENT, 0, NULL) + +#define BIO_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef) +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(const BIO *bio, int idx); +uint64_t BIO_number_read(BIO *bio); +uint64_t BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +const BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +# ifndef OPENSSL_NO_STDIO +BIO *BIO_new_fp(FILE *stream, int close_flag); +# endif +BIO *BIO_new(const BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_set_data(BIO *a, void *ptr); +void *BIO_get_data(BIO *a); +void BIO_set_init(BIO *a, int init); +int BIO_get_init(BIO *a); +void BIO_set_shutdown(BIO *a, int shut); +int BIO_get_shutdown(BIO *a); +void BIO_vfree(BIO *a); +int BIO_up_ref(BIO *a); +int BIO_read(BIO *b, void *data, int dlen); +int BIO_read_ex(BIO *b, void *data, size_t dlen, size_t *readbytes); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int dlen); +int BIO_write_ex(BIO *b, const void *data, size_t dlen, size_t *written); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp); +void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +void BIO_set_next(BIO *b, BIO *next); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +void BIO_set_retry_reason(BIO *bio, int reason); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +const BIO_METHOD *BIO_s_mem(void); +const BIO_METHOD *BIO_s_secmem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +# ifndef OPENSSL_NO_SOCK +const BIO_METHOD *BIO_s_socket(void); +const BIO_METHOD *BIO_s_connect(void); +const BIO_METHOD *BIO_s_accept(void); +# endif +const BIO_METHOD *BIO_s_fd(void); +const BIO_METHOD *BIO_s_log(void); +const BIO_METHOD *BIO_s_bio(void); +const BIO_METHOD *BIO_s_null(void); +const BIO_METHOD *BIO_f_null(void); +const BIO_METHOD *BIO_f_buffer(void); +const BIO_METHOD *BIO_f_linebuffer(void); +const BIO_METHOD *BIO_f_nbio_test(void); +const BIO_METHOD *BIO_f_prefix(void); +# ifndef OPENSSL_NO_DGRAM +const BIO_METHOD *BIO_s_datagram(void); +int BIO_dgram_non_fatal_error(int error); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +const BIO_METHOD *BIO_s_datagram_sctp(void); +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + BIO_dgram_sctp_notification_handler_fn handle_notifications, + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +# endif + +# ifndef OPENSSL_NO_SOCK +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +int BIO_socket_wait(int fd, int for_read, time_t max_time); +# endif +int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds); +int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const void *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const void *s, int len, int indent); +int BIO_dump(BIO *b, const void *bytes, int len); +int BIO_dump_indent(BIO *b, const void *bytes, int len, int indent); +# ifndef OPENSSL_NO_STDIO +int BIO_dump_fp(FILE *fp, const void *s, int len); +int BIO_dump_indent_fp(FILE *fp, const void *s, int len, int indent); +# endif +int BIO_hex_string(BIO *out, int indent, int width, const void *data, + int datalen); + +# ifndef OPENSSL_NO_SOCK +BIO_ADDR *BIO_ADDR_new(void); +int BIO_ADDR_rawmake(BIO_ADDR *ap, int family, + const void *where, size_t wherelen, unsigned short port); +void BIO_ADDR_free(BIO_ADDR *); +void BIO_ADDR_clear(BIO_ADDR *ap); +int BIO_ADDR_family(const BIO_ADDR *ap); +int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l); +unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap); +char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric); +char *BIO_ADDR_path_string(const BIO_ADDR *ap); + +const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai); +int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai); +const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai); +void BIO_ADDRINFO_free(BIO_ADDRINFO *bai); + +enum BIO_hostserv_priorities { + BIO_PARSE_PRIO_HOST, BIO_PARSE_PRIO_SERV +}; +int BIO_parse_hostserv(const char *hostserv, char **host, char **service, + enum BIO_hostserv_priorities hostserv_prio); +enum BIO_lookup_type { + BIO_LOOKUP_CLIENT, BIO_LOOKUP_SERVER +}; +int BIO_lookup(const char *host, const char *service, + enum BIO_lookup_type lookup_type, + int family, int socktype, BIO_ADDRINFO **res); +int BIO_lookup_ex(const char *host, const char *service, + int lookup_type, int family, int socktype, int protocol, + BIO_ADDRINFO **res); +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_sock_init(void); +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define BIO_sock_cleanup() while(0) continue +# endif +int BIO_set_tcp_ndelay(int sock, int turn_on); + +DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name)) +DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr)) +DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip)) +DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode)) +DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port)) + +union BIO_sock_info_u { + BIO_ADDR *addr; +}; +enum BIO_sock_info_type { + BIO_SOCK_INFO_ADDRESS +}; +int BIO_sock_info(int sock, + enum BIO_sock_info_type type, union BIO_sock_info_u *info); + +# define BIO_SOCK_REUSEADDR 0x01 +# define BIO_SOCK_V6_ONLY 0x02 +# define BIO_SOCK_KEEPALIVE 0x04 +# define BIO_SOCK_NONBLOCK 0x08 +# define BIO_SOCK_NODELAY 0x10 + +int BIO_socket(int domain, int socktype, int protocol, int options); +int BIO_connect(int sock, const BIO_ADDR *addr, int options); +int BIO_bind(int sock, const BIO_ADDR *addr, int options); +int BIO_listen(int sock, const BIO_ADDR *addr, int options); +int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options); +int BIO_closesocket(int sock); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); +# endif /* OPENSSL_NO_SOCK*/ + +BIO *BIO_new_fd(int fd, int close_flag); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# define ossl_bio__attr__(x) +# if defined(__GNUC__) && defined(__STDC_VERSION__) \ + && !defined(__APPLE__) + /* + * Because we support the 'z' modifier, which made its appearance in C99, + * we can't use __attribute__ with pre C99 dialects. + */ +# if __STDC_VERSION__ >= 199901L +# undef ossl_bio__attr__ +# define ossl_bio__attr__ __attribute__ +# if __GNUC__*10 + __GNUC_MINOR__ >= 44 +# define ossl_bio__printf__ __gnu_printf__ +# else +# define ossl_bio__printf__ __printf__ +# endif +# endif +# endif +int BIO_printf(BIO *bio, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +ossl_bio__attr__((__format__(ossl_bio__printf__, 3, 0))); +# undef ossl_bio__attr__ +# undef ossl_bio__printf__ + + +BIO_METHOD *BIO_meth_new(int type, const char *name); +void BIO_meth_free(BIO_METHOD *biom); +int (*BIO_meth_get_write(const BIO_METHOD *biom)) (BIO *, const char *, int); +int (*BIO_meth_get_write_ex(const BIO_METHOD *biom)) (BIO *, const char *, size_t, + size_t *); +int BIO_meth_set_write(BIO_METHOD *biom, + int (*write) (BIO *, const char *, int)); +int BIO_meth_set_write_ex(BIO_METHOD *biom, + int (*bwrite) (BIO *, const char *, size_t, size_t *)); +int (*BIO_meth_get_read(const BIO_METHOD *biom)) (BIO *, char *, int); +int (*BIO_meth_get_read_ex(const BIO_METHOD *biom)) (BIO *, char *, size_t, size_t *); +int BIO_meth_set_read(BIO_METHOD *biom, + int (*read) (BIO *, char *, int)); +int BIO_meth_set_read_ex(BIO_METHOD *biom, + int (*bread) (BIO *, char *, size_t, size_t *)); +int (*BIO_meth_get_puts(const BIO_METHOD *biom)) (BIO *, const char *); +int BIO_meth_set_puts(BIO_METHOD *biom, + int (*puts) (BIO *, const char *)); +int (*BIO_meth_get_gets(const BIO_METHOD *biom)) (BIO *, char *, int); +int BIO_meth_set_gets(BIO_METHOD *biom, + int (*gets) (BIO *, char *, int)); +long (*BIO_meth_get_ctrl(const BIO_METHOD *biom)) (BIO *, int, long, void *); +int BIO_meth_set_ctrl(BIO_METHOD *biom, + long (*ctrl) (BIO *, int, long, void *)); +int (*BIO_meth_get_create(const BIO_METHOD *bion)) (BIO *); +int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *)); +int (*BIO_meth_get_destroy(const BIO_METHOD *biom)) (BIO *); +int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *)); +long (*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom)) + (BIO *, int, BIO_info_cb *); +int BIO_meth_set_callback_ctrl(BIO_METHOD *biom, + long (*callback_ctrl) (BIO *, int, + BIO_info_cb *)); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/bn.h b/include/openssl/bn.h index cafb66e905..f3c8ab956b 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -206,9 +206,9 @@ void BN_zero_ex(BIGNUM *a); const BIGNUM *BN_value_one(void); char *BN_options(void); -BN_CTX *BN_CTX_new_ex(OPENSSL_CTX *ctx); +BN_CTX *BN_CTX_new_ex(OSSL_LIB_CTX *ctx); BN_CTX *BN_CTX_new(void); -BN_CTX *BN_CTX_secure_new_ex(OPENSSL_CTX *ctx); +BN_CTX *BN_CTX_secure_new_ex(OSSL_LIB_CTX *ctx); BN_CTX *BN_CTX_secure_new(void); void BN_CTX_free(BN_CTX *c); void BN_CTX_start(BN_CTX *ctx); diff --git a/include/openssl/cmp.h b/include/openssl/cmp.h index 519117d622..c577c11058 100644 --- a/include/openssl/cmp.h +++ b/include/openssl/cmp.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/cmp.h.in + * * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 @@ -9,6 +12,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_CMP_H # define OPENSSL_CMP_H @@ -210,21 +215,146 @@ typedef struct ossl_cmp_msg_st OSSL_CMP_MSG; DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG) DECLARE_ASN1_ENCODE_FUNCTIONS(OSSL_CMP_MSG, OSSL_CMP_MSG, OSSL_CMP_MSG) typedef struct ossl_cmp_certstatus_st OSSL_CMP_CERTSTATUS; -DEFINE_OR_DECLARE_STACK_OF(OSSL_CMP_CERTSTATUS) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CERTSTATUS, OSSL_CMP_CERTSTATUS, OSSL_CMP_CERTSTATUS) +#define sk_OSSL_CMP_CERTSTATUS_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CERTSTATUS_value(sk, idx) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk), (idx))) +#define sk_OSSL_CMP_CERTSTATUS_new(cmp) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CERTSTATUS_compfunc_type(cmp))) +#define sk_OSSL_CMP_CERTSTATUS_new_null() ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_CERTSTATUS_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CERTSTATUS_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_CERTSTATUS_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), (n)) +#define sk_OSSL_CMP_CERTSTATUS_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CERTSTATUS_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CERTSTATUS_delete(sk, i) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), (i))) +#define sk_OSSL_CMP_CERTSTATUS_delete_ptr(sk, ptr) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr))) +#define sk_OSSL_CMP_CERTSTATUS_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr)) +#define sk_OSSL_CMP_CERTSTATUS_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr)) +#define sk_OSSL_CMP_CERTSTATUS_pop(sk) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk))) +#define sk_OSSL_CMP_CERTSTATUS_shift(sk) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk))) +#define sk_OSSL_CMP_CERTSTATUS_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk),ossl_check_OSSL_CMP_CERTSTATUS_freefunc_type(freefunc)) +#define sk_OSSL_CMP_CERTSTATUS_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr), (idx)) +#define sk_OSSL_CMP_CERTSTATUS_set(sk, idx, ptr) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), (idx), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr))) +#define sk_OSSL_CMP_CERTSTATUS_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr)) +#define sk_OSSL_CMP_CERTSTATUS_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr)) +#define sk_OSSL_CMP_CERTSTATUS_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CERTSTATUS_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk)) +#define sk_OSSL_CMP_CERTSTATUS_dup(sk) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk))) +#define sk_OSSL_CMP_CERTSTATUS_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CERTSTATUS_freefunc_type(freefunc))) +#define sk_OSSL_CMP_CERTSTATUS_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CERTSTATUS_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_compfunc_type(cmp))) + typedef struct ossl_cmp_itav_st OSSL_CMP_ITAV; DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV) -DEFINE_OR_DECLARE_STACK_OF(OSSL_CMP_ITAV) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_ITAV, OSSL_CMP_ITAV, OSSL_CMP_ITAV) +#define sk_OSSL_CMP_ITAV_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_value(sk, idx) ((OSSL_CMP_ITAV *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), (idx))) +#define sk_OSSL_CMP_ITAV_new(cmp) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp))) +#define sk_OSSL_CMP_ITAV_new_null() ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_ITAV_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_ITAV_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (n)) +#define sk_OSSL_CMP_ITAV_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_delete(sk, i) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (i))) +#define sk_OSSL_CMP_ITAV_delete_ptr(sk, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))) +#define sk_OSSL_CMP_ITAV_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_pop(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_ITAV_sk_type(sk))) +#define sk_OSSL_CMP_ITAV_shift(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_ITAV_sk_type(sk))) +#define sk_OSSL_CMP_ITAV_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk),ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc)) +#define sk_OSSL_CMP_ITAV_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), (idx)) +#define sk_OSSL_CMP_ITAV_set(sk, idx, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_set(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (idx), ossl_check_OSSL_CMP_ITAV_type(ptr))) +#define sk_OSSL_CMP_ITAV_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)) +#define sk_OSSL_CMP_ITAV_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)) +#define sk_OSSL_CMP_ITAV_dup(sk) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk))) +#define sk_OSSL_CMP_ITAV_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc))) +#define sk_OSSL_CMP_ITAV_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_ITAV_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp))) + typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT; typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI; DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI) DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI) -DEFINE_OR_DECLARE_STACK_OF(OSSL_CMP_PKISI) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_PKISI, OSSL_CMP_PKISI, OSSL_CMP_PKISI) +#define sk_OSSL_CMP_PKISI_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk)) +#define sk_OSSL_CMP_PKISI_value(sk, idx) ((OSSL_CMP_PKISI *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk), (idx))) +#define sk_OSSL_CMP_PKISI_new(cmp) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_PKISI_compfunc_type(cmp))) +#define sk_OSSL_CMP_PKISI_new_null() ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_PKISI_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_PKISI_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_PKISI_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_PKISI_sk_type(sk), (n)) +#define sk_OSSL_CMP_PKISI_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_PKISI_sk_type(sk)) +#define sk_OSSL_CMP_PKISI_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_PKISI_sk_type(sk)) +#define sk_OSSL_CMP_PKISI_delete(sk, i) ((OSSL_CMP_PKISI *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_PKISI_sk_type(sk), (i))) +#define sk_OSSL_CMP_PKISI_delete_ptr(sk, ptr) ((OSSL_CMP_PKISI *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr))) +#define sk_OSSL_CMP_PKISI_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr)) +#define sk_OSSL_CMP_PKISI_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr)) +#define sk_OSSL_CMP_PKISI_pop(sk) ((OSSL_CMP_PKISI *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_PKISI_sk_type(sk))) +#define sk_OSSL_CMP_PKISI_shift(sk) ((OSSL_CMP_PKISI *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_PKISI_sk_type(sk))) +#define sk_OSSL_CMP_PKISI_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_PKISI_sk_type(sk),ossl_check_OSSL_CMP_PKISI_freefunc_type(freefunc)) +#define sk_OSSL_CMP_PKISI_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr), (idx)) +#define sk_OSSL_CMP_PKISI_set(sk, idx, ptr) ((OSSL_CMP_PKISI *)OPENSSL_sk_set(ossl_check_OSSL_CMP_PKISI_sk_type(sk), (idx), ossl_check_OSSL_CMP_PKISI_type(ptr))) +#define sk_OSSL_CMP_PKISI_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr)) +#define sk_OSSL_CMP_PKISI_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr)) +#define sk_OSSL_CMP_PKISI_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_PKISI_sk_type(sk)) +#define sk_OSSL_CMP_PKISI_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk)) +#define sk_OSSL_CMP_PKISI_dup(sk) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk))) +#define sk_OSSL_CMP_PKISI_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_PKISI_freefunc_type(freefunc))) +#define sk_OSSL_CMP_PKISI_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_PKISI_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_compfunc_type(cmp))) + typedef struct ossl_cmp_certrepmessage_st OSSL_CMP_CERTREPMESSAGE; -DEFINE_OR_DECLARE_STACK_OF(OSSL_CMP_CERTREPMESSAGE) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CERTREPMESSAGE, OSSL_CMP_CERTREPMESSAGE, OSSL_CMP_CERTREPMESSAGE) +#define sk_OSSL_CMP_CERTREPMESSAGE_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)) +#define sk_OSSL_CMP_CERTREPMESSAGE_value(sk, idx) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (idx))) +#define sk_OSSL_CMP_CERTREPMESSAGE_new(cmp) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CERTREPMESSAGE_compfunc_type(cmp))) +#define sk_OSSL_CMP_CERTREPMESSAGE_new_null() ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_CERTREPMESSAGE_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CERTREPMESSAGE_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_CERTREPMESSAGE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (n)) +#define sk_OSSL_CMP_CERTREPMESSAGE_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)) +#define sk_OSSL_CMP_CERTREPMESSAGE_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)) +#define sk_OSSL_CMP_CERTREPMESSAGE_delete(sk, i) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (i))) +#define sk_OSSL_CMP_CERTREPMESSAGE_delete_ptr(sk, ptr) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr))) +#define sk_OSSL_CMP_CERTREPMESSAGE_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr)) +#define sk_OSSL_CMP_CERTREPMESSAGE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr)) +#define sk_OSSL_CMP_CERTREPMESSAGE_pop(sk) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))) +#define sk_OSSL_CMP_CERTREPMESSAGE_shift(sk) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))) +#define sk_OSSL_CMP_CERTREPMESSAGE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk),ossl_check_OSSL_CMP_CERTREPMESSAGE_freefunc_type(freefunc)) +#define sk_OSSL_CMP_CERTREPMESSAGE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr), (idx)) +#define sk_OSSL_CMP_CERTREPMESSAGE_set(sk, idx, ptr) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (idx), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr))) +#define sk_OSSL_CMP_CERTREPMESSAGE_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr)) +#define sk_OSSL_CMP_CERTREPMESSAGE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr)) +#define sk_OSSL_CMP_CERTREPMESSAGE_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)) +#define sk_OSSL_CMP_CERTREPMESSAGE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)) +#define sk_OSSL_CMP_CERTREPMESSAGE_dup(sk) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))) +#define sk_OSSL_CMP_CERTREPMESSAGE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CERTREPMESSAGE_freefunc_type(freefunc))) +#define sk_OSSL_CMP_CERTREPMESSAGE_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CERTREPMESSAGE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_compfunc_type(cmp))) + typedef struct ossl_cmp_pollrep_st OSSL_CMP_POLLREP; typedef STACK_OF(OSSL_CMP_POLLREP) OSSL_CMP_POLLREPCONTENT; typedef struct ossl_cmp_certresponse_st OSSL_CMP_CERTRESPONSE; -DEFINE_OR_DECLARE_STACK_OF(OSSL_CMP_CERTRESPONSE) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CERTRESPONSE, OSSL_CMP_CERTRESPONSE, OSSL_CMP_CERTRESPONSE) +#define sk_OSSL_CMP_CERTRESPONSE_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk)) +#define sk_OSSL_CMP_CERTRESPONSE_value(sk, idx) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk), (idx))) +#define sk_OSSL_CMP_CERTRESPONSE_new(cmp) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CERTRESPONSE_compfunc_type(cmp))) +#define sk_OSSL_CMP_CERTRESPONSE_new_null() ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CMP_CERTRESPONSE_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CERTRESPONSE_compfunc_type(cmp), (n))) +#define sk_OSSL_CMP_CERTRESPONSE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), (n)) +#define sk_OSSL_CMP_CERTRESPONSE_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk)) +#define sk_OSSL_CMP_CERTRESPONSE_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk)) +#define sk_OSSL_CMP_CERTRESPONSE_delete(sk, i) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), (i))) +#define sk_OSSL_CMP_CERTRESPONSE_delete_ptr(sk, ptr) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr))) +#define sk_OSSL_CMP_CERTRESPONSE_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr)) +#define sk_OSSL_CMP_CERTRESPONSE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr)) +#define sk_OSSL_CMP_CERTRESPONSE_pop(sk) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk))) +#define sk_OSSL_CMP_CERTRESPONSE_shift(sk) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk))) +#define sk_OSSL_CMP_CERTRESPONSE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk),ossl_check_OSSL_CMP_CERTRESPONSE_freefunc_type(freefunc)) +#define sk_OSSL_CMP_CERTRESPONSE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr), (idx)) +#define sk_OSSL_CMP_CERTRESPONSE_set(sk, idx, ptr) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), (idx), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr))) +#define sk_OSSL_CMP_CERTRESPONSE_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr)) +#define sk_OSSL_CMP_CERTRESPONSE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr)) +#define sk_OSSL_CMP_CERTRESPONSE_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk)) +#define sk_OSSL_CMP_CERTRESPONSE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk)) +#define sk_OSSL_CMP_CERTRESPONSE_dup(sk) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk))) +#define sk_OSSL_CMP_CERTRESPONSE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CERTRESPONSE_freefunc_type(freefunc))) +#define sk_OSSL_CMP_CERTRESPONSE_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CERTRESPONSE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_compfunc_type(cmp))) + typedef STACK_OF(ASN1_UTF8STRING) OSSL_CMP_PKIFREETEXT; /* @@ -243,7 +373,7 @@ void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav); void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg); /* from cmp_ctx.c */ -OSSL_CMP_CTX *OSSL_CMP_CTX_new(void); +OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq); void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx); /* various CMP options: */ @@ -291,10 +421,12 @@ int OSSL_CMP_CTX_set1_srvCert(OSSL_CMP_CTX *ctx, X509 *cert); int OSSL_CMP_CTX_set1_expected_sender(OSSL_CMP_CTX *ctx, const X509_NAME *name); int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store); X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx); -int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs); -STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx); +int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs); +STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx); /* client authentication: */ int OSSL_CMP_CTX_set1_cert(OSSL_CMP_CTX *ctx, X509 *cert); +int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted, + STACK_OF(X509) *candidates); int OSSL_CMP_CTX_set1_pkey(OSSL_CMP_CTX *ctx, EVP_PKEY *pkey); int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, const unsigned char *ref, int len); @@ -322,6 +454,8 @@ int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav); /* certificate confirmation: */ typedef int (*OSSL_CMP_certConf_cb_t) (OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, const char **txt); +int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, + const char **text); int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb); int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg); void *OSSL_CMP_CTX_get_certConf_cb_arg(const OSSL_CMP_CTX *ctx); @@ -331,6 +465,7 @@ OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx); # define OSSL_CMP_PKISI_BUFLEN 1024 X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx); +STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx); STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx); STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx); int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, @@ -375,7 +510,7 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req); OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx, const OSSL_CMP_MSG *req); -OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void); +OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq); void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx); typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t) (OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req, int certReqId, @@ -436,8 +571,6 @@ X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type, OSSL_CMP_exec_certreq(ctx, OSSL_CMP_KUR, NULL) int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, const OSSL_CRMF_MSG *crm, int *checkAfter); -int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, - const char **text); X509 *OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx); STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx); diff --git a/include/openssl/cmp.h.in b/include/openssl/cmp.h.in new file mode 100644 index 0000000000..94c8ccf978 --- /dev/null +++ b/include/openssl/cmp.h.in @@ -0,0 +1,467 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_CMP_H +# define OPENSSL_CMP_H + +# include +# ifndef OPENSSL_NO_CMP + +# include +# include +# include +# include + +/* explicit #includes not strictly needed since implied by the above: */ +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# define OSSL_CMP_PVNO 2 + +/*- + * PKIFailureInfo ::= BIT STRING { + * -- since we can fail in more than one way! + * -- More codes may be added in the future if/when required. + * badAlg (0), + * -- unrecognized or unsupported Algorithm Identifier + * badMessageCheck (1), + * -- integrity check failed (e.g., signature did not verify) + * badRequest (2), + * -- transaction not permitted or supported + * badTime (3), + * -- messageTime was not sufficiently close to the system time, + * -- as defined by local policy + * badCertId (4), + * -- no certificate could be found matching the provided criteria + * badDataFormat (5), + * -- the data submitted has the wrong format + * wrongAuthority (6), + * -- the authority indicated in the request is different from the + * -- one creating the response token + * incorrectData (7), + * -- the requester's data is incorrect (for notary services) + * missingTimeStamp (8), + * -- when the timestamp is missing but should be there + * -- (by policy) + * badPOP (9), + * -- the proof-of-possession failed + * certRevoked (10), + * -- the certificate has already been revoked + * certConfirmed (11), + * -- the certificate has already been confirmed + * wrongIntegrity (12), + * -- invalid integrity, password based instead of signature or + * -- vice versa + * badRecipientNonce (13), + * -- invalid recipient nonce, either missing or wrong value + * timeNotAvailable (14), + * -- the TSA's time source is not available + * unacceptedPolicy (15), + * -- the requested TSA policy is not supported by the TSA. + * unacceptedExtension (16), + * -- the requested extension is not supported by the TSA. + * addInfoNotAvailable (17), + * -- the additional information requested could not be + * -- understood or is not available + * badSenderNonce (18), + * -- invalid sender nonce, either missing or wrong size + * badCertTemplate (19), + * -- invalid cert. template or missing mandatory information + * signerNotTrusted (20), + * -- signer of the message unknown or not trusted + * transactionIdInUse (21), + * -- the transaction identifier is already in use + * unsupportedVersion (22), + * -- the version of the message is not supported + * notAuthorized (23), + * -- the sender was not authorized to make the preceding + * -- request or perform the preceding action + * systemUnavail (24), + * -- the request cannot be handled due to system unavailability + * systemFailure (25), + * -- the request cannot be handled due to system failure + * duplicateCertReq (26) + * -- certificate cannot be issued because a duplicate + * -- certificate already exists + * } + */ +# define OSSL_CMP_PKIFAILUREINFO_badAlg 0 +# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1 +# define OSSL_CMP_PKIFAILUREINFO_badRequest 2 +# define OSSL_CMP_PKIFAILUREINFO_badTime 3 +# define OSSL_CMP_PKIFAILUREINFO_badCertId 4 +# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5 +# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6 +# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7 +# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8 +# define OSSL_CMP_PKIFAILUREINFO_badPOP 9 +# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10 +# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11 +# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12 +# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13 +# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14 +# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15 +# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16 +# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17 +# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18 +# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19 +# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20 +# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21 +# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22 +# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23 +# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24 +# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25 +# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26 +# define OSSL_CMP_PKIFAILUREINFO_MAX 26 +# define OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN \ + ((1 << (OSSL_CMP_PKIFAILUREINFO_MAX + 1)) - 1) +# if OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN > INT_MAX +# error CMP_PKIFAILUREINFO_MAX bit pattern does not fit in type int +# endif + +typedef ASN1_BIT_STRING OSSL_CMP_PKIFAILUREINFO; + +# define OSSL_CMP_CTX_FAILINFO_badAlg (1 << 0) +# define OSSL_CMP_CTX_FAILINFO_badMessageCheck (1 << 1) +# define OSSL_CMP_CTX_FAILINFO_badRequest (1 << 2) +# define OSSL_CMP_CTX_FAILINFO_badTime (1 << 3) +# define OSSL_CMP_CTX_FAILINFO_badCertId (1 << 4) +# define OSSL_CMP_CTX_FAILINFO_badDataFormat (1 << 5) +# define OSSL_CMP_CTX_FAILINFO_wrongAuthority (1 << 6) +# define OSSL_CMP_CTX_FAILINFO_incorrectData (1 << 7) +# define OSSL_CMP_CTX_FAILINFO_missingTimeStamp (1 << 8) +# define OSSL_CMP_CTX_FAILINFO_badPOP (1 << 9) +# define OSSL_CMP_CTX_FAILINFO_certRevoked (1 << 10) +# define OSSL_CMP_CTX_FAILINFO_certConfirmed (1 << 11) +# define OSSL_CMP_CTX_FAILINFO_wrongIntegrity (1 << 12) +# define OSSL_CMP_CTX_FAILINFO_badRecipientNonce (1 << 13) +# define OSSL_CMP_CTX_FAILINFO_timeNotAvailable (1 << 14) +# define OSSL_CMP_CTX_FAILINFO_unacceptedPolicy (1 << 15) +# define OSSL_CMP_CTX_FAILINFO_unacceptedExtension (1 << 16) +# define OSSL_CMP_CTX_FAILINFO_addInfoNotAvailable (1 << 17) +# define OSSL_CMP_CTX_FAILINFO_badSenderNonce (1 << 18) +# define OSSL_CMP_CTX_FAILINFO_badCertTemplate (1 << 19) +# define OSSL_CMP_CTX_FAILINFO_signerNotTrusted (1 << 20) +# define OSSL_CMP_CTX_FAILINFO_transactionIdInUse (1 << 21) +# define OSSL_CMP_CTX_FAILINFO_unsupportedVersion (1 << 22) +# define OSSL_CMP_CTX_FAILINFO_notAuthorized (1 << 23) +# define OSSL_CMP_CTX_FAILINFO_systemUnavail (1 << 24) +# define OSSL_CMP_CTX_FAILINFO_systemFailure (1 << 25) +# define OSSL_CMP_CTX_FAILINFO_duplicateCertReq (1 << 26) + +/*- + * PKIStatus ::= INTEGER { + * accepted (0), + * -- you got exactly what you asked for + * grantedWithMods (1), + * -- you got something like what you asked for; the + * -- requester is responsible for ascertaining the differences + * rejection (2), + * -- you don't get it, more information elsewhere in the message + * waiting (3), + * -- the request body part has not yet been processed; expect to + * -- hear more later (note: proper handling of this status + * -- response MAY use the polling req/rep PKIMessages specified + * -- in Section 5.3.22; alternatively, polling in the underlying + * -- transport layer MAY have some utility in this regard) + * revocationWarning (4), + * -- this message contains a warning that a revocation is + * -- imminent + * revocationNotification (5), + * -- notification that a revocation has occurred + * keyUpdateWarning (6) + * -- update already done for the oldCertId specified in + * -- CertReqMsg + * } + */ +# define OSSL_CMP_PKISTATUS_accepted 0 +# define OSSL_CMP_PKISTATUS_grantedWithMods 1 +# define OSSL_CMP_PKISTATUS_rejection 2 +# define OSSL_CMP_PKISTATUS_waiting 3 +# define OSSL_CMP_PKISTATUS_revocationWarning 4 +# define OSSL_CMP_PKISTATUS_revocationNotification 5 +# define OSSL_CMP_PKISTATUS_keyUpdateWarning 6 + +typedef ASN1_INTEGER OSSL_CMP_PKISTATUS; +DECLARE_ASN1_ITEM(OSSL_CMP_PKISTATUS) + +# define OSSL_CMP_CERTORENCCERT_CERTIFICATE 0 +# define OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT 1 + +/* data type declarations */ +typedef struct ossl_cmp_ctx_st OSSL_CMP_CTX; +typedef struct ossl_cmp_pkiheader_st OSSL_CMP_PKIHEADER; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKIHEADER) +typedef struct ossl_cmp_msg_st OSSL_CMP_MSG; +DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG) +DECLARE_ASN1_ENCODE_FUNCTIONS(OSSL_CMP_MSG, OSSL_CMP_MSG, OSSL_CMP_MSG) +typedef struct ossl_cmp_certstatus_st OSSL_CMP_CERTSTATUS; +{- + generate_stack_macros("OSSL_CMP_CERTSTATUS"); +-} +typedef struct ossl_cmp_itav_st OSSL_CMP_ITAV; +DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV) +{- + generate_stack_macros("OSSL_CMP_ITAV"); +-} +typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT; +typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI; +DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI) +{- + generate_stack_macros("OSSL_CMP_PKISI"); +-} +typedef struct ossl_cmp_certrepmessage_st OSSL_CMP_CERTREPMESSAGE; +{- + generate_stack_macros("OSSL_CMP_CERTREPMESSAGE"); +-} +typedef struct ossl_cmp_pollrep_st OSSL_CMP_POLLREP; +typedef STACK_OF(OSSL_CMP_POLLREP) OSSL_CMP_POLLREPCONTENT; +typedef struct ossl_cmp_certresponse_st OSSL_CMP_CERTRESPONSE; +{- + generate_stack_macros("OSSL_CMP_CERTRESPONSE"); +-} +typedef STACK_OF(ASN1_UTF8STRING) OSSL_CMP_PKIFREETEXT; + +/* + * function DECLARATIONS + */ + +/* from cmp_asn.c */ +OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value); +void OSSL_CMP_ITAV_set0(OSSL_CMP_ITAV *itav, ASN1_OBJECT *type, + ASN1_TYPE *value); +ASN1_OBJECT *OSSL_CMP_ITAV_get0_type(const OSSL_CMP_ITAV *itav); +ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav); +int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p, + OSSL_CMP_ITAV *itav); +void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav); +void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg); + +/* from cmp_ctx.c */ +OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq); +void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx); +int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx); +/* various CMP options: */ +# define OSSL_CMP_OPT_LOG_VERBOSITY 0 +# define OSSL_CMP_OPT_MSG_TIMEOUT 1 +# define OSSL_CMP_OPT_TOTAL_TIMEOUT 2 +# define OSSL_CMP_OPT_VALIDITY_DAYS 3 +# define OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT 4 +# define OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL 5 +# define OSSL_CMP_OPT_POLICIES_CRITICAL 6 +# define OSSL_CMP_OPT_POPO_METHOD 7 +# define OSSL_CMP_OPT_DIGEST_ALGNID 8 +# define OSSL_CMP_OPT_OWF_ALGNID 9 +# define OSSL_CMP_OPT_MAC_ALGNID 10 +# define OSSL_CMP_OPT_REVOCATION_REASON 11 +# define OSSL_CMP_OPT_IMPLICIT_CONFIRM 12 +# define OSSL_CMP_OPT_DISABLE_CONFIRM 13 +# define OSSL_CMP_OPT_UNPROTECTED_SEND 14 +# define OSSL_CMP_OPT_UNPROTECTED_ERRORS 15 +# define OSSL_CMP_OPT_IGNORE_KEYUSAGE 16 +# define OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR 17 +int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val); +int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt); +/* CMP-specific callback for logging and outputting the error queue: */ +int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb); +# define OSSL_CMP_CTX_set_log_verbosity(ctx, level) \ + OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_LOG_VERBOSITY, level) +void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx); +/* message transfer: */ +int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path); +int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address); +int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port); +int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name); +int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names); +int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb); +int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg); +void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx); +typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t) (OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *req); +int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb); +int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg); +void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx); +/* server authentication: */ +int OSSL_CMP_CTX_set1_srvCert(OSSL_CMP_CTX *ctx, X509 *cert); +int OSSL_CMP_CTX_set1_expected_sender(OSSL_CMP_CTX *ctx, const X509_NAME *name); +int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store); +X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx); +int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs); +STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx); +/* client authentication: */ +int OSSL_CMP_CTX_set1_cert(OSSL_CMP_CTX *ctx, X509 *cert); +int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted, + STACK_OF(X509) *candidates); +int OSSL_CMP_CTX_set1_pkey(OSSL_CMP_CTX *ctx, EVP_PKEY *pkey); +int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, + const unsigned char *ref, int len); +int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec, + const int len); +/* CMP message header and extra certificates: */ +int OSSL_CMP_CTX_set1_recipient(OSSL_CMP_CTX *ctx, const X509_NAME *name); +int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav); +int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, + STACK_OF(X509) *extraCertsOut); +/* certificate template: */ +int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey); +EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv); +int OSSL_CMP_CTX_set1_issuer(OSSL_CMP_CTX *ctx, const X509_NAME *name); +int OSSL_CMP_CTX_set1_subjectName(OSSL_CMP_CTX *ctx, const X509_NAME *name); +int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, + const GENERAL_NAME *name); +int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts); +int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx); +int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo); +int OSSL_CMP_CTX_set1_oldCert(OSSL_CMP_CTX *ctx, X509 *cert); +int OSSL_CMP_CTX_set1_p10CSR(OSSL_CMP_CTX *ctx, const X509_REQ *csr); +/* misc body contents: */ +int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav); +/* certificate confirmation: */ +typedef int (*OSSL_CMP_certConf_cb_t) (OSSL_CMP_CTX *ctx, X509 *cert, + int fail_info, const char **txt); +int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, + const char **text); +int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb); +int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg); +void *OSSL_CMP_CTX_get_certConf_cb_arg(const OSSL_CMP_CTX *ctx); +/* result fetching: */ +int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx); +OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx); +int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx); +# define OSSL_CMP_PKISI_BUFLEN 1024 +X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx); +STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx); +STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx); +STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx); +int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *id); +int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *nonce); + +/* from cmp_status.c */ +char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf, + size_t bufsize); +char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo, + char *buf, size_t bufsize); +OSSL_CMP_PKISI * +OSSL_CMP_STATUSINFO_new(int status, int fail_info, const char *text); + +/* from cmp_hdr.c */ +ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const + OSSL_CMP_PKIHEADER *hdr); +ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr); + +/* from cmp_msg.c */ +OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg); +int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); +OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid); +OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file); +int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg); +OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg); +int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg); + +/* from cmp_vfy.c */ +int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg); +int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, + X509_STORE *trusted_store, X509 *cert); + +/* from cmp_http.c */ +OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *req); + +/* from cmp_server.c */ +typedef struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_CTX; +OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req); +OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx, + const OSSL_CMP_MSG *req); +OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq); +void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx); +typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t) + (OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req, int certReqId, + const OSSL_CRMF_MSG *crm, const X509_REQ *p10cr, + X509 **certOut, STACK_OF(X509) **chainOut, STACK_OF(X509) **caPubs); +typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_rr_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req, + const X509_NAME *issuer, + const ASN1_INTEGER *serial); +typedef int (*OSSL_CMP_SRV_genm_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req, + const STACK_OF(OSSL_CMP_ITAV) *in, + STACK_OF(OSSL_CMP_ITAV) **out); +typedef void (*OSSL_CMP_SRV_error_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req, + const OSSL_CMP_PKISI *statusInfo, + const ASN1_INTEGER *errorCode, + const OSSL_CMP_PKIFREETEXT *errDetails); +typedef int (*OSSL_CMP_SRV_certConf_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req, + int certReqId, + const ASN1_OCTET_STRING *certHash, + const OSSL_CMP_PKISI *si); +typedef int (*OSSL_CMP_SRV_pollReq_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx, + const OSSL_CMP_MSG *req, int certReqId, + OSSL_CMP_MSG **certReq, + int64_t *check_after); +int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx, + OSSL_CMP_SRV_cert_request_cb_t process_cert_request, + OSSL_CMP_SRV_rr_cb_t process_rr, + OSSL_CMP_SRV_genm_cb_t process_genm, + OSSL_CMP_SRV_error_cb_t process_error, + OSSL_CMP_SRV_certConf_cb_t process_certConf, + OSSL_CMP_SRV_pollReq_cb_t process_pollReq); +OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); +void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx); +int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx, + int val); +int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val); +int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val); +int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx, + int val); + +/* from cmp_client.c */ +X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type, + const OSSL_CRMF_MSG *crm); +# define OSSL_CMP_IR 0 +# define OSSL_CMP_CR 2 +# define OSSL_CMP_P10CR 4 +# define OSSL_CMP_KUR 7 +# define OSSL_CMP_exec_IR_ses(ctx) \ + OSSL_CMP_exec_certreq(ctx, OSSL_CMP_IR, NULL) +# define OSSL_CMP_exec_CR_ses(ctx) \ + OSSL_CMP_exec_certreq(ctx, OSSL_CMP_CR, NULL) +# define OSSL_CMP_exec_P10CR_ses(ctx) \ + OSSL_CMP_exec_certreq(ctx, OSSL_CMP_P10CR, NULL) +# define OSSL_CMP_exec_KUR_ses(ctx) \ + OSSL_CMP_exec_certreq(ctx, OSSL_CMP_KUR, NULL) +int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, + const OSSL_CRMF_MSG *crm, int *checkAfter); +X509 *OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx); +STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx); + +# ifdef __cplusplus +} +# endif +# endif /* !defined(OPENSSL_NO_CMP) */ +#endif /* !defined(OPENSSL_CMP_H) */ diff --git a/include/openssl/cmp_util.h b/include/openssl/cmp_util.h index a243d7e742..becbc9208e 100644 --- a/include/openssl/cmp_util.h +++ b/include/openssl/cmp_util.h @@ -38,6 +38,8 @@ typedef int OSSL_CMP_severity; # define OSSL_CMP_LOG_NOTICE 5 # define OSSL_CMP_LOG_INFO 6 # define OSSL_CMP_LOG_DEBUG 7 +# define OSSL_CMP_LOG_TRACE 8 +# define OSSL_CMP_LOG_MAX OSSL_CMP_LOG_TRACE typedef int (*OSSL_CMP_log_cb_t)(const char *func, const char *file, int line, OSSL_CMP_severity level, const char *msg); diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h index f18ba386bc..190e1a96bd 100644 --- a/include/openssl/cmperr.h +++ b/include/openssl/cmperr.h @@ -45,7 +45,6 @@ int ERR_load_CMP_strings(void); # define CMP_R_CERTRESPONSE_NOT_FOUND 113 # define CMP_R_CERT_AND_KEY_DO_NOT_MATCH 114 # define CMP_R_CHECKAFTER_OUT_OF_RANGE 181 -# define CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE 166 # define CMP_R_ENCOUNTERED_KEYUPDATEWARNING 176 # define CMP_R_ENCOUNTERED_WAITING 162 # define CMP_R_ERROR_CALCULATING_PROTECTION 115 @@ -67,6 +66,7 @@ int ERR_load_CMP_strings(void); # define CMP_R_ERROR_UNEXPECTED_CERTCONF 160 # define CMP_R_ERROR_VALIDATING_PROTECTION 140 # define CMP_R_ERROR_VALIDATING_SIGNATURE 171 +# define CMP_R_FAILED_BUILDING_OWN_CHAIN 164 # define CMP_R_FAILED_EXTRACTING_PUBKEY 141 # define CMP_R_FAILURE_OBTAINING_RANDOM 110 # define CMP_R_FAIL_INFO_OUT_OF_RANGE 129 @@ -75,6 +75,7 @@ int ERR_load_CMP_strings(void); # define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130 # define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE 142 # define CMP_R_MISSING_P10CSR 121 +# define CMP_R_MISSING_PBM_SECRET 166 # define CMP_R_MISSING_PRIVATE_KEY 131 # define CMP_R_MISSING_PROTECTION 143 # define CMP_R_MISSING_REFERENCE_CERT 168 diff --git a/include/openssl/cms.h b/include/openssl/cms.h index a0f4b6a0ec..10a8b33e83 100644 --- a/include/openssl/cms.h +++ b/include/openssl/cms.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/cms.h.in + * * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_CMS_H # define OPENSSL_CMS_H # pragma once @@ -36,15 +41,114 @@ typedef struct CMS_Receipt_st CMS_Receipt; typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; -DEFINE_OR_DECLARE_STACK_OF(CMS_SignerInfo) -DEFINE_OR_DECLARE_STACK_OF(CMS_RecipientEncryptedKey) -DEFINE_OR_DECLARE_STACK_OF(CMS_RecipientInfo) -DEFINE_OR_DECLARE_STACK_OF(CMS_RevocationInfoChoice) +SKM_DEFINE_STACK_OF_INTERNAL(CMS_SignerInfo, CMS_SignerInfo, CMS_SignerInfo) +#define sk_CMS_SignerInfo_num(sk) OPENSSL_sk_num(ossl_check_const_CMS_SignerInfo_sk_type(sk)) +#define sk_CMS_SignerInfo_value(sk, idx) ((CMS_SignerInfo *)OPENSSL_sk_value(ossl_check_const_CMS_SignerInfo_sk_type(sk), (idx))) +#define sk_CMS_SignerInfo_new(cmp) ((STACK_OF(CMS_SignerInfo) *)OPENSSL_sk_new(ossl_check_CMS_SignerInfo_compfunc_type(cmp))) +#define sk_CMS_SignerInfo_new_null() ((STACK_OF(CMS_SignerInfo) *)OPENSSL_sk_new_null()) +#define sk_CMS_SignerInfo_new_reserve(cmp, n) ((STACK_OF(CMS_SignerInfo) *)OPENSSL_sk_new_reserve(ossl_check_CMS_SignerInfo_compfunc_type(cmp), (n))) +#define sk_CMS_SignerInfo_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_CMS_SignerInfo_sk_type(sk), (n)) +#define sk_CMS_SignerInfo_free(sk) OPENSSL_sk_free(ossl_check_CMS_SignerInfo_sk_type(sk)) +#define sk_CMS_SignerInfo_zero(sk) OPENSSL_sk_zero(ossl_check_CMS_SignerInfo_sk_type(sk)) +#define sk_CMS_SignerInfo_delete(sk, i) ((CMS_SignerInfo *)OPENSSL_sk_delete(ossl_check_CMS_SignerInfo_sk_type(sk), (i))) +#define sk_CMS_SignerInfo_delete_ptr(sk, ptr) ((CMS_SignerInfo *)OPENSSL_sk_delete_ptr(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_type(ptr))) +#define sk_CMS_SignerInfo_push(sk, ptr) OPENSSL_sk_push(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_type(ptr)) +#define sk_CMS_SignerInfo_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_type(ptr)) +#define sk_CMS_SignerInfo_pop(sk) ((CMS_SignerInfo *)OPENSSL_sk_pop(ossl_check_CMS_SignerInfo_sk_type(sk))) +#define sk_CMS_SignerInfo_shift(sk) ((CMS_SignerInfo *)OPENSSL_sk_shift(ossl_check_CMS_SignerInfo_sk_type(sk))) +#define sk_CMS_SignerInfo_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_CMS_SignerInfo_sk_type(sk),ossl_check_CMS_SignerInfo_freefunc_type(freefunc)) +#define sk_CMS_SignerInfo_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_type(ptr), (idx)) +#define sk_CMS_SignerInfo_set(sk, idx, ptr) ((CMS_SignerInfo *)OPENSSL_sk_set(ossl_check_CMS_SignerInfo_sk_type(sk), (idx), ossl_check_CMS_SignerInfo_type(ptr))) +#define sk_CMS_SignerInfo_find(sk, ptr) OPENSSL_sk_find(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_type(ptr)) +#define sk_CMS_SignerInfo_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_type(ptr)) +#define sk_CMS_SignerInfo_sort(sk) OPENSSL_sk_sort(ossl_check_CMS_SignerInfo_sk_type(sk)) +#define sk_CMS_SignerInfo_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_CMS_SignerInfo_sk_type(sk)) +#define sk_CMS_SignerInfo_dup(sk) ((STACK_OF(CMS_SignerInfo) *)OPENSSL_sk_dup(ossl_check_const_CMS_SignerInfo_sk_type(sk))) +#define sk_CMS_SignerInfo_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CMS_SignerInfo) *)OPENSSL_sk_deep_copy(ossl_check_const_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_copyfunc_type(copyfunc), ossl_check_CMS_SignerInfo_freefunc_type(freefunc))) +#define sk_CMS_SignerInfo_set_cmp_func(sk, cmp) ((sk_CMS_SignerInfo_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CMS_SignerInfo_sk_type(sk), ossl_check_CMS_SignerInfo_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey) +#define sk_CMS_RecipientEncryptedKey_num(sk) OPENSSL_sk_num(ossl_check_const_CMS_RecipientEncryptedKey_sk_type(sk)) +#define sk_CMS_RecipientEncryptedKey_value(sk, idx) ((CMS_RecipientEncryptedKey *)OPENSSL_sk_value(ossl_check_const_CMS_RecipientEncryptedKey_sk_type(sk), (idx))) +#define sk_CMS_RecipientEncryptedKey_new(cmp) ((STACK_OF(CMS_RecipientEncryptedKey) *)OPENSSL_sk_new(ossl_check_CMS_RecipientEncryptedKey_compfunc_type(cmp))) +#define sk_CMS_RecipientEncryptedKey_new_null() ((STACK_OF(CMS_RecipientEncryptedKey) *)OPENSSL_sk_new_null()) +#define sk_CMS_RecipientEncryptedKey_new_reserve(cmp, n) ((STACK_OF(CMS_RecipientEncryptedKey) *)OPENSSL_sk_new_reserve(ossl_check_CMS_RecipientEncryptedKey_compfunc_type(cmp), (n))) +#define sk_CMS_RecipientEncryptedKey_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), (n)) +#define sk_CMS_RecipientEncryptedKey_free(sk) OPENSSL_sk_free(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk)) +#define sk_CMS_RecipientEncryptedKey_zero(sk) OPENSSL_sk_zero(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk)) +#define sk_CMS_RecipientEncryptedKey_delete(sk, i) ((CMS_RecipientEncryptedKey *)OPENSSL_sk_delete(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), (i))) +#define sk_CMS_RecipientEncryptedKey_delete_ptr(sk, ptr) ((CMS_RecipientEncryptedKey *)OPENSSL_sk_delete_ptr(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_type(ptr))) +#define sk_CMS_RecipientEncryptedKey_push(sk, ptr) OPENSSL_sk_push(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_type(ptr)) +#define sk_CMS_RecipientEncryptedKey_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_type(ptr)) +#define sk_CMS_RecipientEncryptedKey_pop(sk) ((CMS_RecipientEncryptedKey *)OPENSSL_sk_pop(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk))) +#define sk_CMS_RecipientEncryptedKey_shift(sk) ((CMS_RecipientEncryptedKey *)OPENSSL_sk_shift(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk))) +#define sk_CMS_RecipientEncryptedKey_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk),ossl_check_CMS_RecipientEncryptedKey_freefunc_type(freefunc)) +#define sk_CMS_RecipientEncryptedKey_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_type(ptr), (idx)) +#define sk_CMS_RecipientEncryptedKey_set(sk, idx, ptr) ((CMS_RecipientEncryptedKey *)OPENSSL_sk_set(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), (idx), ossl_check_CMS_RecipientEncryptedKey_type(ptr))) +#define sk_CMS_RecipientEncryptedKey_find(sk, ptr) OPENSSL_sk_find(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_type(ptr)) +#define sk_CMS_RecipientEncryptedKey_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_type(ptr)) +#define sk_CMS_RecipientEncryptedKey_sort(sk) OPENSSL_sk_sort(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk)) +#define sk_CMS_RecipientEncryptedKey_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_CMS_RecipientEncryptedKey_sk_type(sk)) +#define sk_CMS_RecipientEncryptedKey_dup(sk) ((STACK_OF(CMS_RecipientEncryptedKey) *)OPENSSL_sk_dup(ossl_check_const_CMS_RecipientEncryptedKey_sk_type(sk))) +#define sk_CMS_RecipientEncryptedKey_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CMS_RecipientEncryptedKey) *)OPENSSL_sk_deep_copy(ossl_check_const_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_copyfunc_type(copyfunc), ossl_check_CMS_RecipientEncryptedKey_freefunc_type(freefunc))) +#define sk_CMS_RecipientEncryptedKey_set_cmp_func(sk, cmp) ((sk_CMS_RecipientEncryptedKey_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CMS_RecipientEncryptedKey_sk_type(sk), ossl_check_CMS_RecipientEncryptedKey_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(CMS_RecipientInfo, CMS_RecipientInfo, CMS_RecipientInfo) +#define sk_CMS_RecipientInfo_num(sk) OPENSSL_sk_num(ossl_check_const_CMS_RecipientInfo_sk_type(sk)) +#define sk_CMS_RecipientInfo_value(sk, idx) ((CMS_RecipientInfo *)OPENSSL_sk_value(ossl_check_const_CMS_RecipientInfo_sk_type(sk), (idx))) +#define sk_CMS_RecipientInfo_new(cmp) ((STACK_OF(CMS_RecipientInfo) *)OPENSSL_sk_new(ossl_check_CMS_RecipientInfo_compfunc_type(cmp))) +#define sk_CMS_RecipientInfo_new_null() ((STACK_OF(CMS_RecipientInfo) *)OPENSSL_sk_new_null()) +#define sk_CMS_RecipientInfo_new_reserve(cmp, n) ((STACK_OF(CMS_RecipientInfo) *)OPENSSL_sk_new_reserve(ossl_check_CMS_RecipientInfo_compfunc_type(cmp), (n))) +#define sk_CMS_RecipientInfo_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_CMS_RecipientInfo_sk_type(sk), (n)) +#define sk_CMS_RecipientInfo_free(sk) OPENSSL_sk_free(ossl_check_CMS_RecipientInfo_sk_type(sk)) +#define sk_CMS_RecipientInfo_zero(sk) OPENSSL_sk_zero(ossl_check_CMS_RecipientInfo_sk_type(sk)) +#define sk_CMS_RecipientInfo_delete(sk, i) ((CMS_RecipientInfo *)OPENSSL_sk_delete(ossl_check_CMS_RecipientInfo_sk_type(sk), (i))) +#define sk_CMS_RecipientInfo_delete_ptr(sk, ptr) ((CMS_RecipientInfo *)OPENSSL_sk_delete_ptr(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_type(ptr))) +#define sk_CMS_RecipientInfo_push(sk, ptr) OPENSSL_sk_push(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_type(ptr)) +#define sk_CMS_RecipientInfo_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_type(ptr)) +#define sk_CMS_RecipientInfo_pop(sk) ((CMS_RecipientInfo *)OPENSSL_sk_pop(ossl_check_CMS_RecipientInfo_sk_type(sk))) +#define sk_CMS_RecipientInfo_shift(sk) ((CMS_RecipientInfo *)OPENSSL_sk_shift(ossl_check_CMS_RecipientInfo_sk_type(sk))) +#define sk_CMS_RecipientInfo_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_CMS_RecipientInfo_sk_type(sk),ossl_check_CMS_RecipientInfo_freefunc_type(freefunc)) +#define sk_CMS_RecipientInfo_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_type(ptr), (idx)) +#define sk_CMS_RecipientInfo_set(sk, idx, ptr) ((CMS_RecipientInfo *)OPENSSL_sk_set(ossl_check_CMS_RecipientInfo_sk_type(sk), (idx), ossl_check_CMS_RecipientInfo_type(ptr))) +#define sk_CMS_RecipientInfo_find(sk, ptr) OPENSSL_sk_find(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_type(ptr)) +#define sk_CMS_RecipientInfo_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_type(ptr)) +#define sk_CMS_RecipientInfo_sort(sk) OPENSSL_sk_sort(ossl_check_CMS_RecipientInfo_sk_type(sk)) +#define sk_CMS_RecipientInfo_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_CMS_RecipientInfo_sk_type(sk)) +#define sk_CMS_RecipientInfo_dup(sk) ((STACK_OF(CMS_RecipientInfo) *)OPENSSL_sk_dup(ossl_check_const_CMS_RecipientInfo_sk_type(sk))) +#define sk_CMS_RecipientInfo_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CMS_RecipientInfo) *)OPENSSL_sk_deep_copy(ossl_check_const_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_copyfunc_type(copyfunc), ossl_check_CMS_RecipientInfo_freefunc_type(freefunc))) +#define sk_CMS_RecipientInfo_set_cmp_func(sk, cmp) ((sk_CMS_RecipientInfo_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CMS_RecipientInfo_sk_type(sk), ossl_check_CMS_RecipientInfo_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(CMS_RevocationInfoChoice, CMS_RevocationInfoChoice, CMS_RevocationInfoChoice) +#define sk_CMS_RevocationInfoChoice_num(sk) OPENSSL_sk_num(ossl_check_const_CMS_RevocationInfoChoice_sk_type(sk)) +#define sk_CMS_RevocationInfoChoice_value(sk, idx) ((CMS_RevocationInfoChoice *)OPENSSL_sk_value(ossl_check_const_CMS_RevocationInfoChoice_sk_type(sk), (idx))) +#define sk_CMS_RevocationInfoChoice_new(cmp) ((STACK_OF(CMS_RevocationInfoChoice) *)OPENSSL_sk_new(ossl_check_CMS_RevocationInfoChoice_compfunc_type(cmp))) +#define sk_CMS_RevocationInfoChoice_new_null() ((STACK_OF(CMS_RevocationInfoChoice) *)OPENSSL_sk_new_null()) +#define sk_CMS_RevocationInfoChoice_new_reserve(cmp, n) ((STACK_OF(CMS_RevocationInfoChoice) *)OPENSSL_sk_new_reserve(ossl_check_CMS_RevocationInfoChoice_compfunc_type(cmp), (n))) +#define sk_CMS_RevocationInfoChoice_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), (n)) +#define sk_CMS_RevocationInfoChoice_free(sk) OPENSSL_sk_free(ossl_check_CMS_RevocationInfoChoice_sk_type(sk)) +#define sk_CMS_RevocationInfoChoice_zero(sk) OPENSSL_sk_zero(ossl_check_CMS_RevocationInfoChoice_sk_type(sk)) +#define sk_CMS_RevocationInfoChoice_delete(sk, i) ((CMS_RevocationInfoChoice *)OPENSSL_sk_delete(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), (i))) +#define sk_CMS_RevocationInfoChoice_delete_ptr(sk, ptr) ((CMS_RevocationInfoChoice *)OPENSSL_sk_delete_ptr(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_type(ptr))) +#define sk_CMS_RevocationInfoChoice_push(sk, ptr) OPENSSL_sk_push(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_type(ptr)) +#define sk_CMS_RevocationInfoChoice_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_type(ptr)) +#define sk_CMS_RevocationInfoChoice_pop(sk) ((CMS_RevocationInfoChoice *)OPENSSL_sk_pop(ossl_check_CMS_RevocationInfoChoice_sk_type(sk))) +#define sk_CMS_RevocationInfoChoice_shift(sk) ((CMS_RevocationInfoChoice *)OPENSSL_sk_shift(ossl_check_CMS_RevocationInfoChoice_sk_type(sk))) +#define sk_CMS_RevocationInfoChoice_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_CMS_RevocationInfoChoice_sk_type(sk),ossl_check_CMS_RevocationInfoChoice_freefunc_type(freefunc)) +#define sk_CMS_RevocationInfoChoice_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_type(ptr), (idx)) +#define sk_CMS_RevocationInfoChoice_set(sk, idx, ptr) ((CMS_RevocationInfoChoice *)OPENSSL_sk_set(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), (idx), ossl_check_CMS_RevocationInfoChoice_type(ptr))) +#define sk_CMS_RevocationInfoChoice_find(sk, ptr) OPENSSL_sk_find(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_type(ptr)) +#define sk_CMS_RevocationInfoChoice_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_type(ptr)) +#define sk_CMS_RevocationInfoChoice_sort(sk) OPENSSL_sk_sort(ossl_check_CMS_RevocationInfoChoice_sk_type(sk)) +#define sk_CMS_RevocationInfoChoice_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_CMS_RevocationInfoChoice_sk_type(sk)) +#define sk_CMS_RevocationInfoChoice_dup(sk) ((STACK_OF(CMS_RevocationInfoChoice) *)OPENSSL_sk_dup(ossl_check_const_CMS_RevocationInfoChoice_sk_type(sk))) +#define sk_CMS_RevocationInfoChoice_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CMS_RevocationInfoChoice) *)OPENSSL_sk_deep_copy(ossl_check_const_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_copyfunc_type(copyfunc), ossl_check_CMS_RevocationInfoChoice_freefunc_type(freefunc))) +#define sk_CMS_RevocationInfoChoice_set_cmp_func(sk, cmp) ((sk_CMS_RevocationInfoChoice_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CMS_RevocationInfoChoice_sk_type(sk), ossl_check_CMS_RevocationInfoChoice_compfunc_type(cmp))) + DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) +CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq); + # define CMS_SIGNERINFO_ISSUER_SERIAL 0 # define CMS_SIGNERINFO_KEYIDENTIFIER 1 @@ -104,6 +208,7 @@ int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **ci); int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, @@ -112,6 +217,10 @@ int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, unsigned int flags); +CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags, OSSL_LIB_CTX *ctx, + const char *propq); CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, X509 *signcert, EVP_PKEY *pkey, @@ -119,11 +228,16 @@ CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); +CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, + OSSL_LIB_CTX *ctx, const char *propq); int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, unsigned int flags); CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, unsigned int flags); +CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, + unsigned int flags, OSSL_LIB_CTX *ctx, + const char *propq); int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, const unsigned char *key, size_t keylen, @@ -132,6 +246,11 @@ int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, const unsigned char *key, size_t keylen, unsigned int flags); +CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags, + OSSL_LIB_CTX *ctx, + const char *propq); int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, const unsigned char *key, size_t keylen); @@ -147,12 +266,16 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, unsigned int flags); +CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags, + OSSL_LIB_CTX *ctx, const char *propq); int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *dcont, BIO *out, unsigned int flags); int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); -int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, X509 *peer); +int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, + X509 *cert, X509 *peer); int CMS_decrypt_set1_key(CMS_ContentInfo *cms, unsigned char *key, size_t keylen, const unsigned char *id, size_t idlen); @@ -162,7 +285,15 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms, STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher); +CMS_ContentInfo * +CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *ctx, + const char *propq); CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, + OSSL_LIB_CTX *ctx, + const char *propq); + CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip, unsigned int flags); CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, @@ -297,11 +428,16 @@ void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, int lastpos, int type); int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); -CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, - int allorfirst, - STACK_OF(GENERAL_NAMES) - *receiptList, STACK_OF(GENERAL_NAMES) - *receiptsTo); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, + STACK_OF(GENERAL_NAMES) *receiptsTo); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, + STACK_OF(GENERAL_NAMES) *receiptsTo, + OSSL_LIB_CTX *ctx, const char *propq); + int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, ASN1_STRING **pcid, diff --git a/include/openssl/cms.h.in b/include/openssl/cms.h.in new file mode 100644 index 0000000000..5ffd3b4405 --- /dev/null +++ b/include/openssl/cms.h.in @@ -0,0 +1,394 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_CMS_H +# define OPENSSL_CMS_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_CMS_H +# endif + +# include + +# ifndef OPENSSL_NO_CMS +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +{- + generate_stack_macros("CMS_SignerInfo") + .generate_stack_macros("CMS_RecipientEncryptedKey") + .generate_stack_macros("CMS_RecipientInfo") + .generate_stack_macros("CMS_RevocationInfoChoice"); +-} + +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq); + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_NONE -1 +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 +# define CMS_KEY_PARAM 0x40000 +# define CMS_ASCIICRLF 0x80000 +# define CMS_CADES 0x100000 +# define CMS_USE_ORIGINATOR_KEYID 0x200000 + +const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef OPENSSL_PEM_H +DECLARE_PEM_rw(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, BIO **bcont, CMS_ContentInfo **ci); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); +CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags, OSSL_LIB_CTX *ctx, + const char *propq); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); +CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, + OSSL_LIB_CTX *ctx, const char *propq); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, + unsigned int flags, OSSL_LIB_CTX *ctx, + const char *propq); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); +CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags, + OSSL_LIB_CTX *ctx, + const char *propq); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); +CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags, + OSSL_LIB_CTX *ctx, const char *propq); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, + X509 *cert, X509 *peer); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + const unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher); +CMS_ContentInfo * +CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *ctx, + const char *propq); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher, + OSSL_LIB_CTX *ctx, + const char *propq); + +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip, + EVP_PKEY *originatorPrivKey, X509 * originator, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, + STACK_OF(GENERAL_NAMES) *receiptsTo); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, + STACK_OF(GENERAL_NAMES) *receiptsTo, + OSSL_LIB_CTX *ctx, const char *propq); + +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +int CMS_RecipientInfo_kari_set0_pkey_and_peer(CMS_RecipientInfo *ri, EVP_PKEY *pk, X509 *peer); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* Backward compatibility for spelling errors. */ +# define CMS_R_UNKNOWN_DIGEST_ALGORITM CMS_R_UNKNOWN_DIGEST_ALGORITHM +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE \ + CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h index 97704bfa52..e234ad0126 100644 --- a/include/openssl/cmserr.h +++ b/include/openssl/cmserr.h @@ -131,6 +131,8 @@ int ERR_load_CMS_strings(void); # define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 # define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 # define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_AEAD_SET_TAG_ERROR 184 +# define CMS_R_CIPHER_GET_TAG 185 # define CMS_R_CIPHER_INITIALISATION_ERROR 101 # define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 # define CMS_R_CMS_DATAFINAL_ERROR 103 @@ -144,6 +146,7 @@ int ERR_load_CMS_strings(void); # define CMS_R_CONTENT_VERIFY_ERROR 109 # define CMS_R_CTRL_ERROR 110 # define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECODE_ERROR 187 # define CMS_R_DECRYPT_ERROR 112 # define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 # define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 @@ -154,6 +157,9 @@ int ERR_load_CMS_strings(void); # define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 # define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 # define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_INVALID_LABEL 190 +# define CMS_R_INVALID_OAEP_PARAMETERS 191 +# define CMS_R_KDF_PARAMETER_ERROR 186 # define CMS_R_MD_BIO_INIT_ERROR 119 # define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 # define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 @@ -184,9 +190,11 @@ int ERR_load_CMS_strings(void); # define CMS_R_NO_PUBLIC_KEY 134 # define CMS_R_NO_RECEIPT_REQUEST 168 # define CMS_R_NO_SIGNERS 135 +# define CMS_R_PEER_KEY_ERROR 188 # define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 # define CMS_R_RECEIPT_DECODE_ERROR 169 # define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SHARED_INFO_ERROR 189 # define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 # define CMS_R_SIGNFINAL_ERROR 139 # define CMS_R_SMIME_TEXT_ERROR 140 @@ -202,8 +210,10 @@ int ERR_load_CMS_strings(void); # define CMS_R_UNKNOWN_ID 150 # define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 # define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_ENCRYPTION_TYPE 192 # define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 # define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_LABEL_SOURCE 193 # define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155 # define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 # define CMS_R_UNSUPPORTED_TYPE 156 diff --git a/include/openssl/conf.h b/include/openssl/conf.h index 24cdcbb1cf..6fe49c8a3b 100644 --- a/include/openssl/conf.h +++ b/include/openssl/conf.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/conf.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_CONF_H # define OPENSSL_CONF_H # pragma once @@ -33,9 +38,47 @@ typedef struct { char *value; } CONF_VALUE; -DEFINE_OR_DECLARE_STACK_OF(CONF_VALUE) +SKM_DEFINE_STACK_OF_INTERNAL(CONF_VALUE, CONF_VALUE, CONF_VALUE) +#define sk_CONF_VALUE_num(sk) OPENSSL_sk_num(ossl_check_const_CONF_VALUE_sk_type(sk)) +#define sk_CONF_VALUE_value(sk, idx) ((CONF_VALUE *)OPENSSL_sk_value(ossl_check_const_CONF_VALUE_sk_type(sk), (idx))) +#define sk_CONF_VALUE_new(cmp) ((STACK_OF(CONF_VALUE) *)OPENSSL_sk_new(ossl_check_CONF_VALUE_compfunc_type(cmp))) +#define sk_CONF_VALUE_new_null() ((STACK_OF(CONF_VALUE) *)OPENSSL_sk_new_null()) +#define sk_CONF_VALUE_new_reserve(cmp, n) ((STACK_OF(CONF_VALUE) *)OPENSSL_sk_new_reserve(ossl_check_CONF_VALUE_compfunc_type(cmp), (n))) +#define sk_CONF_VALUE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_CONF_VALUE_sk_type(sk), (n)) +#define sk_CONF_VALUE_free(sk) OPENSSL_sk_free(ossl_check_CONF_VALUE_sk_type(sk)) +#define sk_CONF_VALUE_zero(sk) OPENSSL_sk_zero(ossl_check_CONF_VALUE_sk_type(sk)) +#define sk_CONF_VALUE_delete(sk, i) ((CONF_VALUE *)OPENSSL_sk_delete(ossl_check_CONF_VALUE_sk_type(sk), (i))) +#define sk_CONF_VALUE_delete_ptr(sk, ptr) ((CONF_VALUE *)OPENSSL_sk_delete_ptr(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_type(ptr))) +#define sk_CONF_VALUE_push(sk, ptr) OPENSSL_sk_push(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_type(ptr)) +#define sk_CONF_VALUE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_type(ptr)) +#define sk_CONF_VALUE_pop(sk) ((CONF_VALUE *)OPENSSL_sk_pop(ossl_check_CONF_VALUE_sk_type(sk))) +#define sk_CONF_VALUE_shift(sk) ((CONF_VALUE *)OPENSSL_sk_shift(ossl_check_CONF_VALUE_sk_type(sk))) +#define sk_CONF_VALUE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_CONF_VALUE_sk_type(sk),ossl_check_CONF_VALUE_freefunc_type(freefunc)) +#define sk_CONF_VALUE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_type(ptr), (idx)) +#define sk_CONF_VALUE_set(sk, idx, ptr) ((CONF_VALUE *)OPENSSL_sk_set(ossl_check_CONF_VALUE_sk_type(sk), (idx), ossl_check_CONF_VALUE_type(ptr))) +#define sk_CONF_VALUE_find(sk, ptr) OPENSSL_sk_find(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_type(ptr)) +#define sk_CONF_VALUE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_type(ptr)) +#define sk_CONF_VALUE_sort(sk) OPENSSL_sk_sort(ossl_check_CONF_VALUE_sk_type(sk)) +#define sk_CONF_VALUE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_CONF_VALUE_sk_type(sk)) +#define sk_CONF_VALUE_dup(sk) ((STACK_OF(CONF_VALUE) *)OPENSSL_sk_dup(ossl_check_const_CONF_VALUE_sk_type(sk))) +#define sk_CONF_VALUE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CONF_VALUE) *)OPENSSL_sk_deep_copy(ossl_check_const_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_copyfunc_type(copyfunc), ossl_check_CONF_VALUE_freefunc_type(freefunc))) +#define sk_CONF_VALUE_set_cmp_func(sk, cmp) ((sk_CONF_VALUE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CONF_VALUE_sk_type(sk), ossl_check_CONF_VALUE_compfunc_type(cmp))) +DEFINE_LHASH_OF_INTERNAL(CONF_VALUE); +#define lh_CONF_VALUE_new(hfn, cmp) ((LHASH_OF(CONF_VALUE) *)OPENSSL_LH_new(ossl_check_CONF_VALUE_lh_hashfunc_type(hfn), ossl_check_CONF_VALUE_lh_compfunc_type(cmp))) +#define lh_CONF_VALUE_free(lh) OPENSSL_LH_free(ossl_check_CONF_VALUE_lh_type(lh)) +#define lh_CONF_VALUE_flush(lh) OPENSSL_LH_flush(ossl_check_CONF_VALUE_lh_type(lh)) +#define lh_CONF_VALUE_insert(lh, ptr) ((CONF_VALUE *)OPENSSL_LH_insert(ossl_check_CONF_VALUE_lh_type(lh), ossl_check_CONF_VALUE_lh_plain_type(ptr))) +#define lh_CONF_VALUE_delete(lh, ptr) ((CONF_VALUE *)OPENSSL_LH_delete(ossl_check_CONF_VALUE_lh_type(lh), ossl_check_const_CONF_VALUE_lh_plain_type(ptr))) +#define lh_CONF_VALUE_retrieve(lh, ptr) ((CONF_VALUE *)OPENSSL_LH_retrieve(ossl_check_CONF_VALUE_lh_type(lh), ossl_check_const_CONF_VALUE_lh_plain_type(ptr))) +#define lh_CONF_VALUE_error(lh) OPENSSL_LH_error(ossl_check_CONF_VALUE_lh_type(lh)) +#define lh_CONF_VALUE_num_items(lh) OPENSSL_LH_num_items(ossl_check_CONF_VALUE_lh_type(lh)) +#define lh_CONF_VALUE_node_stats_bio(lh, out) OPENSSL_LH_node_stats_bio(ossl_check_const_CONF_VALUE_lh_type(lh), out) +#define lh_CONF_VALUE_node_usage_stats_bio(lh, out) OPENSSL_LH_node_usage_stats_bio(ossl_check_const_CONF_VALUE_lh_type(lh), out) +#define lh_CONF_VALUE_stats_bio(lh, out) OPENSSL_LH_stats_bio(ossl_check_const_CONF_VALUE_lh_type(lh), out) +#define lh_CONF_VALUE_get_down_load(lh) OPENSSL_LH_get_down_load(ossl_check_CONF_VALUE_lh_type(lh)) +#define lh_CONF_VALUE_set_down_load(lh, dl) OPENSSL_LH_set_down_load(ossl_check_CONF_VALUE_lh_type(lh), dl) +#define lh_CONF_VALUE_doall(lh, dfn) OPENSSL_LH_doall(ossl_check_CONF_VALUE_lh_type(lh), ossl_check_CONF_VALUE_lh_doallfunc_type(dfn)) -DEFINE_LHASH_OF(CONF_VALUE); struct conf_st; struct conf_method_st; @@ -112,10 +155,10 @@ struct conf_st { void *meth_data; LHASH_OF(CONF_VALUE) *data; unsigned int flag_dollarid:1; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; }; -CONF *NCONF_new_with_libctx(OPENSSL_CTX *libctx, CONF_METHOD *meth); +CONF *NCONF_new_ex(OSSL_LIB_CTX *libctx, CONF_METHOD *meth); CONF *NCONF_new(CONF_METHOD *meth); CONF_METHOD *NCONF_default(void); DEPRECATEDIN_3_0(CONF_METHOD *NCONF_WIN32(void)) @@ -143,8 +186,8 @@ int NCONF_dump_bio(const CONF *conf, BIO *out); int CONF_modules_load(const CONF *cnf, const char *appname, unsigned long flags); -int CONF_modules_load_file_with_libctx(OPENSSL_CTX *libctx, const char *filename, - const char *appname, unsigned long flags); +int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename, + const char *appname, unsigned long flags); int CONF_modules_load_file(const char *filename, const char *appname, unsigned long flags); void CONF_modules_unload(int all); diff --git a/include/openssl/conf.h.in b/include/openssl/conf.h.in new file mode 100644 index 0000000000..c57c50a77f --- /dev/null +++ b/include/openssl/conf.h.in @@ -0,0 +1,187 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros generate_lhash_macros); +-} + +#ifndef OPENSSL_CONF_H +# define OPENSSL_CONF_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_CONF_H +# endif + +# include +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +{- + generate_stack_macros("CONF_VALUE") + .generate_lhash_macros("CONF_VALUE"); +-} + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +STACK_OF(CONF_MODULE); +STACK_OF(CONF_IMODULE); + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_STDIO +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +#ifndef OPENSSL_NO_STDIO +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +#endif +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name)) + +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define OPENSSL_no_config() \ + OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL) +#endif + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; + unsigned int flag_dollarid:1; + OSSL_LIB_CTX *libctx; +}; + +CONF *NCONF_new_ex(OSSL_LIB_CTX *libctx, CONF_METHOD *meth); +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +DEPRECATEDIN_3_0(CONF_METHOD *NCONF_WIN32(void)) +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_STDIO +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +#ifndef OPENSSL_NO_STDIO +int NCONF_dump_fp(const CONF *conf, FILE *out); +#endif +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file_ex(OSSL_LIB_CTX *libctx, const char *filename, + const char *appname, unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define CONF_modules_free() while(0) continue +#endif +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/conferr.h b/include/openssl/conferr.h index 1afa12bd56..80bf53f365 100644 --- a/include/openssl/conferr.h +++ b/include/openssl/conferr.h @@ -68,6 +68,7 @@ int ERR_load_CONF_strings(void); # define CONF_R_NO_SUCH_FILE 114 # define CONF_R_NO_VALUE 108 # define CONF_R_NUMBER_TOO_LARGE 121 +# define CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION 124 # define CONF_R_RECURSIVE_DIRECTORY_INCLUDE 111 # define CONF_R_SSL_COMMAND_SECTION_EMPTY 117 # define CONF_R_SSL_COMMAND_SECTION_NOT_FOUND 118 diff --git a/include/openssl/core.h b/include/openssl/core.h index e77c2ba22f..80ba32d9bf 100644 --- a/include/openssl/core.h +++ b/include/openssl/core.h @@ -107,18 +107,18 @@ struct ossl_param_st { # define OSSL_PARAM_REAL 3 /*- * OSSL_PARAM_UTF8_STRING - * is a printable string. Is expteced to be printed as it is. + * is a printable string. It is expected to be printed as it is. */ # define OSSL_PARAM_UTF8_STRING 4 /*- * OSSL_PARAM_OCTET_STRING - * is a string of bytes with no further specification. Is expected to be + * is a string of bytes with no further specification. It is expected to be * printed as a hexdump. */ # define OSSL_PARAM_OCTET_STRING 5 /*- * OSSL_PARAM_UTF8_PTR - * is a pointer to a printable string. Is expteced to be printed as it is. + * is a pointer to a printable string. It is expected to be printed as it is. * * The difference between this and OSSL_PARAM_UTF8_STRING is that only pointers * are manipulated for this type. diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index c3f6c88f46..249d5e2506 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -66,8 +66,8 @@ OSSL_CORE_MAKE_FUNC(int,core_get_params,(const OSSL_CORE_HANDLE *prov, # define OSSL_FUNC_CORE_THREAD_START 3 OSSL_CORE_MAKE_FUNC(int,core_thread_start,(const OSSL_CORE_HANDLE *prov, OSSL_thread_stop_handler_fn handfn)) -# define OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT 4 -OSSL_CORE_MAKE_FUNC(OPENSSL_CORE_CTX *,core_get_library_context, +# define OSSL_FUNC_CORE_GET_LIBCTX 4 +OSSL_CORE_MAKE_FUNC(OPENSSL_CORE_CTX *,core_get_libctx, (const OSSL_CORE_HANDLE *prov)) # define OSSL_FUNC_CORE_NEW_ERROR 5 OSSL_CORE_MAKE_FUNC(void,core_new_error,(const OSSL_CORE_HANDLE *prov)) @@ -137,6 +137,7 @@ OSSL_CORE_MAKE_FUNC(void, #define OSSL_FUNC_BIO_VSNPRINTF 46 #define OSSL_FUNC_BIO_PUTS 47 #define OSSL_FUNC_BIO_GETS 48 +#define OSSL_FUNC_BIO_CTRL 49 OSSL_CORE_MAKE_FUNC(OSSL_CORE_BIO *, BIO_new_file, (const char *filename, @@ -153,6 +154,8 @@ OSSL_CORE_MAKE_FUNC(int, BIO_vprintf, (OSSL_CORE_BIO *bio, const char *format, va_list args)) OSSL_CORE_MAKE_FUNC(int, BIO_vsnprintf, (char *buf, size_t n, const char *fmt, va_list args)) +OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio, + int cmd, long num, void *ptr)) #define OSSL_FUNC_SELF_TEST_CB 100 OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, @@ -176,6 +179,8 @@ OSSL_CORE_MAKE_FUNC(const OSSL_ITEM *,provider_get_reason_strings, # define OSSL_FUNC_PROVIDER_GET_CAPABILITIES 1029 OSSL_CORE_MAKE_FUNC(int, provider_get_capabilities, (void *provctx, const char *capability, OSSL_CALLBACK *cb, void *arg)) +# define OSSL_FUNC_PROVIDER_SELF_TEST 1030 +OSSL_CORE_MAKE_FUNC(int, provider_self_test, (void *provctx)) /* Operations */ @@ -188,11 +193,13 @@ OSSL_CORE_MAKE_FUNC(int, provider_get_capabilities, (void *provctx, # define OSSL_OP_KEYEXCH 11 # define OSSL_OP_SIGNATURE 12 # define OSSL_OP_ASYM_CIPHER 13 +# define OSSL_OP_KEM 14 /* New section for non-EVP operations */ -# define OSSL_OP_SERIALIZER 20 -# define OSSL_OP_DESERIALIZER 21 +# define OSSL_OP_ENCODER 20 +# define OSSL_OP_DECODER 21 +# define OSSL_OP_STORE 22 /* Highest known operation number */ -# define OSSL_OP__HIGHEST 21 +# define OSSL_OP__HIGHEST 22 /* Digests */ @@ -229,9 +236,12 @@ OSSL_CORE_MAKE_FUNC(int, digest_set_ctx_params, (void *vctx, const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, digest_get_ctx_params, (void *vctx, OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, digest_gettable_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, digest_settable_ctx_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, digest_gettable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, digest_gettable_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, digest_settable_ctx_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, digest_gettable_ctx_params, + (void *provctx)) /* Symmetric Ciphers */ @@ -279,9 +289,12 @@ OSSL_CORE_MAKE_FUNC(int, cipher_get_ctx_params, (void *cctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, cipher_set_ctx_params, (void *cctx, const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, cipher_gettable_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, cipher_settable_ctx_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, cipher_gettable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, cipher_gettable_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, cipher_settable_ctx_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, cipher_gettable_ctx_params, + (void *provctx)) /* MACs */ @@ -308,9 +321,11 @@ OSSL_CORE_MAKE_FUNC(int, mac_update, OSSL_CORE_MAKE_FUNC(int, mac_final, (void *mctx, unsigned char *out, size_t *outl, size_t outsize)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, mac_gettable_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, mac_gettable_ctx_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, mac_settable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, mac_gettable_params, (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, mac_gettable_ctx_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, mac_settable_ctx_params, + (void *provctx)) OSSL_CORE_MAKE_FUNC(int, mac_get_params, (OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, mac_get_ctx_params, (void *mctx, OSSL_PARAM params[])) @@ -337,9 +352,11 @@ OSSL_CORE_MAKE_FUNC(void, kdf_freectx, (void *kctx)) OSSL_CORE_MAKE_FUNC(void, kdf_reset, (void *kctx)) OSSL_CORE_MAKE_FUNC(int, kdf_derive, (void *kctx, unsigned char *key, size_t keylen)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kdf_gettable_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kdf_gettable_ctx_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kdf_settable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kdf_gettable_params, (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kdf_gettable_ctx_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kdf_settable_ctx_params, + (void *provctx)) OSSL_CORE_MAKE_FUNC(int, kdf_get_params, (OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int, kdf_get_ctx_params, (void *kctx, OSSL_PARAM params[])) @@ -364,8 +381,7 @@ OSSL_CORE_MAKE_FUNC(int, kdf_set_ctx_params, # define OSSL_FUNC_RAND_GET_PARAMS 14 # define OSSL_FUNC_RAND_GET_CTX_PARAMS 15 # define OSSL_FUNC_RAND_SET_CTX_PARAMS 16 -# define OSSL_FUNC_RAND_SET_CALLBACKS 17 -# define OSSL_FUNC_RAND_VERIFY_ZEROIZATION 18 +# define OSSL_FUNC_RAND_VERIFY_ZEROIZATION 17 OSSL_CORE_MAKE_FUNC(void *,rand_newctx, (void *provctx, void *parent, @@ -390,9 +406,11 @@ OSSL_CORE_MAKE_FUNC(size_t,rand_nonce, OSSL_CORE_MAKE_FUNC(int,rand_enable_locking, (void *vctx)) OSSL_CORE_MAKE_FUNC(int,rand_lock, (void *vctx)) OSSL_CORE_MAKE_FUNC(void,rand_unlock, (void *vctx)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,rand_gettable_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,rand_gettable_ctx_params, (void)) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,rand_settable_ctx_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,rand_gettable_params, (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,rand_gettable_ctx_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *,rand_settable_ctx_params, + (void *provctx)) OSSL_CORE_MAKE_FUNC(int,rand_get_params, (OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(int,rand_get_ctx_params, (void *vctx, OSSL_PARAM params[])) @@ -497,13 +515,13 @@ OSSL_CORE_MAKE_FUNC(void, keymgmt_free, (void *keydata)) #define OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS 12 OSSL_CORE_MAKE_FUNC(int, keymgmt_get_params, (void *keydata, OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_gettable_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_gettable_params, (void *)) #define OSSL_FUNC_KEYMGMT_SET_PARAMS 13 #define OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS 14 OSSL_CORE_MAKE_FUNC(int, keymgmt_set_params, (void *keydata, const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_settable_params, (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_settable_params, (void *)) /* Key checks - discovery of supported operations */ # define OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME 20 @@ -568,11 +586,11 @@ OSSL_CORE_MAKE_FUNC(void *, keyexch_dupctx, (void *ctx)) OSSL_CORE_MAKE_FUNC(int, keyexch_set_ctx_params, (void *ctx, const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keyexch_settable_ctx_params, - (void)) + (void *provctx)) OSSL_CORE_MAKE_FUNC(int, keyexch_get_ctx_params, (void *ctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keyexch_gettable_ctx_params, - (void)) + (void *provctx)) /* Signature */ @@ -647,11 +665,11 @@ OSSL_CORE_MAKE_FUNC(void *, signature_dupctx, (void *ctx)) OSSL_CORE_MAKE_FUNC(int, signature_get_ctx_params, (void *ctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, signature_gettable_ctx_params, - (void)) + (void *provctx)) OSSL_CORE_MAKE_FUNC(int, signature_set_ctx_params, (void *ctx, const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, signature_settable_ctx_params, - (void)) + (void *provctx)) OSSL_CORE_MAKE_FUNC(int, signature_get_ctx_md_params, (void *ctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, signature_gettable_ctx_md_params, @@ -694,58 +712,139 @@ OSSL_CORE_MAKE_FUNC(void *, asym_cipher_dupctx, (void *ctx)) OSSL_CORE_MAKE_FUNC(int, asym_cipher_get_ctx_params, (void *ctx, OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, asym_cipher_gettable_ctx_params, - (void)) + (void *provctx)) OSSL_CORE_MAKE_FUNC(int, asym_cipher_set_ctx_params, (void *ctx, const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, asym_cipher_settable_ctx_params, - (void)) - -/* Serializers and deserializers */ -# define OSSL_FUNC_SERIALIZER_NEWCTX 1 -# define OSSL_FUNC_SERIALIZER_FREECTX 2 -# define OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS 3 -# define OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS 4 -# define OSSL_FUNC_SERIALIZER_SERIALIZE_DATA 10 -# define OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT 11 -OSSL_CORE_MAKE_FUNC(void *, serializer_newctx, (void *provctx)) -OSSL_CORE_MAKE_FUNC(void, serializer_freectx, (void *ctx)) -OSSL_CORE_MAKE_FUNC(int, serializer_set_ctx_params, + (void *provctx)) + +/* Asymmetric Key encapsulation */ +# define OSSL_FUNC_KEM_NEWCTX 1 +# define OSSL_FUNC_KEM_ENCAPSULATE_INIT 2 +# define OSSL_FUNC_KEM_ENCAPSULATE 3 +# define OSSL_FUNC_KEM_DECAPSULATE_INIT 4 +# define OSSL_FUNC_KEM_DECAPSULATE 5 +# define OSSL_FUNC_KEM_FREECTX 6 +# define OSSL_FUNC_KEM_DUPCTX 7 +# define OSSL_FUNC_KEM_GET_CTX_PARAMS 8 +# define OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS 9 +# define OSSL_FUNC_KEM_SET_CTX_PARAMS 10 +# define OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS 11 + +OSSL_CORE_MAKE_FUNC(void *, kem_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, kem_encapsulate_init, (void *ctx, void *provkey)) +OSSL_CORE_MAKE_FUNC(int, kem_encapsulate, (void *ctx, + unsigned char *out, size_t *outlen, + unsigned char *secret, + size_t *secretlen)) +OSSL_CORE_MAKE_FUNC(int, kem_decapsulate_init, (void *ctx, void *provkey)) +OSSL_CORE_MAKE_FUNC(int, kem_decapsulate, (void *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)) +OSSL_CORE_MAKE_FUNC(void, kem_freectx, (void *ctx)) +OSSL_CORE_MAKE_FUNC(void *, kem_dupctx, (void *ctx)) +OSSL_CORE_MAKE_FUNC(int, kem_get_ctx_params, (void *ctx, OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kem_gettable_ctx_params, (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, kem_set_ctx_params, + (void *ctx, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, kem_settable_ctx_params, (void *provctx)) + +/* Encoders and decoders */ +# define OSSL_FUNC_ENCODER_NEWCTX 1 +# define OSSL_FUNC_ENCODER_FREECTX 2 +# define OSSL_FUNC_ENCODER_GET_PARAMS 3 +# define OSSL_FUNC_ENCODER_GETTABLE_PARAMS 4 +# define OSSL_FUNC_ENCODER_SET_CTX_PARAMS 5 +# define OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS 6 +# define OSSL_FUNC_ENCODER_ENCODE 10 +# define OSSL_FUNC_ENCODER_IMPORT_OBJECT 20 +# define OSSL_FUNC_ENCODER_FREE_OBJECT 21 +OSSL_CORE_MAKE_FUNC(void *, encoder_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(void, encoder_freectx, (void *ctx)) +OSSL_CORE_MAKE_FUNC(int, encoder_get_params, (OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, encoder_gettable_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, encoder_set_ctx_params, (void *ctx, const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, serializer_settable_ctx_params, - (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, encoder_settable_ctx_params, + (void *provctx)) -OSSL_CORE_MAKE_FUNC(int, serializer_serialize_data, - (void *ctx, const OSSL_PARAM[], OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)) -OSSL_CORE_MAKE_FUNC(int, serializer_serialize_object, - (void *ctx, void *obj, OSSL_CORE_BIO *out, +/* + * TODO(3.0) investigate if this should be two functions, one that takes a + * raw object and one that takes an object abstraction. + */ +OSSL_CORE_MAKE_FUNC(int, encoder_encode, + (void *ctx, OSSL_CORE_BIO *out, + const void *obj_raw, const OSSL_PARAM obj_abstract[], + int selection, OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)) -# define OSSL_FUNC_DESERIALIZER_NEWCTX 1 -# define OSSL_FUNC_DESERIALIZER_FREECTX 2 -# define OSSL_FUNC_DESERIALIZER_GET_PARAMS 3 -# define OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS 4 -# define OSSL_FUNC_DESERIALIZER_SET_CTX_PARAMS 5 -# define OSSL_FUNC_DESERIALIZER_SETTABLE_CTX_PARAMS 6 -# define OSSL_FUNC_DESERIALIZER_DESERIALIZE 10 -# define OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT 11 -OSSL_CORE_MAKE_FUNC(void *, deserializer_newctx, (void *provctx)) -OSSL_CORE_MAKE_FUNC(void, deserializer_freectx, (void *ctx)) -OSSL_CORE_MAKE_FUNC(int, deserializer_get_params, (OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_gettable_params, (void)) -OSSL_CORE_MAKE_FUNC(int, deserializer_set_ctx_params, +OSSL_CORE_MAKE_FUNC(void *, encoder_import_object, + (void *ctx, int selection, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(void, encoder_free_object, (void *obj)) + +# define OSSL_FUNC_DECODER_NEWCTX 1 +# define OSSL_FUNC_DECODER_FREECTX 2 +# define OSSL_FUNC_DECODER_GET_PARAMS 3 +# define OSSL_FUNC_DECODER_GETTABLE_PARAMS 4 +# define OSSL_FUNC_DECODER_SET_CTX_PARAMS 5 +# define OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS 6 +# define OSSL_FUNC_DECODER_DECODE 10 +# define OSSL_FUNC_DECODER_EXPORT_OBJECT 11 +OSSL_CORE_MAKE_FUNC(void *, decoder_newctx, (void *provctx)) +OSSL_CORE_MAKE_FUNC(void, decoder_freectx, (void *ctx)) +OSSL_CORE_MAKE_FUNC(int, decoder_get_params, (OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, decoder_gettable_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, decoder_set_ctx_params, (void *ctx, const OSSL_PARAM params[])) -OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, deserializer_settable_ctx_params, - (void)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, decoder_settable_ctx_params, + (void *provctx)) -OSSL_CORE_MAKE_FUNC(int, deserializer_deserialize, +OSSL_CORE_MAKE_FUNC(int, decoder_decode, (void *ctx, OSSL_CORE_BIO *in, OSSL_CALLBACK *metadata_cb, void *metadata_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) -OSSL_CORE_MAKE_FUNC(int, deserializer_export_object, +OSSL_CORE_MAKE_FUNC(int, decoder_export_object, (void *ctx, const void *objref, size_t objref_sz, OSSL_CALLBACK *export_cb, void *export_cbarg)) +/*- + * Store + * + * Objects are scanned by using the 'open', 'load', 'eof' and 'close' + * functions, which implement an OSSL_STORE loader. + * + * store_load() works in a way that's very similar to the decoders, in + * that they pass an abstract object through a callback, either as a DER + * octet string or as an object reference, which libcrypto will have to + * deal with. + */ + +#define OSSL_FUNC_STORE_OPEN 1 +#define OSSL_FUNC_STORE_ATTACH 2 +#define OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS 3 +#define OSSL_FUNC_STORE_SET_CTX_PARAMS 4 +#define OSSL_FUNC_STORE_LOAD 5 +#define OSSL_FUNC_STORE_EOF 6 +#define OSSL_FUNC_STORE_CLOSE 7 +#define OSSL_FUNC_STORE_EXPORT_OBJECT 8 +OSSL_CORE_MAKE_FUNC(void *, store_open, (void *provctx, const char *uri)) +OSSL_CORE_MAKE_FUNC(void *, store_attach, (void *provctx, OSSL_CORE_BIO *in)) +OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, store_settable_ctx_params, + (void *provctx)) +OSSL_CORE_MAKE_FUNC(int, store_set_ctx_params, + (void *loaderctx, const OSSL_PARAM params[])) +OSSL_CORE_MAKE_FUNC(int, store_load, + (void *loaderctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)) +OSSL_CORE_MAKE_FUNC(int, store_eof, (void *loaderctx)) +OSSL_CORE_MAKE_FUNC(int, store_close, (void *loaderctx)) +OSSL_CORE_MAKE_FUNC(int, store_export_object, + (void *loaderctx, const void *objref, size_t objref_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg)) + # ifdef __cplusplus } # endif diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index 9ce4115a89..4a4bd36cbe 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -23,12 +23,31 @@ extern "C" { #define OSSL_PROV_PARAM_NAME "name" /* utf8_string */ #define OSSL_PROV_PARAM_VERSION "version" /* utf8_string */ #define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_string */ +#define OSSL_PROV_PARAM_STATUS "status" /* uint */ +#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */ /* Self test callback parameters */ #define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */ #define OSSL_PROV_PARAM_SELF_TEST_TYPE "st-type" /* utf8_string */ #define OSSL_PROV_PARAM_SELF_TEST_DESC "st-desc" /* utf8_string */ +/*- + * Provider-native object abstractions + * + * These are used when a provider wants to pass object data or an object + * reference back to libcrypto. This is only useful for provider functions + * that take a callback to which an OSSL_PARAM array with these parameters + * can be passed. + * + * This set of parameter names is explained in detail in provider-object(7) + * (doc/man7/provider-object.pod) + */ +#define OSSL_OBJECT_PARAM_TYPE "type" /* INTEGER */ +#define OSSL_OBJECT_PARAM_DATA_TYPE "data-type" /* UTF8_STRING */ +#define OSSL_OBJECT_PARAM_REFERENCE "reference" /* OCTET_STRING */ +#define OSSL_OBJECT_PARAM_DATA "data" /* OCTET_STRING or UTF8_STRING */ +#define OSSL_OBJECT_PARAM_DESC "desc" /* UTF8_STRING */ + /* * Algorithm parameters * If "engine" or "properties" are specified, they should always be paired @@ -38,6 +57,7 @@ extern "C" { */ #define OSSL_ALG_PARAM_DIGEST "digest" /* utf8_string */ #define OSSL_ALG_PARAM_CIPHER "cipher" /* utf8_string */ +#define OSSL_ALG_PARAM_ENGINE "engine" /* utf8_string */ #define OSSL_ALG_PARAM_MAC "mac" /* utf8_string */ #define OSSL_ALG_PARAM_PROPERTIES "properties"/* utf8_string */ @@ -52,6 +72,7 @@ extern "C" { #define OSSL_CIPHER_PARAM_KEYLEN "keylen" /* size_t */ #define OSSL_CIPHER_PARAM_IVLEN "ivlen" /* size_t */ #define OSSL_CIPHER_PARAM_IV "iv" /* octet_string OR octet_ptr */ +#define OSSL_CIPHER_PARAM_IV_STATE "iv-state" /* octet_string OR octet_ptr */ #define OSSL_CIPHER_PARAM_NUM "num" /* uint */ #define OSSL_CIPHER_PARAM_ROUNDS "rounds" /* uint */ #define OSSL_CIPHER_PARAM_AEAD_TAG "tag" /* octet_string */ @@ -121,6 +142,7 @@ extern "C" { #define OSSL_DIGEST_NAME_SHA3_512 "SHA3-512" #define OSSL_DIGEST_NAME_KECCAK_KMAC128 "KECCAK-KMAC-128" #define OSSL_DIGEST_NAME_KECCAK_KMAC256 "KECCAK-KMAC-256" +#define OSSL_DIGEST_NAME_SM3 "SM3" /* MAC parameters */ #define OSSL_MAC_PARAM_KEY "key" /* octet string */ @@ -133,10 +155,11 @@ extern "C" { * If "engine" or "properties" are specified, they should always be paired * with "cipher" or "digest". */ -#define OSSL_MAC_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ -#define OSSL_MAC_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */ -#define OSSL_MAC_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES /* utf8 string */ -#define OSSL_MAC_PARAM_SIZE "size" /* size_t */ +#define OSSL_MAC_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ +#define OSSL_MAC_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */ +#define OSSL_MAC_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES /* utf8 string */ +#define OSSL_MAC_PARAM_SIZE "size" /* size_t */ +#define OSSL_MAC_PARAM_TLS_DATA_SIZE "tls-data-size" /* size_t */ /* Known MAC names */ #define OSSL_MAC_NAME_BLAKE2BMAC "BLAKE2BMAC" @@ -176,6 +199,7 @@ extern "C" { #define OSSL_KDF_PARAM_SIZE "size" /* size_t */ #define OSSL_KDF_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ #define OSSL_KDF_PARAM_CONSTANT "constant" /* octet string */ +#define OSSL_KDF_PARAM_PKCS12_ID "id" /* int */ /* Known KDF names */ #define OSSL_KDF_NAME_HKDF "HKDF" @@ -205,7 +229,7 @@ extern "C" { #define OSSL_DRBG_PARAM_MAX_NONCELEN "max_noncelen" #define OSSL_DRBG_PARAM_MAX_PERSLEN "max_perslen" #define OSSL_DRBG_PARAM_MAX_ADINLEN "max_adinlen" -#define OSSL_DRBG_PARAM_RESEED_CTR "reseed_counter" +#define OSSL_DRBG_PARAM_RESEED_COUNTER "reseed_counter" #define OSSL_DRBG_PARAM_RESEED_TIME "reseed_time" #define OSSL_DRBG_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES #define OSSL_DRBG_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST @@ -227,6 +251,8 @@ extern "C" { #define OSSL_PKEY_PARAM_MAX_SIZE "max-size" /* integer */ #define OSSL_PKEY_PARAM_SECURITY_BITS "security-bits" /* integer */ #define OSSL_PKEY_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST +#define OSSL_PKEY_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ +#define OSSL_PKEY_PARAM_ENGINE OSSL_ALG_PARAM_ENGINE /* utf8 string */ #define OSSL_PKEY_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES #define OSSL_PKEY_PARAM_DEFAULT_DIGEST "default-digest" /* utf8 string */ #define OSSL_PKEY_PARAM_MANDATORY_DIGEST "mandatory-digest" /* utf8 string */ @@ -237,8 +263,7 @@ extern "C" { #define OSSL_PKEY_PARAM_MGF1_PROPERTIES "mgf1-properties" #define OSSL_PKEY_PARAM_TLS_ENCODED_PT "tls-encoded-pt" #define OSSL_PKEY_PARAM_GROUP_NAME "group" - -/* Diffie-Hellman/DSA public/private key */ +#define OSSL_PKEY_PARAM_DIST_ID "distid" #define OSSL_PKEY_PARAM_PUB_KEY "pub" #define OSSL_PKEY_PARAM_PRIV_KEY "priv" @@ -266,6 +291,22 @@ extern "C" { #define OSSL_PKEY_PARAM_EC_PUB_X "qx" #define OSSL_PKEY_PARAM_EC_PUB_Y "qy" +/* Elliptic Curve Explicit Domain Parameters */ +#define OSSL_PKEY_PARAM_EC_FIELD_TYPE "field-type" +#define OSSL_PKEY_PARAM_EC_P "p" +#define OSSL_PKEY_PARAM_EC_A "a" +#define OSSL_PKEY_PARAM_EC_B "b" +#define OSSL_PKEY_PARAM_EC_GENERATOR "generator" +#define OSSL_PKEY_PARAM_EC_ORDER "order" +#define OSSL_PKEY_PARAM_EC_COFACTOR "cofactor" +#define OSSL_PKEY_PARAM_EC_SEED "seed" +#define OSSL_PKEY_PARAM_EC_CHAR2_M "m" +#define OSSL_PKEY_PARAM_EC_CHAR2_TYPE "basis-type" +#define OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS "tp" +#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K1 "k1" +#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K2 "k2" +#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K3 "k3" + /* Elliptic Curve Key Parameters */ #define OSSL_PKEY_PARAM_USE_COFACTOR_FLAG "use-cofactor-flag" #define OSSL_PKEY_PARAM_USE_COFACTOR_ECDH \ @@ -338,6 +379,7 @@ extern "C" { #define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS #define OSSL_PKEY_PARAM_RSA_PRIMES "primes" #define OSSL_PKEY_PARAM_RSA_DIGEST OSSL_PKEY_PARAM_DIGEST +#define OSSL_PKEY_PARAM_RSA_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES #define OSSL_PKEY_PARAM_RSA_MASKGENFUNC OSSL_PKEY_PARAM_MASKGENFUNC #define OSSL_PKEY_PARAM_RSA_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST #define OSSL_PKEY_PARAM_RSA_PSS_SALTLEN "saltlen" @@ -349,6 +391,12 @@ extern "C" { #define OSSL_PKEY_PARAM_FFC_DIGEST OSSL_PKEY_PARAM_DIGEST #define OSSL_PKEY_PARAM_FFC_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES +#define OSSL_PKEY_PARAM_EC_ENCODING "encoding" /* utf8_string */ + +/* OSSL_PKEY_PARAM_EC_ENCODING values */ +#define OSSL_PKEY_EC_ENCODING_EXPLICIT "explicit" +#define OSSL_PKEY_EC_ENCODING_GROUP "named_curve" + /* Key Exchange parameters */ #define OSSL_EXCHANGE_PARAM_PAD "pad" /* uint */ #define OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE "ecdh-cofactor-mode" /* int */ @@ -384,6 +432,9 @@ extern "C" { #define OSSL_SIGNATURE_PARAM_DIGEST_SIZE OSSL_PKEY_PARAM_DIGEST_SIZE /* Asym cipher parameters */ +#define OSSL_ASYM_CIPHER_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST +#define OSSL_ASYM_CIPHER_PARAM_PROPERTIES OSSL_PKEY_PARAM_PROPERTIES +#define OSSL_ASYM_CIPHER_PARAM_ENGINE OSSL_PKEY_PARAM_ENGINE #define OSSL_ASYM_CIPHER_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE #define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST \ OSSL_PKEY_PARAM_MGF1_DIGEST @@ -397,23 +448,18 @@ extern "C" { #define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION "tls-negotiated-version" /* - * Serializer / deserializer parameters + * Encoder / decoder parameters */ -/* The passphrase may be passed as a utf8 string or an octet string */ -#define OSSL_SERIALIZER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER -#define OSSL_SERIALIZER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES -#define OSSL_SERIALIZER_PARAM_PASS "passphrase" - -#define OSSL_DESERIALIZER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER -#define OSSL_DESERIALIZER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES -#define OSSL_DESERIALIZER_PARAM_PASS "passphrase" -#define OSSL_DESERIALIZER_PARAM_INPUT_TYPE "input-type" -#define OSSL_DESERIALIZER_PARAM_DATA_TYPE "data-type" -#define OSSL_DESERIALIZER_PARAM_DATA "data" -#define OSSL_DESERIALIZER_PARAM_REFERENCE "reference" +#define OSSL_ENCODER_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER +#define OSSL_ENCODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +#define OSSL_ENCODER_PARAM_INPUT_TYPE "input-type" +#define OSSL_ENCODER_PARAM_OUTPUT_TYPE "output-type" + +#define OSSL_DECODER_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +#define OSSL_DECODER_PARAM_INPUT_TYPE "input-type" /* Passphrase callback parameters */ -#define OSSL_PASSPHRASE_PARAM_INFO "info" +#define OSSL_PASSPHRASE_PARAM_INFO "info" /* Keygen callback parameters, from provider to libcrypto */ #define OSSL_GEN_PARAM_POTENTIAL "potential" /* integer */ @@ -432,19 +478,54 @@ extern "C" { #define OSSL_PKEY_PARAM_RSA_TEST_Q2 "q2" #define OSSL_SIGNATURE_PARAM_KAT "kat" +/* KEM parameters */ +#define OSSL_KEM_PARAM_OPERATION "operation" + +/* OSSL_KEM_PARAM_OPERATION values */ +#define OSSL_KEM_PARAM_OPERATION_RSASVE "RSASVE" + /* Capabilities */ -/* TLS-GROUP Capbility */ +/* TLS-GROUP Capability */ #define OSSL_CAPABILITY_TLS_GROUP_NAME "tls-group-name" #define OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL "tls-group-name-internal" #define OSSL_CAPABILITY_TLS_GROUP_ID "tls-group-id" #define OSSL_CAPABILITY_TLS_GROUP_ALG "tls-group-alg" #define OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS "tls-group-sec-bits" +#define OSSL_CAPABILITY_TLS_GROUP_IS_KEM "tls-group-is-kem" #define OSSL_CAPABILITY_TLS_GROUP_MIN_TLS "tls-min-tls" #define OSSL_CAPABILITY_TLS_GROUP_MAX_TLS "tls-max-tls" #define OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS "tls-min-dtls" #define OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS "tls-max-dtls" +/*- + * storemgmt parameters + */ + +/* + * Used by storemgmt_ctx_set_params(): + * + * - OSSL_STORE_PARAM_EXPECT is an INTEGER, and the value is any of the + * OSSL_STORE_INFO numbers. This is used to set the expected type of + * object loaded. + * + * - OSSL_STORE_PARAM_SUBJECT, OSSL_STORE_PARAM_ISSUER, + * OSSL_STORE_PARAM_SERIAL, OSSL_STORE_PARAM_FINGERPRINT, + * OSSL_STORE_PARAM_DIGEST, OSSL_STORE_PARAM_ALIAS + * are used as search criteria. + * (OSSL_STORE_PARAM_DIGEST is used with OSSL_STORE_PARAM_FINGERPRINT) + */ +#define OSSL_STORE_PARAM_EXPECT "expect" /* INTEGER */ +#define OSSL_STORE_PARAM_SUBJECT "subject" /* DER blob => OCTET_STRING */ +#define OSSL_STORE_PARAM_ISSUER "name" /* DER blob => OCTET_STRING */ +#define OSSL_STORE_PARAM_SERIAL "serial" /* INTEGER */ +#define OSSL_STORE_PARAM_DIGEST "digest" /* UTF8_STRING */ +#define OSSL_STORE_PARAM_FINGERPRINT "fingerprint" /* OCTET_STRING */ +#define OSSL_STORE_PARAM_ALIAS "alias" /* UTF8_STRING */ + +/* You may want to pass properties for the provider implementation to use */ +#define OSSL_STORE_PARAM_PROPERTIES "properties" /* utf8_string */ + # ifdef __cplusplus } # endif diff --git a/include/openssl/core_object.h b/include/openssl/core_object.h new file mode 100644 index 0000000000..395279d7bc --- /dev/null +++ b/include/openssl/core_object.h @@ -0,0 +1,40 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_CORE_OBJECT_H +# define OPENSSL_CORE_OBJECT_H + +# ifdef __cplusplus +extern "C" { +# endif + +/*- + * Known object types + * + * These numbers are used as values for the OSSL_PARAM parameter + * OSSL_OBJECT_PARAM_TYPE. + * + * For most of these types, there's a corresponding libcrypto object type. + * The corresponding type is indicated with a comment after the number. + */ +# define OSSL_OBJECT_UNKNOWN 0 +# define OSSL_OBJECT_NAME 1 /* char * */ +# define OSSL_OBJECT_PKEY 2 /* EVP_PKEY * */ +# define OSSL_OBJECT_CERT 3 /* X509 * */ +# define OSSL_OBJECT_CRL 4 /* X509_CRL * */ + +/* + * The rest of the associated OSSL_PARAM elements is described in core_names.h + */ + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/include/openssl/crmf.h b/include/openssl/crmf.h index bf0e32d499..bdb30ce11a 100644 --- a/include/openssl/crmf.h +++ b/include/openssl/crmf.h @@ -1,4 +1,7 @@ /*- + * WARNING: do not edit! + * Generated by Makefile from include/openssl/crmf.h.in + * * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 @@ -11,6 +14,8 @@ * CRMF (RFC 4211) implementation by M. Peylo, M. Viljanen, and D. von Oheimb. */ + + #ifndef OPENSSL_CRMF_H # define OPENSSL_CRMF_H @@ -44,7 +49,32 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE) typedef struct ossl_crmf_msg_st OSSL_CRMF_MSG; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSG) DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_MSG) -DEFINE_OR_DECLARE_STACK_OF(OSSL_CRMF_MSG) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CRMF_MSG, OSSL_CRMF_MSG, OSSL_CRMF_MSG) +#define sk_OSSL_CRMF_MSG_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk)) +#define sk_OSSL_CRMF_MSG_value(sk, idx) ((OSSL_CRMF_MSG *)OPENSSL_sk_value(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk), (idx))) +#define sk_OSSL_CRMF_MSG_new(cmp) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_new(ossl_check_OSSL_CRMF_MSG_compfunc_type(cmp))) +#define sk_OSSL_CRMF_MSG_new_null() ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CRMF_MSG_new_reserve(cmp, n) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CRMF_MSG_compfunc_type(cmp), (n))) +#define sk_OSSL_CRMF_MSG_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CRMF_MSG_sk_type(sk), (n)) +#define sk_OSSL_CRMF_MSG_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CRMF_MSG_sk_type(sk)) +#define sk_OSSL_CRMF_MSG_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CRMF_MSG_sk_type(sk)) +#define sk_OSSL_CRMF_MSG_delete(sk, i) ((OSSL_CRMF_MSG *)OPENSSL_sk_delete(ossl_check_OSSL_CRMF_MSG_sk_type(sk), (i))) +#define sk_OSSL_CRMF_MSG_delete_ptr(sk, ptr) ((OSSL_CRMF_MSG *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr))) +#define sk_OSSL_CRMF_MSG_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr)) +#define sk_OSSL_CRMF_MSG_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr)) +#define sk_OSSL_CRMF_MSG_pop(sk) ((OSSL_CRMF_MSG *)OPENSSL_sk_pop(ossl_check_OSSL_CRMF_MSG_sk_type(sk))) +#define sk_OSSL_CRMF_MSG_shift(sk) ((OSSL_CRMF_MSG *)OPENSSL_sk_shift(ossl_check_OSSL_CRMF_MSG_sk_type(sk))) +#define sk_OSSL_CRMF_MSG_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CRMF_MSG_sk_type(sk),ossl_check_OSSL_CRMF_MSG_freefunc_type(freefunc)) +#define sk_OSSL_CRMF_MSG_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr), (idx)) +#define sk_OSSL_CRMF_MSG_set(sk, idx, ptr) ((OSSL_CRMF_MSG *)OPENSSL_sk_set(ossl_check_OSSL_CRMF_MSG_sk_type(sk), (idx), ossl_check_OSSL_CRMF_MSG_type(ptr))) +#define sk_OSSL_CRMF_MSG_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr)) +#define sk_OSSL_CRMF_MSG_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr)) +#define sk_OSSL_CRMF_MSG_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CRMF_MSG_sk_type(sk)) +#define sk_OSSL_CRMF_MSG_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk)) +#define sk_OSSL_CRMF_MSG_dup(sk) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk))) +#define sk_OSSL_CRMF_MSG_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_copyfunc_type(copyfunc), ossl_check_OSSL_CRMF_MSG_freefunc_type(freefunc))) +#define sk_OSSL_CRMF_MSG_set_cmp_func(sk, cmp) ((sk_OSSL_CRMF_MSG_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_compfunc_type(cmp))) + typedef struct ossl_crmf_attributetypeandvalue_st OSSL_CRMF_ATTRIBUTETYPEANDVALUE; typedef struct ossl_crmf_pbmparameter_st OSSL_CRMF_PBMPARAMETER; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER) @@ -53,7 +83,32 @@ typedef struct ossl_crmf_certrequest_st OSSL_CRMF_CERTREQUEST; typedef struct ossl_crmf_certid_st OSSL_CRMF_CERTID; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTID) DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) -DEFINE_OR_DECLARE_STACK_OF(OSSL_CRMF_CERTID) +SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CRMF_CERTID, OSSL_CRMF_CERTID, OSSL_CRMF_CERTID) +#define sk_OSSL_CRMF_CERTID_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk)) +#define sk_OSSL_CRMF_CERTID_value(sk, idx) ((OSSL_CRMF_CERTID *)OPENSSL_sk_value(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk), (idx))) +#define sk_OSSL_CRMF_CERTID_new(cmp) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_new(ossl_check_OSSL_CRMF_CERTID_compfunc_type(cmp))) +#define sk_OSSL_CRMF_CERTID_new_null() ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_new_null()) +#define sk_OSSL_CRMF_CERTID_new_reserve(cmp, n) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CRMF_CERTID_compfunc_type(cmp), (n))) +#define sk_OSSL_CRMF_CERTID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), (n)) +#define sk_OSSL_CRMF_CERTID_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CRMF_CERTID_sk_type(sk)) +#define sk_OSSL_CRMF_CERTID_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CRMF_CERTID_sk_type(sk)) +#define sk_OSSL_CRMF_CERTID_delete(sk, i) ((OSSL_CRMF_CERTID *)OPENSSL_sk_delete(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), (i))) +#define sk_OSSL_CRMF_CERTID_delete_ptr(sk, ptr) ((OSSL_CRMF_CERTID *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr))) +#define sk_OSSL_CRMF_CERTID_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr)) +#define sk_OSSL_CRMF_CERTID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr)) +#define sk_OSSL_CRMF_CERTID_pop(sk) ((OSSL_CRMF_CERTID *)OPENSSL_sk_pop(ossl_check_OSSL_CRMF_CERTID_sk_type(sk))) +#define sk_OSSL_CRMF_CERTID_shift(sk) ((OSSL_CRMF_CERTID *)OPENSSL_sk_shift(ossl_check_OSSL_CRMF_CERTID_sk_type(sk))) +#define sk_OSSL_CRMF_CERTID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CRMF_CERTID_sk_type(sk),ossl_check_OSSL_CRMF_CERTID_freefunc_type(freefunc)) +#define sk_OSSL_CRMF_CERTID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr), (idx)) +#define sk_OSSL_CRMF_CERTID_set(sk, idx, ptr) ((OSSL_CRMF_CERTID *)OPENSSL_sk_set(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), (idx), ossl_check_OSSL_CRMF_CERTID_type(ptr))) +#define sk_OSSL_CRMF_CERTID_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr)) +#define sk_OSSL_CRMF_CERTID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr)) +#define sk_OSSL_CRMF_CERTID_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CRMF_CERTID_sk_type(sk)) +#define sk_OSSL_CRMF_CERTID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk)) +#define sk_OSSL_CRMF_CERTID_dup(sk) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk))) +#define sk_OSSL_CRMF_CERTID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_copyfunc_type(copyfunc), ossl_check_OSSL_CRMF_CERTID_freefunc_type(freefunc))) +#define sk_OSSL_CRMF_CERTID_set_cmp_func(sk, cmp) ((sk_OSSL_CRMF_CERTID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_compfunc_type(cmp))) + typedef struct ossl_crmf_pkipublicationinfo_st OSSL_CRMF_PKIPUBLICATIONINFO; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PKIPUBLICATIONINFO) @@ -67,9 +122,11 @@ DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSGS) typedef struct ossl_crmf_optionalvalidity_st OSSL_CRMF_OPTIONALVALIDITY; /* crmf_pbm.c */ -OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(size_t slen, int owfnid, - int itercnt, int macnid); -int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, +OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen, + int owfnid, size_t itercnt, + int macnid); +int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_CRMF_PBMPARAMETER *pbmp, const unsigned char *msg, size_t msglen, const unsigned char *sec, size_t seclen, unsigned char **mac, size_t *maclen); @@ -118,10 +175,12 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext); # define OSSL_CRMF_POPO_SIGNATURE 1 # define OSSL_CRMF_POPO_KEYENC 2 # define OSSL_CRMF_POPO_KEYAGREE 3 -int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey, - int dgst, int ppmtd); +int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm, + EVP_PKEY *pkey, const EVP_MD *digest, + OSSL_LIB_CTX *libctx, const char *propq); int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, - int rid, int acceptRAVerified); + int rid, int acceptRAVerified, + OSSL_LIB_CTX *libctx, const char *propq); OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm); ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl); @@ -137,6 +196,7 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, const ASN1_INTEGER *serial); X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert, + OSSL_LIB_CTX *libctx, const char *propq, EVP_PKEY *pkey); # ifdef __cplusplus diff --git a/include/openssl/crmf.h.in b/include/openssl/crmf.h.in new file mode 100644 index 0000000000..73d4a0f1f0 --- /dev/null +++ b/include/openssl/crmf.h.in @@ -0,0 +1,161 @@ +/*- + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright Nokia 2007-2019 + * Copyright Siemens AG 2015-2019 + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * CRMF (RFC 4211) implementation by M. Peylo, M. Viljanen, and D. von Oheimb. + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_CRMF_H +# define OPENSSL_CRMF_H + +# include + +# ifndef OPENSSL_NO_CRMF +# include +# include +# include +# include /* for GENERAL_NAME etc. */ + +/* explicit #includes not strictly needed since implied by the above: */ +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +# define OSSL_CRMF_POPOPRIVKEY_THISMESSAGE 0 +# define OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE 1 +# define OSSL_CRMF_POPOPRIVKEY_DHMAC 2 +# define OSSL_CRMF_POPOPRIVKEY_AGREEMAC 3 +# define OSSL_CRMF_POPOPRIVKEY_ENCRYPTEDKEY 4 + +# define OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT 0 +# define OSSL_CRMF_SUBSEQUENTMESSAGE_CHALLENGERESP 1 + +typedef struct ossl_crmf_encryptedvalue_st OSSL_CRMF_ENCRYPTEDVALUE; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE) +typedef struct ossl_crmf_msg_st OSSL_CRMF_MSG; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSG) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_MSG) +{- + generate_stack_macros("OSSL_CRMF_MSG"); +-} +typedef struct ossl_crmf_attributetypeandvalue_st OSSL_CRMF_ATTRIBUTETYPEANDVALUE; +typedef struct ossl_crmf_pbmparameter_st OSSL_CRMF_PBMPARAMETER; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER) +typedef struct ossl_crmf_poposigningkey_st OSSL_CRMF_POPOSIGNINGKEY; +typedef struct ossl_crmf_certrequest_st OSSL_CRMF_CERTREQUEST; +typedef struct ossl_crmf_certid_st OSSL_CRMF_CERTID; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTID) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) +{- + generate_stack_macros("OSSL_CRMF_CERTID"); +-} + +typedef struct ossl_crmf_pkipublicationinfo_st OSSL_CRMF_PKIPUBLICATIONINFO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PKIPUBLICATIONINFO) +typedef struct ossl_crmf_singlepubinfo_st OSSL_CRMF_SINGLEPUBINFO; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_SINGLEPUBINFO) +typedef struct ossl_crmf_certtemplate_st OSSL_CRMF_CERTTEMPLATE; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE) +typedef STACK_OF(OSSL_CRMF_MSG) OSSL_CRMF_MSGS; +DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSGS) + +typedef struct ossl_crmf_optionalvalidity_st OSSL_CRMF_OPTIONALVALIDITY; + +/* crmf_pbm.c */ +OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen, + int owfnid, size_t itercnt, + int macnid); +int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_CRMF_PBMPARAMETER *pbmp, + const unsigned char *msg, size_t msglen, + const unsigned char *sec, size_t seclen, + unsigned char **mac, size_t *maclen); + +/* crmf_lib.c */ +int OSSL_CRMF_MSG_set1_regCtrl_regToken(OSSL_CRMF_MSG *msg, + const ASN1_UTF8STRING *tok); +int OSSL_CRMF_MSG_set1_regCtrl_authenticator(OSSL_CRMF_MSG *msg, + const ASN1_UTF8STRING *auth); +int +OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(OSSL_CRMF_PKIPUBLICATIONINFO *pi, + OSSL_CRMF_SINGLEPUBINFO *spi); +# define OSSL_CRMF_PUB_METHOD_DONTCARE 0 +# define OSSL_CRMF_PUB_METHOD_X500 1 +# define OSSL_CRMF_PUB_METHOD_WEB 2 +# define OSSL_CRMF_PUB_METHOD_LDAP 3 +int OSSL_CRMF_MSG_set0_SinglePubInfo(OSSL_CRMF_SINGLEPUBINFO *spi, + int method, GENERAL_NAME *nm); +# define OSSL_CRMF_PUB_ACTION_DONTPUBLISH 0 +# define OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH 1 +int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(OSSL_CRMF_PKIPUBLICATIONINFO *pi, + int action); +int OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo(OSSL_CRMF_MSG *msg, + const OSSL_CRMF_PKIPUBLICATIONINFO *pi); +int OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey(OSSL_CRMF_MSG *msg, + const X509_PUBKEY *pubkey); +int OSSL_CRMF_MSG_set1_regCtrl_oldCertID(OSSL_CRMF_MSG *msg, + const OSSL_CRMF_CERTID *cid); +OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer, + const ASN1_INTEGER *serial); + +int OSSL_CRMF_MSG_set1_regInfo_utf8Pairs(OSSL_CRMF_MSG *msg, + const ASN1_UTF8STRING *utf8pairs); +int OSSL_CRMF_MSG_set1_regInfo_certReq(OSSL_CRMF_MSG *msg, + const OSSL_CRMF_CERTREQUEST *cr); + +int OSSL_CRMF_MSG_set0_validity(OSSL_CRMF_MSG *crm, + ASN1_TIME *notBefore, ASN1_TIME *notAfter); +int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid); +int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm); +int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, X509_EXTENSIONS *exts); + +int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext); +# define OSSL_CRMF_POPO_NONE -1 +# define OSSL_CRMF_POPO_RAVERIFIED 0 +# define OSSL_CRMF_POPO_SIGNATURE 1 +# define OSSL_CRMF_POPO_KEYENC 2 +# define OSSL_CRMF_POPO_KEYAGREE 3 +int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm, + EVP_PKEY *pkey, const EVP_MD *digest, + OSSL_LIB_CTX *libctx, const char *propq); +int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, + int rid, int acceptRAVerified, + OSSL_LIB_CTX *libctx, const char *propq); +OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm); +ASN1_INTEGER +*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl); +const X509_NAME +*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl); +const X509_NAME +*OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid); +ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid); +int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl, + EVP_PKEY *pubkey, + const X509_NAME *subject, + const X509_NAME *issuer, + const ASN1_INTEGER *serial); +X509 +*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert, + OSSL_LIB_CTX *libctx, const char *propq, + EVP_PKEY *pkey); + +# ifdef __cplusplus +} +# endif +# endif /* !defined(OPENSSL_NO_CRMF) */ +#endif /* !defined(OPENSSL_CRMF_H) */ diff --git a/include/openssl/crmferr.h b/include/openssl/crmferr.h index 17e5c85cc2..a4c194e094 100644 --- a/include/openssl/crmferr.h +++ b/include/openssl/crmferr.h @@ -10,6 +10,7 @@ #ifndef OPENSSL_CRMFERR_H # define OPENSSL_CRMFERR_H +# pragma once # include # include @@ -62,6 +63,7 @@ int ERR_load_CRMF_strings(void); # define CRMF_R_ITERATIONCOUNT_BELOW_100 108 # define CRMF_R_MALFORMED_IV 101 # define CRMF_R_NULL_ARGUMENT 109 +# define CRMF_R_POPOSKINPUT_NOT_SUPPORTED 113 # define CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY 117 # define CRMF_R_POPO_MISSING 121 # define CRMF_R_POPO_MISSING_PUBLIC_KEY 118 @@ -70,7 +72,6 @@ int ERR_load_CRMF_strings(void); # define CRMF_R_SETTING_MAC_ALGOR_FAILURE 110 # define CRMF_R_SETTING_OWF_ALGOR_FAILURE 111 # define CRMF_R_UNSUPPORTED_ALGORITHM 112 -# define CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY 113 # define CRMF_R_UNSUPPORTED_CIPHER 114 # define CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO 115 # define CRMF_R_UNSUPPORTED_POPO_METHOD 116 diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index abd3a68cd4..3283c73f30 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/crypto.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * @@ -8,6 +11,9 @@ * https://www.openssl.org/source/license.html */ + + + #ifndef OPENSSL_CRYPTO_H # define OPENSSL_CRYPTO_H # pragma once @@ -166,11 +172,37 @@ const char *OPENSSL_info(int type); int OPENSSL_issetugid(void); struct crypto_ex_data_st { - OPENSSL_CTX *ctx; + OSSL_LIB_CTX *ctx; STACK_OF(void) *sk; }; -DEFINE_OR_DECLARE_STACK_OF(void) +SKM_DEFINE_STACK_OF_INTERNAL(void, void, void) +#define sk_void_num(sk) OPENSSL_sk_num(ossl_check_const_void_sk_type(sk)) +#define sk_void_value(sk, idx) ((void *)OPENSSL_sk_value(ossl_check_const_void_sk_type(sk), (idx))) +#define sk_void_new(cmp) ((STACK_OF(void) *)OPENSSL_sk_new(ossl_check_void_compfunc_type(cmp))) +#define sk_void_new_null() ((STACK_OF(void) *)OPENSSL_sk_new_null()) +#define sk_void_new_reserve(cmp, n) ((STACK_OF(void) *)OPENSSL_sk_new_reserve(ossl_check_void_compfunc_type(cmp), (n))) +#define sk_void_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_void_sk_type(sk), (n)) +#define sk_void_free(sk) OPENSSL_sk_free(ossl_check_void_sk_type(sk)) +#define sk_void_zero(sk) OPENSSL_sk_zero(ossl_check_void_sk_type(sk)) +#define sk_void_delete(sk, i) ((void *)OPENSSL_sk_delete(ossl_check_void_sk_type(sk), (i))) +#define sk_void_delete_ptr(sk, ptr) ((void *)OPENSSL_sk_delete_ptr(ossl_check_void_sk_type(sk), ossl_check_void_type(ptr))) +#define sk_void_push(sk, ptr) OPENSSL_sk_push(ossl_check_void_sk_type(sk), ossl_check_void_type(ptr)) +#define sk_void_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_void_sk_type(sk), ossl_check_void_type(ptr)) +#define sk_void_pop(sk) ((void *)OPENSSL_sk_pop(ossl_check_void_sk_type(sk))) +#define sk_void_shift(sk) ((void *)OPENSSL_sk_shift(ossl_check_void_sk_type(sk))) +#define sk_void_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_void_sk_type(sk),ossl_check_void_freefunc_type(freefunc)) +#define sk_void_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_void_sk_type(sk), ossl_check_void_type(ptr), (idx)) +#define sk_void_set(sk, idx, ptr) ((void *)OPENSSL_sk_set(ossl_check_void_sk_type(sk), (idx), ossl_check_void_type(ptr))) +#define sk_void_find(sk, ptr) OPENSSL_sk_find(ossl_check_void_sk_type(sk), ossl_check_void_type(ptr)) +#define sk_void_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_void_sk_type(sk), ossl_check_void_type(ptr)) +#define sk_void_sort(sk) OPENSSL_sk_sort(ossl_check_void_sk_type(sk)) +#define sk_void_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_void_sk_type(sk)) +#define sk_void_dup(sk) ((STACK_OF(void) *)OPENSSL_sk_dup(ossl_check_const_void_sk_type(sk))) +#define sk_void_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(void) *)OPENSSL_sk_deep_copy(ossl_check_const_void_sk_type(sk), ossl_check_void_copyfunc_type(copyfunc), ossl_check_void_freefunc_type(freefunc))) +#define sk_void_set_cmp_func(sk, cmp) ((sk_void_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_void_sk_type(sk), ossl_check_void_compfunc_type(cmp))) + + /* * Per class, we have a STACK of function pointers. @@ -192,7 +224,7 @@ DEFINE_OR_DECLARE_STACK_OF(void) # define CRYPTO_EX_INDEX_UI_METHOD 14 # define CRYPTO_EX_INDEX_RAND_DRBG 15 # define CRYPTO_EX_INDEX_DRBG CRYPTO_EX_INDEX_RAND_DRBG -# define CRYPTO_EX_INDEX_OPENSSL_CTX 16 +# define CRYPTO_EX_INDEX_OSSL_LIB_CTX 16 # define CRYPTO_EX_INDEX_EVP_PKEY 17 # define CRYPTO_EX_INDEX__COUNT 18 @@ -439,7 +471,7 @@ void OPENSSL_cleanup(void); int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); int OPENSSL_atexit(void (*handler)(void)); void OPENSSL_thread_stop(void); -void OPENSSL_thread_stop_ex(OPENSSL_CTX *ctx); +void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx); /* Low-level control of initialization */ OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void); @@ -464,7 +496,13 @@ typedef LONG CRYPTO_ONCE; # define CRYPTO_ONCE_STATIC_INIT 0 # endif # else -# include +# if defined(__TANDEM) && defined(_SPT_MODEL_) +# define SPT_THREAD_SIGNAL 1 +# define SPT_THREAD_AWARE 1 +# include +# else +# include +# endif typedef pthread_once_t CRYPTO_ONCE; typedef pthread_key_t CRYPTO_THREAD_LOCAL; typedef pthread_t CRYPTO_THREAD_ID; @@ -490,10 +528,10 @@ int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); -OPENSSL_CTX *OPENSSL_CTX_new(void); -int OPENSSL_CTX_load_config(OPENSSL_CTX *ctx, const char *config_file); -void OPENSSL_CTX_free(OPENSSL_CTX *); -OPENSSL_CTX *OPENSSL_CTX_set0_default(OPENSSL_CTX *libctx); +OSSL_LIB_CTX *OSSL_LIB_CTX_new(void); +int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file); +void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); +OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx); # ifdef __cplusplus } diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in new file mode 100644 index 0000000000..b84712f227 --- /dev/null +++ b/include/openssl/crypto.h.in @@ -0,0 +1,517 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + + +#ifndef OPENSSL_CRYPTO_H +# define OPENSSL_CRYPTO_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_CRYPTO_H +# endif + +# include +# include + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif + +# include +# include +# include +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define SSLeay OpenSSL_version_num +# define SSLeay_version OpenSSL_version +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION OPENSSL_VERSION +# define SSLEAY_CFLAGS OPENSSL_CFLAGS +# define SSLEAY_BUILT_ON OPENSSL_BUILT_ON +# define SSLEAY_PLATFORM OPENSSL_PLATFORM +# define SSLEAY_DIR OPENSSL_DIR + +/* + * Old type for allocating dynamic locks. No longer used. Use the new thread + * API instead. + */ +typedef struct { + int dummy; +} CRYPTO_dynlock; + +# endif /* OPENSSL_NO_DEPRECATED_1_1_0 */ + +typedef void CRYPTO_RWLOCK; + +CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); +int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); +int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock); +void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock); + +int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock); + +/* No longer needed, so this is a no-op */ +#define OPENSSL_malloc_init() while(0) continue + +# define OPENSSL_malloc(num) \ + CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_zalloc(num) \ + CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_realloc(addr, num) \ + CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_realloc(addr, old_num, num) \ + CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_clear_free(addr, num) \ + CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_free(addr) \ + CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_memdup(str, s) \ + CRYPTO_memdup((str), s, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strdup(str) \ + CRYPTO_strdup(str, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_strndup(str, n) \ + CRYPTO_strndup(str, n, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_malloc(num) \ + CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_zalloc(num) \ + CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_free(addr) \ + CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_clear_free(addr, num) \ + CRYPTO_secure_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_secure_actual_size(ptr) \ + CRYPTO_secure_actual_size(ptr) + +size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz); +size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz); +size_t OPENSSL_strnlen(const char *str, size_t maxlen); +int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, + const unsigned char *buf, size_t buflen); +char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen); +int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, + const char *str); +unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen); +int OPENSSL_hexchar2int(unsigned char c); + +# define OPENSSL_MALLOC_MAX_NELEMS(type) (((1U<<(sizeof(int)*8-1))-1)/sizeof(type)) + +/* + * These functions return the values of OPENSSL_VERSION_MAJOR, + * OPENSSL_VERSION_MINOR, OPENSSL_VERSION_PATCH, OPENSSL_VERSION_PRE_RELEASE + * and OPENSSL_VERSION_BUILD_METADATA, respectively. + */ +unsigned int OPENSSL_version_major(void); +unsigned int OPENSSL_version_minor(void); +unsigned int OPENSSL_version_patch(void); +const char *OPENSSL_version_pre_release(void); +const char *OPENSSL_version_build_metadata(void); + +unsigned long OpenSSL_version_num(void); +const char *OpenSSL_version(int type); +# define OPENSSL_VERSION 0 +# define OPENSSL_CFLAGS 1 +# define OPENSSL_BUILT_ON 2 +# define OPENSSL_PLATFORM 3 +# define OPENSSL_DIR 4 +# define OPENSSL_ENGINES_DIR 5 +# define OPENSSL_VERSION_STRING 6 +# define OPENSSL_FULL_VERSION_STRING 7 +# define OPENSSL_MODULES_DIR 8 +# define OPENSSL_CPU_INFO 9 + +const char *OPENSSL_info(int type); +/* + * The series starts at 1001 to avoid confusion with the OpenSSL_version + * types. + */ +# define OPENSSL_INFO_CONFIG_DIR 1001 +# define OPENSSL_INFO_ENGINES_DIR 1002 +# define OPENSSL_INFO_MODULES_DIR 1003 +# define OPENSSL_INFO_DSO_EXTENSION 1004 +# define OPENSSL_INFO_DIR_FILENAME_SEPARATOR 1005 +# define OPENSSL_INFO_LIST_SEPARATOR 1006 +# define OPENSSL_INFO_SEED_SOURCE 1007 +# define OPENSSL_INFO_CPU_SETTINGS 1008 + +int OPENSSL_issetugid(void); + +struct crypto_ex_data_st { + OSSL_LIB_CTX *ctx; + STACK_OF(void) *sk; +}; + +{- + generate_stack_macros("void"); +-} + + +/* + * Per class, we have a STACK of function pointers. + */ +# define CRYPTO_EX_INDEX_SSL 0 +# define CRYPTO_EX_INDEX_SSL_CTX 1 +# define CRYPTO_EX_INDEX_SSL_SESSION 2 +# define CRYPTO_EX_INDEX_X509 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_DH 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_EC_KEY 8 +# define CRYPTO_EX_INDEX_RSA 9 +# define CRYPTO_EX_INDEX_ENGINE 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_BIO 12 +# define CRYPTO_EX_INDEX_APP 13 +# define CRYPTO_EX_INDEX_UI_METHOD 14 +# define CRYPTO_EX_INDEX_RAND_DRBG 15 +# define CRYPTO_EX_INDEX_DRBG CRYPTO_EX_INDEX_RAND_DRBG +# define CRYPTO_EX_INDEX_OSSL_LIB_CTX 16 +# define CRYPTO_EX_INDEX_EVP_PKEY 17 +# define CRYPTO_EX_INDEX__COUNT 18 + +typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void **from_d, int idx, long argl, void *argp); +__owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* No longer use an index. */ +int CRYPTO_free_ex_index(int class_index, int idx); + +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + const CRYPTO_EX_DATA *from); + +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); + +/* Allocate a single item in the CRYPTO_EX_DATA variable */ +int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad, + int idx); + +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +# define CRYPTO_cleanup_all_ex_data() while(0) continue + +/* + * The old locking functions have been removed completely without compatibility + * macros. This is because the old functions either could not properly report + * errors, or the returned error values were not clearly documented. + * Replacing the locking functions with no-ops would cause race condition + * issues in the affected applications. It is far better for them to fail at + * compile time. + * On the other hand, the locking callbacks are no longer used. Consequently, + * the callback management functions can be safely replaced with no-op macros. + */ +# define CRYPTO_num_locks() (1) +# define CRYPTO_set_locking_callback(func) +# define CRYPTO_get_locking_callback() (NULL) +# define CRYPTO_set_add_lock_callback(func) +# define CRYPTO_get_add_lock_callback() (NULL) + +/* + * These defines where used in combination with the old locking callbacks, + * they are not called anymore, but old code that's not called might still + * use them. + */ +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +/* This structure is no longer used */ +typedef struct crypto_threadid_st { + int dummy; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +# define CRYPTO_THREADID_set_numeric(id, val) +# define CRYPTO_THREADID_set_pointer(id, ptr) +# define CRYPTO_THREADID_set_callback(threadid_func) (0) +# define CRYPTO_THREADID_get_callback() (NULL) +# define CRYPTO_THREADID_current(id) +# define CRYPTO_THREADID_cmp(a, b) (-1) +# define CRYPTO_THREADID_cpy(dest, src) +# define CRYPTO_THREADID_hash(id) (0UL) + +# ifndef OPENSSL_NO_DEPRECATED_1_0_0 +# define CRYPTO_set_id_callback(func) +# define CRYPTO_get_id_callback() (NULL) +# define CRYPTO_thread_id() (0UL) +# endif /* OPENSSL_NO_DEPRECATED_1_0_0 */ + +# define CRYPTO_set_dynlock_create_callback(dyn_create_function) +# define CRYPTO_set_dynlock_lock_callback(dyn_lock_function) +# define CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function) +# define CRYPTO_get_dynlock_create_callback() (NULL) +# define CRYPTO_get_dynlock_lock_callback() (NULL) +# define CRYPTO_get_dynlock_destroy_callback() (NULL) +# endif /* OPENSSL_NO_DEPRECATED_1_1_0 */ + +typedef void *(*CRYPTO_malloc_fn)(size_t num, const char *file, int line); +typedef void *(*CRYPTO_realloc_fn)(void *addr, size_t num, const char *file, + int line); +typedef void (*CRYPTO_free_fn)(void *addr, const char *file, int line); +int CRYPTO_set_mem_functions(CRYPTO_malloc_fn malloc_fn, + CRYPTO_realloc_fn realloc_fn, + CRYPTO_free_fn free_fn); +void CRYPTO_get_mem_functions(CRYPTO_malloc_fn *malloc_fn, + CRYPTO_realloc_fn *realloc_fn, + CRYPTO_free_fn *free_fn); + +void *CRYPTO_malloc(size_t num, const char *file, int line); +void *CRYPTO_zalloc(size_t num, const char *file, int line); +void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line); +void CRYPTO_free(void *ptr, const char *file, int line); +void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line); +void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line); +void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num, + const char *file, int line); + +int CRYPTO_secure_malloc_init(size_t sz, size_t minsize); +int CRYPTO_secure_malloc_done(void); +void *CRYPTO_secure_malloc(size_t num, const char *file, int line); +void *CRYPTO_secure_zalloc(size_t num, const char *file, int line); +void CRYPTO_secure_free(void *ptr, const char *file, int line); +void CRYPTO_secure_clear_free(void *ptr, size_t num, + const char *file, int line); +int CRYPTO_secure_allocated(const void *ptr); +int CRYPTO_secure_malloc_initialized(void); +size_t CRYPTO_secure_actual_size(void *ptr); +size_t CRYPTO_secure_used(void); + +void OPENSSL_cleanse(void *ptr, size_t len); + +# ifndef OPENSSL_NO_CRYPTO_MDEBUG +/* + * The following can be used to detect memory leaks in the library. If + * used, it turns on malloc checking + */ +# define CRYPTO_MEM_CHECK_OFF 0x0 /* Control only */ +# define CRYPTO_MEM_CHECK_ON 0x1 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2 /* Control and mode bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3 /* Control only */ + +void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount); +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define OPENSSL_mem_debug_push(info) \ + CRYPTO_mem_debug_push(info, OPENSSL_FILE, OPENSSL_LINE) +# define OPENSSL_mem_debug_pop() \ + CRYPTO_mem_debug_pop() +# endif +DEPRECATEDIN_3_0(int CRYPTO_set_mem_debug(int flag)) +DEPRECATEDIN_3_0(int CRYPTO_mem_ctrl(int mode)) +DEPRECATEDIN_3_0(int CRYPTO_mem_debug_push(const char *info, + const char *file, int line)) +DEPRECATEDIN_3_0(int CRYPTO_mem_debug_pop(void)) + +DEPRECATEDIN_3_0(void CRYPTO_mem_debug_malloc(void *addr, size_t num, + int flag, + const char *file, int line)) +DEPRECATEDIN_3_0(void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, + size_t num, int flag, + const char *file, int line)) +DEPRECATEDIN_3_0(void CRYPTO_mem_debug_free(void *addr, int flag, + const char *file, int line)) + +DEPRECATEDIN_3_0(int CRYPTO_mem_leaks_cb( + int (*cb)(const char *str, size_t len, void *u), void *u)) +# ifndef OPENSSL_NO_STDIO +DEPRECATEDIN_3_0(int CRYPTO_mem_leaks_fp(FILE *)) +# endif +DEPRECATEDIN_3_0(int CRYPTO_mem_leaks(BIO *bio)) +# endif /* OPENSSL_NO_CRYPTO_MDEBUG */ + +/* die if we have to */ +ossl_noreturn void OPENSSL_die(const char *assertion, const char *file, int line); +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define OpenSSLDie(f,l,a) OPENSSL_die((a),(f),(l)) +# endif +# define OPENSSL_assert(e) \ + (void)((e) ? 0 : (OPENSSL_die("assertion failed: " #e, OPENSSL_FILE, OPENSSL_LINE), 1)) + +int OPENSSL_isservice(void); + +void OPENSSL_init(void); +# ifdef OPENSSL_SYS_UNIX +void OPENSSL_fork_prepare(void); +void OPENSSL_fork_parent(void); +void OPENSSL_fork_child(void); +# endif + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +int OPENSSL_gmtime_diff(int *pday, int *psec, + const struct tm *from, const struct tm *to); + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const void * in_a, const void * in_b, size_t len); + +/* Standard initialisation options */ +# define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0x00000001L +# define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L +# define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L +# define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L +# define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0x00000010L +# define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0x00000020L +# define OPENSSL_INIT_LOAD_CONFIG 0x00000040L +# define OPENSSL_INIT_NO_LOAD_CONFIG 0x00000080L +# define OPENSSL_INIT_ASYNC 0x00000100L +# define OPENSSL_INIT_ENGINE_RDRAND 0x00000200L +# define OPENSSL_INIT_ENGINE_DYNAMIC 0x00000400L +# define OPENSSL_INIT_ENGINE_OPENSSL 0x00000800L +# define OPENSSL_INIT_ENGINE_CRYPTODEV 0x00001000L +# define OPENSSL_INIT_ENGINE_CAPI 0x00002000L +# define OPENSSL_INIT_ENGINE_PADLOCK 0x00004000L +# define OPENSSL_INIT_ENGINE_AFALG 0x00008000L +/* OPENSSL_INIT_ZLIB 0x00010000L */ +# define OPENSSL_INIT_ATFORK 0x00020000L +/* OPENSSL_INIT_BASE_ONLY 0x00040000L */ +# define OPENSSL_INIT_NO_ATEXIT 0x00080000L +/* OPENSSL_INIT flag range 0x03f00000 reserved for OPENSSL_init_ssl() */ +/* FREE: 0x04000000L */ +/* FREE: 0x08000000L */ +/* FREE: 0x10000000L */ +/* FREE: 0x20000000L */ +/* FREE: 0x40000000L */ +/* FREE: 0x80000000L */ +/* Max OPENSSL_INIT flag value is 0x80000000 */ + +/* openssl and dasync not counted as builtin */ +# define OPENSSL_INIT_ENGINE_ALL_BUILTIN \ + (OPENSSL_INIT_ENGINE_RDRAND | OPENSSL_INIT_ENGINE_DYNAMIC \ + | OPENSSL_INIT_ENGINE_CRYPTODEV | OPENSSL_INIT_ENGINE_CAPI | \ + OPENSSL_INIT_ENGINE_PADLOCK) + +/* Library initialisation functions */ +void OPENSSL_cleanup(void); +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); +int OPENSSL_atexit(void (*handler)(void)); +void OPENSSL_thread_stop(void); +void OPENSSL_thread_stop_ex(OSSL_LIB_CTX *ctx); + +/* Low-level control of initialization */ +OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void); +# ifndef OPENSSL_NO_STDIO +int OPENSSL_INIT_set_config_filename(OPENSSL_INIT_SETTINGS *settings, + const char *config_filename); +void OPENSSL_INIT_set_config_file_flags(OPENSSL_INIT_SETTINGS *settings, + unsigned long flags); +int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, + const char *config_appname); +# endif +void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings); + +# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) +# if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include in order to use this */ +typedef DWORD CRYPTO_THREAD_LOCAL; +typedef DWORD CRYPTO_THREAD_ID; + +typedef LONG CRYPTO_ONCE; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif +# else +# if defined(__TANDEM) && defined(_SPT_MODEL_) +# define SPT_THREAD_SIGNAL 1 +# define SPT_THREAD_AWARE 1 +# include +# else +# include +# endif +typedef pthread_once_t CRYPTO_ONCE; +typedef pthread_key_t CRYPTO_THREAD_LOCAL; +typedef pthread_t CRYPTO_THREAD_ID; + +# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# endif +# endif + +# if !defined(CRYPTO_ONCE_STATIC_INIT) +typedef unsigned int CRYPTO_ONCE; +typedef unsigned int CRYPTO_THREAD_LOCAL; +typedef unsigned int CRYPTO_THREAD_ID; +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif + +int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)); + +int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *)); +void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key); +int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val); +int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key); + +CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void); +int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b); + +OSSL_LIB_CTX *OSSL_LIB_CTX_new(void); +int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file); +void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); +OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/cryptoerr.h b/include/openssl/cryptoerr.h index 5ccddd0214..6add92a9ca 100644 --- a/include/openssl/cryptoerr.h +++ b/include/openssl/cryptoerr.h @@ -90,11 +90,13 @@ int ERR_load_CRYPTO_strings(void); # define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 # define CRYPTO_R_PROVIDER_ALREADY_EXISTS 104 # define CRYPTO_R_PROVIDER_SECTION_ERROR 105 +# define CRYPTO_R_RANDOM_SECTION_ERROR 119 # define CRYPTO_R_SECURE_MALLOC_FAILURE 111 # define CRYPTO_R_STRING_TOO_LONG 112 # define CRYPTO_R_TOO_MANY_BYTES 113 # define CRYPTO_R_TOO_MANY_RECORDS 114 # define CRYPTO_R_TOO_SMALL_BUFFER 116 +# define CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION 120 # define CRYPTO_R_ZERO_LENGTH_NUMBER 115 #endif diff --git a/include/openssl/ct.h b/include/openssl/ct.h index a69c986f06..1d95a8ad3a 100644 --- a/include/openssl/ct.h +++ b/include/openssl/ct.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/ct.h.in + * * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_CT_H # define OPENSSL_CT_H # pragma once @@ -34,8 +39,58 @@ extern "C" { /* All hashes are SHA256 in v1 of Certificate Transparency */ # define CT_V1_HASHLEN SHA256_DIGEST_LENGTH -DEFINE_OR_DECLARE_STACK_OF(SCT) -DEFINE_OR_DECLARE_STACK_OF(CTLOG) +SKM_DEFINE_STACK_OF_INTERNAL(SCT, SCT, SCT) +#define sk_SCT_num(sk) OPENSSL_sk_num(ossl_check_const_SCT_sk_type(sk)) +#define sk_SCT_value(sk, idx) ((SCT *)OPENSSL_sk_value(ossl_check_const_SCT_sk_type(sk), (idx))) +#define sk_SCT_new(cmp) ((STACK_OF(SCT) *)OPENSSL_sk_new(ossl_check_SCT_compfunc_type(cmp))) +#define sk_SCT_new_null() ((STACK_OF(SCT) *)OPENSSL_sk_new_null()) +#define sk_SCT_new_reserve(cmp, n) ((STACK_OF(SCT) *)OPENSSL_sk_new_reserve(ossl_check_SCT_compfunc_type(cmp), (n))) +#define sk_SCT_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SCT_sk_type(sk), (n)) +#define sk_SCT_free(sk) OPENSSL_sk_free(ossl_check_SCT_sk_type(sk)) +#define sk_SCT_zero(sk) OPENSSL_sk_zero(ossl_check_SCT_sk_type(sk)) +#define sk_SCT_delete(sk, i) ((SCT *)OPENSSL_sk_delete(ossl_check_SCT_sk_type(sk), (i))) +#define sk_SCT_delete_ptr(sk, ptr) ((SCT *)OPENSSL_sk_delete_ptr(ossl_check_SCT_sk_type(sk), ossl_check_SCT_type(ptr))) +#define sk_SCT_push(sk, ptr) OPENSSL_sk_push(ossl_check_SCT_sk_type(sk), ossl_check_SCT_type(ptr)) +#define sk_SCT_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SCT_sk_type(sk), ossl_check_SCT_type(ptr)) +#define sk_SCT_pop(sk) ((SCT *)OPENSSL_sk_pop(ossl_check_SCT_sk_type(sk))) +#define sk_SCT_shift(sk) ((SCT *)OPENSSL_sk_shift(ossl_check_SCT_sk_type(sk))) +#define sk_SCT_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SCT_sk_type(sk),ossl_check_SCT_freefunc_type(freefunc)) +#define sk_SCT_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SCT_sk_type(sk), ossl_check_SCT_type(ptr), (idx)) +#define sk_SCT_set(sk, idx, ptr) ((SCT *)OPENSSL_sk_set(ossl_check_SCT_sk_type(sk), (idx), ossl_check_SCT_type(ptr))) +#define sk_SCT_find(sk, ptr) OPENSSL_sk_find(ossl_check_SCT_sk_type(sk), ossl_check_SCT_type(ptr)) +#define sk_SCT_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SCT_sk_type(sk), ossl_check_SCT_type(ptr)) +#define sk_SCT_sort(sk) OPENSSL_sk_sort(ossl_check_SCT_sk_type(sk)) +#define sk_SCT_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SCT_sk_type(sk)) +#define sk_SCT_dup(sk) ((STACK_OF(SCT) *)OPENSSL_sk_dup(ossl_check_const_SCT_sk_type(sk))) +#define sk_SCT_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SCT) *)OPENSSL_sk_deep_copy(ossl_check_const_SCT_sk_type(sk), ossl_check_SCT_copyfunc_type(copyfunc), ossl_check_SCT_freefunc_type(freefunc))) +#define sk_SCT_set_cmp_func(sk, cmp) ((sk_SCT_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SCT_sk_type(sk), ossl_check_SCT_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(CTLOG, CTLOG, CTLOG) +#define sk_CTLOG_num(sk) OPENSSL_sk_num(ossl_check_const_CTLOG_sk_type(sk)) +#define sk_CTLOG_value(sk, idx) ((CTLOG *)OPENSSL_sk_value(ossl_check_const_CTLOG_sk_type(sk), (idx))) +#define sk_CTLOG_new(cmp) ((STACK_OF(CTLOG) *)OPENSSL_sk_new(ossl_check_CTLOG_compfunc_type(cmp))) +#define sk_CTLOG_new_null() ((STACK_OF(CTLOG) *)OPENSSL_sk_new_null()) +#define sk_CTLOG_new_reserve(cmp, n) ((STACK_OF(CTLOG) *)OPENSSL_sk_new_reserve(ossl_check_CTLOG_compfunc_type(cmp), (n))) +#define sk_CTLOG_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_CTLOG_sk_type(sk), (n)) +#define sk_CTLOG_free(sk) OPENSSL_sk_free(ossl_check_CTLOG_sk_type(sk)) +#define sk_CTLOG_zero(sk) OPENSSL_sk_zero(ossl_check_CTLOG_sk_type(sk)) +#define sk_CTLOG_delete(sk, i) ((CTLOG *)OPENSSL_sk_delete(ossl_check_CTLOG_sk_type(sk), (i))) +#define sk_CTLOG_delete_ptr(sk, ptr) ((CTLOG *)OPENSSL_sk_delete_ptr(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_type(ptr))) +#define sk_CTLOG_push(sk, ptr) OPENSSL_sk_push(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_type(ptr)) +#define sk_CTLOG_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_type(ptr)) +#define sk_CTLOG_pop(sk) ((CTLOG *)OPENSSL_sk_pop(ossl_check_CTLOG_sk_type(sk))) +#define sk_CTLOG_shift(sk) ((CTLOG *)OPENSSL_sk_shift(ossl_check_CTLOG_sk_type(sk))) +#define sk_CTLOG_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_CTLOG_sk_type(sk),ossl_check_CTLOG_freefunc_type(freefunc)) +#define sk_CTLOG_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_type(ptr), (idx)) +#define sk_CTLOG_set(sk, idx, ptr) ((CTLOG *)OPENSSL_sk_set(ossl_check_CTLOG_sk_type(sk), (idx), ossl_check_CTLOG_type(ptr))) +#define sk_CTLOG_find(sk, ptr) OPENSSL_sk_find(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_type(ptr)) +#define sk_CTLOG_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_type(ptr)) +#define sk_CTLOG_sort(sk) OPENSSL_sk_sort(ossl_check_CTLOG_sk_type(sk)) +#define sk_CTLOG_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_CTLOG_sk_type(sk)) +#define sk_CTLOG_dup(sk) ((STACK_OF(CTLOG) *)OPENSSL_sk_dup(ossl_check_const_CTLOG_sk_type(sk))) +#define sk_CTLOG_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(CTLOG) *)OPENSSL_sk_deep_copy(ossl_check_const_CTLOG_sk_type(sk), ossl_check_CTLOG_copyfunc_type(copyfunc), ossl_check_CTLOG_freefunc_type(freefunc))) +#define sk_CTLOG_set_cmp_func(sk, cmp) ((sk_CTLOG_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_CTLOG_sk_type(sk), ossl_check_CTLOG_compfunc_type(cmp))) + + typedef enum { CT_LOG_ENTRY_TYPE_NOT_SET = -1, @@ -74,11 +129,11 @@ typedef enum { * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished * with the CT_POLICY_EVAL_CTX. */ -CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx, - const char *propq); +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, + const char *propq); /* - * The same as CT_POLICY_EVAL_CTX_new_with_libctx() but the default library + * The same as CT_POLICY_EVAL_CTX_new_ex() but the default library * context and property query string is used. */ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); @@ -424,11 +479,11 @@ SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len); * Returns NULL if malloc fails or if |public_key| cannot be converted to DER. * Should be deleted by the caller using CTLOG_free when no longer needed. */ -CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name, - OPENSSL_CTX *libctx, const char *propq); +CTLOG *CTLOG_new_ex(EVP_PKEY *public_key, const char *name, OSSL_LIB_CTX *libctx, + const char *propq); /* - * The same as CTLOG_new_with_libctx except that the default library context and + * The same as CTLOG_new_ex except that the default library context and * property query string are used. */ CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); @@ -441,12 +496,12 @@ CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); * Returns 1 on success, 0 on failure. * Should be deleted by the caller using CTLOG_free when no longer needed. */ -int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64, - const char *name, OPENSSL_CTX *libctx, - const char *propq); +int CTLOG_new_from_base64_ex(CTLOG **ct_log, const char *pkey_base64, + const char *name, OSSL_LIB_CTX *libctx, + const char *propq); /* - * The same as CTLOG_new_from_base64_with_libctx() except that the default + * The same as CTLOG_new_from_base64_ex() except that the default * library context and property query string are used. * Returns 1 on success, 0 on failure. */ @@ -475,10 +530,10 @@ EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log); * property query string. * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. */ -CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq); +CTLOG_STORE *CTLOG_STORE_new_ex(OSSL_LIB_CTX *libctx, const char *propq); /* - * Same as CTLOG_STORE_new_with_libctx except that the default libctx and + * Same as CTLOG_STORE_new_ex except that the default libctx and * property query string are used. * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. */ diff --git a/include/openssl/ct.h.in b/include/openssl/ct.h.in new file mode 100644 index 0000000000..16086b33bd --- /dev/null +++ b/include/openssl/ct.h.in @@ -0,0 +1,525 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_CT_H +# define OPENSSL_CT_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_CT_H +# endif + +# include + +# ifndef OPENSSL_NO_CT +# include +# include +# include +# include +# ifdef __cplusplus +extern "C" { +# endif + + +/* Minimum RSA key size, from RFC6962 */ +# define SCT_MIN_RSA_BITS 2048 + +/* All hashes are SHA256 in v1 of Certificate Transparency */ +# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH + +{- + generate_stack_macros("SCT") + .generate_stack_macros("CTLOG"); +-} + + +typedef enum { + CT_LOG_ENTRY_TYPE_NOT_SET = -1, + CT_LOG_ENTRY_TYPE_X509 = 0, + CT_LOG_ENTRY_TYPE_PRECERT = 1 +} ct_log_entry_type_t; + +typedef enum { + SCT_VERSION_NOT_SET = -1, + SCT_VERSION_V1 = 0 +} sct_version_t; + +typedef enum { + SCT_SOURCE_UNKNOWN, + SCT_SOURCE_TLS_EXTENSION, + SCT_SOURCE_X509V3_EXTENSION, + SCT_SOURCE_OCSP_STAPLED_RESPONSE +} sct_source_t; + +typedef enum { + SCT_VALIDATION_STATUS_NOT_SET, + SCT_VALIDATION_STATUS_UNKNOWN_LOG, + SCT_VALIDATION_STATUS_VALID, + SCT_VALIDATION_STATUS_INVALID, + SCT_VALIDATION_STATUS_UNVERIFIED, + SCT_VALIDATION_STATUS_UNKNOWN_VERSION +} sct_validation_status_t; + +/****************************************** + * CT policy evaluation context functions * + ******************************************/ + +/* + * Creates a new, empty policy evaluation context associated with the given + * library context and property query string. + * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished + * with the CT_POLICY_EVAL_CTX. + */ +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_ex(OSSL_LIB_CTX *libctx, + const char *propq); + +/* + * The same as CT_POLICY_EVAL_CTX_new_ex() but the default library + * context and property query string is used. + */ +CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void); + +/* Deletes a policy evaluation context and anything it owns. */ +void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx); + +/* Gets the peer certificate that the SCTs are for */ +X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the certificate associated with the received SCTs. + * Increments the reference count of cert. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert); + +/* Gets the issuer of the aforementioned certificate */ +X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the issuer of the certificate associated with the received SCTs. + * Increments the reference count of issuer. + * Returns 1 on success, 0 otherwise. + */ +int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer); + +/* Gets the CT logs that are trusted sources of SCTs */ +const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx); + +/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */ +void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx, + CTLOG_STORE *log_store); + +/* + * Gets the time, in milliseconds since the Unix epoch, that will be used as the + * current time when checking whether an SCT was issued in the future. + * Such SCTs will fail validation, as required by RFC6962. + */ +uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx); + +/* + * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch. + * If an SCT's timestamp is after this time, it will be interpreted as having + * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs + * whose timestamp is in the future", so an SCT will not validate in this case. + */ +void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms); + +/***************** + * SCT functions * + *****************/ + +/* + * Creates a new, blank SCT. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new(void); + +/* + * Creates a new SCT from some base64-encoded strings. + * The caller is responsible for calling SCT_free when finished with the SCT. + */ +SCT *SCT_new_from_base64(unsigned char version, + const char *logid_base64, + ct_log_entry_type_t entry_type, + uint64_t timestamp, + const char *extensions_base64, + const char *signature_base64); + +/* + * Frees the SCT and the underlying data structures. + */ +void SCT_free(SCT *sct); + +/* + * Free a stack of SCTs, and the underlying SCTs themselves. + * Intended to be compatible with X509V3_EXT_FREE. + */ +void SCT_LIST_free(STACK_OF(SCT) *a); + +/* + * Returns the version of the SCT. + */ +sct_version_t SCT_get_version(const SCT *sct); + +/* + * Set the version of an SCT. + * Returns 1 on success, 0 if the version is unrecognized. + */ +__owur int SCT_set_version(SCT *sct, sct_version_t version); + +/* + * Returns the log entry type of the SCT. + */ +ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct); + +/* + * Set the log entry type of an SCT. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type); + +/* + * Gets the ID of the log that an SCT came from. + * Ownership of the log ID remains with the SCT. + * Returns the length of the log ID. + */ +size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id); + +/* + * Set the log ID of an SCT to point directly to the *log_id specified. + * The SCT takes ownership of the specified pointer. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len); + +/* + * Set the log ID of an SCT. + * This makes a copy of the log_id. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, + size_t log_id_len); + +/* + * Returns the timestamp for the SCT (epoch time in milliseconds). + */ +uint64_t SCT_get_timestamp(const SCT *sct); + +/* + * Set the timestamp of an SCT (epoch time in milliseconds). + */ +void SCT_set_timestamp(SCT *sct, uint64_t timestamp); + +/* + * Return the NID for the signature used by the SCT. + * For CT v1, this will be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset). + */ +int SCT_get_signature_nid(const SCT *sct); + +/* + * Set the signature type of an SCT + * For CT v1, this should be either NID_sha256WithRSAEncryption or + * NID_ecdsa_with_SHA256. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_signature_nid(SCT *sct, int nid); + +/* + * Set *ext to point to the extension data for the SCT. ext must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext); + +/* + * Set the extensions of an SCT to point directly to the *ext specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len); + +/* + * Set the extensions of an SCT. + * This takes a copy of the ext. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_extensions(SCT *sct, const unsigned char *ext, + size_t ext_len); + +/* + * Set *sig to point to the signature for the SCT. sig must not be NULL. + * The SCT retains ownership of this pointer. + * Returns length of the data pointed to. + */ +size_t SCT_get0_signature(const SCT *sct, unsigned char **sig); + +/* + * Set the signature of an SCT to point directly to the *sig specified. + * The SCT takes ownership of the specified pointer. + */ +void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len); + +/* + * Set the signature of an SCT to be a copy of the *sig specified. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set1_signature(SCT *sct, const unsigned char *sig, + size_t sig_len); + +/* + * The origin of this SCT, e.g. TLS extension, OCSP response, etc. + */ +sct_source_t SCT_get_source(const SCT *sct); + +/* + * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc. + * Returns 1 on success, 0 otherwise. + */ +__owur int SCT_set_source(SCT *sct, sct_source_t source); + +/* + * Returns a text string describing the validation status of |sct|. + */ +const char *SCT_validation_status_string(const SCT *sct); + +/* + * Pretty-prints an |sct| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came + * from, so that the log name can be printed. + */ +void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs); + +/* + * Pretty-prints an |sct_list| to |out|. + * It will be indented by the number of spaces specified by |indent|. + * SCTs will be delimited by |separator|. + * If |logs| is not NULL, it will be used to lookup the CT log that each SCT + * came from, so that the log names can be printed. + */ +void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, + const char *separator, const CTLOG_STORE *logs); + +/* + * Gets the last result of validating this SCT. + * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET. + */ +sct_validation_status_t SCT_get_validation_status(const SCT *sct); + +/* + * Validates the given SCT with the provided context. + * Sets the "validation_status" field of the SCT. + * Returns 1 if the SCT is valid and the signature verifies. + * Returns 0 if the SCT is invalid or could not be verified. + * Returns -1 if an error occurs. + */ +__owur int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx); + +/* + * Validates the given list of SCTs with the provided context. + * Sets the "validation_status" field of each SCT. + * Returns 1 if there are no invalid SCTs and all signatures verify. + * Returns 0 if at least one SCT is invalid or could not be verified. + * Returns a negative integer if an error occurs. + */ +__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts, + CT_POLICY_EVAL_CTX *ctx); + + +/********************************* + * SCT parsing and serialization * + *********************************/ + +/* + * Serialize (to TLS format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just return the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Convert TLS format SCT list to a stack of SCTs. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + size_t len); + +/* + * Serialize (to DER format) a stack of SCTs and return the length. + * "a" must not be NULL. + * If "pp" is NULL, just returns the length of what would have been serialized. + * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer + * for data that caller is responsible for freeing (only if function returns + * successfully). + * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring + * that "*pp" is large enough to accept all of the serialized data. + * Returns < 0 on error, >= 0 indicating bytes written (or would have been) + * on success. + */ +__owur int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp); + +/* + * Parses an SCT list in DER format and returns it. + * If "a" or "*a" is NULL, a new stack will be created that the caller is + * responsible for freeing (by calling SCT_LIST_free). + * "**pp" and "*pp" must not be NULL. + * Upon success, "*pp" will point to after the last bytes read, and a stack + * will be returned. + * Upon failure, a NULL pointer will be returned, and the position of "*pp" is + * not defined. + */ +STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, + long len); + +/* + * Serialize (to TLS format) an |sct| and write it to |out|. + * If |out| is null, no SCT will be output but the length will still be returned. + * If |out| points to a null pointer, a string will be allocated to hold the + * TLS-format SCT. It is the responsibility of the caller to free it. + * If |out| points to an allocated string, the TLS-format SCT will be written + * to it. + * The length of the SCT in TLS format will be returned. + */ +__owur int i2o_SCT(const SCT *sct, unsigned char **out); + +/* + * Parses an SCT in TLS format and returns it. + * If |psct| is not null, it will end up pointing to the parsed SCT. If it + * already points to a non-null pointer, the pointer will be free'd. + * |in| should be a pointer to a string containing the TLS-format SCT. + * |in| will be advanced to the end of the SCT if parsing succeeds. + * |len| should be the length of the SCT in |in|. + * Returns NULL if an error occurs. + * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len' + * fields will be populated (with |in| and |len| respectively). + */ +SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len); + +/******************** + * CT log functions * + ********************/ + +/* + * Creates a new CT log instance with the given |public_key| and |name| and + * associates it with the give library context |libctx| and property query + * string |propq|. + * Takes ownership of |public_key| but copies |name|. + * Returns NULL if malloc fails or if |public_key| cannot be converted to DER. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +CTLOG *CTLOG_new_ex(EVP_PKEY *public_key, const char *name, OSSL_LIB_CTX *libctx, + const char *propq); + +/* + * The same as CTLOG_new_ex except that the default library context and + * property query string are used. + */ +CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name); + +/* + * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER + * in |pkey_base64| and associated with the given library context |libctx| and + * property query string |propq|. The |name| is a string to help users identify + * this log. + * Returns 1 on success, 0 on failure. + * Should be deleted by the caller using CTLOG_free when no longer needed. + */ +int CTLOG_new_from_base64_ex(CTLOG **ct_log, const char *pkey_base64, + const char *name, OSSL_LIB_CTX *libctx, + const char *propq); + +/* + * The same as CTLOG_new_from_base64_ex() except that the default + * library context and property query string are used. + * Returns 1 on success, 0 on failure. + */ +int CTLOG_new_from_base64(CTLOG ** ct_log, + const char *pkey_base64, const char *name); + +/* + * Deletes a CT log instance and its fields. + */ +void CTLOG_free(CTLOG *log); + +/* Gets the name of the CT log */ +const char *CTLOG_get0_name(const CTLOG *log); +/* Gets the ID of the CT log */ +void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id, + size_t *log_id_len); +/* Gets the public key of the CT log */ +EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log); + +/************************** + * CT log store functions * + **************************/ + +/* + * Creates a new CT log store and associates it with the given libctx and + * property query string. + * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. + */ +CTLOG_STORE *CTLOG_STORE_new_ex(OSSL_LIB_CTX *libctx, const char *propq); + +/* + * Same as CTLOG_STORE_new_ex except that the default libctx and + * property query string are used. + * Should be deleted by the caller using CTLOG_STORE_free when no longer needed. + */ +CTLOG_STORE *CTLOG_STORE_new(void); + +/* + * Deletes a CT log store and all of the CT log instances held within. + */ +void CTLOG_STORE_free(CTLOG_STORE *store); + +/* + * Finds a CT log in the store based on its log ID. + * Returns the CT log, or NULL if no match is found. + */ +const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store, + const uint8_t *log_id, + size_t log_id_len); + +/* + * Loads a CT log list into a |store| from a |file|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file); + +/* + * Loads the default CT log list into a |store|. + * Returns 1 if loading is successful, or 0 otherwise. + */ +__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store); + +# ifdef __cplusplus +} +# endif +# endif +#endif diff --git a/include/openssl/decoder.h b/include/openssl/decoder.h new file mode 100644 index 0000000000..1c6bc8e498 --- /dev/null +++ b/include/openssl/decoder.h @@ -0,0 +1,124 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_DECODER_H +# define OPENSSL_DECODER_H +# pragma once + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +OSSL_DECODER *OSSL_DECODER_fetch(OSSL_LIB_CTX *libctx, const char *name, + const char *properties); +int OSSL_DECODER_up_ref(OSSL_DECODER *encoder); +void OSSL_DECODER_free(OSSL_DECODER *encoder); + +const OSSL_PROVIDER *OSSL_DECODER_provider(const OSSL_DECODER *encoder); +const char *OSSL_DECODER_properties(const OSSL_DECODER *encoder); +int OSSL_DECODER_number(const OSSL_DECODER *encoder); +int OSSL_DECODER_is_a(const OSSL_DECODER *encoder, const char *name); + +void OSSL_DECODER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(OSSL_DECODER *encoder, void *arg), + void *arg); +void OSSL_DECODER_names_do_all(const OSSL_DECODER *encoder, + void (*fn)(const char *name, void *data), + void *data); +const OSSL_PARAM *OSSL_DECODER_gettable_params(OSSL_DECODER *decoder); +int OSSL_DECODER_get_params(OSSL_DECODER *decoder, OSSL_PARAM params[]); + +const OSSL_PARAM *OSSL_DECODER_settable_ctx_params(OSSL_DECODER *encoder); +OSSL_DECODER_CTX *OSSL_DECODER_CTX_new(void); +int OSSL_DECODER_CTX_set_params(OSSL_DECODER_CTX *ctx, + const OSSL_PARAM params[]); +void OSSL_DECODER_CTX_free(OSSL_DECODER_CTX *ctx); + +/* Utilities that help set specific parameters */ +int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, + const unsigned char *kstr, size_t klen); +int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx, + pem_password_cb *cb, void *cbarg); +int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg); +int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data); + +/* + * Utilities to read the object to decode, with the result sent to cb. + * These will discover all provided methods + */ + +int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, + const char *input_type); +int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder); +int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); +int OSSL_DECODER_CTX_get_num_decoders(OSSL_DECODER_CTX *ctx); + +typedef struct ossl_decoder_instance_st OSSL_DECODER_INSTANCE; +OSSL_DECODER * +OSSL_DECODER_INSTANCE_get_decoder(OSSL_DECODER_INSTANCE *decoder_inst); +void * +OSSL_DECODER_INSTANCE_get_decoder_ctx(OSSL_DECODER_INSTANCE *decoder_inst); +const char * +OSSL_DECODER_INSTANCE_get_input_type(OSSL_DECODER_INSTANCE *decoder_inst); + +typedef int OSSL_DECODER_CONSTRUCT(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, + void *construct_data); +typedef void OSSL_DECODER_CLEANUP(void *construct_data); + +int OSSL_DECODER_CTX_set_construct(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CONSTRUCT *construct); +int OSSL_DECODER_CTX_set_construct_data(OSSL_DECODER_CTX *ctx, + void *construct_data); +int OSSL_DECODER_CTX_set_cleanup(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_CLEANUP *cleanup); +OSSL_DECODER_CONSTRUCT *OSSL_DECODER_CTX_get_construct(OSSL_DECODER_CTX *ctx); +void *OSSL_DECODER_CTX_get_construct_data(OSSL_DECODER_CTX *ctx); +OSSL_DECODER_CLEANUP *OSSL_DECODER_CTX_get_cleanup(OSSL_DECODER_CTX *ctx); + +int OSSL_DECODER_export(OSSL_DECODER_INSTANCE *decoder_inst, + void *reference, size_t reference_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg); + +int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in); +#ifndef OPENSSL_NO_STDIO +int OSSL_DECODER_from_fp(OSSL_DECODER_CTX *ctx, FILE *in); +#endif +int OSSL_DECODER_from_data(OSSL_DECODER_CTX *ctx, const unsigned char **pdata, + size_t *pdata_len); + +/* + * Create the OSSL_DECODER_CTX with an associated type. This will perform + * an implicit OSSL_DECODER_fetch(), suitable for the object of that type. + */ +OSSL_DECODER_CTX * +OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, + const char *input_type, const char *keytype, + OSSL_LIB_CTX *libctx, const char *propquery); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/deserializererr.h b/include/openssl/decodererr.h similarity index 68% rename from include/openssl/deserializererr.h rename to include/openssl/decodererr.h index 1c6573afb6..8da9157814 100644 --- a/include/openssl/deserializererr.h +++ b/include/openssl/decodererr.h @@ -8,8 +8,8 @@ * https://www.openssl.org/source/license.html */ -#ifndef OPENSSL_OSSL_DESERIALIZERERR_H -# define OPENSSL_OSSL_DESERIALIZERERR_H +#ifndef OPENSSL_OSSL_DECODERERR_H +# define OPENSSL_OSSL_DECODERERR_H # pragma once # include @@ -19,17 +19,17 @@ # ifdef __cplusplus extern "C" # endif -int ERR_load_OSSL_DESERIALIZER_strings(void); +int ERR_load_OSSL_DECODER_strings(void); /* - * OSSL_DESERIALIZER function codes. + * OSSL_DECODER function codes. */ # ifndef OPENSSL_NO_DEPRECATED_3_0 # endif /* - * OSSL_DESERIALIZER reason codes. + * OSSL_DECODER reason codes. */ -# define OSSL_DESERIALIZER_R_MISSING_GET_PARAMS 100 +# define OSSL_DECODER_R_MISSING_GET_PARAMS 100 #endif diff --git a/include/openssl/deserializer.h b/include/openssl/deserializer.h deleted file mode 100644 index 0133785b50..0000000000 --- a/include/openssl/deserializer.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_DESERIALIZER_H -# define OPENSSL_DESERIALIZER_H -# pragma once - -# include - -# ifndef OPENSSL_NO_STDIO -# include -# endif -# include -# include -# include -# include -# include - -# ifdef __cplusplus -extern "C" { -# endif - -OSSL_DESERIALIZER *OSSL_DESERIALIZER_fetch(OPENSSL_CTX *libctx, - const char *name, - const char *properties); -int OSSL_DESERIALIZER_up_ref(OSSL_DESERIALIZER *ser); -void OSSL_DESERIALIZER_free(OSSL_DESERIALIZER *ser); - -const OSSL_PROVIDER *OSSL_DESERIALIZER_provider(const OSSL_DESERIALIZER *ser); -const char *OSSL_DESERIALIZER_properties(const OSSL_DESERIALIZER *ser); -int OSSL_DESERIALIZER_number(const OSSL_DESERIALIZER *ser); -int OSSL_DESERIALIZER_is_a(const OSSL_DESERIALIZER *ser, - const char *name); - -void OSSL_DESERIALIZER_do_all_provided(OPENSSL_CTX *libctx, - void (*fn)(OSSL_DESERIALIZER *ser, - void *arg), - void *arg); -void OSSL_DESERIALIZER_names_do_all(const OSSL_DESERIALIZER *ser, - void (*fn)(const char *name, void *data), - void *data); -const OSSL_PARAM *OSSL_DESERIALIZER_gettable_params(OSSL_DESERIALIZER *deser); -int OSSL_DESERIALIZER_get_params(OSSL_DESERIALIZER *deser, OSSL_PARAM params[]); - -const OSSL_PARAM *OSSL_DESERIALIZER_settable_ctx_params(OSSL_DESERIALIZER *ser); -OSSL_DESERIALIZER_CTX *OSSL_DESERIALIZER_CTX_new(void); -int OSSL_DESERIALIZER_CTX_set_params(OSSL_DESERIALIZER_CTX *ctx, - const OSSL_PARAM params[]); -void OSSL_DESERIALIZER_CTX_free(OSSL_DESERIALIZER_CTX *ctx); - -/* Utilities that help set specific parameters */ -int OSSL_DESERIALIZER_CTX_set_passphrase(OSSL_DESERIALIZER_CTX *ctx, - const unsigned char *kstr, - size_t klen); -int OSSL_DESERIALIZER_CTX_set_pem_password_cb(OSSL_DESERIALIZER_CTX *ctx, - pem_password_cb *cb, - void *cbarg); -int OSSL_DESERIALIZER_CTX_set_passphrase_ui(OSSL_DESERIALIZER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data); - -/* - * Utilities to read the object to deserialize, with the result sent to cb. - * These will discover all provided methods - */ - -int OSSL_DESERIALIZER_CTX_set_input_type(OSSL_DESERIALIZER_CTX *ctx, - const char *input_type); -int OSSL_DESERIALIZER_CTX_add_deserializer(OSSL_DESERIALIZER_CTX *ctx, - OSSL_DESERIALIZER *deser); -int OSSL_DESERIALIZER_CTX_add_extra(OSSL_DESERIALIZER_CTX *ctx, - OPENSSL_CTX *libctx, const char *propq); -int OSSL_DESERIALIZER_CTX_num_deserializers(OSSL_DESERIALIZER_CTX *ctx); - -typedef struct ossl_deserializer_instance_st OSSL_DESERIALIZER_INSTANCE; -OSSL_DESERIALIZER *OSSL_DESERIALIZER_INSTANCE_deserializer - (OSSL_DESERIALIZER_INSTANCE *deser_inst); -void *OSSL_DESERIALIZER_INSTANCE_deserializer_ctx - (OSSL_DESERIALIZER_INSTANCE *deser_inst); - -typedef int (OSSL_DESERIALIZER_CONSTRUCT) - (OSSL_DESERIALIZER_INSTANCE *deser_inst, - const OSSL_PARAM *params, void *construct_data); -typedef void (OSSL_DESERIALIZER_CLEANUP)(void *construct_data); - -int OSSL_DESERIALIZER_CTX_set_construct(OSSL_DESERIALIZER_CTX *ctx, - OSSL_DESERIALIZER_CONSTRUCT *construct); -int OSSL_DESERIALIZER_CTX_set_construct_data(OSSL_DESERIALIZER_CTX *ctx, - void *construct_data); -int OSSL_DESERIALIZER_CTX_set_cleanup(OSSL_DESERIALIZER_CTX *ctx, - OSSL_DESERIALIZER_CLEANUP *cleanup); -OSSL_DESERIALIZER_CONSTRUCT * -OSSL_DESERIALIZER_CTX_get_construct(OSSL_DESERIALIZER_CTX *ctx); -void *OSSL_DESERIALIZER_CTX_get_construct_data(OSSL_DESERIALIZER_CTX *ctx); -OSSL_DESERIALIZER_CLEANUP * -OSSL_DESERIALIZER_CTX_get_cleanup(OSSL_DESERIALIZER_CTX *ctx); - -int OSSL_DESERIALIZER_export(OSSL_DESERIALIZER_INSTANCE *deser_inst, - void *reference, size_t reference_sz, - OSSL_CALLBACK *export_cb, void *export_cbarg); - -int OSSL_DESERIALIZER_from_bio(OSSL_DESERIALIZER_CTX *ctx, BIO *in); -#ifndef OPENSSL_NO_STDIO -int OSSL_DESERIALIZER_from_fp(OSSL_DESERIALIZER_CTX *ctx, FILE *in); -#endif - -/* - * Create the OSSL_DESERIALIZER_CTX with an associated type. This will perform - * an implicit OSSL_DESERIALIZER_fetch(), suitable for the object of that type. - */ -OSSL_DESERIALIZER_CTX * -OSSL_DESERIALIZER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, const char *input_type, - OPENSSL_CTX *libctx, - const char *propquery); - -# ifdef __cplusplus -} -# endif -#endif diff --git a/include/openssl/dh.h b/include/openssl/dh.h index 4907bc6567..69a5b79c18 100644 --- a/include/openssl/dh.h +++ b/include/openssl/dh.h @@ -40,6 +40,10 @@ extern "C" { # define DH_FLAG_CACHE_MONT_P 0x01 +# define DH_FLAG_TYPE_MASK 0xF000 +# define DH_FLAG_TYPE_DH 0x0000 +# define DH_FLAG_TYPE_DHX 0x1000 + # ifndef OPENSSL_NO_DEPRECATED_1_1_0 /* * Does nothing. Previously this switched off constant time behaviour. @@ -198,14 +202,12 @@ DH *DH_get_2048_256(void); DH *DH_new_by_nid(int nid); DEPRECATEDIN_3_0(int DH_get_nid(const DH *dh)) -# ifndef OPENSSL_NO_CMS /* RFC2631 KDF */ DEPRECATEDIN_3_0(int DH_KDF_X9_42(unsigned char *out, size_t outlen, const unsigned char *Z, size_t Zlen, ASN1_OBJECT *key_oid, const unsigned char *ukm, size_t ukmlen, const EVP_MD *md)) -# endif void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); @@ -282,45 +284,16 @@ int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen); int EVP_PKEY_CTX_set_dhx_rfc5114(EVP_PKEY_CTX *ctx, int gen); int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad); -# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) - -# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) - -# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)(oid)) - -# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)(poid)) - -# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)(md)) - -# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)(pmd)) - -# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) - -# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)(plen)) - -# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)(p)) - -# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)(p)) +int EVP_PKEY_CTX_set_dh_kdf_type(EVP_PKEY_CTX *ctx, int kdf); +int EVP_PKEY_CTX_get_dh_kdf_type(EVP_PKEY_CTX *ctx); +int EVP_PKEY_CTX_set0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT *oid); +int EVP_PKEY_CTX_get0_dh_kdf_oid(EVP_PKEY_CTX *ctx, ASN1_OBJECT **oid); +int EVP_PKEY_CTX_set_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_get_dh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **md); +int EVP_PKEY_CTX_set_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int len); +int EVP_PKEY_CTX_get_dh_kdf_outlen(EVP_PKEY_CTX *ctx, int *len); +int EVP_PKEY_CTX_set0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len); +int EVP_PKEY_CTX_get0_dh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); # define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) # define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) @@ -341,9 +314,7 @@ int EVP_PKEY_CTX_set_dh_pad(EVP_PKEY_CTX *ctx, int pad); /* KDF types */ # define EVP_PKEY_DH_KDF_NONE 1 -# ifndef OPENSSL_NO_CMS -# define EVP_PKEY_DH_KDF_X9_42 2 -# endif +# define EVP_PKEY_DH_KDF_X9_42 2 # ifdef __cplusplus } diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h index 7b51939e3d..13420d9928 100644 --- a/include/openssl/e_os2.h +++ b/include/openssl/e_os2.h @@ -138,6 +138,21 @@ extern "C" { # endif # endif +/* ---------------------------- HP NonStop -------------------------------- */ +# ifdef __TANDEM +# ifdef _STRING +# include +# endif +# define OPENSSL_USE_BUILD_DATE +# if defined(OPENSSL_THREADS) && defined(_SPT_MODEL_) +# define SPT_THREAD_SIGNAL 1 +# define SPT_THREAD_AWARE 1 +# include +# elif defined(OPENSSL_THREADS) && defined(_PUT_MODEL_) +# include +# endif +# endif + /** * That's it for OS-specific stuff *****************************************************************************/ diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 35dbeb9301..0d41ef8297 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -47,6 +47,7 @@ typedef enum { POINT_CONVERSION_HYBRID = 6 } point_conversion_form_t; +# include # ifndef OPENSSL_NO_DEPRECATED_3_0 typedef struct ec_method_st EC_METHOD; # endif @@ -379,6 +380,19 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); # endif +/** + * Creates a EC_GROUP object with a curve specified by parameters. + * The parameters may be explicit or a named curve, + * \param params A list of parameters describing the group. + * \param libctx The associated library context or NULL for the default + * context + * \param propq A property query string + * \return newly created EC_GROUP object with specified parameters or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx, const char *propq); + /** * Creates a EC_GROUP object with a curve specified by a NID * \param libctx The associated library context or NULL for the default @@ -388,12 +402,12 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, * \return newly created EC_GROUP object with specified curve or NULL * if an error occurred */ -EC_GROUP *EC_GROUP_new_by_curve_name_with_libctx(OPENSSL_CTX *libctx, - const char *propq, int nid); +EC_GROUP *EC_GROUP_new_by_curve_name_ex(OSSL_LIB_CTX *libctx, const char *propq, + int nid); /** * Creates a EC_GROUP object with a curve specified by a NID. Same as - * EC_GROUP_new_by_curve_name_with_libctx but the libctx and propq are always + * EC_GROUP_new_by_curve_name_ex but the libctx and propq are always * NULL. * \param nid NID of the OID of the curve name * \return newly created EC_GROUP object with specified curve or NULL @@ -860,6 +874,7 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); # define EC_FLAG_NON_FIPS_ALLOW 0x1 # define EC_FLAG_FIPS_CHECKED 0x2 # define EC_FLAG_COFACTOR_ECDH 0x1000 +# define EC_FLAG_SM2_RANGE 0x4 /** * Creates a new EC_KEY object. @@ -867,10 +882,10 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); * which case the default library context is used. * \return EC_KEY object or NULL if an error occurred. */ -EC_KEY *EC_KEY_new_with_libctx(OPENSSL_CTX *ctx, const char *propq); +EC_KEY *EC_KEY_new_ex(OSSL_LIB_CTX *ctx, const char *propq); /** - * Creates a new EC_KEY object. Same as calling EC_KEY_new_with_libctx with a + * Creates a new EC_KEY object. Same as calling EC_KEY_new_ex with a * NULL library context * \return EC_KEY object or NULL if an error occurred. */ @@ -882,6 +897,8 @@ void EC_KEY_set_flags(EC_KEY *key, int flags); void EC_KEY_clear_flags(EC_KEY *key, int flags); +int EC_KEY_decoded_from_explicit_params(const EC_KEY *key); + /** * Creates a new EC_KEY object using a named curve as underlying * EC_GROUP object. @@ -891,8 +908,8 @@ void EC_KEY_clear_flags(EC_KEY *key, int flags); * \param nid NID of the named curve. * \return EC_KEY object or NULL if an error occurred. */ -EC_KEY *EC_KEY_new_by_curve_name_with_libctx(OPENSSL_CTX *ctx, const char *propq, - int nid); +EC_KEY *EC_KEY_new_by_curve_name_ex(OSSL_LIB_CTX *ctx, const char *propq, + int nid); /** * Creates a new EC_KEY object using a named curve as underlying @@ -1456,12 +1473,7 @@ DEPRECATEDIN_3_0(void EC_KEY_METHOD_get_verify # endif int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid); - -# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ - EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) - +int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc); int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode); int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx); @@ -1478,18 +1490,6 @@ int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len); int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); -/* SM2 will skip the operation check so no need to pass operation here */ -# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \ - EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ - EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id)) -# define EVP_PKEY_CTX_get1_id(ctx, id) \ - EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ - EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id)) - -# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \ - EVP_PKEY_CTX_ctrl(ctx, -1, -1, \ - EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len)) - # define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) # define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) # define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) @@ -1500,9 +1500,6 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **ukm); # define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) # define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) # define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) -# define EVP_PKEY_CTRL_SET1_ID (EVP_PKEY_ALG_CTRL + 11) -# define EVP_PKEY_CTRL_GET1_ID (EVP_PKEY_ALG_CTRL + 12) -# define EVP_PKEY_CTRL_GET1_ID_LEN (EVP_PKEY_ALG_CTRL + 13) /* KDF types */ # define EVP_PKEY_ECDH_KDF_NONE 1 diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h index b12e222510..60677d8560 100644 --- a/include/openssl/ecerr.h +++ b/include/openssl/ecerr.h @@ -233,7 +233,6 @@ int ERR_load_EC_strings(void); # define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH 160 # define EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA 170 # define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159 -# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 # define EC_R_DECODE_ERROR 142 # define EC_R_DISCRIMINANT_IS_ZERO 118 # define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 @@ -243,7 +242,10 @@ int ERR_load_EC_strings(void); # define EC_R_GROUP2PKPARAMETERS_FAILURE 120 # define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 # define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_A 168 # define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_B 169 +# define EC_R_INVALID_COFACTOR 171 # define EC_R_INVALID_COMPRESSED_POINT 110 # define EC_R_INVALID_COMPRESSION_BIT 109 # define EC_R_INVALID_CURVE 141 @@ -252,12 +254,16 @@ int ERR_load_EC_strings(void); # define EC_R_INVALID_ENCODING 102 # define EC_R_INVALID_FIELD 103 # define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GENERATOR 173 # define EC_R_INVALID_GROUP_ORDER 122 # define EC_R_INVALID_KEY 116 +# define EC_R_INVALID_NAMED_GROUP_CONVERSION 174 # define EC_R_INVALID_OUTPUT_LENGTH 161 +# define EC_R_INVALID_P 172 # define EC_R_INVALID_PEER_KEY 133 # define EC_R_INVALID_PENTANOMIAL_BASIS 132 # define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_SEED 175 # define EC_R_INVALID_TRINOMIAL_BASIS 137 # define EC_R_KDF_PARAMETER_ERROR 148 # define EC_R_KEYS_NOT_SET 140 @@ -276,7 +282,6 @@ int ERR_load_EC_strings(void); # define EC_R_OPERATION_NOT_SUPPORTED 152 # define EC_R_PASSED_NULL_PARAMETER 134 # define EC_R_PEER_KEY_ERROR 149 -# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 # define EC_R_POINT_ARITHMETIC_FAILURE 155 # define EC_R_POINT_AT_INFINITY 106 # define EC_R_POINT_COORDINATES_BLIND_FAILURE 163 diff --git a/include/openssl/encoder.h b/include/openssl/encoder.h new file mode 100644 index 0000000000..669f688b2d --- /dev/null +++ b/include/openssl/encoder.h @@ -0,0 +1,121 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_ENCODER_H +# define OPENSSL_ENCODER_H +# pragma once + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# endif +# include +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +OSSL_ENCODER *OSSL_ENCODER_fetch(OSSL_LIB_CTX *libctx, const char *name, + const char *properties); +int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder); +void OSSL_ENCODER_free(OSSL_ENCODER *encoder); + +const OSSL_PROVIDER *OSSL_ENCODER_provider(const OSSL_ENCODER *encoder); +const char *OSSL_ENCODER_properties(const OSSL_ENCODER *encoder); +int OSSL_ENCODER_number(const OSSL_ENCODER *encoder); +int OSSL_ENCODER_is_a(const OSSL_ENCODER *encoder, const char *name); + +void OSSL_ENCODER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(OSSL_ENCODER *encoder, void *arg), + void *arg); +void OSSL_ENCODER_names_do_all(const OSSL_ENCODER *encoder, + void (*fn)(const char *name, void *data), + void *data); +const OSSL_PARAM *OSSL_ENCODER_gettable_params(OSSL_ENCODER *encoder); +int OSSL_ENCODER_get_params(OSSL_ENCODER *encoder, OSSL_PARAM params[]); + +const OSSL_PARAM *OSSL_ENCODER_settable_ctx_params(OSSL_ENCODER *encoder); +OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new(void); +int OSSL_ENCODER_CTX_set_params(OSSL_ENCODER_CTX *ctx, + const OSSL_PARAM params[]); +void OSSL_ENCODER_CTX_free(OSSL_ENCODER_CTX *ctx); + +/* Utilities that help set specific parameters */ +int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx, + const unsigned char *kstr, size_t klen); +int OSSL_ENCODER_CTX_set_pem_password_cb(OSSL_ENCODER_CTX *ctx, + pem_password_cb *cb, void *cbarg); +int OSSL_ENCODER_CTX_set_passphrase_cb(OSSL_ENCODER_CTX *ctx, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg); +int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx, + const UI_METHOD *ui_method, + void *ui_data); +int OSSL_ENCODER_CTX_set_cipher(OSSL_ENCODER_CTX *ctx, + const char *cipher_name, + const char *propquery); +int OSSL_ENCODER_CTX_set_output_type(OSSL_ENCODER_CTX *ctx, + const char *output_type); +int OSSL_ENCODER_CTX_set_selection(OSSL_ENCODER_CTX *ctx, int selection); + +/* Utilities to add encoders */ +int OSSL_ENCODER_CTX_add_encoder(OSSL_ENCODER_CTX *ctx, OSSL_ENCODER *encoder); +int OSSL_ENCODER_CTX_add_extra(OSSL_ENCODER_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); +int OSSL_ENCODER_CTX_get_num_encoders(OSSL_ENCODER_CTX *ctx); + +typedef struct ossl_encoder_instance_st OSSL_ENCODER_INSTANCE; +OSSL_ENCODER * +OSSL_ENCODER_INSTANCE_get_encoder(OSSL_ENCODER_INSTANCE *encoder_inst); +void * +OSSL_ENCODER_INSTANCE_get_encoder_ctx(OSSL_ENCODER_INSTANCE *encoder_inst); +const char * +OSSL_ENCODER_INSTANCE_get_input_type(OSSL_ENCODER_INSTANCE *encoder_inst); +const char * +OSSL_ENCODER_INSTANCE_get_output_type(OSSL_ENCODER_INSTANCE *encoder_inst); + +typedef const void *OSSL_ENCODER_CONSTRUCT(OSSL_ENCODER_INSTANCE *encoder_inst, + void *construct_data); +typedef void OSSL_ENCODER_CLEANUP(void *construct_data); + +int OSSL_ENCODER_CTX_set_construct(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_CONSTRUCT *construct); +int OSSL_ENCODER_CTX_set_construct_data(OSSL_ENCODER_CTX *ctx, + void *construct_data); +int OSSL_ENCODER_CTX_set_cleanup(OSSL_ENCODER_CTX *ctx, + OSSL_ENCODER_CLEANUP *cleanup); + +/* Utilities to output the object to encode */ +int OSSL_ENCODER_to_bio(OSSL_ENCODER_CTX *ctx, BIO *out); +#ifndef OPENSSL_NO_STDIO +int OSSL_ENCODER_to_fp(OSSL_ENCODER_CTX *ctx, FILE *fp); +#endif +int OSSL_ENCODER_to_data(OSSL_ENCODER_CTX *ctx, unsigned char **pdata, + size_t *pdata_len); + +/* + * Create the OSSL_ENCODER_CTX with an associated type. This will perform + * an implicit OSSL_ENCODER_fetch(), suitable for the object of that type. + * This is more useful than calling OSSL_ENCODER_CTX_new(). + */ +OSSL_ENCODER_CTX *OSSL_ENCODER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, + const char *output_type, + int selection, + OSSL_LIB_CTX *libctx, + const char *propquery); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/serializererr.h b/include/openssl/encodererr.h similarity index 61% rename from include/openssl/serializererr.h rename to include/openssl/encodererr.h index f99143b4d1..e146d6ec92 100644 --- a/include/openssl/serializererr.h +++ b/include/openssl/encodererr.h @@ -8,8 +8,8 @@ * https://www.openssl.org/source/license.html */ -#ifndef OPENSSL_OSSL_SERIALIZERERR_H -# define OPENSSL_OSSL_SERIALIZERERR_H +#ifndef OPENSSL_OSSL_ENCODERERR_H +# define OPENSSL_OSSL_ENCODERERR_H # pragma once # include @@ -19,18 +19,19 @@ # ifdef __cplusplus extern "C" # endif -int ERR_load_OSSL_SERIALIZER_strings(void); +int ERR_load_OSSL_ENCODER_strings(void); /* - * OSSL_SERIALIZER function codes. + * OSSL_ENCODER function codes. */ # ifndef OPENSSL_NO_DEPRECATED_3_0 # endif /* - * OSSL_SERIALIZER reason codes. + * OSSL_ENCODER reason codes. */ -# define OSSL_SERIALIZER_R_INCORRECT_PROPERTY_QUERY 100 -# define OSSL_SERIALIZER_R_SERIALIZER_NOT_FOUND 101 +# define OSSL_ENCODER_R_ENCODER_NOT_FOUND 101 +# define OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY 100 +# define OSSL_ENCODER_R_MISSING_GET_PARAMS 102 #endif diff --git a/include/openssl/engine.h b/include/openssl/engine.h index 3af9ecccc9..51260e42a2 100644 --- a/include/openssl/engine.h +++ b/include/openssl/engine.h @@ -763,7 +763,7 @@ typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, void *ENGINE_get_static_state(void); # if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -DEPRECATEDIN_3_0(DEPRECATEDIN_1_1_0(void ENGINE_setup_bsd_cryptodev(void))) +DEPRECATEDIN_1_1_0(void ENGINE_setup_bsd_cryptodev(void)) # endif diff --git a/include/openssl/err.h b/include/openssl/err.h index 77bbba4f9f..8c45087852 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_ERR_H # define OPENSSL_ERR_H # pragma once @@ -113,8 +115,8 @@ struct err_state_st { # define ERR_LIB_CRMF 56 # define ERR_LIB_PROV 57 # define ERR_LIB_CMP 58 -# define ERR_LIB_OSSL_SERIALIZER 59 -# define ERR_LIB_OSSL_DESERIALIZER 60 +# define ERR_LIB_OSSL_ENCODER 59 +# define ERR_LIB_OSSL_DECODER 60 # define ERR_LIB_HTTP 61 # define ERR_LIB_USER 128 @@ -186,24 +188,43 @@ struct err_state_st { * * A few of the reason bits are reserved as flags with special meaning: * - * <4 bits><-------------- 19 bits -------------> - * +-------+-------------------------------------+ - * | rflags| reason | - * +-------+-------------------------------------+ + * <5 bits-<>--------- 19 bits -----------------> + * +-------+-+-----------------------------------+ + * | rflags| | reason | + * +-------+-+-----------------------------------+ + * ^ + * | + * ERR_RFLAG_FATAL = ERR_R_FATAL + * + * The reason flags are part of the overall reason code for practical + * reasons, as they provide an easy way to place different types of + * reason codes in different numeric ranges. + * + * The currently known reason flags are: * - * We have the reason flags being part of the overall reason code for - * backward compatibility reasons, i.e. how ERR_R_FATAL was implemented. + * ERR_RFLAG_FATAL Flags that the reason code is considered fatal. + * For backward compatibility reasons, this flag + * is also the code for ERR_R_FATAL (that reason + * code served the dual purpose of flag and reason + * code in one in pre-3.0 OpenSSL). + * ERR_RFLAG_COMMON Flags that the reason code is common to all + * libraries. All ERR_R_ macros must use this flag, + * and no other _R_ macro is allowed to use it. */ /* Macros to help decode recorded system errors */ # define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1) # define ERR_SYSTEM_MASK ((unsigned int)INT_MAX) -/* Macros to help decode recorded OpenSSL errors */ +/* + * Macros to help decode recorded OpenSSL errors + * As expressed above, RFLAGS and REASON overlap by one bit to allow + * ERR_R_FATAL to use ERR_RFLAG_FATAL as its reason code. + */ # define ERR_LIB_OFFSET 23L # define ERR_LIB_MASK 0xFF -# define ERR_RFLAGS_OFFSET 19L -# define ERR_RFLAGS_MASK 0xF +# define ERR_RFLAGS_OFFSET 18L +# define ERR_RFLAGS_MASK 0x1F # define ERR_REASON_MASK 0X7FFFFF /* @@ -211,40 +232,46 @@ struct err_state_st { * number. */ # define ERR_RFLAG_FATAL (0x1 << ERR_RFLAGS_OFFSET) +# define ERR_RFLAG_COMMON (0x2 << ERR_RFLAGS_OFFSET) # define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0) -static ossl_inline int ERR_GET_LIB(unsigned long errcode) +static ossl_unused ossl_inline int ERR_GET_LIB(unsigned long errcode) { if (ERR_SYSTEM_ERROR(errcode)) return ERR_LIB_SYS; return (errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK; } -static ossl_inline int ERR_GET_FUNC(unsigned long errcode ossl_unused) +static ossl_unused ossl_inline int ERR_GET_FUNC(unsigned long errcode ossl_unused) { return 0; } -static ossl_inline int ERR_GET_RFLAGS(unsigned long errcode) +static ossl_unused ossl_inline int ERR_GET_RFLAGS(unsigned long errcode) { if (ERR_SYSTEM_ERROR(errcode)) return 0; return errcode & (ERR_RFLAGS_MASK << ERR_RFLAGS_OFFSET); } -static ossl_inline int ERR_GET_REASON(unsigned long errcode) +static ossl_unused ossl_inline int ERR_GET_REASON(unsigned long errcode) { if (ERR_SYSTEM_ERROR(errcode)) return errcode & ERR_SYSTEM_MASK; return errcode & ERR_REASON_MASK; } -static ossl_inline int ERR_FATAL_ERROR(unsigned long errcode) +static ossl_unused ossl_inline int ERR_FATAL_ERROR(unsigned long errcode) { return (ERR_GET_RFLAGS(errcode) & ERR_RFLAG_FATAL) != 0; } +static ossl_unused ossl_inline int ERR_COMMON_ERROR(unsigned long errcode) +{ + return (ERR_GET_RFLAGS(errcode) & ERR_RFLAG_COMMON) != 0; +} + /* * ERR_PACK is a helper macro to properly pack OpenSSL error codes and may * only be used for that purpose. System errors are packed internally. @@ -283,59 +310,69 @@ static ossl_inline int ERR_FATAL_ERROR(unsigned long errcode) # define SYS_F_SENDFILE 0 # endif -/* "we came from here" global reason codes, range 1..63 */ -# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ -# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ -# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ -# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ -# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ -# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ -# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ -# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ -# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ -# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ -# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ -# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ -# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ -# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ -# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ -# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ -# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ -# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ -# define ERR_R_OSSL_STORE_LIB ERR_LIB_OSSL_STORE/* 44 */ - /* - * global reason codes, range 64..99 (sub-system specific codes start at 100) - * - * ERR_R_FATAL had dual purposes in pre-3.0 OpenSSL, as a standalone reason - * code as well as a fatal flag. This is still possible to do, as 2**6 (64) - * is present in the whole range of global reason codes. + * All ERR_R_ codes must be combined with ERR_RFLAG_COMMON. */ -# define ERR_R_FATAL (64|ERR_RFLAG_FATAL) -# define ERR_R_MALLOC_FAILURE (65|ERR_RFLAG_FATAL) -# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (66|ERR_RFLAG_FATAL) -# define ERR_R_PASSED_NULL_PARAMETER (67|ERR_RFLAG_FATAL) -# define ERR_R_INTERNAL_ERROR (68|ERR_RFLAG_FATAL) -# define ERR_R_DISABLED (69|ERR_RFLAG_FATAL) -# define ERR_R_INIT_FAIL (70|ERR_RFLAG_FATAL) -# define ERR_R_PASSED_INVALID_ARGUMENT (71) -# define ERR_R_OPERATION_FAIL (72|ERR_RFLAG_FATAL) -# define ERR_R_INVALID_PROVIDER_FUNCTIONS (73|ERR_RFLAG_FATAL) -# define ERR_R_INTERRUPTED_OR_CANCELLED (74) -# define ERR_R_NESTED_ASN1_ERROR (76) -# define ERR_R_MISSING_ASN1_EOS (77) -/* - * 99 is the maximum possible ERR_R_... code, higher values are reserved for - * the individual libraries - */ +/* "we came from here" global reason codes, range 1..255 */ +# define ERR_R_SYS_LIB (ERR_LIB_SYS/* 2 */ | ERR_RFLAG_COMMON) +# define ERR_R_BN_LIB (ERR_LIB_BN/* 3 */ | ERR_RFLAG_COMMON) +# define ERR_R_RSA_LIB (ERR_LIB_RSA/* 4 */ | ERR_RFLAG_COMMON) +# define ERR_R_DH_LIB (ERR_LIB_DH/* 5 */ | ERR_RFLAG_COMMON) +# define ERR_R_EVP_LIB (ERR_LIB_EVP/* 6 */ | ERR_RFLAG_COMMON) +# define ERR_R_BUF_LIB (ERR_LIB_BUF/* 7 */ | ERR_RFLAG_COMMON) +# define ERR_R_OBJ_LIB (ERR_LIB_OBJ/* 8 */ | ERR_RFLAG_COMMON) +# define ERR_R_PEM_LIB (ERR_LIB_PEM/* 9 */ | ERR_RFLAG_COMMON) +# define ERR_R_DSA_LIB (ERR_LIB_DSA/* 10 */ | ERR_RFLAG_COMMON) +# define ERR_R_X509_LIB (ERR_LIB_X509/* 11 */ | ERR_RFLAG_COMMON) +# define ERR_R_ASN1_LIB (ERR_LIB_ASN1/* 13 */ | ERR_RFLAG_COMMON) +# define ERR_R_CRYPTO_LIB (ERR_LIB_CRYPTO/* 15 */ | ERR_RFLAG_COMMON) +# define ERR_R_EC_LIB (ERR_LIB_EC/* 16 */ | ERR_RFLAG_COMMON) +# define ERR_R_BIO_LIB (ERR_LIB_BIO/* 32 */ | ERR_RFLAG_COMMON) +# define ERR_R_PKCS7_LIB (ERR_LIB_PKCS7/* 33 */ | ERR_RFLAG_COMMON) +# define ERR_R_X509V3_LIB (ERR_LIB_X509V3/* 34 */ | ERR_RFLAG_COMMON) +# define ERR_R_ENGINE_LIB (ERR_LIB_ENGINE/* 38 */ | ERR_RFLAG_COMMON) +# define ERR_R_UI_LIB (ERR_LIB_UI/* 40 */ | ERR_RFLAG_COMMON) +# define ERR_R_ECDSA_LIB (ERR_LIB_ECDSA/* 42 */ | ERR_RFLAG_COMMON) +# define ERR_R_OSSL_STORE_LIB (ERR_LIB_OSSL_STORE/* 44 */ | ERR_RFLAG_COMMON) +# define ERR_R_OSSL_DECODER_LIB (ERR_LIB_OSSL_DECODER/* 60 */ | ERR_RFLAG_COMMON) + +/* Other common error codes, range 256..2^ERR_RFLAGS_OFFSET-1 */ +# define ERR_R_FATAL (ERR_RFLAG_FATAL|ERR_RFLAG_COMMON) +# define ERR_R_MALLOC_FAILURE (256|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (257|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (258|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (259|ERR_R_FATAL) +# define ERR_R_DISABLED (260|ERR_R_FATAL) +# define ERR_R_INIT_FAIL (261|ERR_R_FATAL) +# define ERR_R_PASSED_INVALID_ARGUMENT (262|ERR_RFLAG_COMMON) +# define ERR_R_OPERATION_FAIL (263|ERR_R_FATAL) +# define ERR_R_INVALID_PROVIDER_FUNCTIONS (264|ERR_R_FATAL) +# define ERR_R_INTERRUPTED_OR_CANCELLED (265|ERR_RFLAG_COMMON) +# define ERR_R_NESTED_ASN1_ERROR (266|ERR_RFLAG_COMMON) +# define ERR_R_MISSING_ASN1_EOS (267|ERR_RFLAG_COMMON) typedef struct ERR_string_data_st { unsigned long error; const char *string; } ERR_STRING_DATA; -DEFINE_LHASH_OF(ERR_STRING_DATA); +DEFINE_LHASH_OF_INTERNAL(ERR_STRING_DATA); +#define lh_ERR_STRING_DATA_new(hfn, cmp) ((LHASH_OF(ERR_STRING_DATA) *)OPENSSL_LH_new(ossl_check_ERR_STRING_DATA_lh_hashfunc_type(hfn), ossl_check_ERR_STRING_DATA_lh_compfunc_type(cmp))) +#define lh_ERR_STRING_DATA_free(lh) OPENSSL_LH_free(ossl_check_ERR_STRING_DATA_lh_type(lh)) +#define lh_ERR_STRING_DATA_flush(lh) OPENSSL_LH_flush(ossl_check_ERR_STRING_DATA_lh_type(lh)) +#define lh_ERR_STRING_DATA_insert(lh, ptr) ((ERR_STRING_DATA *)OPENSSL_LH_insert(ossl_check_ERR_STRING_DATA_lh_type(lh), ossl_check_ERR_STRING_DATA_lh_plain_type(ptr))) +#define lh_ERR_STRING_DATA_delete(lh, ptr) ((ERR_STRING_DATA *)OPENSSL_LH_delete(ossl_check_ERR_STRING_DATA_lh_type(lh), ossl_check_const_ERR_STRING_DATA_lh_plain_type(ptr))) +#define lh_ERR_STRING_DATA_retrieve(lh, ptr) ((ERR_STRING_DATA *)OPENSSL_LH_retrieve(ossl_check_ERR_STRING_DATA_lh_type(lh), ossl_check_const_ERR_STRING_DATA_lh_plain_type(ptr))) +#define lh_ERR_STRING_DATA_error(lh) OPENSSL_LH_error(ossl_check_ERR_STRING_DATA_lh_type(lh)) +#define lh_ERR_STRING_DATA_num_items(lh) OPENSSL_LH_num_items(ossl_check_ERR_STRING_DATA_lh_type(lh)) +#define lh_ERR_STRING_DATA_node_stats_bio(lh, out) OPENSSL_LH_node_stats_bio(ossl_check_const_ERR_STRING_DATA_lh_type(lh), out) +#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh, out) OPENSSL_LH_node_usage_stats_bio(ossl_check_const_ERR_STRING_DATA_lh_type(lh), out) +#define lh_ERR_STRING_DATA_stats_bio(lh, out) OPENSSL_LH_stats_bio(ossl_check_const_ERR_STRING_DATA_lh_type(lh), out) +#define lh_ERR_STRING_DATA_get_down_load(lh) OPENSSL_LH_get_down_load(ossl_check_ERR_STRING_DATA_lh_type(lh)) +#define lh_ERR_STRING_DATA_set_down_load(lh, dl) OPENSSL_LH_set_down_load(ossl_check_ERR_STRING_DATA_lh_type(lh), dl) +#define lh_ERR_STRING_DATA_doall(lh, dfn) OPENSSL_LH_doall(ossl_check_ERR_STRING_DATA_lh_type(lh), ossl_check_ERR_STRING_DATA_lh_doallfunc_type(dfn)) + /* 12 lines and some on an 80 column terminal */ #define ERR_MAX_DATA_SIZE 1024 diff --git a/include/openssl/err.h.in b/include/openssl/err.h.in new file mode 100644 index 0000000000..0e6f4fbad2 --- /dev/null +++ b/include/openssl/err.h.in @@ -0,0 +1,478 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_lhash_macros); +-} + +#ifndef OPENSSL_ERR_H +# define OPENSSL_ERR_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_ERR_H +# endif + +# include + +# ifndef OPENSSL_NO_STDIO +# include +# include +# endif + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef OPENSSL_NO_FILENAMES +# define ERR_PUT_error(l,f,r,fn,ln) ERR_put_error(l,f,r,fn,ln) +# else +# define ERR_PUT_error(l,f,r,fn,ln) ERR_put_error(l,f,r,NULL,0) +# endif +# endif + +# include +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# if !defined(OPENSSL_NO_DEPRECATED_3_0) || defined(OSSL_FORCE_ERR_STATE) +# define ERR_FLAG_MARK 0x01 +# define ERR_FLAG_CLEAR 0x02 + +# define ERR_NUM_ERRORS 16 +struct err_state_st { + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + size_t err_data_size[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + const char *err_func[ERR_NUM_ERRORS]; + int top, bottom; +}; +# endif + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_OSSL_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +/* # define ERR_LIB_JPAKE 49 */ +# define ERR_LIB_CT 50 +# define ERR_LIB_ASYNC 51 +# define ERR_LIB_KDF 52 +# define ERR_LIB_SM2 53 +# define ERR_LIB_ESS 54 +# define ERR_LIB_PROP 55 +# define ERR_LIB_CRMF 56 +# define ERR_LIB_PROV 57 +# define ERR_LIB_CMP 58 +# define ERR_LIB_OSSL_ENCODER 59 +# define ERR_LIB_OSSL_DECODER 60 +# define ERR_LIB_HTTP 61 + +# define ERR_LIB_USER 128 + +# if 1 || !defined(OPENSSL_NO_DEPRECATED_3_0) +# define ASN1err(f, r) ERR_raise_data(ERR_LIB_ASN1, (r), NULL) +# define ASYNCerr(f, r) ERR_raise_data(ERR_LIB_ASYNC, (r), NULL) +# define BIOerr(f, r) ERR_raise_data(ERR_LIB_BIO, (r), NULL) +# define BNerr(f, r) ERR_raise_data(ERR_LIB_BN, (r), NULL) +# define BUFerr(f, r) ERR_raise_data(ERR_LIB_BUF, (r), NULL) +# define CMPerr(f, r) ERR_raise_data(ERR_LIB_CMP, (r), NULL) +# define CMSerr(f, r) ERR_raise_data(ERR_LIB_CMS, (r), NULL) +# define COMPerr(f, r) ERR_raise_data(ERR_LIB_COMP, (r), NULL) +# define CONFerr(f, r) ERR_raise_data(ERR_LIB_CONF, (r), NULL) +# define CRMFerr(f, r) ERR_raise_data(ERR_LIB_CRMF, (r), NULL) +# define CRYPTOerr(f, r) ERR_raise_data(ERR_LIB_CRYPTO, (r), NULL) +# define CTerr(f, r) ERR_raise_data(ERR_LIB_CT, (r), NULL) +# define DHerr(f, r) ERR_raise_data(ERR_LIB_DH, (r), NULL) +# define DSAerr(f, r) ERR_raise_data(ERR_LIB_DSA, (r), NULL) +# define DSOerr(f, r) ERR_raise_data(ERR_LIB_DSO, (r), NULL) +# define ECDHerr(f, r) ERR_raise_data(ERR_LIB_ECDH, (r), NULL) +# define ECDSAerr(f, r) ERR_raise_data(ERR_LIB_ECDSA, (r), NULL) +# define ECerr(f, r) ERR_raise_data(ERR_LIB_EC, (r), NULL) +# define ENGINEerr(f, r) ERR_raise_data(ERR_LIB_ENGINE, (r), NULL) +# define ESSerr(f, r) ERR_raise_data(ERR_LIB_ESS, (r), NULL) +# define EVPerr(f, r) ERR_raise_data(ERR_LIB_EVP, (r), NULL) +# define FIPSerr(f, r) ERR_raise_data(ERR_LIB_FIPS, (r), NULL) +# define HMACerr(f, r) ERR_raise_data(ERR_LIB_HMAC, (r), NULL) +# define HTTPerr(f, r) ERR_raise_data(ERR_LIB_HTTP, (r), NULL) +# define KDFerr(f, r) ERR_raise_data(ERR_LIB_KDF, (r), NULL) +# define OBJerr(f, r) ERR_raise_data(ERR_LIB_OBJ, (r), NULL) +# define OCSPerr(f, r) ERR_raise_data(ERR_LIB_OCSP, (r), NULL) +# define OSSL_STOREerr(f, r) ERR_raise_data(ERR_LIB_OSSL_STORE, (r), NULL) +# define PEMerr(f, r) ERR_raise_data(ERR_LIB_PEM, (r), NULL) +# define PKCS12err(f, r) ERR_raise_data(ERR_LIB_PKCS12, (r), NULL) +# define PKCS7err(f, r) ERR_raise_data(ERR_LIB_PKCS7, (r), NULL) +# define PROPerr(f, r) ERR_raise_data(ERR_LIB_PROP, (r), NULL) +# define PROVerr(f, r) ERR_raise_data(ERR_LIB_PROV, (r), NULL) +# define RANDerr(f, r) ERR_raise_data(ERR_LIB_RAND, (r), NULL) +# define RSAerr(f, r) ERR_raise_data(ERR_LIB_RSA, (r), NULL) +# define KDFerr(f, r) ERR_raise_data(ERR_LIB_KDF, (r), NULL) +# define SM2err(f, r) ERR_raise_data(ERR_LIB_SM2, (r), NULL) +# define SSLerr(f, r) ERR_raise_data(ERR_LIB_SSL, (r), NULL) +# define SYSerr(f, r) ERR_raise_data(ERR_LIB_SYS, (r), NULL) +# define TSerr(f, r) ERR_raise_data(ERR_LIB_TS, (r), NULL) +# define UIerr(f, r) ERR_raise_data(ERR_LIB_UI, (r), NULL) +# define X509V3err(f, r) ERR_raise_data(ERR_LIB_X509V3, (r), NULL) +# define X509err(f, r) ERR_raise_data(ERR_LIB_X509, (r), NULL) +# endif + +/*- + * The error code packs differently depending on if it records a system + * error or an OpenSSL error. + * + * A system error packs like this (we follow POSIX and only allow positive + * numbers that fit in an |int|): + * + * +-+-------------------------------------------------------------+ + * |1| system error number | + * +-+-------------------------------------------------------------+ + * + * An OpenSSL error packs like this: + * + * <---------------------------- 32 bits --------------------------> + * <--- 8 bits ---><------------------ 23 bits -----------------> + * +-+---------------+---------------------------------------------+ + * |0| library | reason | + * +-+---------------+---------------------------------------------+ + * + * A few of the reason bits are reserved as flags with special meaning: + * + * <5 bits-<>--------- 19 bits -----------------> + * +-------+-+-----------------------------------+ + * | rflags| | reason | + * +-------+-+-----------------------------------+ + * ^ + * | + * ERR_RFLAG_FATAL = ERR_R_FATAL + * + * The reason flags are part of the overall reason code for practical + * reasons, as they provide an easy way to place different types of + * reason codes in different numeric ranges. + * + * The currently known reason flags are: + * + * ERR_RFLAG_FATAL Flags that the reason code is considered fatal. + * For backward compatibility reasons, this flag + * is also the code for ERR_R_FATAL (that reason + * code served the dual purpose of flag and reason + * code in one in pre-3.0 OpenSSL). + * ERR_RFLAG_COMMON Flags that the reason code is common to all + * libraries. All ERR_R_ macros must use this flag, + * and no other _R_ macro is allowed to use it. + */ + +/* Macros to help decode recorded system errors */ +# define ERR_SYSTEM_FLAG ((unsigned int)INT_MAX + 1) +# define ERR_SYSTEM_MASK ((unsigned int)INT_MAX) + +/* + * Macros to help decode recorded OpenSSL errors + * As expressed above, RFLAGS and REASON overlap by one bit to allow + * ERR_R_FATAL to use ERR_RFLAG_FATAL as its reason code. + */ +# define ERR_LIB_OFFSET 23L +# define ERR_LIB_MASK 0xFF +# define ERR_RFLAGS_OFFSET 18L +# define ERR_RFLAGS_MASK 0x1F +# define ERR_REASON_MASK 0X7FFFFF + +/* + * Reason flags are defined pre-shifted to easily combine with the reason + * number. + */ +# define ERR_RFLAG_FATAL (0x1 << ERR_RFLAGS_OFFSET) +# define ERR_RFLAG_COMMON (0x2 << ERR_RFLAGS_OFFSET) + +# define ERR_SYSTEM_ERROR(errcode) (((errcode) & ERR_SYSTEM_FLAG) != 0) + +static ossl_unused ossl_inline int ERR_GET_LIB(unsigned long errcode) +{ + if (ERR_SYSTEM_ERROR(errcode)) + return ERR_LIB_SYS; + return (errcode >> ERR_LIB_OFFSET) & ERR_LIB_MASK; +} + +static ossl_unused ossl_inline int ERR_GET_FUNC(unsigned long errcode ossl_unused) +{ + return 0; +} + +static ossl_unused ossl_inline int ERR_GET_RFLAGS(unsigned long errcode) +{ + if (ERR_SYSTEM_ERROR(errcode)) + return 0; + return errcode & (ERR_RFLAGS_MASK << ERR_RFLAGS_OFFSET); +} + +static ossl_unused ossl_inline int ERR_GET_REASON(unsigned long errcode) +{ + if (ERR_SYSTEM_ERROR(errcode)) + return errcode & ERR_SYSTEM_MASK; + return errcode & ERR_REASON_MASK; +} + +static ossl_unused ossl_inline int ERR_FATAL_ERROR(unsigned long errcode) +{ + return (ERR_GET_RFLAGS(errcode) & ERR_RFLAG_FATAL) != 0; +} + +static ossl_unused ossl_inline int ERR_COMMON_ERROR(unsigned long errcode) +{ + return (ERR_GET_RFLAGS(errcode) & ERR_RFLAG_COMMON) != 0; +} + +/* + * ERR_PACK is a helper macro to properly pack OpenSSL error codes and may + * only be used for that purpose. System errors are packed internally. + * ERR_PACK takes reason flags and reason code combined in |reason|. + * ERR_PACK ignores |func|, that parameter is just legacy from pre-3.0 OpenSSL. + */ +# define ERR_PACK(lib,func,reason) \ + ( (((unsigned long)(lib) & ERR_LIB_MASK ) << ERR_LIB_OFFSET) | \ + (((unsigned long)(reason) & ERR_REASON_MASK)) ) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define SYS_F_FOPEN 0 +# define SYS_F_CONNECT 0 +# define SYS_F_GETSERVBYNAME 0 +# define SYS_F_SOCKET 0 +# define SYS_F_IOCTLSOCKET 0 +# define SYS_F_BIND 0 +# define SYS_F_LISTEN 0 +# define SYS_F_ACCEPT 0 +# define SYS_F_WSASTARTUP 0 +# define SYS_F_OPENDIR 0 +# define SYS_F_FREAD 0 +# define SYS_F_GETADDRINFO 0 +# define SYS_F_GETNAMEINFO 0 +# define SYS_F_SETSOCKOPT 0 +# define SYS_F_GETSOCKOPT 0 +# define SYS_F_GETSOCKNAME 0 +# define SYS_F_GETHOSTBYNAME 0 +# define SYS_F_FFLUSH 0 +# define SYS_F_OPEN 0 +# define SYS_F_CLOSE 0 +# define SYS_F_IOCTL 0 +# define SYS_F_STAT 0 +# define SYS_F_FCNTL 0 +# define SYS_F_FSTAT 0 +# define SYS_F_SENDFILE 0 +# endif + +/* + * All ERR_R_ codes must be combined with ERR_RFLAG_COMMON. + */ + +/* "we came from here" global reason codes, range 1..255 */ +# define ERR_R_SYS_LIB (ERR_LIB_SYS/* 2 */ | ERR_RFLAG_COMMON) +# define ERR_R_BN_LIB (ERR_LIB_BN/* 3 */ | ERR_RFLAG_COMMON) +# define ERR_R_RSA_LIB (ERR_LIB_RSA/* 4 */ | ERR_RFLAG_COMMON) +# define ERR_R_DH_LIB (ERR_LIB_DH/* 5 */ | ERR_RFLAG_COMMON) +# define ERR_R_EVP_LIB (ERR_LIB_EVP/* 6 */ | ERR_RFLAG_COMMON) +# define ERR_R_BUF_LIB (ERR_LIB_BUF/* 7 */ | ERR_RFLAG_COMMON) +# define ERR_R_OBJ_LIB (ERR_LIB_OBJ/* 8 */ | ERR_RFLAG_COMMON) +# define ERR_R_PEM_LIB (ERR_LIB_PEM/* 9 */ | ERR_RFLAG_COMMON) +# define ERR_R_DSA_LIB (ERR_LIB_DSA/* 10 */ | ERR_RFLAG_COMMON) +# define ERR_R_X509_LIB (ERR_LIB_X509/* 11 */ | ERR_RFLAG_COMMON) +# define ERR_R_ASN1_LIB (ERR_LIB_ASN1/* 13 */ | ERR_RFLAG_COMMON) +# define ERR_R_CRYPTO_LIB (ERR_LIB_CRYPTO/* 15 */ | ERR_RFLAG_COMMON) +# define ERR_R_EC_LIB (ERR_LIB_EC/* 16 */ | ERR_RFLAG_COMMON) +# define ERR_R_BIO_LIB (ERR_LIB_BIO/* 32 */ | ERR_RFLAG_COMMON) +# define ERR_R_PKCS7_LIB (ERR_LIB_PKCS7/* 33 */ | ERR_RFLAG_COMMON) +# define ERR_R_X509V3_LIB (ERR_LIB_X509V3/* 34 */ | ERR_RFLAG_COMMON) +# define ERR_R_ENGINE_LIB (ERR_LIB_ENGINE/* 38 */ | ERR_RFLAG_COMMON) +# define ERR_R_UI_LIB (ERR_LIB_UI/* 40 */ | ERR_RFLAG_COMMON) +# define ERR_R_ECDSA_LIB (ERR_LIB_ECDSA/* 42 */ | ERR_RFLAG_COMMON) +# define ERR_R_OSSL_STORE_LIB (ERR_LIB_OSSL_STORE/* 44 */ | ERR_RFLAG_COMMON) +# define ERR_R_OSSL_DECODER_LIB (ERR_LIB_OSSL_DECODER/* 60 */ | ERR_RFLAG_COMMON) + +/* Other common error codes, range 256..2^ERR_RFLAGS_OFFSET-1 */ +# define ERR_R_FATAL (ERR_RFLAG_FATAL|ERR_RFLAG_COMMON) +# define ERR_R_MALLOC_FAILURE (256|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (257|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (258|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (259|ERR_R_FATAL) +# define ERR_R_DISABLED (260|ERR_R_FATAL) +# define ERR_R_INIT_FAIL (261|ERR_R_FATAL) +# define ERR_R_PASSED_INVALID_ARGUMENT (262|ERR_RFLAG_COMMON) +# define ERR_R_OPERATION_FAIL (263|ERR_R_FATAL) +# define ERR_R_INVALID_PROVIDER_FUNCTIONS (264|ERR_R_FATAL) +# define ERR_R_INTERRUPTED_OR_CANCELLED (265|ERR_RFLAG_COMMON) +# define ERR_R_NESTED_ASN1_ERROR (266|ERR_RFLAG_COMMON) +# define ERR_R_MISSING_ASN1_EOS (267|ERR_RFLAG_COMMON) + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +{- + generate_lhash_macros("ERR_STRING_DATA"); +-} + +/* 12 lines and some on an 80 column terminal */ +#define ERR_MAX_DATA_SIZE 1024 + +/* Building blocks */ +void ERR_new(void); +void ERR_set_debug(const char *file, int line, const char *func); +void ERR_set_error(int lib, int reason, const char *fmt, ...); +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args); + +/* Main error raising functions */ +# define ERR_raise(lib, reason) ERR_raise_data((lib),(reason),NULL) +# define ERR_raise_data \ + (ERR_new(), \ + ERR_set_debug(OPENSSL_FILE,OPENSSL_LINE,OPENSSL_FUNC), \ + ERR_set_error) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 +/* Backward compatibility */ +# define ERR_put_error(lib, func, reason, file, line) \ + (ERR_new(), \ + ERR_set_debug((file), (line), OPENSSL_FUNC), \ + ERR_set_error((lib), (reason), NULL)) +# endif + +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +/* + * TODO(3.0) consider if the following three functions should be deprecated. + * They all drop the error record from the error queue, so regardless of which + * one is used, the rest of the information is lost, making them not so useful. + * The recommendation should be to use the peek functions to extract all the + * additional data. + */ +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_func(const char **func); +unsigned long ERR_get_error_data(const char **data, int *flags); +unsigned long ERR_get_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags); +DEPRECATEDIN_3_0(unsigned long ERR_get_error_line_data(const char **file, + int *line, + const char **data, + int *flags)) +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_func(const char **func); +unsigned long ERR_peek_error_data(const char **data, int *flags); +unsigned long ERR_peek_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags); +DEPRECATEDIN_3_0(unsigned long ERR_peek_error_line_data(const char **file, + int *line, + const char **data, + int *flags)) +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_func(const char **func); +unsigned long ERR_peek_last_error_data(const char **data, int *flags); +unsigned long ERR_peek_last_error_all(const char **file, int *line, + const char **func, + const char **data, int *flags); +DEPRECATEDIN_3_0(unsigned long ERR_peek_last_error_line_data(const char **file, + int *line, + const char **data, + int *flags)) + +void ERR_clear_error(void); + +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +DEPRECATEDIN_3_0(const char *ERR_func_error_string(unsigned long e)) +const char *ERR_reason_error_string(unsigned long e); + +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_STDIO +void ERR_print_errors_fp(FILE *fp); +# endif +void ERR_print_errors(BIO *bp); + +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +void ERR_add_error_txt(const char *sepr, const char *txt); +void ERR_add_error_mem_bio(const char *sep, BIO *bio); + +int ERR_load_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_strings_const(const ERR_STRING_DATA *str); +int ERR_unload_strings(int lib, ERR_STRING_DATA *str); +int ERR_load_ERR_strings(void); + +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define ERR_load_crypto_strings() \ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# define ERR_free_strings() while(0) continue +#endif + +DEPRECATEDIN_1_1_0(void ERR_remove_thread_state(void *)) +DEPRECATEDIN_1_0_0(void ERR_remove_state(unsigned long pid)) +DEPRECATEDIN_3_0(ERR_STATE *ERR_get_state(void)) + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); +int ERR_clear_last_mark(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/openssl/ess.h b/include/openssl/ess.h index 17962473c1..a1f7d6a05f 100644 --- a/include/openssl/ess.h +++ b/include/openssl/ess.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/ess.h.in + * * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_ESS_H # define OPENSSL_ESS_H @@ -24,12 +29,64 @@ typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL; typedef struct ESS_cert_id ESS_CERT_ID; typedef struct ESS_signing_cert ESS_SIGNING_CERT; -DEFINE_OR_DECLARE_STACK_OF(ESS_CERT_ID) +SKM_DEFINE_STACK_OF_INTERNAL(ESS_CERT_ID, ESS_CERT_ID, ESS_CERT_ID) +#define sk_ESS_CERT_ID_num(sk) OPENSSL_sk_num(ossl_check_const_ESS_CERT_ID_sk_type(sk)) +#define sk_ESS_CERT_ID_value(sk, idx) ((ESS_CERT_ID *)OPENSSL_sk_value(ossl_check_const_ESS_CERT_ID_sk_type(sk), (idx))) +#define sk_ESS_CERT_ID_new(cmp) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_new(ossl_check_ESS_CERT_ID_compfunc_type(cmp))) +#define sk_ESS_CERT_ID_new_null() ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_new_null()) +#define sk_ESS_CERT_ID_new_reserve(cmp, n) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_new_reserve(ossl_check_ESS_CERT_ID_compfunc_type(cmp), (n))) +#define sk_ESS_CERT_ID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ESS_CERT_ID_sk_type(sk), (n)) +#define sk_ESS_CERT_ID_free(sk) OPENSSL_sk_free(ossl_check_ESS_CERT_ID_sk_type(sk)) +#define sk_ESS_CERT_ID_zero(sk) OPENSSL_sk_zero(ossl_check_ESS_CERT_ID_sk_type(sk)) +#define sk_ESS_CERT_ID_delete(sk, i) ((ESS_CERT_ID *)OPENSSL_sk_delete(ossl_check_ESS_CERT_ID_sk_type(sk), (i))) +#define sk_ESS_CERT_ID_delete_ptr(sk, ptr) ((ESS_CERT_ID *)OPENSSL_sk_delete_ptr(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr))) +#define sk_ESS_CERT_ID_push(sk, ptr) OPENSSL_sk_push(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr)) +#define sk_ESS_CERT_ID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr)) +#define sk_ESS_CERT_ID_pop(sk) ((ESS_CERT_ID *)OPENSSL_sk_pop(ossl_check_ESS_CERT_ID_sk_type(sk))) +#define sk_ESS_CERT_ID_shift(sk) ((ESS_CERT_ID *)OPENSSL_sk_shift(ossl_check_ESS_CERT_ID_sk_type(sk))) +#define sk_ESS_CERT_ID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ESS_CERT_ID_sk_type(sk),ossl_check_ESS_CERT_ID_freefunc_type(freefunc)) +#define sk_ESS_CERT_ID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr), (idx)) +#define sk_ESS_CERT_ID_set(sk, idx, ptr) ((ESS_CERT_ID *)OPENSSL_sk_set(ossl_check_ESS_CERT_ID_sk_type(sk), (idx), ossl_check_ESS_CERT_ID_type(ptr))) +#define sk_ESS_CERT_ID_find(sk, ptr) OPENSSL_sk_find(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr)) +#define sk_ESS_CERT_ID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr)) +#define sk_ESS_CERT_ID_sort(sk) OPENSSL_sk_sort(ossl_check_ESS_CERT_ID_sk_type(sk)) +#define sk_ESS_CERT_ID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ESS_CERT_ID_sk_type(sk)) +#define sk_ESS_CERT_ID_dup(sk) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_dup(ossl_check_const_ESS_CERT_ID_sk_type(sk))) +#define sk_ESS_CERT_ID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_deep_copy(ossl_check_const_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_copyfunc_type(copyfunc), ossl_check_ESS_CERT_ID_freefunc_type(freefunc))) +#define sk_ESS_CERT_ID_set_cmp_func(sk, cmp) ((sk_ESS_CERT_ID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_compfunc_type(cmp))) + + typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2; typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2; -DEFINE_OR_DECLARE_STACK_OF(ESS_CERT_ID_V2) +SKM_DEFINE_STACK_OF_INTERNAL(ESS_CERT_ID_V2, ESS_CERT_ID_V2, ESS_CERT_ID_V2) +#define sk_ESS_CERT_ID_V2_num(sk) OPENSSL_sk_num(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk)) +#define sk_ESS_CERT_ID_V2_value(sk, idx) ((ESS_CERT_ID_V2 *)OPENSSL_sk_value(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk), (idx))) +#define sk_ESS_CERT_ID_V2_new(cmp) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_new(ossl_check_ESS_CERT_ID_V2_compfunc_type(cmp))) +#define sk_ESS_CERT_ID_V2_new_null() ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_new_null()) +#define sk_ESS_CERT_ID_V2_new_reserve(cmp, n) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_new_reserve(ossl_check_ESS_CERT_ID_V2_compfunc_type(cmp), (n))) +#define sk_ESS_CERT_ID_V2_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ESS_CERT_ID_V2_sk_type(sk), (n)) +#define sk_ESS_CERT_ID_V2_free(sk) OPENSSL_sk_free(ossl_check_ESS_CERT_ID_V2_sk_type(sk)) +#define sk_ESS_CERT_ID_V2_zero(sk) OPENSSL_sk_zero(ossl_check_ESS_CERT_ID_V2_sk_type(sk)) +#define sk_ESS_CERT_ID_V2_delete(sk, i) ((ESS_CERT_ID_V2 *)OPENSSL_sk_delete(ossl_check_ESS_CERT_ID_V2_sk_type(sk), (i))) +#define sk_ESS_CERT_ID_V2_delete_ptr(sk, ptr) ((ESS_CERT_ID_V2 *)OPENSSL_sk_delete_ptr(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr))) +#define sk_ESS_CERT_ID_V2_push(sk, ptr) OPENSSL_sk_push(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr)) +#define sk_ESS_CERT_ID_V2_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr)) +#define sk_ESS_CERT_ID_V2_pop(sk) ((ESS_CERT_ID_V2 *)OPENSSL_sk_pop(ossl_check_ESS_CERT_ID_V2_sk_type(sk))) +#define sk_ESS_CERT_ID_V2_shift(sk) ((ESS_CERT_ID_V2 *)OPENSSL_sk_shift(ossl_check_ESS_CERT_ID_V2_sk_type(sk))) +#define sk_ESS_CERT_ID_V2_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ESS_CERT_ID_V2_sk_type(sk),ossl_check_ESS_CERT_ID_V2_freefunc_type(freefunc)) +#define sk_ESS_CERT_ID_V2_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr), (idx)) +#define sk_ESS_CERT_ID_V2_set(sk, idx, ptr) ((ESS_CERT_ID_V2 *)OPENSSL_sk_set(ossl_check_ESS_CERT_ID_V2_sk_type(sk), (idx), ossl_check_ESS_CERT_ID_V2_type(ptr))) +#define sk_ESS_CERT_ID_V2_find(sk, ptr) OPENSSL_sk_find(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr)) +#define sk_ESS_CERT_ID_V2_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr)) +#define sk_ESS_CERT_ID_V2_sort(sk) OPENSSL_sk_sort(ossl_check_ESS_CERT_ID_V2_sk_type(sk)) +#define sk_ESS_CERT_ID_V2_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk)) +#define sk_ESS_CERT_ID_V2_dup(sk) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_dup(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk))) +#define sk_ESS_CERT_ID_V2_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_deep_copy(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_copyfunc_type(copyfunc), ossl_check_ESS_CERT_ID_V2_freefunc_type(freefunc))) +#define sk_ESS_CERT_ID_V2_set_cmp_func(sk, cmp) ((sk_ESS_CERT_ID_V2_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_compfunc_type(cmp))) + + DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_ISSUER_SERIAL) DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_ISSUER_SERIAL, ESS_ISSUER_SERIAL) diff --git a/include/openssl/ess.h.in b/include/openssl/ess.h.in new file mode 100644 index 0000000000..185bdd8f8b --- /dev/null +++ b/include/openssl/ess.h.in @@ -0,0 +1,69 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_ESS_H +# define OPENSSL_ESS_H + +# include + +# ifdef __cplusplus +extern "C" { +# endif +# include +# include +# include + + +typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL; +typedef struct ESS_cert_id ESS_CERT_ID; +typedef struct ESS_signing_cert ESS_SIGNING_CERT; + +{- + generate_stack_macros("ESS_CERT_ID"); +-} + + +typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2; +typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2; + +{- + generate_stack_macros("ESS_CERT_ID_V2"); +-} + + +DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_ISSUER_SERIAL) +DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_ISSUER_SERIAL, ESS_ISSUER_SERIAL) +DECLARE_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) + +DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_CERT_ID) +DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_CERT_ID, ESS_CERT_ID) +DECLARE_ASN1_DUP_FUNCTION(ESS_CERT_ID) + +DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_SIGNING_CERT) +DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_SIGNING_CERT, ESS_SIGNING_CERT) +DECLARE_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) + +DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_CERT_ID_V2) +DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_CERT_ID_V2, ESS_CERT_ID_V2) +DECLARE_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2) + +DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_SIGNING_CERT_V2) +DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_SIGNING_CERT_V2, ESS_SIGNING_CERT_V2) +DECLARE_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2) + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 57b6ff1f7c..326289a1dd 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -79,9 +79,9 @@ extern "C" { #endif -int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq); -int EVP_default_properties_is_fips_enabled(OPENSSL_CTX *libctx); -int EVP_default_properties_enable_fips(OPENSSL_CTX *libctx, int enable); +int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq); +int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX *libctx); +int EVP_default_properties_enable_fips(OSSL_LIB_CTX *libctx, int enable); # define EVP_PKEY_MO_SIGN 0x0001 # define EVP_PKEY_MO_VERIFY 0x0002 @@ -386,8 +386,7 @@ DEPRECATEDIN_3_0(int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher)) # define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24 /* Get the IV length used by the cipher */ # define EVP_CTRL_GET_IVLEN 0x25 -/* Get the IV used by the cipher */ -# define EVP_CTRL_GET_IV 0x26 +/* 0x26 is unused */ /* Tell the cipher it's doing a speed test (SIV disallows multiple ops) */ # define EVP_CTRL_SET_SPEED 0x27 /* Get the unprotectedAttrs from cipher ctx */ @@ -466,14 +465,6 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, # ifndef OPENSSL_NO_EC # define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ (eckey)) -# define EVP_PKEY_assign_X25519(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_X25519,\ - (ecxkey)) -# define EVP_PKEY_assign_X448(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_X448,\ - (ecxkey)) -# define EVP_PKEY_assign_ED25519(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_ED25519,\ - (ecxkey)) -# define EVP_PKEY_assign_ED448(pkey,ecxkey) EVP_PKEY_assign((pkey),EVP_PKEY_ED448,\ - (ecxkey)) # endif # ifndef OPENSSL_NO_SIPHASH # define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),\ @@ -533,7 +524,7 @@ int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); int EVP_CIPHER_mode(const EVP_CIPHER *cipher); -EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_CIPHER *EVP_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); int EVP_CIPHER_up_ref(EVP_CIPHER *cipher); void EVP_CIPHER_free(EVP_CIPHER *cipher); @@ -545,9 +536,11 @@ int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_tag_length(const EVP_CIPHER_CTX *ctx); -const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx); -const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx); -unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx); +DEPRECATEDIN_3_0(const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)) +DEPRECATEDIN_3_0(const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)) +DEPRECATEDIN_3_0(unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)) +int EVP_CIPHER_CTX_get_iv_state(EVP_CIPHER_CTX *ctx, void *buf, size_t len); +int EVP_CIPHER_CTX_get_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len); unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num); @@ -635,8 +628,9 @@ __owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, __owur int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, unsigned char *md, size_t len); -__owur EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm, +__owur EVP_MD *EVP_MD_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); + int EVP_MD_up_ref(EVP_MD *md); void EVP_MD_free(EVP_MD *md); @@ -697,6 +691,9 @@ __owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, __owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, EVP_PKEY *pkey); +__owur int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey, OSSL_LIB_CTX *libctx, + const char *propq); __owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, @@ -704,14 +701,17 @@ __owur int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, __owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, unsigned int siglen, EVP_PKEY *pkey); +__owur int EVP_VerifyFinal_ex(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey, + OSSL_LIB_CTX *libctx, const char *propq); __owur int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen); int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, EVP_PKEY *pkey, - OPENSSL_CTX *libctx); + const char *mdname, OSSL_LIB_CTX *libctx, + const char *props, EVP_PKEY *pkey); /*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); @@ -720,8 +720,8 @@ __owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen); int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const char *mdname, const char *props, - EVP_PKEY *pkey, OPENSSL_CTX *libctx); + const char *mdname, OSSL_LIB_CTX *libctx, + const char *props, EVP_PKEY *pkey); __owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); @@ -1072,7 +1072,7 @@ void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph, const char *from, const char *to, void *x), void *arg); -void EVP_CIPHER_do_all_provided(OPENSSL_CTX *libctx, +void EVP_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_CIPHER *cipher, void *arg), void *arg); @@ -1082,17 +1082,18 @@ void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *ciph, const char *from, const char *to, void *x), void *arg); -void EVP_MD_do_all_provided(OPENSSL_CTX *libctx, +void EVP_MD_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_MD *md, void *arg), void *arg); /* MAC stuff */ -EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, +EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties); int EVP_MAC_up_ref(EVP_MAC *mac); void EVP_MAC_free(EVP_MAC *mac); int EVP_MAC_number(const EVP_MAC *mac); +const char *EVP_MAC_name(const EVP_MAC *mac); int EVP_MAC_is_a(const EVP_MAC *mac, const char *name); const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac); int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); @@ -1113,7 +1114,7 @@ const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac); const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac); const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac); -void EVP_MAC_do_all_provided(OPENSSL_CTX *libctx, +void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_MAC *mac, void *arg), void *arg); void EVP_MAC_names_do_all(const EVP_MAC *mac, @@ -1121,7 +1122,7 @@ void EVP_MAC_names_do_all(const EVP_MAC *mac, void *data); /* RAND stuff */ -EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm, +EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties); int EVP_RAND_up_ref(EVP_RAND *rand); void EVP_RAND_free(EVP_RAND *rand); @@ -1140,7 +1141,7 @@ const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand); const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand); const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand); -void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx, +void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_RAND *rand, void *arg), void *arg); void EVP_RAND_names_do_all(const EVP_RAND *rand, @@ -1160,11 +1161,7 @@ int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, const unsigned char *addin, size_t addin_len); __owur int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen); __owur int EVP_RAND_enable_locking(EVP_RAND_CTX *ctx); -int EVP_RAND_set_callbacks(EVP_RAND_CTX *ctx, - OSSL_INOUT_CALLBACK *get_entropy, - OSSL_CALLBACK *cleanup_entropy, - OSSL_INOUT_CALLBACK *get_nonce, - OSSL_CALLBACK *cleanup_nonce, void *arg); + int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx); unsigned int EVP_RAND_strength(EVP_RAND_CTX *ctx); int EVP_RAND_state(EVP_RAND_CTX *ctx); @@ -1182,6 +1179,9 @@ DEPRECATEDIN_3_0(int EVP_PKEY_encrypt_old(unsigned char *enc_key, const unsigned char *key, int key_len, EVP_PKEY *pub_key)) int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name); +void EVP_PKEY_typenames_do_all(const EVP_PKEY *pkey, + void (*fn)(const char *name, void *data), + void *data); int EVP_PKEY_type(int type); int EVP_PKEY_id(const EVP_PKEY *pkey); int EVP_PKEY_base_id(const EVP_PKEY *pkey); @@ -1192,7 +1192,7 @@ int EVP_PKEY_can_sign(const EVP_PKEY *pkey); int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt); -int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type); +DEPRECATEDIN_3_0(int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)) # ifndef OPENSSL_NO_ENGINE int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e); ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey); @@ -1230,19 +1230,6 @@ struct ec_key_st; int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); struct ec_key_st *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey); struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); -struct ecx_key_st; -int EVP_PKEY_set1_X25519(EVP_PKEY *pkey, struct ecx_key_st *key); -struct ecx_key_st *EVP_PKEY_get0_X25519(const EVP_PKEY *pkey); -struct ecx_key_st *EVP_PKEY_get1_X25519(EVP_PKEY *pkey); -int EVP_PKEY_set1_X448(EVP_PKEY *pkey, struct ecx_key_st *key); -struct ecx_key_st *EVP_PKEY_get0_X448(const EVP_PKEY *pkey); -struct ecx_key_st *EVP_PKEY_get1_X448(EVP_PKEY *pkey); -int EVP_PKEY_set1_ED25519(EVP_PKEY *pkey, struct ecx_key_st *key); -struct ecx_key_st *EVP_PKEY_get0_ED25519(const EVP_PKEY *pkey); -struct ecx_key_st *EVP_PKEY_get1_ED25519(EVP_PKEY *pkey); -int EVP_PKEY_set1_ED448(EVP_PKEY *pkey, struct ecx_key_st *key); -struct ecx_key_st *EVP_PKEY_get0_ED448(const EVP_PKEY *pkey); -struct ecx_key_st *EVP_PKEY_get1_ED448(EVP_PKEY *pkey); # endif EVP_PKEY *EVP_PKEY_new(void); @@ -1255,11 +1242,12 @@ int i2d_PublicKey(const EVP_PKEY *a, unsigned char **pp); EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp, - long length, OPENSSL_CTX *libctx, const char *propq); + long length, OSSL_LIB_CTX *libctx, + const char *propq); EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length); EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp, - long length, OPENSSL_CTX *libctx, + long length, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length); @@ -1274,14 +1262,10 @@ EVP_PKEY *d2i_KeyParams_bio(int type, EVP_PKEY **a, BIO *in); int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); -#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); -#endif int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b); -#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); -#endif int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b); int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, @@ -1439,13 +1423,13 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, - void *asn, - X509_ALGOR *a, - ASN1_BIT_STRING *sig, + const void *data, + const X509_ALGOR *a, + const ASN1_BIT_STRING *sig, EVP_PKEY *pkey), int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, - void *asn, + const void *data, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig)); @@ -1489,6 +1473,14 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth, int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **md); int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len); +int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id); +int EVP_PKEY_CTX_get1_id_len(EVP_PKEY_CTX *ctx, size_t *id_len); + +int EVP_PKEY_CTX_set_kem_op(EVP_PKEY_CTX *ctx, const char *op); + +const char *EVP_PKEY_get0_first_alg_name(const EVP_PKEY *key); + # define EVP_PKEY_OP_UNDEFINED 0 # define EVP_PKEY_OP_PARAMGEN (1<<1) # define EVP_PKEY_OP_KEYGEN (1<<2) @@ -1502,6 +1494,8 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); # define EVP_PKEY_OP_ENCRYPT (1<<10) # define EVP_PKEY_OP_DECRYPT (1<<11) # define EVP_PKEY_OP_DERIVE (1<<12) +# define EVP_PKEY_OP_ENCAPSULATE (1<<13) +# define EVP_PKEY_OP_DECAPSULATE (1<<14) # define EVP_PKEY_OP_TYPE_SIG \ (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ @@ -1519,34 +1513,27 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); # define EVP_PKEY_OP_TYPE_FROMDATA \ (EVP_PKEY_OP_PARAMFROMDATA | EVP_PKEY_OP_KEYFROMDATA) -# define EVP_PKEY_CTX_set_mac_key(ctx, key, len) \ - EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN, \ - EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)(key)) +int EVP_PKEY_CTX_set_mac_key(EVP_PKEY_CTX *ctx, const unsigned char *key, + int keylen); # define EVP_PKEY_CTRL_MD 1 # define EVP_PKEY_CTRL_PEER_KEY 2 - # define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 # define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 - # define EVP_PKEY_CTRL_PKCS7_SIGN 5 - # define EVP_PKEY_CTRL_SET_MAC_KEY 6 - # define EVP_PKEY_CTRL_DIGESTINIT 7 - /* Used by GOST key encryption in TLS */ # define EVP_PKEY_CTRL_SET_IV 8 - # define EVP_PKEY_CTRL_CMS_ENCRYPT 9 # define EVP_PKEY_CTRL_CMS_DECRYPT 10 # define EVP_PKEY_CTRL_CMS_SIGN 11 - # define EVP_PKEY_CTRL_CIPHER 12 - # define EVP_PKEY_CTRL_GET_MD 13 - # define EVP_PKEY_CTRL_SET_DIGEST_SIZE 14 +# define EVP_PKEY_CTRL_SET1_ID 15 +# define EVP_PKEY_CTRL_GET1_ID 16 +# define EVP_PKEY_CTRL_GET1_ID_LEN 17 # define EVP_PKEY_ALG_CTRL 0x1000 @@ -1568,26 +1555,30 @@ DEPRECATEDIN_3_0(int EVP_PKEY_meth_remove(const EVP_PKEY_METHOD *pmeth)) DEPRECATEDIN_3_0(size_t EVP_PKEY_meth_get_count(void)) DEPRECATEDIN_3_0(const EVP_PKEY_METHOD *EVP_PKEY_meth_get0(size_t idx)) -EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_KEYMGMT *EVP_KEYMGMT_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt); void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt); const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt); +const char *EVP_KEYMGMT_get0_first_name(const EVP_KEYMGMT *keymgmt); int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt); int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name); -void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx, +void EVP_KEYMGMT_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_KEYMGMT *keymgmt, void *arg), void *arg); void EVP_KEYMGMT_names_do_all(const EVP_KEYMGMT *keymgmt, void (*fn)(const char *name, void *data), void *data); +const OSSL_PARAM *EVP_KEYMGMT_gettable_params(const EVP_KEYMGMT *keymgmt); +const OSSL_PARAM *EVP_KEYMGMT_settable_params(const EVP_KEYMGMT *keymgmt); +const OSSL_PARAM *EVP_KEYMGMT_gen_settable_params(const EVP_KEYMGMT *keymgmt); EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); -EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OPENSSL_CTX *libctx, +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_name(OSSL_LIB_CTX *libctx, const char *name, const char *propquery); -EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, +EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX *libctx, EVP_PKEY *pkey, const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); @@ -1613,19 +1604,16 @@ void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key, int keylen); -EVP_PKEY *EVP_PKEY_new_raw_private_key_with_libctx(OPENSSL_CTX *libctx, - const char *keytype, - const char *propq, - const unsigned char *priv, - size_t len); +EVP_PKEY *EVP_PKEY_new_raw_private_key_ex(OSSL_LIB_CTX *libctx, + const char *keytype, + const char *propq, + const unsigned char *priv, size_t len); EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e, const unsigned char *priv, size_t len); -EVP_PKEY *EVP_PKEY_new_raw_public_key_with_libctx(OPENSSL_CTX *libctx, - const char *keytype, - const char *propq, - const unsigned char *pub, - size_t len); +EVP_PKEY *EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX *libctx, + const char *keytype, const char *propq, + const unsigned char *pub, size_t len); EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *pub, size_t len); @@ -1634,6 +1622,9 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv, int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, size_t *len); +EVP_PKEY *EVP_PKEY_new_CMAC_key_ex(const unsigned char *priv, size_t len, + const char *cipher_name, OSSL_LIB_CTX *libctx, + const char *propq); EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, size_t len, const EVP_CIPHER *cipher); @@ -1649,32 +1640,50 @@ void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); void EVP_SIGNATURE_free(EVP_SIGNATURE *signature); int EVP_SIGNATURE_up_ref(EVP_SIGNATURE *signature); OSSL_PROVIDER *EVP_SIGNATURE_provider(const EVP_SIGNATURE *signature); -EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_SIGNATURE *EVP_SIGNATURE_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name); int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature); -void EVP_SIGNATURE_do_all_provided(OPENSSL_CTX *libctx, +void EVP_SIGNATURE_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_SIGNATURE *signature, void *data), void *data); void EVP_SIGNATURE_names_do_all(const EVP_SIGNATURE *signature, void (*fn)(const char *name, void *data), void *data); +const OSSL_PARAM *EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig); +const OSSL_PARAM *EVP_SIGNATURE_settable_ctx_params(const EVP_SIGNATURE *sig); void EVP_ASYM_CIPHER_free(EVP_ASYM_CIPHER *cipher); int EVP_ASYM_CIPHER_up_ref(EVP_ASYM_CIPHER *cipher); OSSL_PROVIDER *EVP_ASYM_CIPHER_provider(const EVP_ASYM_CIPHER *cipher); -EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name); int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher); -void EVP_ASYM_CIPHER_do_all_provided(OPENSSL_CTX *libctx, +void EVP_ASYM_CIPHER_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_ASYM_CIPHER *cipher, void *arg), void *arg); void EVP_ASYM_CIPHER_names_do_all(const EVP_ASYM_CIPHER *cipher, void (*fn)(const char *name, void *data), void *data); +const OSSL_PARAM *EVP_ASYM_CIPHER_gettable_ctx_params(const EVP_ASYM_CIPHER *ciph); +const OSSL_PARAM *EVP_ASYM_CIPHER_settable_ctx_params(const EVP_ASYM_CIPHER *ciph); + +void EVP_KEM_free(EVP_KEM *wrap); +int EVP_KEM_up_ref(EVP_KEM *wrap); +OSSL_PROVIDER *EVP_KEM_provider(const EVP_KEM *wrap); +EVP_KEM *EVP_KEM_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, + const char *properties); +int EVP_KEM_is_a(const EVP_KEM *wrap, const char *name); +int EVP_KEM_number(const EVP_KEM *wrap); +void EVP_KEM_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(EVP_KEM *wrap, void *arg), void *arg); +void EVP_KEM_names_do_all(const EVP_KEM *wrap, + void (*fn)(const char *name, void *data), void *data); +const OSSL_PARAM *EVP_KEM_gettable_ctx_params(const EVP_KEM *kem); +const OSSL_PARAM *EVP_KEM_settable_ctx_params(const EVP_KEM *kem); int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, @@ -1701,6 +1710,15 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, + unsigned char *wrappedkey, size_t *wrappedkeylen, + unsigned char *genkey, size_t *genkeylen); +int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, + unsigned char *unwrapped, size_t *unwrappedlen, + const unsigned char *wrapped, size_t wrappedlen); + typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx); @@ -1921,17 +1939,19 @@ DEPRECATEDIN_3_0(void EVP_PKEY_meth_get_digest_custom void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange); int EVP_KEYEXCH_up_ref(EVP_KEYEXCH *exchange); -EVP_KEYEXCH *EVP_KEYEXCH_fetch(OPENSSL_CTX *ctx, const char *algorithm, +EVP_KEYEXCH *EVP_KEYEXCH_fetch(OSSL_LIB_CTX *ctx, const char *algorithm, const char *properties); OSSL_PROVIDER *EVP_KEYEXCH_provider(const EVP_KEYEXCH *exchange); int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name); int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch); -void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx, +void EVP_KEYEXCH_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_KEYEXCH *keyexch, void *data), void *data); void EVP_KEYEXCH_names_do_all(const EVP_KEYEXCH *keyexch, void (*fn)(const char *name, void *data), void *data); +const OSSL_PARAM *EVP_KEYEXCH_gettable_ctx_params(const EVP_KEYEXCH *keyexch); +const OSSL_PARAM *EVP_KEYEXCH_settable_ctx_params(const EVP_KEYEXCH *keyexch); void EVP_add_alg_module(void); @@ -1947,6 +1967,9 @@ int EVP_hex2ctrl(int (*cb)(void *ctx, int cmd, void *buf, size_t buflen), int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name); int EVP_PKEY_CTX_get_group_name(EVP_PKEY_CTX *ctx, char *name, size_t namelen); +OSSL_LIB_CTX *EVP_PKEY_CTX_get0_libctx(EVP_PKEY_CTX *ctx); +const char *EVP_PKEY_CTX_get0_propq(EVP_PKEY_CTX *ctx); + # ifdef __cplusplus } # endif diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h index 5aa002815a..1a3f5b6fbd 100644 --- a/include/openssl/evperr.h +++ b/include/openssl/evperr.h @@ -206,11 +206,14 @@ int ERR_load_EVP_strings(void); # define EVP_R_INVALID_IV_LENGTH 194 # define EVP_R_INVALID_KEY 163 # define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_LENGTH 221 # define EVP_R_INVALID_NULL_ALGORITHM 218 # define EVP_R_INVALID_OPERATION 148 # define EVP_R_INVALID_PROVIDER_FUNCTIONS 193 # define EVP_R_INVALID_SALT_LENGTH 186 -# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_INVALID_SECRET_LENGTH 223 +# define EVP_R_INVALID_SEED_LENGTH 220 +# define EVP_R_INVALID_VALUE 222 # define EVP_R_KEYMGMT_EXPORT_FAILURE 205 # define EVP_R_KEY_SETUP_FAILED 180 # define EVP_R_LOCKING_NOT_SUPPORTED 213 diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h index 493ddb046d..b42fe503f9 100644 --- a/include/openssl/fips_names.h +++ b/include/openssl/fips_names.h @@ -39,6 +39,19 @@ extern "C" { */ # define OSSL_PROV_FIPS_PARAM_INSTALL_STATUS "install-status" +/* + * A boolean that determines if the FIPS conditional test errors result in + * the module entering an error state. + * Type: OSSL_PARAM_UTF8_STRING + */ +# define OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS "conditional-errors" + +/* + * A boolean that determines if the runtime FIPS security checks are performed. + * Type: OSSL_PARAM_UTF8_STRING + */ +# define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks" + # ifdef __cplusplus } # endif diff --git a/include/openssl/fipskey.h b/include/openssl/fipskey.h new file mode 100644 index 0000000000..cd97079f90 --- /dev/null +++ b/include/openssl/fipskey.h @@ -0,0 +1,35 @@ +/* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/fipskey.h.in + * + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OPENSSL_FIPSKEY_H +# define OPENSSL_FIPSKEY_H + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * The FIPS validation HMAC key, usable as an array initializer. + */ +#define FIPS_KEY_ELEMENTS \ + 0xf4, 0x55, 0x66, 0x50, 0xac, 0x31, 0xd3, 0x54, 0x61, 0x61, 0x0b, 0xac, 0x4e, 0xd8, 0x1b, 0x1a, 0x18, 0x1b, 0x2d, 0x8a, 0x43, 0xea, 0x28, 0x54, 0xcb, 0xae, 0x22, 0xca, 0x74, 0x56, 0x08, 0x13 + +/* + * The FIPS validation key, as a string. + */ +#define FIPS_KEY_STRING "f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813" + +# ifdef __cplusplus +} +# endif + +#endif diff --git a/include/openssl/http.h b/include/openssl/http.h index 45c8f11d7b..2c9ce9d86e 100644 --- a/include/openssl/http.h +++ b/include/openssl/http.h @@ -74,7 +74,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, int timeout, BIO *bio_err, const char *prog); int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, - char **ppath, int *pssl); + int *pport_num, char **ppath, int *pssl); # ifdef __cplusplus } diff --git a/include/openssl/httperr.h b/include/openssl/httperr.h index e4acb1df8c..7747643bfa 100644 --- a/include/openssl/httperr.h +++ b/include/openssl/httperr.h @@ -10,6 +10,7 @@ #ifndef OPENSSL_HTTPERR_H # define OPENSSL_HTTPERR_H +# pragma once # include # include @@ -37,6 +38,9 @@ int ERR_load_HTTP_strings(void); # define HTTP_R_ERROR_RECEIVING 103 # define HTTP_R_ERROR_SENDING 102 # define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120 +# define HTTP_R_INVALID_PORT_NUMBER 123 +# define HTTP_R_INVALID_URL_PATH 125 +# define HTTP_R_INVALID_URL_PREFIX 124 # define HTTP_R_MAX_RESP_LEN_EXCEEDED 117 # define HTTP_R_MISSING_ASN1_ENCODING 110 # define HTTP_R_MISSING_CONTENT_TYPE 121 diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index b3dee525dc..96521922ed 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -27,7 +27,7 @@ extern "C" { int EVP_KDF_up_ref(EVP_KDF *kdf); void EVP_KDF_free(EVP_KDF *kdf); -EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, +EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, const char *properties); EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf); @@ -35,6 +35,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src); int EVP_KDF_number(const EVP_KDF *kdf); int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name); +const char *EVP_KDF_name(const EVP_KDF *kdf); const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf); const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx); @@ -48,7 +49,7 @@ const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf); const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf); const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf); -void EVP_KDF_do_all_provided(OPENSSL_CTX *libctx, +void EVP_KDF_do_all_provided(OSSL_LIB_CTX *libctx, void (*fn)(EVP_KDF *kdf, void *arg), void *arg); void EVP_KDF_names_do_all(const EVP_KDF *kdf, @@ -115,61 +116,41 @@ void EVP_KDF_names_do_all(const EVP_KDF *kdf, # define EVP_PKEY_HKDEF_MODE_EXPAND_ONLY \ EVP_KDF_HKDF_MODE_EXPAND_ONLY -# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_TLS_MD, 0, (void *)(md)) +int EVP_PKEY_CTX_set_tls1_prf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); -# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)(sec)) +int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *pctx, + const unsigned char *sec, int seclen); -# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)(seed)) +int EVP_PKEY_CTX_add1_tls1_prf_seed(EVP_PKEY_CTX *pctx, + const unsigned char *seed, int seedlen); -# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_MD, 0, (void *)(md)) +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); -# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)(salt)) +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen); -# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)(key)) +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx, + const unsigned char *key, int keylen); -# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)(info)) +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx, + const unsigned char *info, int infolen); -# define EVP_PKEY_CTX_hkdf_mode(pctx, mode) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_HKDF_MODE, mode, NULL) +int EVP_PKEY_CTX_hkdf_mode(EVP_PKEY_CTX *ctx, int mode); -# define EVP_PKEY_CTX_set1_pbe_pass(pctx, pass, passlen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_PASS, passlen, (void *)(pass)) +int EVP_PKEY_CTX_set1_pbe_pass(EVP_PKEY_CTX *ctx, const char *pass, + int passlen); -# define EVP_PKEY_CTX_set1_scrypt_salt(pctx, salt, saltlen) \ - EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_SCRYPT_SALT, saltlen, (void *)(salt)) +int EVP_PKEY_CTX_set1_scrypt_salt(EVP_PKEY_CTX *ctx, + const unsigned char *salt, int saltlen); -# define EVP_PKEY_CTX_set_scrypt_N(pctx, n) \ - EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_SCRYPT_N, n) +int EVP_PKEY_CTX_set_scrypt_N(EVP_PKEY_CTX *ctx, uint64_t n); -# define EVP_PKEY_CTX_set_scrypt_r(pctx, r) \ - EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_SCRYPT_R, r) +int EVP_PKEY_CTX_set_scrypt_r(EVP_PKEY_CTX *ctx, uint64_t r); -# define EVP_PKEY_CTX_set_scrypt_p(pctx, p) \ - EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_SCRYPT_P, p) +int EVP_PKEY_CTX_set_scrypt_p(EVP_PKEY_CTX *ctx, uint64_t p); -# define EVP_PKEY_CTX_set_scrypt_maxmem_bytes(pctx, maxmem_bytes) \ - EVP_PKEY_CTX_ctrl_uint64(pctx, -1, EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES, maxmem_bytes) +int EVP_PKEY_CTX_set_scrypt_maxmem_bytes(EVP_PKEY_CTX *ctx, + uint64_t maxmem_bytes); # ifdef __cplusplus diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h index 5ad9b16ab2..ccdd3a60ee 100644 --- a/include/openssl/lhash.h +++ b/include/openssl/lhash.h @@ -125,6 +125,42 @@ void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); # define LHASH_OF(type) struct lhash_st_##type +/* Helper macro for internal use */ +# define DEFINE_LHASH_OF_INTERNAL(type) \ + LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ + typedef int (*lh_##type##_compfunc)(const type *a, const type *b); \ + typedef unsigned long (*lh_##type##_hashfunc)(const type *a); \ + typedef void (*lh_##type##_doallfunc)(type *a); \ + static ossl_unused ossl_inline type *ossl_check_##type##_lh_plain_type(type *ptr) \ + { \ + return ptr; \ + } \ + static ossl_unused ossl_inline const type *ossl_check_const_##type##_lh_plain_type(const type *ptr) \ + { \ + return ptr; \ + } \ + static ossl_unused ossl_inline const OPENSSL_LHASH *ossl_check_const_##type##_lh_type(const LHASH_OF(type) *lh) \ + { \ + return (const OPENSSL_LHASH *)lh; \ + } \ + static ossl_unused ossl_inline OPENSSL_LHASH *ossl_check_##type##_lh_type(LHASH_OF(type) *lh) \ + { \ + return (OPENSSL_LHASH *)lh; \ + } \ + static ossl_unused ossl_inline OPENSSL_LH_COMPFUNC ossl_check_##type##_lh_compfunc_type(lh_##type##_compfunc cmp) \ + { \ + return (OPENSSL_LH_COMPFUNC)cmp; \ + } \ + static ossl_unused ossl_inline OPENSSL_LH_HASHFUNC ossl_check_##type##_lh_hashfunc_type(lh_##type##_hashfunc hfn) \ + { \ + return (OPENSSL_LH_HASHFUNC)hfn; \ + } \ + static ossl_unused ossl_inline OPENSSL_LH_DOALL_FUNC ossl_check_##type##_lh_doallfunc_type(lh_##type##_doallfunc dfn) \ + { \ + return (OPENSSL_LH_DOALL_FUNC)dfn; \ + } \ + LHASH_OF(type) + # define DEFINE_LHASH_OF(type) \ LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \ @@ -220,32 +256,6 @@ DEFINE_LHASH_OF(OPENSSL_CSTRING); # pragma warning (pop) # endif -/* - * If called without higher optimization (min. -xO3) the Oracle Developer - * Studio compiler generates code for the defined (static inline) functions - * above. - * This would later lead to the linker complaining about missing symbols when - * this header file is included but the resulting object is not linked against - * the Crypto library (openssl#6912). - */ -# ifdef __SUNPRO_C -# pragma weak OPENSSL_LH_new -# pragma weak OPENSSL_LH_flush -# pragma weak OPENSSL_LH_free -# pragma weak OPENSSL_LH_insert -# pragma weak OPENSSL_LH_delete -# pragma weak OPENSSL_LH_retrieve -# pragma weak OPENSSL_LH_error -# pragma weak OPENSSL_LH_num_items -# pragma weak OPENSSL_LH_node_stats_bio -# pragma weak OPENSSL_LH_node_usage_stats_bio -# pragma weak OPENSSL_LH_stats_bio -# pragma weak OPENSSL_LH_get_down_load -# pragma weak OPENSSL_LH_set_down_load -# pragma weak OPENSSL_LH_doall -# pragma weak OPENSSL_LH_doall_arg -# endif /* __SUNPRO_C */ - #ifdef __cplusplus } #endif diff --git a/include/openssl/macros.h b/include/openssl/macros.h index 2ed8fcf002..24fad673bd 100644 --- a/include/openssl/macros.h +++ b/include/openssl/macros.h @@ -25,27 +25,56 @@ /* * Generic deprecation macro - * - * If OPENSSL_SUPPRESS_DEPRECATED is defined, then DECLARE_DEPRECATED - * becomes a no-op + * + * If OPENSSL_SUPPRESS_DEPRECATED is defined, then OSSL_DEPRECATED and + * OSSL_DEPRECATED_FOR become no-ops */ -# ifndef DECLARE_DEPRECATED -# define DECLARE_DEPRECATED(f) f; +# ifndef OSSL_DEPRECATED +# undef OSSL_DEPRECATED_FOR # ifndef OPENSSL_SUPPRESS_DEPRECATED -# ifdef __GNUC__ -# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) -# undef DECLARE_DEPRECATED -# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated)); +# if defined(_MSC_VER) + /* + * MSVC supports __declspec(deprecated) since MSVC 2003 (13.10), + * and __declspec(deprecated(message)) since MSVC 2005 (14.00) + */ +# if _MSC_VER >= 1400 +# define OSSL_DEPRECATED(since) \ + __declspec(deprecated("Since OpenSSL " # since)) +# define OSSL_DEPRECATED_FOR(since, message) \ + __declspec(deprecated("Since OpenSSL " # since ";" message)) +# elif _MSC_VER >= 1310 +# define OSSL_DEPRECATED(since) __declspec(deprecated) +# define OSSL_DEPRECATED_FOR(since, message) __declspec(deprecated) +# endif +# elif defined(__GNUC__) + /* + * According to GCC documentation, deprecations with message appeared in + * GCC 4.5.0 + */ +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +# define OSSL_DEPRECATED(since) \ + __attribute__((deprecated("Since OpenSSL " # since))) +# define OSSL_DEPRECATED_FOR(since, message) \ + __attribute__((deprecated("Since OpenSSL " # since ";" message))) +# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) +# define OSSL_DEPRECATED(since) __attribute__((deprecated)) +# define OSSL_DEPRECATED_FOR(since, message) __attribute__((deprecated)) # endif # elif defined(__SUNPRO_C) # if (__SUNPRO_C >= 0x5130) -# undef DECLARE_DEPRECATED -# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated)); +# define OSSL_DEPRECATED(since) __attribute__ ((deprecated)) +# define OSSL_DEPRECATED_FOR(since, message) __attribute__ ((deprecated)) # endif # endif # endif # endif +/* Still not defined? Then define empty macros */ +# ifndef OSSL_DEPRECATED +# define OSSL_DEPRECATED(since) +# define OSSL_DEPRECATED_FOR(since, message) +# endif + /* * Applications should use -DOPENSSL_API_COMPAT= to suppress the * declarations of functions deprecated in or before . If this is @@ -122,10 +151,17 @@ # endif /* - * Define macros for deprecation purposes. We always define the macros - * DEPERECATEDIN_{major}_{minor}() for all OpenSSL versions we care for, - * and OPENSSL_NO_DEPRECATED_{major}_{minor} to be used to check if - * removal of deprecated functions applies on that particular version. + * Define macros for deprecation and simulated removal purposes. + * + * The macros OSSL_DEPRECATED_{major}_{minor} are always defined for + * all OpenSSL versions we care for. They can be used as attributes + * in function declarations where appropriate. + * + * The macros OPENSSL_NO_DEPRECATED_{major}_{minor} are defined for + * all OpenSSL versions up to or equal to the version given with + * OPENSSL_API_COMPAT. They are used as guards around anything that's + * deprecated up to that version, as an effect of the developer option + * 'no-deprecated'. */ # undef OPENSSL_NO_DEPRECATED_3_0 @@ -138,73 +174,101 @@ # if OPENSSL_API_LEVEL >= 30000 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_3_0(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_3_0 OSSL_DEPRECATED(3.0) +# define OSSL_DEPRECATEDIN_3_0_FOR(msg) OSSL_DEPRECATED_FOR(3.0, msg) +# define DEPRECATEDIN_3_0(f) OSSL_DEPRECATEDIN_3_0 f; # else -# define DEPRECATEDIN_3_0(f) # define OPENSSL_NO_DEPRECATED_3_0 +# define DEPRECATEDIN_3_0(f) # endif # else -# define DEPRECATEDIN_3_0(f) f; +# define OSSL_DEPRECATEDIN_3_0 +# define OSSL_DEPRECATEDIN_3_0_FOR(msg) +# define DEPRECATEDIN_3_0(f) f; # endif # if OPENSSL_API_LEVEL >= 10101 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_1_1_1(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_1_1_1 OSSL_DEPRECATED(1.1.1) +# define OSSL_DEPRECATEDIN_1_1_1_FOR(msg) OSSL_DEPRECATED_FOR(1.1.1, msg) +# define DEPRECATEDIN_1_1_1(f) OSSL_DEPRECATEDIN_1_1_1 f; # else -# define DEPRECATEDIN_1_1_1(f) # define OPENSSL_NO_DEPRECATED_1_1_1 +# define DEPRECATEDIN_1_1_1(f) # endif # else -# define DEPRECATEDIN_1_1_1(f) f; +# define OSSL_DEPRECATEDIN_1_1_1 +# define OSSL_DEPRECATEDIN_1_1_1_FOR(msg) +# define DEPRECATEDIN_1_1_1(f) f; # endif # if OPENSSL_API_LEVEL >= 10100 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_1_1_0(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_1_1_0 OSSL_DEPRECATED(1.1.0) +# define OSSL_DEPRECATEDIN_1_1_0_FOR(msg) OSSL_DEPRECATED_FOR(1.1.0, msg) +# define DEPRECATEDIN_1_1_0(f) OSSL_DEPRECATEDIN_1_1_0 f; # else -# define DEPRECATEDIN_1_1_0(f) # define OPENSSL_NO_DEPRECATED_1_1_0 +# define DEPRECATEDIN_1_1_0(f) # endif # else -# define DEPRECATEDIN_1_1_0(f) f; +# define OSSL_DEPRECATEDIN_1_1_0 +# define OSSL_DEPRECATEDIN_1_1_0_FOR(msg) +# define DEPRECATEDIN_1_1_0(f) f; # endif # if OPENSSL_API_LEVEL >= 10002 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_1_0_2(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_1_0_2 OSSL_DEPRECATED(1.0.2) +# define OSSL_DEPRECATEDIN_1_0_2_FOR(msg) OSSL_DEPRECATED_FOR(1.0.2, msg) +# define DEPRECATEDIN_1_0_2(f) OSSL_DEPRECATEDIN_1_0_2 f; # else -# define DEPRECATEDIN_1_0_2(f) # define OPENSSL_NO_DEPRECATED_1_0_2 +# define DEPRECATEDIN_1_0_2(f) # endif # else -# define DEPRECATEDIN_1_0_2(f) f; +# define OSSL_DEPRECATEDIN_1_0_2 +# define OSSL_DEPRECATEDIN_1_0_2_FOR(msg) +# define DEPRECATEDIN_1_0_2(f) f; # endif # if OPENSSL_API_LEVEL >= 10001 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_1_0_1(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_1_0_1 OSSL_DEPRECATED(1.0.1) +# define OSSL_DEPRECATEDIN_1_0_1_FOR(msg) OSSL_DEPRECATED_FOR(1.0.1, msg) +# define DEPRECATEDIN_1_0_1(f) OSSL_DEPRECATEDIN_1_0_1 f; # else -# define DEPRECATEDIN_1_0_1(f) # define OPENSSL_NO_DEPRECATED_1_0_1 +# define DEPRECATEDIN_1_0_1(f) # endif # else -# define DEPRECATEDIN_1_0_1(f) f; +# define OSSL_DEPRECATEDIN_1_0_1 +# define OSSL_DEPRECATEDIN_1_0_1_FOR(msg) +# define DEPRECATEDIN_1_0_1(f) f; # endif # if OPENSSL_API_LEVEL >= 10000 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_1_0_0(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_1_0_0 OSSL_DEPRECATED(1.0.0) +# define OSSL_DEPRECATEDIN_1_0_0_FOR(msg) OSSL_DEPRECATED_FOR(1.0.0, msg) +# define DEPRECATEDIN_1_0_0(f) OSSL_DEPRECATEDIN_1_0_0 f; # else -# define DEPRECATEDIN_1_0_0(f) # define OPENSSL_NO_DEPRECATED_1_0_0 +# define DEPRECATEDIN_1_0_0(f) # endif # else -# define DEPRECATEDIN_1_0_0(f) f; +# define OSSL_DEPRECATEDIN_1_0_0 +# define OSSL_DEPRECATEDIN_1_0_0_FOR(msg) +# define DEPRECATEDIN_1_0_0(f) f; # endif # if OPENSSL_API_LEVEL >= 908 # ifndef OPENSSL_NO_DEPRECATED -# define DEPRECATEDIN_0_9_8(f) DECLARE_DEPRECATED(f) +# define OSSL_DEPRECATEDIN_0_9_8 OSSL_DEPRECATED(0.9.8) +# define OSSL_DEPRECATEDIN_0_9_8_FOR(msg) OSSL_DEPRECATED_FOR(0.9.8, msg) +# define DEPRECATEDIN_0_9_8(f) OSSL_DEPRECATEDIN_0_9_8 f; # else -# define DEPRECATEDIN_0_9_8(f) # define OPENSSL_NO_DEPRECATED_0_9_8 +# define DEPRECATEDIN_0_9_8(f) # endif # else -# define DEPRECATEDIN_0_9_8(f) f; +# define OSSL_DEPRECATEDIN_0_9_8 +# define OSSL_DEPRECATEDIN_0_9_8_FOR(msg) +# define DEPRECATEDIN_0_9_8(f) f; # endif /* diff --git a/include/openssl/md5.h b/include/openssl/md5.h index 0a75b084a2..c111639b5d 100644 --- a/include/openssl/md5.h +++ b/include/openssl/md5.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,22 +19,24 @@ # include # ifndef OPENSSL_NO_MD5 -# include -# include -# ifdef __cplusplus +# include +# include +# ifdef __cplusplus extern "C" { -# endif +# endif + +# define MD5_DIGEST_LENGTH 16 +# if !defined(OPENSSL_NO_DEPRECATED_3_0) /* * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * ! MD5_LONG has to be at least 32 bits wide. ! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -# define MD5_LONG unsigned int +# define MD5_LONG unsigned int -# define MD5_CBLOCK 64 -# define MD5_LBLOCK (MD5_CBLOCK/4) -# define MD5_DIGEST_LENGTH 16 +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) typedef struct MD5state_st { MD5_LONG A, B, C, D; @@ -42,15 +44,18 @@ typedef struct MD5state_st { MD5_LONG data[MD5_LBLOCK]; unsigned int num; } MD5_CTX; +# endif -int MD5_Init(MD5_CTX *c); -int MD5_Update(MD5_CTX *c, const void *data, size_t len); -int MD5_Final(unsigned char *md, MD5_CTX *c); -unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); -void MD5_Transform(MD5_CTX *c, const unsigned char *b); -# ifdef __cplusplus +DEPRECATEDIN_3_0(int MD5_Init(MD5_CTX *c)) +DEPRECATEDIN_3_0(int MD5_Update(MD5_CTX *c, const void *data, size_t len)) +DEPRECATEDIN_3_0(int MD5_Final(unsigned char *md, MD5_CTX *c)) +DEPRECATEDIN_3_0(unsigned char *MD5(const unsigned char *d, size_t n, + unsigned char *md)) +DEPRECATEDIN_3_0(void MD5_Transform(MD5_CTX *c, const unsigned char *b)) + +# ifdef __cplusplus } -# endif +# endif # endif #endif diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index 0f9adc9b6a..5af0024989 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -1647,6 +1647,26 @@ #define NID_cmcRA 1132 #define OBJ_cmcRA OBJ_id_kp,28L +#define SN_cmcArchive "cmcArchive" +#define LN_cmcArchive "CMC Archive Server" +#define NID_cmcArchive 1219 +#define OBJ_cmcArchive OBJ_id_kp,29L + +#define SN_id_kp_bgpsec_router "id-kp-bgpsec-router" +#define LN_id_kp_bgpsec_router "BGPsec Router" +#define NID_id_kp_bgpsec_router 1220 +#define OBJ_id_kp_bgpsec_router OBJ_id_kp,30L + +#define SN_id_kp_BrandIndicatorforMessageIdentification "id-kp-BrandIndicatorforMessageIdentification" +#define LN_id_kp_BrandIndicatorforMessageIdentification "Brand Indicator for Message Identification" +#define NID_id_kp_BrandIndicatorforMessageIdentification 1221 +#define OBJ_id_kp_BrandIndicatorforMessageIdentification OBJ_id_kp,31L + +#define SN_cmKGA "cmKGA" +#define LN_cmKGA "Certificate Management Key Generation Authority" +#define NID_cmKGA 1222 +#define OBJ_cmKGA OBJ_id_kp,32L + #define SN_id_it_caProtEncCert "id-it-caProtEncCert" #define NID_id_it_caProtEncCert 298 #define OBJ_id_it_caProtEncCert OBJ_id_it,1L @@ -1711,6 +1731,18 @@ #define NID_id_it_suppLangTags 784 #define OBJ_id_it_suppLangTags OBJ_id_it,16L +#define SN_id_it_caCerts "id-it-caCerts" +#define NID_id_it_caCerts 1223 +#define OBJ_id_it_caCerts OBJ_id_it,17L + +#define SN_id_it_rootCaKeyUpdate "id-it-rootCaKeyUpdate" +#define NID_id_it_rootCaKeyUpdate 1224 +#define OBJ_id_it_rootCaKeyUpdate OBJ_id_it,18L + +#define SN_id_it_certReqTemplate "id-it-certReqTemplate" +#define NID_id_it_certReqTemplate 1225 +#define OBJ_id_it_certReqTemplate OBJ_id_it,19L + #define SN_id_regCtrl "id-regCtrl" #define NID_id_regCtrl 313 #define OBJ_id_regCtrl OBJ_id_pkip,1L @@ -4420,6 +4452,11 @@ #define NID_SNILS 1006 #define OBJ_SNILS OBJ_member_body,643L,100L,3L +#define SN_OGRNIP "OGRNIP" +#define LN_OGRNIP "OGRNIP" +#define NID_OGRNIP 1226 +#define OBJ_OGRNIP OBJ_member_body,643L,100L,5L + #define SN_subjectSignTool "subjectSignTool" #define LN_subjectSignTool "Signing Tool of Subject" #define NID_subjectSignTool 1007 @@ -4430,6 +4467,41 @@ #define NID_issuerSignTool 1008 #define OBJ_issuerSignTool OBJ_member_body,643L,100L,112L +#define SN_classSignTool "classSignTool" +#define LN_classSignTool "Class of Signing Tool" +#define NID_classSignTool 1227 +#define OBJ_classSignTool OBJ_member_body,643L,100L,113L + +#define SN_classSignToolKC1 "classSignToolKC1" +#define LN_classSignToolKC1 "Class of Signing Tool KC1" +#define NID_classSignToolKC1 1228 +#define OBJ_classSignToolKC1 OBJ_member_body,643L,100L,113L,1L + +#define SN_classSignToolKC2 "classSignToolKC2" +#define LN_classSignToolKC2 "Class of Signing Tool KC2" +#define NID_classSignToolKC2 1229 +#define OBJ_classSignToolKC2 OBJ_member_body,643L,100L,113L,2L + +#define SN_classSignToolKC3 "classSignToolKC3" +#define LN_classSignToolKC3 "Class of Signing Tool KC3" +#define NID_classSignToolKC3 1230 +#define OBJ_classSignToolKC3 OBJ_member_body,643L,100L,113L,3L + +#define SN_classSignToolKB1 "classSignToolKB1" +#define LN_classSignToolKB1 "Class of Signing Tool KB1" +#define NID_classSignToolKB1 1231 +#define OBJ_classSignToolKB1 OBJ_member_body,643L,100L,113L,4L + +#define SN_classSignToolKB2 "classSignToolKB2" +#define LN_classSignToolKB2 "Class of Signing Tool KB2" +#define NID_classSignToolKB2 1232 +#define OBJ_classSignToolKB2 OBJ_member_body,643L,100L,113L,5L + +#define SN_classSignToolKA1 "classSignToolKA1" +#define LN_classSignToolKA1 "Class of Signing Tool KA1" +#define NID_classSignToolKA1 1233 +#define OBJ_classSignToolKA1 OBJ_member_body,643L,100L,113L,6L + #define SN_kuznyechik_ecb "kuznyechik-ecb" #define NID_kuznyechik_ecb 1012 diff --git a/include/openssl/ocsp.h b/include/openssl/ocsp.h index 1c514efeee..cfb66425f3 100644 --- a/include/openssl/ocsp.h +++ b/include/openssl/ocsp.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/ocsp.h.in + * * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_OCSP_H # define OPENSSL_OCSP_H # pragma once @@ -102,6 +107,7 @@ extern "C" { # define OCSP_TRUSTOTHER 0x200 # define OCSP_RESPID_KEY 0x400 # define OCSP_NOTIME 0x800 +# define OCSP_PARTIAL_CHAIN 0x1000 typedef struct ocsp_cert_id_st OCSP_CERTID; typedef struct ocsp_one_request_st OCSP_ONEREQ; @@ -109,8 +115,57 @@ typedef struct ocsp_req_info_st OCSP_REQINFO; typedef struct ocsp_signature_st OCSP_SIGNATURE; typedef struct ocsp_request_st OCSP_REQUEST; -DEFINE_OR_DECLARE_STACK_OF(OCSP_CERTID) -DEFINE_OR_DECLARE_STACK_OF(OCSP_ONEREQ) +SKM_DEFINE_STACK_OF_INTERNAL(OCSP_CERTID, OCSP_CERTID, OCSP_CERTID) +#define sk_OCSP_CERTID_num(sk) OPENSSL_sk_num(ossl_check_const_OCSP_CERTID_sk_type(sk)) +#define sk_OCSP_CERTID_value(sk, idx) ((OCSP_CERTID *)OPENSSL_sk_value(ossl_check_const_OCSP_CERTID_sk_type(sk), (idx))) +#define sk_OCSP_CERTID_new(cmp) ((STACK_OF(OCSP_CERTID) *)OPENSSL_sk_new(ossl_check_OCSP_CERTID_compfunc_type(cmp))) +#define sk_OCSP_CERTID_new_null() ((STACK_OF(OCSP_CERTID) *)OPENSSL_sk_new_null()) +#define sk_OCSP_CERTID_new_reserve(cmp, n) ((STACK_OF(OCSP_CERTID) *)OPENSSL_sk_new_reserve(ossl_check_OCSP_CERTID_compfunc_type(cmp), (n))) +#define sk_OCSP_CERTID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OCSP_CERTID_sk_type(sk), (n)) +#define sk_OCSP_CERTID_free(sk) OPENSSL_sk_free(ossl_check_OCSP_CERTID_sk_type(sk)) +#define sk_OCSP_CERTID_zero(sk) OPENSSL_sk_zero(ossl_check_OCSP_CERTID_sk_type(sk)) +#define sk_OCSP_CERTID_delete(sk, i) ((OCSP_CERTID *)OPENSSL_sk_delete(ossl_check_OCSP_CERTID_sk_type(sk), (i))) +#define sk_OCSP_CERTID_delete_ptr(sk, ptr) ((OCSP_CERTID *)OPENSSL_sk_delete_ptr(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_type(ptr))) +#define sk_OCSP_CERTID_push(sk, ptr) OPENSSL_sk_push(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_type(ptr)) +#define sk_OCSP_CERTID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_type(ptr)) +#define sk_OCSP_CERTID_pop(sk) ((OCSP_CERTID *)OPENSSL_sk_pop(ossl_check_OCSP_CERTID_sk_type(sk))) +#define sk_OCSP_CERTID_shift(sk) ((OCSP_CERTID *)OPENSSL_sk_shift(ossl_check_OCSP_CERTID_sk_type(sk))) +#define sk_OCSP_CERTID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OCSP_CERTID_sk_type(sk),ossl_check_OCSP_CERTID_freefunc_type(freefunc)) +#define sk_OCSP_CERTID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_type(ptr), (idx)) +#define sk_OCSP_CERTID_set(sk, idx, ptr) ((OCSP_CERTID *)OPENSSL_sk_set(ossl_check_OCSP_CERTID_sk_type(sk), (idx), ossl_check_OCSP_CERTID_type(ptr))) +#define sk_OCSP_CERTID_find(sk, ptr) OPENSSL_sk_find(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_type(ptr)) +#define sk_OCSP_CERTID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_type(ptr)) +#define sk_OCSP_CERTID_sort(sk) OPENSSL_sk_sort(ossl_check_OCSP_CERTID_sk_type(sk)) +#define sk_OCSP_CERTID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OCSP_CERTID_sk_type(sk)) +#define sk_OCSP_CERTID_dup(sk) ((STACK_OF(OCSP_CERTID) *)OPENSSL_sk_dup(ossl_check_const_OCSP_CERTID_sk_type(sk))) +#define sk_OCSP_CERTID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OCSP_CERTID) *)OPENSSL_sk_deep_copy(ossl_check_const_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_copyfunc_type(copyfunc), ossl_check_OCSP_CERTID_freefunc_type(freefunc))) +#define sk_OCSP_CERTID_set_cmp_func(sk, cmp) ((sk_OCSP_CERTID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OCSP_CERTID_sk_type(sk), ossl_check_OCSP_CERTID_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(OCSP_ONEREQ, OCSP_ONEREQ, OCSP_ONEREQ) +#define sk_OCSP_ONEREQ_num(sk) OPENSSL_sk_num(ossl_check_const_OCSP_ONEREQ_sk_type(sk)) +#define sk_OCSP_ONEREQ_value(sk, idx) ((OCSP_ONEREQ *)OPENSSL_sk_value(ossl_check_const_OCSP_ONEREQ_sk_type(sk), (idx))) +#define sk_OCSP_ONEREQ_new(cmp) ((STACK_OF(OCSP_ONEREQ) *)OPENSSL_sk_new(ossl_check_OCSP_ONEREQ_compfunc_type(cmp))) +#define sk_OCSP_ONEREQ_new_null() ((STACK_OF(OCSP_ONEREQ) *)OPENSSL_sk_new_null()) +#define sk_OCSP_ONEREQ_new_reserve(cmp, n) ((STACK_OF(OCSP_ONEREQ) *)OPENSSL_sk_new_reserve(ossl_check_OCSP_ONEREQ_compfunc_type(cmp), (n))) +#define sk_OCSP_ONEREQ_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OCSP_ONEREQ_sk_type(sk), (n)) +#define sk_OCSP_ONEREQ_free(sk) OPENSSL_sk_free(ossl_check_OCSP_ONEREQ_sk_type(sk)) +#define sk_OCSP_ONEREQ_zero(sk) OPENSSL_sk_zero(ossl_check_OCSP_ONEREQ_sk_type(sk)) +#define sk_OCSP_ONEREQ_delete(sk, i) ((OCSP_ONEREQ *)OPENSSL_sk_delete(ossl_check_OCSP_ONEREQ_sk_type(sk), (i))) +#define sk_OCSP_ONEREQ_delete_ptr(sk, ptr) ((OCSP_ONEREQ *)OPENSSL_sk_delete_ptr(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_type(ptr))) +#define sk_OCSP_ONEREQ_push(sk, ptr) OPENSSL_sk_push(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_type(ptr)) +#define sk_OCSP_ONEREQ_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_type(ptr)) +#define sk_OCSP_ONEREQ_pop(sk) ((OCSP_ONEREQ *)OPENSSL_sk_pop(ossl_check_OCSP_ONEREQ_sk_type(sk))) +#define sk_OCSP_ONEREQ_shift(sk) ((OCSP_ONEREQ *)OPENSSL_sk_shift(ossl_check_OCSP_ONEREQ_sk_type(sk))) +#define sk_OCSP_ONEREQ_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OCSP_ONEREQ_sk_type(sk),ossl_check_OCSP_ONEREQ_freefunc_type(freefunc)) +#define sk_OCSP_ONEREQ_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_type(ptr), (idx)) +#define sk_OCSP_ONEREQ_set(sk, idx, ptr) ((OCSP_ONEREQ *)OPENSSL_sk_set(ossl_check_OCSP_ONEREQ_sk_type(sk), (idx), ossl_check_OCSP_ONEREQ_type(ptr))) +#define sk_OCSP_ONEREQ_find(sk, ptr) OPENSSL_sk_find(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_type(ptr)) +#define sk_OCSP_ONEREQ_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_type(ptr)) +#define sk_OCSP_ONEREQ_sort(sk) OPENSSL_sk_sort(ossl_check_OCSP_ONEREQ_sk_type(sk)) +#define sk_OCSP_ONEREQ_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OCSP_ONEREQ_sk_type(sk)) +#define sk_OCSP_ONEREQ_dup(sk) ((STACK_OF(OCSP_ONEREQ) *)OPENSSL_sk_dup(ossl_check_const_OCSP_ONEREQ_sk_type(sk))) +#define sk_OCSP_ONEREQ_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OCSP_ONEREQ) *)OPENSSL_sk_deep_copy(ossl_check_const_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_copyfunc_type(copyfunc), ossl_check_OCSP_ONEREQ_freefunc_type(freefunc))) +#define sk_OCSP_ONEREQ_set_cmp_func(sk, cmp) ((sk_OCSP_ONEREQ_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OCSP_ONEREQ_sk_type(sk), ossl_check_OCSP_ONEREQ_compfunc_type(cmp))) + # define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 # define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 @@ -124,7 +179,32 @@ typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES; # define V_OCSP_RESPID_NAME 0 # define V_OCSP_RESPID_KEY 1 -DEFINE_OR_DECLARE_STACK_OF(OCSP_RESPID) +SKM_DEFINE_STACK_OF_INTERNAL(OCSP_RESPID, OCSP_RESPID, OCSP_RESPID) +#define sk_OCSP_RESPID_num(sk) OPENSSL_sk_num(ossl_check_const_OCSP_RESPID_sk_type(sk)) +#define sk_OCSP_RESPID_value(sk, idx) ((OCSP_RESPID *)OPENSSL_sk_value(ossl_check_const_OCSP_RESPID_sk_type(sk), (idx))) +#define sk_OCSP_RESPID_new(cmp) ((STACK_OF(OCSP_RESPID) *)OPENSSL_sk_new(ossl_check_OCSP_RESPID_compfunc_type(cmp))) +#define sk_OCSP_RESPID_new_null() ((STACK_OF(OCSP_RESPID) *)OPENSSL_sk_new_null()) +#define sk_OCSP_RESPID_new_reserve(cmp, n) ((STACK_OF(OCSP_RESPID) *)OPENSSL_sk_new_reserve(ossl_check_OCSP_RESPID_compfunc_type(cmp), (n))) +#define sk_OCSP_RESPID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OCSP_RESPID_sk_type(sk), (n)) +#define sk_OCSP_RESPID_free(sk) OPENSSL_sk_free(ossl_check_OCSP_RESPID_sk_type(sk)) +#define sk_OCSP_RESPID_zero(sk) OPENSSL_sk_zero(ossl_check_OCSP_RESPID_sk_type(sk)) +#define sk_OCSP_RESPID_delete(sk, i) ((OCSP_RESPID *)OPENSSL_sk_delete(ossl_check_OCSP_RESPID_sk_type(sk), (i))) +#define sk_OCSP_RESPID_delete_ptr(sk, ptr) ((OCSP_RESPID *)OPENSSL_sk_delete_ptr(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_type(ptr))) +#define sk_OCSP_RESPID_push(sk, ptr) OPENSSL_sk_push(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_type(ptr)) +#define sk_OCSP_RESPID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_type(ptr)) +#define sk_OCSP_RESPID_pop(sk) ((OCSP_RESPID *)OPENSSL_sk_pop(ossl_check_OCSP_RESPID_sk_type(sk))) +#define sk_OCSP_RESPID_shift(sk) ((OCSP_RESPID *)OPENSSL_sk_shift(ossl_check_OCSP_RESPID_sk_type(sk))) +#define sk_OCSP_RESPID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OCSP_RESPID_sk_type(sk),ossl_check_OCSP_RESPID_freefunc_type(freefunc)) +#define sk_OCSP_RESPID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_type(ptr), (idx)) +#define sk_OCSP_RESPID_set(sk, idx, ptr) ((OCSP_RESPID *)OPENSSL_sk_set(ossl_check_OCSP_RESPID_sk_type(sk), (idx), ossl_check_OCSP_RESPID_type(ptr))) +#define sk_OCSP_RESPID_find(sk, ptr) OPENSSL_sk_find(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_type(ptr)) +#define sk_OCSP_RESPID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_type(ptr)) +#define sk_OCSP_RESPID_sort(sk) OPENSSL_sk_sort(ossl_check_OCSP_RESPID_sk_type(sk)) +#define sk_OCSP_RESPID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OCSP_RESPID_sk_type(sk)) +#define sk_OCSP_RESPID_dup(sk) ((STACK_OF(OCSP_RESPID) *)OPENSSL_sk_dup(ossl_check_const_OCSP_RESPID_sk_type(sk))) +#define sk_OCSP_RESPID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OCSP_RESPID) *)OPENSSL_sk_deep_copy(ossl_check_const_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_copyfunc_type(copyfunc), ossl_check_OCSP_RESPID_freefunc_type(freefunc))) +#define sk_OCSP_RESPID_set_cmp_func(sk, cmp) ((sk_OCSP_RESPID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OCSP_RESPID_sk_type(sk), ossl_check_OCSP_RESPID_compfunc_type(cmp))) + typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; @@ -135,7 +215,32 @@ typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; typedef struct ocsp_cert_status_st OCSP_CERTSTATUS; typedef struct ocsp_single_response_st OCSP_SINGLERESP; -DEFINE_OR_DECLARE_STACK_OF(OCSP_SINGLERESP) +SKM_DEFINE_STACK_OF_INTERNAL(OCSP_SINGLERESP, OCSP_SINGLERESP, OCSP_SINGLERESP) +#define sk_OCSP_SINGLERESP_num(sk) OPENSSL_sk_num(ossl_check_const_OCSP_SINGLERESP_sk_type(sk)) +#define sk_OCSP_SINGLERESP_value(sk, idx) ((OCSP_SINGLERESP *)OPENSSL_sk_value(ossl_check_const_OCSP_SINGLERESP_sk_type(sk), (idx))) +#define sk_OCSP_SINGLERESP_new(cmp) ((STACK_OF(OCSP_SINGLERESP) *)OPENSSL_sk_new(ossl_check_OCSP_SINGLERESP_compfunc_type(cmp))) +#define sk_OCSP_SINGLERESP_new_null() ((STACK_OF(OCSP_SINGLERESP) *)OPENSSL_sk_new_null()) +#define sk_OCSP_SINGLERESP_new_reserve(cmp, n) ((STACK_OF(OCSP_SINGLERESP) *)OPENSSL_sk_new_reserve(ossl_check_OCSP_SINGLERESP_compfunc_type(cmp), (n))) +#define sk_OCSP_SINGLERESP_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OCSP_SINGLERESP_sk_type(sk), (n)) +#define sk_OCSP_SINGLERESP_free(sk) OPENSSL_sk_free(ossl_check_OCSP_SINGLERESP_sk_type(sk)) +#define sk_OCSP_SINGLERESP_zero(sk) OPENSSL_sk_zero(ossl_check_OCSP_SINGLERESP_sk_type(sk)) +#define sk_OCSP_SINGLERESP_delete(sk, i) ((OCSP_SINGLERESP *)OPENSSL_sk_delete(ossl_check_OCSP_SINGLERESP_sk_type(sk), (i))) +#define sk_OCSP_SINGLERESP_delete_ptr(sk, ptr) ((OCSP_SINGLERESP *)OPENSSL_sk_delete_ptr(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_type(ptr))) +#define sk_OCSP_SINGLERESP_push(sk, ptr) OPENSSL_sk_push(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_type(ptr)) +#define sk_OCSP_SINGLERESP_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_type(ptr)) +#define sk_OCSP_SINGLERESP_pop(sk) ((OCSP_SINGLERESP *)OPENSSL_sk_pop(ossl_check_OCSP_SINGLERESP_sk_type(sk))) +#define sk_OCSP_SINGLERESP_shift(sk) ((OCSP_SINGLERESP *)OPENSSL_sk_shift(ossl_check_OCSP_SINGLERESP_sk_type(sk))) +#define sk_OCSP_SINGLERESP_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OCSP_SINGLERESP_sk_type(sk),ossl_check_OCSP_SINGLERESP_freefunc_type(freefunc)) +#define sk_OCSP_SINGLERESP_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_type(ptr), (idx)) +#define sk_OCSP_SINGLERESP_set(sk, idx, ptr) ((OCSP_SINGLERESP *)OPENSSL_sk_set(ossl_check_OCSP_SINGLERESP_sk_type(sk), (idx), ossl_check_OCSP_SINGLERESP_type(ptr))) +#define sk_OCSP_SINGLERESP_find(sk, ptr) OPENSSL_sk_find(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_type(ptr)) +#define sk_OCSP_SINGLERESP_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_type(ptr)) +#define sk_OCSP_SINGLERESP_sort(sk) OPENSSL_sk_sort(ossl_check_OCSP_SINGLERESP_sk_type(sk)) +#define sk_OCSP_SINGLERESP_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OCSP_SINGLERESP_sk_type(sk)) +#define sk_OCSP_SINGLERESP_dup(sk) ((STACK_OF(OCSP_SINGLERESP) *)OPENSSL_sk_dup(ossl_check_const_OCSP_SINGLERESP_sk_type(sk))) +#define sk_OCSP_SINGLERESP_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OCSP_SINGLERESP) *)OPENSSL_sk_deep_copy(ossl_check_const_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_copyfunc_type(copyfunc), ossl_check_OCSP_SINGLERESP_freefunc_type(freefunc))) +#define sk_OCSP_SINGLERESP_set_cmp_func(sk, cmp) ((sk_OCSP_SINGLERESP_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OCSP_SINGLERESP_sk_type(sk), ossl_check_OCSP_SINGLERESP_compfunc_type(cmp))) + typedef struct ocsp_response_data_st OCSP_RESPDATA; @@ -248,7 +353,8 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags); -# define OCSP_parse_url OSSL_HTTP_parse_url /* for backward compatibility */ +# define OCSP_parse_url(url, host, port, path, ssl) \ + OSSL_HTTP_parse_url(url, host, port, NULL, path, ssl) /* backward compat */ int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); @@ -276,9 +382,9 @@ int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, STACK_OF(X509) *certs, unsigned long flags); int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert); int OCSP_RESPID_set_by_key_ex(OCSP_RESPID *respid, X509 *cert, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert); -int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OPENSSL_CTX *libctx, +int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OSSL_LIB_CTX *libctx, const char *propq); int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert); diff --git a/include/openssl/ocsp.h.in b/include/openssl/ocsp.h.in new file mode 100644 index 0000000000..b702f607be --- /dev/null +++ b/include/openssl/ocsp.h.in @@ -0,0 +1,391 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_OCSP_H +# define OPENSSL_OCSP_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_OCSP_H +# endif + +# include +# include /* for OSSL_HTTP_parse_url */ + +/* + * These definitions are outside the OPENSSL_NO_OCSP guard because although for + * historical reasons they have OCSP_* names, they can actually be used + * independently of OCSP. E.g. see RFC5280 + */ +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * -- value 7 is not used + * removeFromCRL (8), + * privilegeWithdrawn (9), + * aACompromise (10) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 +# define OCSP_REVOKED_STATUS_PRIVILEGEWITHDRAWN 9 +# define OCSP_REVOKED_STATUS_AACOMPROMISE 10 + +/* + * These definitions are outside the OPENSSL_NO_OCSP guard because although for + * historical reasons they have OCSP_* names, they are used for the HTTP client. + */ +# include +/* The following functions are used only internally */ +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *wbio, BIO *rbio, + int method_GET, int maxline, + unsigned long max_resp_len, int timeout, + const char *expected_content_type, + int expect_asn1); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, + const char *server, const char *port, const char *path); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const char *content_type, + const ASN1_ITEM *it, ASN1_VALUE *req); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); +ASN1_VALUE *OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +/* End of functions used only internally */ + + +# ifndef OPENSSL_NO_OCSP + +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 +# define OCSP_PARTIAL_CHAIN 0x1000 + +typedef struct ocsp_cert_id_st OCSP_CERTID; +typedef struct ocsp_one_request_st OCSP_ONEREQ; +typedef struct ocsp_req_info_st OCSP_REQINFO; +typedef struct ocsp_signature_st OCSP_SIGNATURE; +typedef struct ocsp_request_st OCSP_REQUEST; + +{- + generate_stack_macros("OCSP_CERTID") + .generate_stack_macros("OCSP_ONEREQ"); +-} + +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES; + +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 + +{- + generate_stack_macros("OCSP_RESPID"); +-} + +typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO; + +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 + +typedef struct ocsp_cert_status_st OCSP_CERTSTATUS; +typedef struct ocsp_single_response_st OCSP_SINGLERESP; + +{- + generate_stack_macros("OCSP_SINGLERESP"); +-} + +typedef struct ocsp_response_data_st OCSP_RESPDATA; + +typedef struct ocsp_basic_response_st OCSP_BASICRESP; + +typedef struct ocsp_crl_id_st OCSP_CRLID; +typedef struct ocsp_service_locator_st OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST, \ + bp,(char **)(x),cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) (OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE, \ + bp,(char **)(x),cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)(o), NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((i2d_of_void *)i2d_OCSP_CERTSTATUS,\ + (d2i_of_void *)d2i_OCSP_CERTSTATUS,(char *)(cs)) + +DECLARE_ASN1_DUP_FUNCTION(OCSP_CERTID) + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); + +/* TODO: remove this (documented but) meanwhile obsolete function? */ +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, const OCSP_REQUEST *req); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, + const X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + const X509_NAME *issuerName, + const ASN1_BIT_STRING *issuerKey, + const ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, const X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs); +const X509_ALGOR *OCSP_resp_get0_tbs_sigalg(const OCSP_BASICRESP *bs); +const OCSP_RESPDATA *OCSP_resp_get0_respdata(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer, + STACK_OF(X509) *extra_certs); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs); +const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); +int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, + const ASN1_OCTET_STRING **pid, + const X509_NAME **pname); +int OCSP_resp_get1_id(const OCSP_BASICRESP *bs, + ASN1_OCTET_STRING **pid, + X509_NAME **pname); + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +# define OCSP_parse_url(url, host, port, path, ssl) \ + OSSL_HTTP_parse_url(url, host, port, NULL, path, ssl) /* backward compat */ + +int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); +int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_basic_sign_ctx(OCSP_BASICRESP *brsp, + X509 *signer, EVP_MD_CTX *ctx, + STACK_OF(X509) *certs, unsigned long flags); +int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_set_by_key_ex(OCSP_RESPID *respid, X509 *cert, + OSSL_LIB_CTX *libctx, const char *propq); +int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert); +int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OSSL_LIB_CTX *libctx, + const char *propq); +int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert); + +X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(const X509_NAME *issuer, const char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); +const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + + +# ifdef __cplusplus +} +# endif +# endif /* !defined(OPENSSL_NO_OCSP) */ +#endif diff --git a/include/openssl/ocsperr.h b/include/openssl/ocsperr.h index f9ad3be022..eea82b8a56 100644 --- a/include/openssl/ocsperr.h +++ b/include/openssl/ocsperr.h @@ -50,6 +50,8 @@ int ERR_load_OCSP_strings(void); */ # define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 # define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_DIGEST_NAME_ERR 106 +# define OCSP_R_DIGEST_SIZE_ERR 107 # define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 # define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 # define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h index d540e4824d..28ae0cd95a 100644 --- a/include/openssl/opensslv.h +++ b/include/openssl/opensslv.h @@ -39,7 +39,7 @@ extern "C" { */ /* Could be: #define OPENSSL_VERSION_PRE_RELEASE "-alpha.1" */ -# define OPENSSL_VERSION_PRE_RELEASE "-alpha6" +# define OPENSSL_VERSION_PRE_RELEASE "-alpha7" /* Could be: #define OPENSSL_VERSION_BUILD_METADATA "+fips" */ /* Could be: #define OPENSSL_VERSION_BUILD_METADATA "+vendor.1" */ # define OPENSSL_VERSION_BUILD_METADATA "" @@ -75,20 +75,20 @@ extern "C" { * OPENSSL_VERSION_BUILD_METADATA_STR appended. */ # define OPENSSL_VERSION_STR "3.0.0" -# define OPENSSL_FULL_VERSION_STR "3.0.0-alpha6" +# define OPENSSL_FULL_VERSION_STR "3.0.0-alpha7" /* * SECTION 3: ADDITIONAL METADATA * * These strings are defined separately to allow them to be parsable. */ -# define OPENSSL_RELEASE_DATE "6 Aug 2020" +# define OPENSSL_RELEASE_DATE "15 Oct 2020" /* * SECTION 4: BACKWARD COMPATIBILITY */ -# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.0-alpha6 6 Aug 2020" +# define OPENSSL_VERSION_TEXT "OpenSSL 3.0.0-alpha7 15 Oct 2020" /* Synthesize OPENSSL_VERSION_NUMBER with the layout 0xMNN00PPSL */ # ifdef OPENSSL_VERSION_PRE_RELEASE diff --git a/include/openssl/params.h b/include/openssl/params.h index 44fc1a6a38..6ed7ecbb24 100644 --- a/include/openssl/params.h +++ b/include/openssl/params.h @@ -142,6 +142,10 @@ int OSSL_PARAM_get_octet_ptr(const OSSL_PARAM *p, const void **val, int OSSL_PARAM_set_octet_ptr(OSSL_PARAM *p, const void *val, size_t used_len); +int OSSL_PARAM_get_utf8_string_ptr(const OSSL_PARAM *p, const char **val); +int OSSL_PARAM_get_octet_string_ptr(const OSSL_PARAM *p, const void **val, + size_t *used_len); + int OSSL_PARAM_modified(const OSSL_PARAM *p); void OSSL_PARAM_set_all_unmodified(OSSL_PARAM *p); diff --git a/include/openssl/pem.h b/include/openssl/pem.h index f4989e3987..3066918b27 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -191,72 +191,110 @@ extern "C" { /* These are the same except they are for the declarations */ +/* + * The mysterious 'extern' that's passed to some macros is innocuous, + * and is there to quiet pre-C99 compilers that may complain about empty + * arguments in macro calls. + */ # if defined(OPENSSL_NO_STDIO) -# define DECLARE_PEM_read_fp(name, type) /**/ -# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_read_fp_attr(attr, name, type) /**/ +# define DECLARE_PEM_write_fp_attr(attr, name, type) /**/ +# define DECLARE_PEM_write_fp_attr(attr, name, type) /**/ # ifndef OPENSSL_NO_DEPRECATED_3_0 -# define DECLARE_PEM_write_fp_const(name, type) /**/ +# define DECLARE_PEM_write_fp_const_attr(attr, name, type) /**/ # endif -# define DECLARE_PEM_write_cb_fp(name, type) /**/ -# else - -# define DECLARE_PEM_read_fp(name, type) \ - type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); +# define DECLARE_PEM_write_cb_fp_attr(attr, name, type) /**/ -# define DECLARE_PEM_write_fp(name, type) \ - PEM_write_fnsig(name, type, FILE, write); +# else +# define DECLARE_PEM_read_fp_attr(attr, name, type) \ + attr type *PEM_read_##name(FILE *fp, type **x, \ + pem_password_cb *cb, void *u); +# define DECLARE_PEM_write_fp_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, FILE, write); # ifndef OPENSSL_NO_DEPRECATED_3_0 -# define DECLARE_PEM_write_fp_const(name, type) \ - PEM_write_fnsig(name, type, FILE, write); +# define DECLARE_PEM_write_fp_const_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, FILE, write); # endif +# define DECLARE_PEM_write_cb_fp_attr(attr, name, type) \ + attr PEM_write_cb_fnsig(name, type, FILE, write); -# define DECLARE_PEM_write_cb_fp(name, type) \ - PEM_write_cb_fnsig(name, type, FILE, write); +# endif +# define DECLARE_PEM_read_fp(name, type) \ + DECLARE_PEM_read_fp_attr(extern, name, type) +# define DECLARE_PEM_write_fp(name, type) \ + DECLARE_PEM_write_fp_attr(extern, name, type) +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_fp_const(name, type) \ + DECLARE_PEM_write_fp_const_attr(extern, name, type) # endif +# define DECLARE_PEM_write_cb_fp(name, type) \ + DECLARE_PEM_write_cb_fp_attr(extern, name, type) -# define DECLARE_PEM_read_bio(name, type) \ - type *PEM_read_bio_##name(BIO *bp, type **x, \ - pem_password_cb *cb, void *u); +# define DECLARE_PEM_read_bio_attr(attr, name, type) \ + attr type *PEM_read_bio_##name(BIO *bp, type **x, \ + pem_password_cb *cb, void *u); +# define DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_bio_attr(extern, name, type) -# define DECLARE_PEM_write_bio(name, type) \ - PEM_write_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_bio_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_bio_attr(extern, name, type) -# ifndef OPENSSL_NO_DEPRECATED_3_0 -# define DECLARE_PEM_write_bio_const(name, type) \ - PEM_write_fnsig(name, type, BIO, write_bio); -# endif +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_write_bio_const_attr(attr, name, type) \ + attr PEM_write_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_bio_const_attr(extern, name, type) +# endif -# define DECLARE_PEM_write_cb_bio(name, type) \ - PEM_write_cb_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_cb_bio_attr(attr, name, type) \ + attr PEM_write_cb_fnsig(name, type, BIO, write_bio); +# define DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_bio_attr(extern, name, type) +# define DECLARE_PEM_write_attr(attr, name, type) \ + DECLARE_PEM_write_bio_attr(attr, name, type) \ + DECLARE_PEM_write_fp_attr(attr, name, type) # define DECLARE_PEM_write(name, type) \ - DECLARE_PEM_write_bio(name, type) \ - DECLARE_PEM_write_fp(name, type) + DECLARE_PEM_write_attr(extern, name, type) # ifndef OPENSSL_NO_DEPRECATED_3_0 -# define DECLARE_PEM_write_const(name, type) \ - DECLARE_PEM_write_bio_const(name, type) \ - DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_const_attr(attr, name, type) \ + DECLARE_PEM_write_bio_const_attr(attr, name, type) \ + DECLARE_PEM_write_fp_const_attr(attr, name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_const_attr(extern, name, type) # endif -# define DECLARE_PEM_write_cb(name, type) \ - DECLARE_PEM_write_cb_bio(name, type) \ - DECLARE_PEM_write_cb_fp(name, type) -# define DECLARE_PEM_read(name, type) \ - DECLARE_PEM_read_bio(name, type) \ - DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_write_cb_attr(attr, name, type) \ + DECLARE_PEM_write_cb_bio_attr(attr, name, type) \ + DECLARE_PEM_write_cb_fp_attr(attr, name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_attr(extern, name, type) +# define DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_read_bio_attr(attr, name, type) \ + DECLARE_PEM_read_fp_attr(attr, name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_attr(extern, name, type) +# define DECLARE_PEM_rw_attr(attr, name, type) \ + DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_write_attr(attr, name, type) # define DECLARE_PEM_rw(name, type) \ - DECLARE_PEM_read(name, type) \ - DECLARE_PEM_write(name, type) + DECLARE_PEM_rw_attr(extern, name, type) # ifndef OPENSSL_NO_DEPRECATED_3_0 +# define DECLARE_PEM_rw_const_attr(attr, name, type) \ + DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_write_const_attr(attr, name, type) # define DECLARE_PEM_rw_const(name, type) \ - DECLARE_PEM_read(name, type) \ - DECLARE_PEM_write_const(name, type) + DECLARE_PEM_rw_const_attr(extern, name, type) # endif +# define DECLARE_PEM_rw_cb_attr(attr, name, type) \ + DECLARE_PEM_read_attr(attr, name, type) \ + DECLARE_PEM_write_cb_attr(attr, name, type) # define DECLARE_PEM_rw_cb(name, type) \ - DECLARE_PEM_read(name, type) \ - DECLARE_PEM_write_cb(name, type) + DECLARE_PEM_rw_cb_attr(extern, name, type) int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, @@ -287,9 +325,9 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); STACK_OF(X509_INFO) -*PEM_X509_INFO_read_bio_with_libctx(BIO *bp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u, - OPENSSL_CTX *libctx, const char *propq); +*PEM_X509_INFO_read_bio_ex(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, + const char *propq); int PEM_X509_INFO_write_bio(BIO *bp, const X509_INFO *xi, EVP_CIPHER *enc, const unsigned char *kstr, int klen, @@ -309,9 +347,8 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); STACK_OF(X509_INFO) -*PEM_X509_INFO_read_with_libctx(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u, - OPENSSL_CTX *libctx, const char *propq); +*PEM_X509_INFO_read_ex(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, + void *u, OSSL_LIB_CTX *libctx, const char *propq); #endif int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); @@ -356,15 +393,23 @@ DECLARE_PEM_rw(DHparams, DH) DECLARE_PEM_write(DHxparams, DH) # endif DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) -EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u, OPENSSL_CTX *libctx, - const char *propq); +EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); # ifndef OPENSSL_NO_STDIO -EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u, OPENSSL_CTX *libctx, - const char *propq); +EVP_PKEY *PEM_read_PrivateKey_ex(FILE *fp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); # endif DECLARE_PEM_rw(PUBKEY, EVP_PKEY) +EVP_PKEY *PEM_read_bio_PUBKEY_ex(BIO *bp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); +# ifndef OPENSSL_NO_STDIO +EVP_PKEY *PEM_read_PUBKEY_ex(FILE *fp, EVP_PKEY **x, + pem_password_cb *cb, void *u, + OSSL_LIB_CTX *libctx, const char *propq); +# endif int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, @@ -405,6 +450,8 @@ int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc const char *kstr, int klen, pem_password_cb *cd, void *u); # endif +EVP_PKEY *PEM_read_bio_Parameters_ex(BIO *bp, EVP_PKEY **x, + OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); int PEM_write_bio_Parameters(BIO *bp, const EVP_PKEY *x); diff --git a/include/openssl/pemerr.h b/include/openssl/pemerr.h index e3450e5eed..a8ad9f2c87 100644 --- a/include/openssl/pemerr.h +++ b/include/openssl/pemerr.h @@ -102,5 +102,6 @@ int ERR_load_PEM_strings(void); # define PEM_R_UNSUPPORTED_CIPHER 113 # define PEM_R_UNSUPPORTED_ENCRYPTION 114 # define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 +# define PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE 110 #endif diff --git a/include/openssl/pkcs12.h b/include/openssl/pkcs12.h index abf124f27a..2d2e99b6f0 100644 --- a/include/openssl/pkcs12.h +++ b/include/openssl/pkcs12.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/pkcs12.h.in + * * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_PKCS12_H # define OPENSSL_PKCS12_H # pragma once @@ -52,7 +57,32 @@ typedef struct PKCS12_st PKCS12; typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG; -DEFINE_OR_DECLARE_STACK_OF(PKCS12_SAFEBAG) +SKM_DEFINE_STACK_OF_INTERNAL(PKCS12_SAFEBAG, PKCS12_SAFEBAG, PKCS12_SAFEBAG) +#define sk_PKCS12_SAFEBAG_num(sk) OPENSSL_sk_num(ossl_check_const_PKCS12_SAFEBAG_sk_type(sk)) +#define sk_PKCS12_SAFEBAG_value(sk, idx) ((PKCS12_SAFEBAG *)OPENSSL_sk_value(ossl_check_const_PKCS12_SAFEBAG_sk_type(sk), (idx))) +#define sk_PKCS12_SAFEBAG_new(cmp) ((STACK_OF(PKCS12_SAFEBAG) *)OPENSSL_sk_new(ossl_check_PKCS12_SAFEBAG_compfunc_type(cmp))) +#define sk_PKCS12_SAFEBAG_new_null() ((STACK_OF(PKCS12_SAFEBAG) *)OPENSSL_sk_new_null()) +#define sk_PKCS12_SAFEBAG_new_reserve(cmp, n) ((STACK_OF(PKCS12_SAFEBAG) *)OPENSSL_sk_new_reserve(ossl_check_PKCS12_SAFEBAG_compfunc_type(cmp), (n))) +#define sk_PKCS12_SAFEBAG_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_PKCS12_SAFEBAG_sk_type(sk), (n)) +#define sk_PKCS12_SAFEBAG_free(sk) OPENSSL_sk_free(ossl_check_PKCS12_SAFEBAG_sk_type(sk)) +#define sk_PKCS12_SAFEBAG_zero(sk) OPENSSL_sk_zero(ossl_check_PKCS12_SAFEBAG_sk_type(sk)) +#define sk_PKCS12_SAFEBAG_delete(sk, i) ((PKCS12_SAFEBAG *)OPENSSL_sk_delete(ossl_check_PKCS12_SAFEBAG_sk_type(sk), (i))) +#define sk_PKCS12_SAFEBAG_delete_ptr(sk, ptr) ((PKCS12_SAFEBAG *)OPENSSL_sk_delete_ptr(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_type(ptr))) +#define sk_PKCS12_SAFEBAG_push(sk, ptr) OPENSSL_sk_push(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_type(ptr)) +#define sk_PKCS12_SAFEBAG_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_type(ptr)) +#define sk_PKCS12_SAFEBAG_pop(sk) ((PKCS12_SAFEBAG *)OPENSSL_sk_pop(ossl_check_PKCS12_SAFEBAG_sk_type(sk))) +#define sk_PKCS12_SAFEBAG_shift(sk) ((PKCS12_SAFEBAG *)OPENSSL_sk_shift(ossl_check_PKCS12_SAFEBAG_sk_type(sk))) +#define sk_PKCS12_SAFEBAG_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_PKCS12_SAFEBAG_sk_type(sk),ossl_check_PKCS12_SAFEBAG_freefunc_type(freefunc)) +#define sk_PKCS12_SAFEBAG_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_type(ptr), (idx)) +#define sk_PKCS12_SAFEBAG_set(sk, idx, ptr) ((PKCS12_SAFEBAG *)OPENSSL_sk_set(ossl_check_PKCS12_SAFEBAG_sk_type(sk), (idx), ossl_check_PKCS12_SAFEBAG_type(ptr))) +#define sk_PKCS12_SAFEBAG_find(sk, ptr) OPENSSL_sk_find(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_type(ptr)) +#define sk_PKCS12_SAFEBAG_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_type(ptr)) +#define sk_PKCS12_SAFEBAG_sort(sk) OPENSSL_sk_sort(ossl_check_PKCS12_SAFEBAG_sk_type(sk)) +#define sk_PKCS12_SAFEBAG_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_PKCS12_SAFEBAG_sk_type(sk)) +#define sk_PKCS12_SAFEBAG_dup(sk) ((STACK_OF(PKCS12_SAFEBAG) *)OPENSSL_sk_dup(ossl_check_const_PKCS12_SAFEBAG_sk_type(sk))) +#define sk_PKCS12_SAFEBAG_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(PKCS12_SAFEBAG) *)OPENSSL_sk_deep_copy(ossl_check_const_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_copyfunc_type(copyfunc), ossl_check_PKCS12_SAFEBAG_freefunc_type(freefunc))) +#define sk_PKCS12_SAFEBAG_set_cmp_func(sk, cmp) ((sk_PKCS12_SAFEBAG_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_PKCS12_SAFEBAG_sk_type(sk), ossl_check_PKCS12_SAFEBAG_compfunc_type(cmp))) + typedef struct pkcs12_bag_st PKCS12_BAGS; @@ -93,6 +123,8 @@ const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag); int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag); int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); +const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag); X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); @@ -103,6 +135,7 @@ const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509); PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len); PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8); PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8); PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, @@ -144,6 +177,10 @@ int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen); int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name, int namelen); +int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type, + const unsigned char *bytes, int len); +int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type, + const unsigned char *bytes, int len); int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); @@ -209,6 +246,8 @@ PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key, int key_usage, int iter, int key_nid, const char *pass); +PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags, + int nid_type, const unsigned char *value, int len); int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, int safe_nid, int iter, const char *pass); PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); diff --git a/include/openssl/pkcs12.h.in b/include/openssl/pkcs12.h.in new file mode 100644 index 0000000000..f829dc7439 --- /dev/null +++ b/include/openssl/pkcs12.h.in @@ -0,0 +1,246 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_PKCS12_H +# define OPENSSL_PKCS12_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_PKCS12_H +# endif + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* It's not clear if these are actually needed... */ +# define PKCS12_key_gen PKCS12_key_gen_utf8 +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_utf8 + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct PKCS12_MAC_DATA_st PKCS12_MAC_DATA; + +typedef struct PKCS12_st PKCS12; + +typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG; + +{- + generate_stack_macros("PKCS12_SAFEBAG"); +-} + +typedef struct pkcs12_bag_st PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 + +# define M_PKCS12_bag_type PKCS12_bag_type +# define M_PKCS12_cert_bag_type PKCS12_cert_bag_type +# define M_PKCS12_crl_bag_type PKCS12_cert_bag_type + +# define PKCS12_certbag2x509 PKCS12_SAFEBAG_get1_cert +# define PKCS12_certbag2scrl PKCS12_SAFEBAG_get1_crl +# define PKCS12_bag_type PKCS12_SAFEBAG_get_nid +# define PKCS12_cert_bag_type PKCS12_SAFEBAG_get_bag_nid +# define PKCS12_x5092certbag PKCS12_SAFEBAG_create_cert +# define PKCS12_x509crl2certbag PKCS12_SAFEBAG_create_crl +# define PKCS12_MAKE_KEYBAG PKCS12_SAFEBAG_create0_p8inf +# define PKCS12_MAKE_SHKEYBAG PKCS12_SAFEBAG_create_pkcs8_encrypt + +#endif + +DEPRECATEDIN_1_1_0(ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)) + +ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid); +int PKCS12_mac_present(const PKCS12 *p12); +void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac, + const X509_ALGOR **pmacalg, + const ASN1_OCTET_STRING **psalt, + const ASN1_INTEGER **piter, + const PKCS12 *p12); + +const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, + int attr_nid); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag); +int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag); +const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag); +const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag); + +X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); +const STACK_OF(PKCS12_SAFEBAG) * +PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); +const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); +const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8); +PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, + const char *pass, + int passlen, + unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen, + PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS12_add1_attr_by_NID(PKCS12_SAFEBAG *bag, int nid, int type, + const unsigned char *bytes, int len); +int PKCS12_add1_attr_by_txt(PKCS12_SAFEBAG *bag, const char *attrname, int type, + const unsigned char *bytes, int len); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs, + int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +const STACK_OF(X509_ATTRIBUTE) * +PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor, + const char *pass, int passlen, + const unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + const ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(const unsigned char *uni, int unilen); +unsigned char *OPENSSL_utf82uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, + X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert, + int iter, int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, const char *pass); +PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags, + int nid_type, const unsigned char *value, int len); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, const char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, const PKCS12 *p12); +# ifndef OPENSSL_NO_STDIO +int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12); +# endif +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +# ifndef OPENSSL_NO_STDIO +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +# endif +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/pkcs12err.h b/include/openssl/pkcs12err.h index 8d69b63f1a..60369447de 100644 --- a/include/openssl/pkcs12err.h +++ b/include/openssl/pkcs12err.h @@ -47,6 +47,7 @@ int ERR_load_PKCS12_strings(void); # define PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF 0 # define PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8 0 # define PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT 0 +# define PKCS12_F_PKCS12_SAFEBAG_CREATE_SECRET 0 # define PKCS12_F_PKCS12_SETUP_MAC 0 # define PKCS12_F_PKCS12_SET_MAC 0 # define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 0 @@ -67,6 +68,7 @@ int ERR_load_PKCS12_strings(void); # define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 # define PKCS12_R_INVALID_NULL_ARGUMENT 104 # define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_INVALID_TYPE 112 # define PKCS12_R_IV_GEN_ERROR 106 # define PKCS12_R_KEY_GEN_ERROR 107 # define PKCS12_R_MAC_ABSENT 108 @@ -75,9 +77,7 @@ int ERR_load_PKCS12_strings(void); # define PKCS12_R_MAC_STRING_SET_ERROR 111 # define PKCS12_R_MAC_VERIFY_FAILURE 113 # define PKCS12_R_PARSE_ERROR 114 -# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 # define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 -# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 # define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 # define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h index 0e1c50032f..77cd8f3c8f 100644 --- a/include/openssl/pkcs7.h +++ b/include/openssl/pkcs7.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/pkcs7.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_PKCS7_H # define OPENSSL_PKCS7_H # pragma once @@ -36,6 +41,11 @@ Digest_Encryption_ID rsaEncryption Key_Encryption_ID rsaEncryption */ +typedef struct PKCS7_CTX_st { + OSSL_LIB_CTX *libctx; + char *propq; +} PKCS7_CTX; + typedef struct pkcs7_issuer_and_serial_st { X509_NAME *issuer; ASN1_INTEGER *serial; @@ -51,8 +61,34 @@ typedef struct pkcs7_signer_info_st { STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ /* The private key to sign with */ EVP_PKEY *pkey; + const PKCS7_CTX *ctx; } PKCS7_SIGNER_INFO; -DEFINE_OR_DECLARE_STACK_OF(PKCS7_SIGNER_INFO) +SKM_DEFINE_STACK_OF_INTERNAL(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) +#define sk_PKCS7_SIGNER_INFO_num(sk) OPENSSL_sk_num(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk)) +#define sk_PKCS7_SIGNER_INFO_value(sk, idx) ((PKCS7_SIGNER_INFO *)OPENSSL_sk_value(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk), (idx))) +#define sk_PKCS7_SIGNER_INFO_new(cmp) ((STACK_OF(PKCS7_SIGNER_INFO) *)OPENSSL_sk_new(ossl_check_PKCS7_SIGNER_INFO_compfunc_type(cmp))) +#define sk_PKCS7_SIGNER_INFO_new_null() ((STACK_OF(PKCS7_SIGNER_INFO) *)OPENSSL_sk_new_null()) +#define sk_PKCS7_SIGNER_INFO_new_reserve(cmp, n) ((STACK_OF(PKCS7_SIGNER_INFO) *)OPENSSL_sk_new_reserve(ossl_check_PKCS7_SIGNER_INFO_compfunc_type(cmp), (n))) +#define sk_PKCS7_SIGNER_INFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), (n)) +#define sk_PKCS7_SIGNER_INFO_free(sk) OPENSSL_sk_free(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk)) +#define sk_PKCS7_SIGNER_INFO_zero(sk) OPENSSL_sk_zero(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk)) +#define sk_PKCS7_SIGNER_INFO_delete(sk, i) ((PKCS7_SIGNER_INFO *)OPENSSL_sk_delete(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), (i))) +#define sk_PKCS7_SIGNER_INFO_delete_ptr(sk, ptr) ((PKCS7_SIGNER_INFO *)OPENSSL_sk_delete_ptr(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_type(ptr))) +#define sk_PKCS7_SIGNER_INFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_type(ptr)) +#define sk_PKCS7_SIGNER_INFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_type(ptr)) +#define sk_PKCS7_SIGNER_INFO_pop(sk) ((PKCS7_SIGNER_INFO *)OPENSSL_sk_pop(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk))) +#define sk_PKCS7_SIGNER_INFO_shift(sk) ((PKCS7_SIGNER_INFO *)OPENSSL_sk_shift(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk))) +#define sk_PKCS7_SIGNER_INFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk),ossl_check_PKCS7_SIGNER_INFO_freefunc_type(freefunc)) +#define sk_PKCS7_SIGNER_INFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_type(ptr), (idx)) +#define sk_PKCS7_SIGNER_INFO_set(sk, idx, ptr) ((PKCS7_SIGNER_INFO *)OPENSSL_sk_set(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), (idx), ossl_check_PKCS7_SIGNER_INFO_type(ptr))) +#define sk_PKCS7_SIGNER_INFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_type(ptr)) +#define sk_PKCS7_SIGNER_INFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_type(ptr)) +#define sk_PKCS7_SIGNER_INFO_sort(sk) OPENSSL_sk_sort(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk)) +#define sk_PKCS7_SIGNER_INFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk)) +#define sk_PKCS7_SIGNER_INFO_dup(sk) ((STACK_OF(PKCS7_SIGNER_INFO) *)OPENSSL_sk_dup(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk))) +#define sk_PKCS7_SIGNER_INFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(PKCS7_SIGNER_INFO) *)OPENSSL_sk_deep_copy(ossl_check_const_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_copyfunc_type(copyfunc), ossl_check_PKCS7_SIGNER_INFO_freefunc_type(freefunc))) +#define sk_PKCS7_SIGNER_INFO_set_cmp_func(sk, cmp) ((sk_PKCS7_SIGNER_INFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_PKCS7_SIGNER_INFO_sk_type(sk), ossl_check_PKCS7_SIGNER_INFO_compfunc_type(cmp))) + typedef struct pkcs7_recip_info_st { ASN1_INTEGER *version; /* version 0 */ @@ -60,8 +96,34 @@ typedef struct pkcs7_recip_info_st { X509_ALGOR *key_enc_algor; ASN1_OCTET_STRING *enc_key; X509 *cert; /* get the pub-key from this */ + const PKCS7_CTX *ctx; } PKCS7_RECIP_INFO; -DEFINE_OR_DECLARE_STACK_OF(PKCS7_RECIP_INFO) +SKM_DEFINE_STACK_OF_INTERNAL(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) +#define sk_PKCS7_RECIP_INFO_num(sk) OPENSSL_sk_num(ossl_check_const_PKCS7_RECIP_INFO_sk_type(sk)) +#define sk_PKCS7_RECIP_INFO_value(sk, idx) ((PKCS7_RECIP_INFO *)OPENSSL_sk_value(ossl_check_const_PKCS7_RECIP_INFO_sk_type(sk), (idx))) +#define sk_PKCS7_RECIP_INFO_new(cmp) ((STACK_OF(PKCS7_RECIP_INFO) *)OPENSSL_sk_new(ossl_check_PKCS7_RECIP_INFO_compfunc_type(cmp))) +#define sk_PKCS7_RECIP_INFO_new_null() ((STACK_OF(PKCS7_RECIP_INFO) *)OPENSSL_sk_new_null()) +#define sk_PKCS7_RECIP_INFO_new_reserve(cmp, n) ((STACK_OF(PKCS7_RECIP_INFO) *)OPENSSL_sk_new_reserve(ossl_check_PKCS7_RECIP_INFO_compfunc_type(cmp), (n))) +#define sk_PKCS7_RECIP_INFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), (n)) +#define sk_PKCS7_RECIP_INFO_free(sk) OPENSSL_sk_free(ossl_check_PKCS7_RECIP_INFO_sk_type(sk)) +#define sk_PKCS7_RECIP_INFO_zero(sk) OPENSSL_sk_zero(ossl_check_PKCS7_RECIP_INFO_sk_type(sk)) +#define sk_PKCS7_RECIP_INFO_delete(sk, i) ((PKCS7_RECIP_INFO *)OPENSSL_sk_delete(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), (i))) +#define sk_PKCS7_RECIP_INFO_delete_ptr(sk, ptr) ((PKCS7_RECIP_INFO *)OPENSSL_sk_delete_ptr(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_type(ptr))) +#define sk_PKCS7_RECIP_INFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_type(ptr)) +#define sk_PKCS7_RECIP_INFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_type(ptr)) +#define sk_PKCS7_RECIP_INFO_pop(sk) ((PKCS7_RECIP_INFO *)OPENSSL_sk_pop(ossl_check_PKCS7_RECIP_INFO_sk_type(sk))) +#define sk_PKCS7_RECIP_INFO_shift(sk) ((PKCS7_RECIP_INFO *)OPENSSL_sk_shift(ossl_check_PKCS7_RECIP_INFO_sk_type(sk))) +#define sk_PKCS7_RECIP_INFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_PKCS7_RECIP_INFO_sk_type(sk),ossl_check_PKCS7_RECIP_INFO_freefunc_type(freefunc)) +#define sk_PKCS7_RECIP_INFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_type(ptr), (idx)) +#define sk_PKCS7_RECIP_INFO_set(sk, idx, ptr) ((PKCS7_RECIP_INFO *)OPENSSL_sk_set(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), (idx), ossl_check_PKCS7_RECIP_INFO_type(ptr))) +#define sk_PKCS7_RECIP_INFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_type(ptr)) +#define sk_PKCS7_RECIP_INFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_type(ptr)) +#define sk_PKCS7_RECIP_INFO_sort(sk) OPENSSL_sk_sort(ossl_check_PKCS7_RECIP_INFO_sk_type(sk)) +#define sk_PKCS7_RECIP_INFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_PKCS7_RECIP_INFO_sk_type(sk)) +#define sk_PKCS7_RECIP_INFO_dup(sk) ((STACK_OF(PKCS7_RECIP_INFO) *)OPENSSL_sk_dup(ossl_check_const_PKCS7_RECIP_INFO_sk_type(sk))) +#define sk_PKCS7_RECIP_INFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(PKCS7_RECIP_INFO) *)OPENSSL_sk_deep_copy(ossl_check_const_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_copyfunc_type(copyfunc), ossl_check_PKCS7_RECIP_INFO_freefunc_type(freefunc))) +#define sk_PKCS7_RECIP_INFO_set_cmp_func(sk, cmp) ((sk_PKCS7_RECIP_INFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_PKCS7_RECIP_INFO_sk_type(sk), ossl_check_PKCS7_RECIP_INFO_compfunc_type(cmp))) + typedef struct pkcs7_signed_st { @@ -82,6 +144,7 @@ typedef struct pkcs7_enc_content_st { X509_ALGOR *algorithm; ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ const EVP_CIPHER *cipher; + const PKCS7_CTX *ctx; } PKCS7_ENC_CONTENT; typedef struct pkcs7_enveloped_st { @@ -147,8 +210,34 @@ typedef struct pkcs7_st { /* Anything else */ ASN1_TYPE *other; } d; + PKCS7_CTX ctx; } PKCS7; -DEFINE_OR_DECLARE_STACK_OF(PKCS7) +SKM_DEFINE_STACK_OF_INTERNAL(PKCS7, PKCS7, PKCS7) +#define sk_PKCS7_num(sk) OPENSSL_sk_num(ossl_check_const_PKCS7_sk_type(sk)) +#define sk_PKCS7_value(sk, idx) ((PKCS7 *)OPENSSL_sk_value(ossl_check_const_PKCS7_sk_type(sk), (idx))) +#define sk_PKCS7_new(cmp) ((STACK_OF(PKCS7) *)OPENSSL_sk_new(ossl_check_PKCS7_compfunc_type(cmp))) +#define sk_PKCS7_new_null() ((STACK_OF(PKCS7) *)OPENSSL_sk_new_null()) +#define sk_PKCS7_new_reserve(cmp, n) ((STACK_OF(PKCS7) *)OPENSSL_sk_new_reserve(ossl_check_PKCS7_compfunc_type(cmp), (n))) +#define sk_PKCS7_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_PKCS7_sk_type(sk), (n)) +#define sk_PKCS7_free(sk) OPENSSL_sk_free(ossl_check_PKCS7_sk_type(sk)) +#define sk_PKCS7_zero(sk) OPENSSL_sk_zero(ossl_check_PKCS7_sk_type(sk)) +#define sk_PKCS7_delete(sk, i) ((PKCS7 *)OPENSSL_sk_delete(ossl_check_PKCS7_sk_type(sk), (i))) +#define sk_PKCS7_delete_ptr(sk, ptr) ((PKCS7 *)OPENSSL_sk_delete_ptr(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_type(ptr))) +#define sk_PKCS7_push(sk, ptr) OPENSSL_sk_push(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_type(ptr)) +#define sk_PKCS7_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_type(ptr)) +#define sk_PKCS7_pop(sk) ((PKCS7 *)OPENSSL_sk_pop(ossl_check_PKCS7_sk_type(sk))) +#define sk_PKCS7_shift(sk) ((PKCS7 *)OPENSSL_sk_shift(ossl_check_PKCS7_sk_type(sk))) +#define sk_PKCS7_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_PKCS7_sk_type(sk),ossl_check_PKCS7_freefunc_type(freefunc)) +#define sk_PKCS7_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_type(ptr), (idx)) +#define sk_PKCS7_set(sk, idx, ptr) ((PKCS7 *)OPENSSL_sk_set(ossl_check_PKCS7_sk_type(sk), (idx), ossl_check_PKCS7_type(ptr))) +#define sk_PKCS7_find(sk, ptr) OPENSSL_sk_find(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_type(ptr)) +#define sk_PKCS7_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_type(ptr)) +#define sk_PKCS7_sort(sk) OPENSSL_sk_sort(ossl_check_PKCS7_sk_type(sk)) +#define sk_PKCS7_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_PKCS7_sk_type(sk)) +#define sk_PKCS7_dup(sk) ((STACK_OF(PKCS7) *)OPENSSL_sk_dup(ossl_check_const_PKCS7_sk_type(sk))) +#define sk_PKCS7_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(PKCS7) *)OPENSSL_sk_deep_copy(ossl_check_const_PKCS7_sk_type(sk), ossl_check_PKCS7_copyfunc_type(copyfunc), ossl_check_PKCS7_freefunc_type(freefunc))) +#define sk_PKCS7_set_cmp_func(sk, cmp) ((sk_PKCS7_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_PKCS7_sk_type(sk), ossl_check_PKCS7_compfunc_type(cmp))) + # define PKCS7_OP_SET_DETACHED_SIGNATURE 1 @@ -231,6 +320,7 @@ DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) DECLARE_ASN1_FUNCTIONS(PKCS7) +PKCS7 *PKCS7_new_ex(OSSL_LIB_CTX *libctx, const char *propq); DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) @@ -240,6 +330,7 @@ DECLARE_ASN1_PRINT_FUNCTION(PKCS7) long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); +int PKCS7_type_is_other(PKCS7 *p7); int PKCS7_set_type(PKCS7 *p7, int type); int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); @@ -275,6 +366,7 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7); ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, void *data); @@ -289,6 +381,9 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, int flags); +PKCS7 *PKCS7_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags, OSSL_LIB_CTX *libctx, + const char *propq); PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, @@ -301,6 +396,9 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); +PKCS7 *PKCS7_encrypt_ex(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, int flags, + OSSL_LIB_CTX *libctx, const char *propq); int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); @@ -315,6 +413,7 @@ int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, const unsigned char *md, int mdlen); int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7); PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); diff --git a/include/openssl/pkcs7.h.in b/include/openssl/pkcs7.h.in new file mode 100644 index 0000000000..df53acc2a1 --- /dev/null +++ b/include/openssl/pkcs7.h.in @@ -0,0 +1,356 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_PKCS7_H +# define OPENSSL_PKCS7_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_PKCS7_H +# endif + +# include +# include +# include + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct PKCS7_CTX_st { + OSSL_LIB_CTX *libctx; + char *propq; +} PKCS7_CTX; + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; + const PKCS7_CTX *ctx; +} PKCS7_SIGNER_INFO; +{- + generate_stack_macros("PKCS7_SIGNER_INFO"); +-} + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ + const PKCS7_CTX *ctx; +} PKCS7_RECIP_INFO; +{- + generate_stack_macros("PKCS7_RECIP_INFO"); +-} + + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; + const PKCS7_CTX *ctx; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; + PKCS7_CTX ctx; +} PKCS7; +{- + generate_stack_macros("PKCS7"); +-} + + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 +# define PKCS7_NO_DUAL_CONTENT 0x10000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +/* CRLF ASCII canonicalisation */ +# define SMIME_ASCIICRLF 0x80000 + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_STDIO +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, const PKCS7 *p7); +# endif +DECLARE_ASN1_DUP_FUNCTION(PKCS7) +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, const PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) +PKCS7 *PKCS7_new_ex(OSSL_LIB_CTX *libctx, const char *propq); + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_type_is_other(PKCS7 *p7); +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); +PKCS7 *PKCS7_sign_ex(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags, OSSL_LIB_CTX *libctx, + const char *propq); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +PKCS7 *PKCS7_encrypt_ex(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, int flags, + OSSL_LIB_CTX *libctx, const char *propq); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7_ex(BIO *bio, BIO **bcont, PKCS7 **p7); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/provider.h b/include/openssl/provider.h index cb5fc9f8bf..80a1b412ed 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -17,18 +17,20 @@ extern "C" { # endif /* Set the default provider search path */ -int OSSL_PROVIDER_set_default_search_path(OPENSSL_CTX *, const char *path); +int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *, const char *path); /* Load and unload a provider */ -OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name); +OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *, const char *name); +OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *, const char *name); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); -int OSSL_PROVIDER_available(OPENSSL_CTX *, const char *name); -int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, +int OSSL_PROVIDER_available(OSSL_LIB_CTX *, const char *name); +int OSSL_PROVIDER_do_all(OSSL_LIB_CTX *ctx, int (*cb)(OSSL_PROVIDER *provider, void *cbdata), void *cbdata); const OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); +int OSSL_PROVIDER_self_test(const OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_capabilities(const OSSL_PROVIDER *prov, const char *capability, OSSL_CALLBACK *cb, @@ -40,7 +42,7 @@ const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov, void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov); /* Add a built in providers */ -int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *, const char *name, +int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *, const char *name, OSSL_provider_init_fn *init_fn); /* Information */ diff --git a/include/openssl/rand.h b/include/openssl/rand.h index d2db26a8ae..73eefd5c14 100644 --- a/include/openssl/rand.h +++ b/include/openssl/rand.h @@ -20,11 +20,22 @@ # include # include # include +# include #ifdef __cplusplus extern "C" { #endif +/* + * Default security strength (in the sense of [NIST SP 800-90Ar1]) + * + * NIST SP 800-90Ar1 supports the strength of the DRBG being smaller than that + * of the cipher by collecting less entropy. The current DRBG implementation + * does not take RAND_DRBG_STRENGTH into account and sets the strength of the + * DRBG to that of the cipher. + */ +# define RAND_DRBG_STRENGTH 256 + struct rand_meth_st { int (*seed) (const void *buf, int num); int (*bytes) (unsigned char *buf, int num); @@ -48,14 +59,18 @@ RAND_METHOD *RAND_OpenSSL(void); int RAND_bytes(unsigned char *buf, int num); int RAND_priv_bytes(unsigned char *buf, int num); -/* Equivalent of RAND_priv_bytes() but additionally taking an OPENSSL_CTX */ -int RAND_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num); +/* Equivalent of RAND_priv_bytes() but additionally taking an OSSL_LIB_CTX */ +int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, int num); -/* Equivalent of RAND_bytes() but additionally taking an OPENSSL_CTX */ -int RAND_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num); +/* Equivalent of RAND_bytes() but additionally taking an OSSL_LIB_CTX */ +int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, int num); DEPRECATEDIN_1_1_0(int RAND_pseudo_bytes(unsigned char *buf, int num)) +EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx); +EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx); +EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx); + void RAND_seed(const void *buf, int num); void RAND_keep_random_devices_open(int keep); diff --git a/include/openssl/rand_drbg.h b/include/openssl/rand_drbg.h deleted file mode 100644 index afc4d43eb8..0000000000 --- a/include/openssl/rand_drbg.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_RAND_DRBG_H -# define OPENSSL_RAND_DRBG_H -# pragma once - -# include -# ifndef OPENSSL_NO_DEPRECATED_3_0 -# define HEADER_DRBG_RAND_H -# endif - -# include -# include -# include - -/* - * RAND_DRBG flags - * - * Note: if new flags are added, the constant `rand_drbg_used_flags` - * in drbg_lib.c needs to be updated accordingly. - */ - -/* In CTR mode, disable derivation function ctr_df */ -# define RAND_DRBG_FLAG_CTR_NO_DF 0x1 -/* - * This flag is only used when a digest NID is specified (i.e: not a CTR cipher) - * Selects DRBG_HMAC if this is set otherwise use DRBG_HASH. - */ -# define RAND_DRBG_FLAG_HMAC 0x2 - -/* Used by RAND_DRBG_set_defaults() to set the primary DRBG type and flags. */ -# define RAND_DRBG_FLAG_PRIMARY 0x4 -/* Used by RAND_DRBG_set_defaults() to set the public DRBG type and flags. */ -# define RAND_DRBG_FLAG_PUBLIC 0x8 -/* Used by RAND_DRBG_set_defaults() to set the private DRBG type and flags. */ -# define RAND_DRBG_FLAG_PRIVATE 0x10 - -# ifndef OPENSSL_NO_DEPRECATED_3_0 -/* This #define was replaced by an internal constant and should not be used. */ -# define RAND_DRBG_USED_FLAGS (RAND_DRBG_FLAG_CTR_NO_DF) -# endif - -/* - * Default security strength (in the sense of [NIST SP 800-90Ar1]) - * - * NIST SP 800-90Ar1 supports the strength of the DRBG being smaller than that - * of the cipher by collecting less entropy. The current DRBG implementation - * does not take RAND_DRBG_STRENGTH into account and sets the strength of the - * DRBG to that of the cipher. - * - * RAND_DRBG_STRENGTH is currently only used for the legacy RAND - * implementation. - * - * Currently supported ciphers are: NID_aes_128_ctr, NID_aes_192_ctr and - * NID_aes_256_ctr. - * The digest types for DRBG_hash or DRBG_hmac are: NID_sha1, NID_sha224, - * NID_sha256, NID_sha384, NID_sha512, NID_sha512_224, NID_sha512_256, - * NID_sha3_224, NID_sha3_256, NID_sha3_384 and NID_sha3_512. - */ -# define RAND_DRBG_STRENGTH 256 -/* Default drbg type */ -# define RAND_DRBG_TYPE NID_aes_256_ctr -/* Default drbg flags */ -# define RAND_DRBG_FLAGS 0 - - -# ifdef __cplusplus -extern "C" { -# endif - -/* - * Object lifetime functions. - */ -RAND_DRBG *RAND_DRBG_new_ex(OPENSSL_CTX *ctx, int type, unsigned int flags, - RAND_DRBG *parent); -RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent); -DEPRECATEDIN_3_0(int RAND_DRBG_set(RAND_DRBG *drbg, int type, - unsigned int flags)) -int RAND_DRBG_set_defaults(int type, unsigned int flags); -int RAND_DRBG_instantiate(RAND_DRBG *drbg, - const unsigned char *pers, size_t perslen); -int RAND_DRBG_uninstantiate(RAND_DRBG *drbg); -void RAND_DRBG_free(RAND_DRBG *drbg); - -/* - * Object "use" functions. - */ -int RAND_DRBG_reseed(RAND_DRBG *drbg, - const unsigned char *adin, size_t adinlen, - int prediction_resistance); -int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, - int prediction_resistance, - const unsigned char *adin, size_t adinlen); -int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen); - -int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval); -int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval); - -int RAND_DRBG_set_reseed_defaults( - unsigned int primary_reseed_interval, - unsigned int secondary_reseed_interval, - time_t primary_reseed_time_interval, - time_t secondary_reseed_time_interval - ); - -RAND_DRBG *OPENSSL_CTX_get0_primary_drbg(OPENSSL_CTX *ctx); -RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx); -RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx); -RAND_DRBG *RAND_DRBG_get0_master(void); -RAND_DRBG *RAND_DRBG_get0_public(void); -RAND_DRBG *RAND_DRBG_get0_private(void); - -# ifndef OPENSSL_NO_DEPRECATED_3_0 -/* Retain legacy deprecated names */ -# define RAND_DRBG_FLAG_MASTER RAND_DRBG_FLAG_PRIMARY -# define OPENSSL_CTX_get0_master_drbg OPENSSL_CTX_get0_primary_drbg -# define RAND_DRBG_get0_master RAND_DRBG_get0_master -# endif - -/* - * EXDATA - */ -# define RAND_DRBG_get_ex_new_index(l, p, newf, dupf, freef) \ - CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RAND_DRBG, l, p, newf, dupf, freef) -int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg); -void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx); - -/* - * Callback function typedefs - */ -typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *drbg, - unsigned char **pout, - int entropy, size_t min_len, - size_t max_len, - int prediction_resistance); -typedef void (*RAND_DRBG_cleanup_entropy_fn)(RAND_DRBG *ctx, - unsigned char *out, size_t outlen); -typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *drbg, unsigned char **pout, - int entropy, size_t min_len, - size_t max_len); -typedef void (*RAND_DRBG_cleanup_nonce_fn)(RAND_DRBG *drbg, - unsigned char *out, size_t outlen); - -int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, - RAND_DRBG_get_entropy_fn get_entropy, - RAND_DRBG_cleanup_entropy_fn cleanup_entropy, - RAND_DRBG_get_nonce_fn get_nonce, - RAND_DRBG_cleanup_nonce_fn cleanup_nonce); - - -int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *data); - -void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg); - -int RAND_DRBG_verify_zeroization(RAND_DRBG *drbg); - -# ifdef __cplusplus -} -# endif - -#endif diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index 2764894b0c..3eef9afdd2 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -98,6 +98,8 @@ int ERR_load_RAND_strings(void); # define RAND_R_SELFTEST_FAILURE 119 # define RAND_R_TOO_LITTLE_NONCE_REQUESTED 135 # define RAND_R_TOO_MUCH_NONCE_REQUESTED 136 +# define RAND_R_UNABLE_TO_CREATE_DRBG 143 +# define RAND_R_UNABLE_TO_FETCH_DRBG 144 # define RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER 141 # define RAND_R_UNABLE_TO_GET_PARENT_STRENGTH 138 # define RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR 142 diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index 140c0d4412..24b2a7eb55 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -132,7 +132,9 @@ int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen); int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen); int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits); -int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); +DEPRECATEDIN_3_0(int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, + BIGNUM *pubexp)) +int EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes); int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen); diff --git a/include/openssl/rsaerr.h b/include/openssl/rsaerr.h index 34df111eaf..794f433a05 100644 --- a/include/openssl/rsaerr.h +++ b/include/openssl/rsaerr.h @@ -41,7 +41,6 @@ int ERR_load_RSA_strings(void); # define RSA_F_RSA_CHECK_KEY_EX 0 # define RSA_F_RSA_CMS_DECRYPT 0 # define RSA_F_RSA_CMS_VERIFY 0 -# define RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES 0 # define RSA_F_RSA_ITEM_VERIFY 0 # define RSA_F_RSA_METH_DUP 0 # define RSA_F_RSA_METH_NEW 0 @@ -85,10 +84,6 @@ int ERR_load_RSA_strings(void); # define RSA_F_RSA_SETUP_BLINDING 0 # define RSA_F_RSA_SIGN 0 # define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 0 -# define RSA_F_RSA_SP800_56B_CHECK_KEYPAIR 0 -# define RSA_F_RSA_SP800_56B_CHECK_PUBLIC 0 -# define RSA_F_RSA_SP800_56B_PAIRWISE_TEST 0 -# define RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH 0 # define RSA_F_RSA_VERIFY 0 # define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 0 # define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 0 diff --git a/include/openssl/safestack.h b/include/openssl/safestack.h index c94ce78cf9..cf2b10890b 100644 --- a/include/openssl/safestack.h +++ b/include/openssl/safestack.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/safestack.h.in + * * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_SAFESTACK_H # define OPENSSL_SAFESTACK_H # pragma once @@ -25,6 +30,37 @@ extern "C" { # define STACK_OF(type) struct stack_st_##type +/* Helper macro for internal use */ +# define SKM_DEFINE_STACK_OF_INTERNAL(t1, t2, t3) \ + STACK_OF(t1); \ + typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ + typedef void (*sk_##t1##_freefunc)(t3 *a); \ + typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ + static ossl_unused ossl_inline t2 *ossl_check_##t1##_type(t2 *ptr) \ + { \ + return ptr; \ + } \ + static ossl_unused ossl_inline const OPENSSL_STACK *ossl_check_const_##t1##_sk_type(const STACK_OF(t1) *sk) \ + { \ + return (const OPENSSL_STACK *)sk; \ + } \ + static ossl_unused ossl_inline OPENSSL_STACK *ossl_check_##t1##_sk_type(STACK_OF(t1) *sk) \ + { \ + return (OPENSSL_STACK *)sk; \ + } \ + static ossl_unused ossl_inline OPENSSL_sk_compfunc ossl_check_##t1##_compfunc_type(sk_##t1##_compfunc cmp) \ + { \ + return (OPENSSL_sk_compfunc)cmp; \ + } \ + static ossl_unused ossl_inline OPENSSL_sk_copyfunc ossl_check_##t1##_copyfunc_type(sk_##t1##_copyfunc cpy) \ + { \ + return (OPENSSL_sk_copyfunc)cpy; \ + } \ + static ossl_unused ossl_inline OPENSSL_sk_freefunc ossl_check_##t1##_freefunc_type(sk_##t1##_freefunc fr) \ + { \ + return (OPENSSL_sk_freefunc)fr; \ + } + # define SKM_DEFINE_STACK_OF(t1, t2, t3) \ STACK_OF(t1); \ typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ @@ -155,28 +191,6 @@ extern "C" { typedef char *OPENSSL_STRING; typedef const char *OPENSSL_CSTRING; -# define DEFINE_STACK_OF_STRING() \ - DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char) -# define DEFINE_STACK_OF_CSTRING() \ - DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char) - -/* - * If we're building OpenSSL, or we have no-deprecated configured, - * then we don't define the inline functions (see |SKM_DEFINE_STACK_OF|, - * above), we just declare the stack datatypes. Otherwise, for compatibility - * and to not remove the API's, we define the functions. We have the - * trailing semicolon so that uses of this never need it. - */ -#if defined(OPENSSL_BUILDING_OPENSSL) || defined(OPENSSL_NO_DEPRECATED_3_0) -# define DEFINE_OR_DECLARE_STACK_OF(s) STACK_OF(s); -# define DEFINE_OR_DECLARE_STACK_OF_STRING() STACK_OF(OPENSSL_STRING); -# define DEFINE_OR_DECLARE_STACK_OF_CSTRING() STACK_OF(OPENSSL_CSTRING); -#else -# define DEFINE_OR_DECLARE_STACK_OF(s) DEFINE_STACK_OF(s) -# define DEFINE_OR_DECLARE_STACK_OF_STRING() DEFINE_STACK_OF_STRING() -# define DEFINE_OR_DECLARE_STACK_OF_CSTRING() DEFINE_STACK_OF_CSTRING() -#endif - /*- * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned @@ -184,8 +198,57 @@ typedef const char *OPENSSL_CSTRING; * chars. So, we have to implement STRING specially for STACK_OF. This is * dealt with in the autogenerated macros below. */ -DEFINE_OR_DECLARE_STACK_OF_STRING() -DEFINE_OR_DECLARE_STACK_OF_CSTRING() +SKM_DEFINE_STACK_OF_INTERNAL(OPENSSL_STRING, char, char) +#define sk_OPENSSL_STRING_num(sk) OPENSSL_sk_num(ossl_check_const_OPENSSL_STRING_sk_type(sk)) +#define sk_OPENSSL_STRING_value(sk, idx) ((char *)OPENSSL_sk_value(ossl_check_const_OPENSSL_STRING_sk_type(sk), (idx))) +#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)OPENSSL_sk_new(ossl_check_OPENSSL_STRING_compfunc_type(cmp))) +#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)OPENSSL_sk_new_null()) +#define sk_OPENSSL_STRING_new_reserve(cmp, n) ((STACK_OF(OPENSSL_STRING) *)OPENSSL_sk_new_reserve(ossl_check_OPENSSL_STRING_compfunc_type(cmp), (n))) +#define sk_OPENSSL_STRING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OPENSSL_STRING_sk_type(sk), (n)) +#define sk_OPENSSL_STRING_free(sk) OPENSSL_sk_free(ossl_check_OPENSSL_STRING_sk_type(sk)) +#define sk_OPENSSL_STRING_zero(sk) OPENSSL_sk_zero(ossl_check_OPENSSL_STRING_sk_type(sk)) +#define sk_OPENSSL_STRING_delete(sk, i) ((char *)OPENSSL_sk_delete(ossl_check_OPENSSL_STRING_sk_type(sk), (i))) +#define sk_OPENSSL_STRING_delete_ptr(sk, ptr) ((char *)OPENSSL_sk_delete_ptr(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_type(ptr))) +#define sk_OPENSSL_STRING_push(sk, ptr) OPENSSL_sk_push(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_type(ptr)) +#define sk_OPENSSL_STRING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_type(ptr)) +#define sk_OPENSSL_STRING_pop(sk) ((char *)OPENSSL_sk_pop(ossl_check_OPENSSL_STRING_sk_type(sk))) +#define sk_OPENSSL_STRING_shift(sk) ((char *)OPENSSL_sk_shift(ossl_check_OPENSSL_STRING_sk_type(sk))) +#define sk_OPENSSL_STRING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OPENSSL_STRING_sk_type(sk),ossl_check_OPENSSL_STRING_freefunc_type(freefunc)) +#define sk_OPENSSL_STRING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_type(ptr), (idx)) +#define sk_OPENSSL_STRING_set(sk, idx, ptr) ((char *)OPENSSL_sk_set(ossl_check_OPENSSL_STRING_sk_type(sk), (idx), ossl_check_OPENSSL_STRING_type(ptr))) +#define sk_OPENSSL_STRING_find(sk, ptr) OPENSSL_sk_find(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_type(ptr)) +#define sk_OPENSSL_STRING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_type(ptr)) +#define sk_OPENSSL_STRING_sort(sk) OPENSSL_sk_sort(ossl_check_OPENSSL_STRING_sk_type(sk)) +#define sk_OPENSSL_STRING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OPENSSL_STRING_sk_type(sk)) +#define sk_OPENSSL_STRING_dup(sk) ((STACK_OF(OPENSSL_STRING) *)OPENSSL_sk_dup(ossl_check_const_OPENSSL_STRING_sk_type(sk))) +#define sk_OPENSSL_STRING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OPENSSL_STRING) *)OPENSSL_sk_deep_copy(ossl_check_const_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_copyfunc_type(copyfunc), ossl_check_OPENSSL_STRING_freefunc_type(freefunc))) +#define sk_OPENSSL_STRING_set_cmp_func(sk, cmp) ((sk_OPENSSL_STRING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OPENSSL_STRING_sk_type(sk), ossl_check_OPENSSL_STRING_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(OPENSSL_CSTRING, const char, char) +#define sk_OPENSSL_CSTRING_num(sk) OPENSSL_sk_num(ossl_check_const_OPENSSL_CSTRING_sk_type(sk)) +#define sk_OPENSSL_CSTRING_value(sk, idx) ((const char *)OPENSSL_sk_value(ossl_check_const_OPENSSL_CSTRING_sk_type(sk), (idx))) +#define sk_OPENSSL_CSTRING_new(cmp) ((STACK_OF(OPENSSL_CSTRING) *)OPENSSL_sk_new(ossl_check_OPENSSL_CSTRING_compfunc_type(cmp))) +#define sk_OPENSSL_CSTRING_new_null() ((STACK_OF(OPENSSL_CSTRING) *)OPENSSL_sk_new_null()) +#define sk_OPENSSL_CSTRING_new_reserve(cmp, n) ((STACK_OF(OPENSSL_CSTRING) *)OPENSSL_sk_new_reserve(ossl_check_OPENSSL_CSTRING_compfunc_type(cmp), (n))) +#define sk_OPENSSL_CSTRING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OPENSSL_CSTRING_sk_type(sk), (n)) +#define sk_OPENSSL_CSTRING_free(sk) OPENSSL_sk_free(ossl_check_OPENSSL_CSTRING_sk_type(sk)) +#define sk_OPENSSL_CSTRING_zero(sk) OPENSSL_sk_zero(ossl_check_OPENSSL_CSTRING_sk_type(sk)) +#define sk_OPENSSL_CSTRING_delete(sk, i) ((const char *)OPENSSL_sk_delete(ossl_check_OPENSSL_CSTRING_sk_type(sk), (i))) +#define sk_OPENSSL_CSTRING_delete_ptr(sk, ptr) ((const char *)OPENSSL_sk_delete_ptr(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_type(ptr))) +#define sk_OPENSSL_CSTRING_push(sk, ptr) OPENSSL_sk_push(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_type(ptr)) +#define sk_OPENSSL_CSTRING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_type(ptr)) +#define sk_OPENSSL_CSTRING_pop(sk) ((const char *)OPENSSL_sk_pop(ossl_check_OPENSSL_CSTRING_sk_type(sk))) +#define sk_OPENSSL_CSTRING_shift(sk) ((const char *)OPENSSL_sk_shift(ossl_check_OPENSSL_CSTRING_sk_type(sk))) +#define sk_OPENSSL_CSTRING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OPENSSL_CSTRING_sk_type(sk),ossl_check_OPENSSL_CSTRING_freefunc_type(freefunc)) +#define sk_OPENSSL_CSTRING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_type(ptr), (idx)) +#define sk_OPENSSL_CSTRING_set(sk, idx, ptr) ((const char *)OPENSSL_sk_set(ossl_check_OPENSSL_CSTRING_sk_type(sk), (idx), ossl_check_OPENSSL_CSTRING_type(ptr))) +#define sk_OPENSSL_CSTRING_find(sk, ptr) OPENSSL_sk_find(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_type(ptr)) +#define sk_OPENSSL_CSTRING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_type(ptr)) +#define sk_OPENSSL_CSTRING_sort(sk) OPENSSL_sk_sort(ossl_check_OPENSSL_CSTRING_sk_type(sk)) +#define sk_OPENSSL_CSTRING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OPENSSL_CSTRING_sk_type(sk)) +#define sk_OPENSSL_CSTRING_dup(sk) ((STACK_OF(OPENSSL_CSTRING) *)OPENSSL_sk_dup(ossl_check_const_OPENSSL_CSTRING_sk_type(sk))) +#define sk_OPENSSL_CSTRING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OPENSSL_CSTRING) *)OPENSSL_sk_deep_copy(ossl_check_const_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_copyfunc_type(copyfunc), ossl_check_OPENSSL_CSTRING_freefunc_type(freefunc))) +#define sk_OPENSSL_CSTRING_set_cmp_func(sk, cmp) ((sk_OPENSSL_CSTRING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OPENSSL_CSTRING_sk_type(sk), ossl_check_OPENSSL_CSTRING_compfunc_type(cmp))) + #if !defined(OPENSSL_NO_DEPRECATED_3_0) /* @@ -193,43 +256,33 @@ DEFINE_OR_DECLARE_STACK_OF_CSTRING() * These should also be distinguished from "normal" stacks. */ typedef void *OPENSSL_BLOCK; -DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) -#endif +SKM_DEFINE_STACK_OF_INTERNAL(OPENSSL_BLOCK, void, void) +#define sk_OPENSSL_BLOCK_num(sk) OPENSSL_sk_num(ossl_check_const_OPENSSL_BLOCK_sk_type(sk)) +#define sk_OPENSSL_BLOCK_value(sk, idx) ((void *)OPENSSL_sk_value(ossl_check_const_OPENSSL_BLOCK_sk_type(sk), (idx))) +#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)OPENSSL_sk_new(ossl_check_OPENSSL_BLOCK_compfunc_type(cmp))) +#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)OPENSSL_sk_new_null()) +#define sk_OPENSSL_BLOCK_new_reserve(cmp, n) ((STACK_OF(OPENSSL_BLOCK) *)OPENSSL_sk_new_reserve(ossl_check_OPENSSL_BLOCK_compfunc_type(cmp), (n))) +#define sk_OPENSSL_BLOCK_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OPENSSL_BLOCK_sk_type(sk), (n)) +#define sk_OPENSSL_BLOCK_free(sk) OPENSSL_sk_free(ossl_check_OPENSSL_BLOCK_sk_type(sk)) +#define sk_OPENSSL_BLOCK_zero(sk) OPENSSL_sk_zero(ossl_check_OPENSSL_BLOCK_sk_type(sk)) +#define sk_OPENSSL_BLOCK_delete(sk, i) ((void *)OPENSSL_sk_delete(ossl_check_OPENSSL_BLOCK_sk_type(sk), (i))) +#define sk_OPENSSL_BLOCK_delete_ptr(sk, ptr) ((void *)OPENSSL_sk_delete_ptr(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_type(ptr))) +#define sk_OPENSSL_BLOCK_push(sk, ptr) OPENSSL_sk_push(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_type(ptr)) +#define sk_OPENSSL_BLOCK_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_type(ptr)) +#define sk_OPENSSL_BLOCK_pop(sk) ((void *)OPENSSL_sk_pop(ossl_check_OPENSSL_BLOCK_sk_type(sk))) +#define sk_OPENSSL_BLOCK_shift(sk) ((void *)OPENSSL_sk_shift(ossl_check_OPENSSL_BLOCK_sk_type(sk))) +#define sk_OPENSSL_BLOCK_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OPENSSL_BLOCK_sk_type(sk),ossl_check_OPENSSL_BLOCK_freefunc_type(freefunc)) +#define sk_OPENSSL_BLOCK_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_type(ptr), (idx)) +#define sk_OPENSSL_BLOCK_set(sk, idx, ptr) ((void *)OPENSSL_sk_set(ossl_check_OPENSSL_BLOCK_sk_type(sk), (idx), ossl_check_OPENSSL_BLOCK_type(ptr))) +#define sk_OPENSSL_BLOCK_find(sk, ptr) OPENSSL_sk_find(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_type(ptr)) +#define sk_OPENSSL_BLOCK_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_type(ptr)) +#define sk_OPENSSL_BLOCK_sort(sk) OPENSSL_sk_sort(ossl_check_OPENSSL_BLOCK_sk_type(sk)) +#define sk_OPENSSL_BLOCK_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OPENSSL_BLOCK_sk_type(sk)) +#define sk_OPENSSL_BLOCK_dup(sk) ((STACK_OF(OPENSSL_BLOCK) *)OPENSSL_sk_dup(ossl_check_const_OPENSSL_BLOCK_sk_type(sk))) +#define sk_OPENSSL_BLOCK_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OPENSSL_BLOCK) *)OPENSSL_sk_deep_copy(ossl_check_const_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_copyfunc_type(copyfunc), ossl_check_OPENSSL_BLOCK_freefunc_type(freefunc))) +#define sk_OPENSSL_BLOCK_set_cmp_func(sk, cmp) ((sk_OPENSSL_BLOCK_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OPENSSL_BLOCK_sk_type(sk), ossl_check_OPENSSL_BLOCK_compfunc_type(cmp))) -/* - * If called without higher optimization (min. -xO3) the Oracle Developer - * Studio compiler generates code for the defined (static inline) functions - * above. - * This would later lead to the linker complaining about missing symbols when - * this header file is included but the resulting object is not linked against - * the Crypto library (openssl#6912). - */ -# ifdef __SUNPRO_C -# pragma weak OPENSSL_sk_num -# pragma weak OPENSSL_sk_value -# pragma weak OPENSSL_sk_new -# pragma weak OPENSSL_sk_new_null -# pragma weak OPENSSL_sk_new_reserve -# pragma weak OPENSSL_sk_reserve -# pragma weak OPENSSL_sk_free -# pragma weak OPENSSL_sk_zero -# pragma weak OPENSSL_sk_delete -# pragma weak OPENSSL_sk_delete_ptr -# pragma weak OPENSSL_sk_push -# pragma weak OPENSSL_sk_unshift -# pragma weak OPENSSL_sk_pop -# pragma weak OPENSSL_sk_shift -# pragma weak OPENSSL_sk_pop_free -# pragma weak OPENSSL_sk_insert -# pragma weak OPENSSL_sk_set -# pragma weak OPENSSL_sk_find -# pragma weak OPENSSL_sk_find_ex -# pragma weak OPENSSL_sk_sort -# pragma weak OPENSSL_sk_is_sorted -# pragma weak OPENSSL_sk_dup -# pragma weak OPENSSL_sk_deep_copy -# pragma weak OPENSSL_sk_set_cmp_func -# endif /* __SUNPRO_C */ +#endif # ifdef __cplusplus } diff --git a/include/openssl/safestack.h.in b/include/openssl/safestack.h.in new file mode 100644 index 0000000000..aac56608ca --- /dev/null +++ b/include/openssl/safestack.h.in @@ -0,0 +1,223 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_string_macros + generate_stack_const_string_macros + generate_stack_block_macros); +-} + +#ifndef OPENSSL_SAFESTACK_H +# define OPENSSL_SAFESTACK_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_SAFESTACK_H +# endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define STACK_OF(type) struct stack_st_##type + +/* Helper macro for internal use */ +# define SKM_DEFINE_STACK_OF_INTERNAL(t1, t2, t3) \ + STACK_OF(t1); \ + typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ + typedef void (*sk_##t1##_freefunc)(t3 *a); \ + typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ + static ossl_unused ossl_inline t2 *ossl_check_##t1##_type(t2 *ptr) \ + { \ + return ptr; \ + } \ + static ossl_unused ossl_inline const OPENSSL_STACK *ossl_check_const_##t1##_sk_type(const STACK_OF(t1) *sk) \ + { \ + return (const OPENSSL_STACK *)sk; \ + } \ + static ossl_unused ossl_inline OPENSSL_STACK *ossl_check_##t1##_sk_type(STACK_OF(t1) *sk) \ + { \ + return (OPENSSL_STACK *)sk; \ + } \ + static ossl_unused ossl_inline OPENSSL_sk_compfunc ossl_check_##t1##_compfunc_type(sk_##t1##_compfunc cmp) \ + { \ + return (OPENSSL_sk_compfunc)cmp; \ + } \ + static ossl_unused ossl_inline OPENSSL_sk_copyfunc ossl_check_##t1##_copyfunc_type(sk_##t1##_copyfunc cpy) \ + { \ + return (OPENSSL_sk_copyfunc)cpy; \ + } \ + static ossl_unused ossl_inline OPENSSL_sk_freefunc ossl_check_##t1##_freefunc_type(sk_##t1##_freefunc fr) \ + { \ + return (OPENSSL_sk_freefunc)fr; \ + } + +# define SKM_DEFINE_STACK_OF(t1, t2, t3) \ + STACK_OF(t1); \ + typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \ + typedef void (*sk_##t1##_freefunc)(t3 *a); \ + typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \ + static ossl_unused ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \ + { \ + return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ + { \ + return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_free((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \ + { \ + return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ + (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \ + { \ + return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \ + { \ + OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \ + { \ + return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \ + } \ + static ossl_unused ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \ + { \ + return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \ + { \ + return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \ + } \ + static ossl_unused ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \ + { \ + OPENSSL_sk_sort((OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \ + { \ + return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ + } \ + static ossl_unused ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \ + sk_##t1##_copyfunc copyfunc, \ + sk_##t1##_freefunc freefunc) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, \ + (OPENSSL_sk_copyfunc)copyfunc, \ + (OPENSSL_sk_freefunc)freefunc); \ + } \ + static ossl_unused ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \ + { \ + return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \ + } + +# define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) +# define DEFINE_STACK_OF_CONST(t) SKM_DEFINE_STACK_OF(t, const t, t) +# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2) +# define DEFINE_SPECIAL_STACK_OF_CONST(t1, t2) \ + SKM_DEFINE_STACK_OF(t1, const t2, t2) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; +typedef const char *OPENSSL_CSTRING; + +/*- + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ +{- + generate_stack_string_macros() + .generate_stack_const_string_macros(); +-} + +#if !defined(OPENSSL_NO_DEPRECATED_3_0) +/* + * This is not used by OpenSSL. A block of bytes, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +{- + generate_stack_block_macros(); +-} +#endif + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h index ff6e1b8e08..9aff14e82b 100644 --- a/include/openssl/self_test.h +++ b/include/openssl/self_test.h @@ -27,8 +27,10 @@ extern "C" { # define OSSL_SELF_TEST_TYPE_NONE "None" # define OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY "Module_Integrity" # define OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY "Install_Integrity" +# define OSSL_SELF_TEST_TYPE_CRNG "Continuous_RNG_Test" # define OSSL_SELF_TEST_TYPE_PCT "Pairwise_Consistency_Test" # define OSSL_SELF_TEST_TYPE_KAT_CIPHER "KAT_Cipher" +# define OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER "KAT_AsymmetricCipher" # define OSSL_SELF_TEST_TYPE_KAT_DIGEST "KAT_Digest" # define OSSL_SELF_TEST_TYPE_KAT_SIGNATURE "KAT_Signature" # define OSSL_SELF_TEST_TYPE_KAT_KDF "KAT_KDF" @@ -43,6 +45,8 @@ extern "C" { # define OSSL_SELF_TEST_DESC_PCT_DSA "DSA" # define OSSL_SELF_TEST_DESC_CIPHER_AES_GCM "AES_GCM" # define OSSL_SELF_TEST_DESC_CIPHER_TDES "TDES" +# define OSSL_SELF_TEST_DESC_ASYM_RSA_ENC "RSA_Encrypt" +# define OSSL_SELF_TEST_DESC_ASYM_RSA_DEC "RSA_Decrypt" # define OSSL_SELF_TEST_DESC_MD_SHA1 "SHA1" # define OSSL_SELF_TEST_DESC_MD_SHA2 "SHA2" # define OSSL_SELF_TEST_DESC_MD_SHA3 "SHA3" @@ -56,14 +60,15 @@ extern "C" { # define OSSL_SELF_TEST_DESC_KA_ECDH "ECDH" # define OSSL_SELF_TEST_DESC_KDF_HKDF "HKDF" # define OSSL_SELF_TEST_DESC_KDF_SSKDF "SSKDF" +# define OSSL_SELF_TEST_DESC_RNG "RNG" # ifdef __cplusplus } # endif -void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb, +void OSSL_SELF_TEST_set_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK *cb, void *cbarg); -void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb, +void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, void **cbarg); OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg); @@ -71,7 +76,7 @@ void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st); void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type, const char *desc); -void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes); +int OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes); void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret); #endif /* OPENSSL_SELF_TEST_H */ diff --git a/include/openssl/serializer.h b/include/openssl/serializer.h deleted file mode 100644 index 50c85d617f..0000000000 --- a/include/openssl/serializer.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_SERIALIZER_H -# define OPENSSL_SERIALIZER_H -# pragma once - -# include - -# ifndef OPENSSL_NO_STDIO -# include -# endif -# include -# include -# include -# include -# include - -# ifdef __cplusplus -extern "C" { -# endif - -OSSL_SERIALIZER *OSSL_SERIALIZER_fetch(OPENSSL_CTX *libctx, - const char *name, - const char *properties); -int OSSL_SERIALIZER_up_ref(OSSL_SERIALIZER *ser); -void OSSL_SERIALIZER_free(OSSL_SERIALIZER *ser); - -const OSSL_PROVIDER *OSSL_SERIALIZER_provider(const OSSL_SERIALIZER *ser); -const char *OSSL_SERIALIZER_properties(const OSSL_SERIALIZER *ser); -int OSSL_SERIALIZER_number(const OSSL_SERIALIZER *ser); -int OSSL_SERIALIZER_is_a(const OSSL_SERIALIZER *ser, - const char *name); - -void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx, - void (*fn)(OSSL_SERIALIZER *ser, - void *arg), - void *arg); -void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser, - void (*fn)(const char *name, void *data), - void *data); - -const OSSL_PARAM *OSSL_SERIALIZER_settable_ctx_params(OSSL_SERIALIZER *ser); -OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new(OSSL_SERIALIZER *ser); -const OSSL_SERIALIZER * -OSSL_SERIALIZER_CTX_get_serializer(OSSL_SERIALIZER_CTX *ctx); -int OSSL_SERIALIZER_CTX_set_params(OSSL_SERIALIZER_CTX *ctx, - const OSSL_PARAM params[]); -void OSSL_SERIALIZER_CTX_free(OSSL_SERIALIZER_CTX *ctx); - -/* Utilities that help set specific parameters */ -int OSSL_SERIALIZER_CTX_set_cipher(OSSL_SERIALIZER_CTX *ctx, - const char *cipher_name, - const char *propquery); -int OSSL_SERIALIZER_CTX_set_passphrase(OSSL_SERIALIZER_CTX *ctx, - const unsigned char *kstr, - size_t klen); -int OSSL_SERIALIZER_CTX_set_passphrase_cb(OSSL_SERIALIZER_CTX *ctx, - pem_password_cb *cb, void *cbarg); -int OSSL_SERIALIZER_CTX_set_passphrase_ui(OSSL_SERIALIZER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data); - -/* Utilities to output the object to serialize */ -int OSSL_SERIALIZER_to_bio(OSSL_SERIALIZER_CTX *ctx, BIO *out); -#ifndef OPENSSL_NO_STDIO -int OSSL_SERIALIZER_to_fp(OSSL_SERIALIZER_CTX *ctx, FILE *fp); -#endif - -/* - * Create the OSSL_SERIALIZER_CTX with an associated type. This will perform - * an implicit OSSL_SERIALIZER_fetch(), suitable for the object of that type. - * This is more useful than calling OSSL_SERIALIZER_CTX_new(). - */ -OSSL_SERIALIZER_CTX *OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(const EVP_PKEY *pkey, - const char *propquery); - -/* - * These macros define the last argument to pass to - * OSSL_SERIALIZER_CTX_new_by_TYPE(). - */ -# define OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ "format=pem,type=public" -# define OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ "format=pem,type=private" -# define OSSL_SERIALIZER_Parameters_TO_PEM_PQ "format=pem,type=parameters" - -# define OSSL_SERIALIZER_PUBKEY_TO_DER_PQ "format=der,type=public" -# define OSSL_SERIALIZER_PrivateKey_TO_DER_PQ "format=der,type=private" -# define OSSL_SERIALIZER_Parameters_TO_DER_PQ "format=der,type=parameters" - -/* Corresponding macros for text output */ -# define OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ "format=text,type=public" -# define OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ "format=text,type=private" -# define OSSL_SERIALIZER_Parameters_TO_TEXT_PQ "format=text,type=parameters" - -# ifdef __cplusplus -} -# endif -#endif diff --git a/include/openssl/sha.h b/include/openssl/sha.h index 18e584a161..eac7cdbba3 100644 --- a/include/openssl/sha.h +++ b/include/openssl/sha.h @@ -23,19 +23,21 @@ extern "C" { # endif +# define SHA_DIGEST_LENGTH 20 + +# ifndef OPENSSL_NO_DEPRECATED_3_0 /*- * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * ! SHA_LONG has to be at least 32 bits wide. ! * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ -# define SHA_LONG unsigned int +# define SHA_LONG unsigned int -# define SHA_LBLOCK 16 -# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a - * contiguous array of 32 bit wide - * big-endian values. */ -# define SHA_LAST_BLOCK (SHA_CBLOCK-8) -# define SHA_DIGEST_LENGTH 20 +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) typedef struct SHAstate_st { SHA_LONG h0, h1, h2, h3, h4; @@ -43,14 +45,17 @@ typedef struct SHAstate_st { SHA_LONG data[SHA_LBLOCK]; unsigned int num; } SHA_CTX; +# endif /* !defined(OPENSSL_NO_DEPRECATED_3_0) */ -int SHA1_Init(SHA_CTX *c); -int SHA1_Update(SHA_CTX *c, const void *data, size_t len); -int SHA1_Final(unsigned char *md, SHA_CTX *c); -unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); -void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +DEPRECATEDIN_3_0(int SHA1_Init(SHA_CTX *c)) +DEPRECATEDIN_3_0(int SHA1_Update(SHA_CTX *c, const void *data, size_t len)) +DEPRECATEDIN_3_0(int SHA1_Final(unsigned char *md, SHA_CTX *c)) +DEPRECATEDIN_3_0(unsigned char *SHA1(const unsigned char *d, size_t n, + unsigned char *md)) +DEPRECATEDIN_3_0(void SHA1_Transform(SHA_CTX *c, const unsigned char *data)) -# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a * contiguous array of 32 bit wide * big-endian values. */ @@ -60,22 +65,27 @@ typedef struct SHA256state_st { SHA_LONG data[SHA_LBLOCK]; unsigned int num, md_len; } SHA256_CTX; - -int SHA224_Init(SHA256_CTX *c); -int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); -int SHA224_Final(unsigned char *md, SHA256_CTX *c); -unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); -int SHA256_Init(SHA256_CTX *c); -int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); -int SHA256_Final(unsigned char *md, SHA256_CTX *c); -unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); -void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +# endif /* !defined(OPENSSL_NO_DEPRECATED_3_0) */ + +DEPRECATEDIN_3_0(int SHA224_Init(SHA256_CTX *c)) +DEPRECATEDIN_3_0(int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)) +DEPRECATEDIN_3_0(int SHA224_Final(unsigned char *md, SHA256_CTX *c)) +DEPRECATEDIN_3_0(unsigned char *SHA224(const unsigned char *d, size_t n, + unsigned char *md)) +DEPRECATEDIN_3_0(int SHA256_Init(SHA256_CTX *c)) +DEPRECATEDIN_3_0(int SHA256_Update(SHA256_CTX *c, const void *data, size_t len)) +DEPRECATEDIN_3_0(int SHA256_Final(unsigned char *md, SHA256_CTX *c)) +DEPRECATEDIN_3_0(unsigned char *SHA256(const unsigned char *d, size_t n, + unsigned char *md)) +DEPRECATEDIN_3_0(void SHA256_Transform(SHA256_CTX *c, + const unsigned char *data)) # define SHA224_DIGEST_LENGTH 28 # define SHA256_DIGEST_LENGTH 32 # define SHA384_DIGEST_LENGTH 48 # define SHA512_DIGEST_LENGTH 64 +# ifndef OPENSSL_NO_DEPRECATED_3_0 /* * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 * being exactly 64-bit wide. See Implementation Notes in sha512.c @@ -86,14 +96,14 @@ void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); * contiguous array of 64 bit * wide big-endian values. */ -# define SHA512_CBLOCK (SHA_LBLOCK*8) -# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -# define SHA_LONG64 unsigned __int64 -# elif defined(__arch64__) -# define SHA_LONG64 unsigned long -# else -# define SHA_LONG64 unsigned long long -# endif +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# else +# define SHA_LONG64 unsigned long long +# endif typedef struct SHA512state_st { SHA_LONG64 h[8]; @@ -104,16 +114,20 @@ typedef struct SHA512state_st { } u; unsigned int num, md_len; } SHA512_CTX; - -int SHA384_Init(SHA512_CTX *c); -int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); -int SHA384_Final(unsigned char *md, SHA512_CTX *c); -unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); -int SHA512_Init(SHA512_CTX *c); -int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); -int SHA512_Final(unsigned char *md, SHA512_CTX *c); -unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); -void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +# endif /* !defined(OPENSSL_NO_DEPRECATED_3_0) */ + +DEPRECATEDIN_3_0(int SHA384_Init(SHA512_CTX *c)) +DEPRECATEDIN_3_0(int SHA384_Update(SHA512_CTX *c, const void *data, size_t len)) +DEPRECATEDIN_3_0(int SHA384_Final(unsigned char *md, SHA512_CTX *c)) +DEPRECATEDIN_3_0(unsigned char *SHA384(const unsigned char *d, size_t n, + unsigned char *md)) +DEPRECATEDIN_3_0(int SHA512_Init(SHA512_CTX *c)) +DEPRECATEDIN_3_0(int SHA512_Update(SHA512_CTX *c, const void *data, size_t len)) +DEPRECATEDIN_3_0(int SHA512_Final(unsigned char *md, SHA512_CTX *c)) +DEPRECATEDIN_3_0(unsigned char *SHA512(const unsigned char *d, size_t n, + unsigned char *md)) +DEPRECATEDIN_3_0(void SHA512_Transform(SHA512_CTX *c, + const unsigned char *data)) # ifdef __cplusplus } diff --git a/include/openssl/srp.h b/include/openssl/srp.h index 5c8f5368f8..3f274ae726 100644 --- a/include/openssl/srp.h +++ b/include/openssl/srp.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/srp.h.in + * * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2004, EdelKey Project. All Rights Reserved. * @@ -11,6 +14,8 @@ * for the EdelKey project. */ + + #ifndef OPENSSL_SRP_H # define OPENSSL_SRP_H # pragma once @@ -37,7 +42,33 @@ typedef struct SRP_gN_cache_st { char *b64_bn; BIGNUM *bn; } SRP_gN_cache; -DEFINE_OR_DECLARE_STACK_OF(SRP_gN_cache) +SKM_DEFINE_STACK_OF_INTERNAL(SRP_gN_cache, SRP_gN_cache, SRP_gN_cache) +#define sk_SRP_gN_cache_num(sk) OPENSSL_sk_num(ossl_check_const_SRP_gN_cache_sk_type(sk)) +#define sk_SRP_gN_cache_value(sk, idx) ((SRP_gN_cache *)OPENSSL_sk_value(ossl_check_const_SRP_gN_cache_sk_type(sk), (idx))) +#define sk_SRP_gN_cache_new(cmp) ((STACK_OF(SRP_gN_cache) *)OPENSSL_sk_new(ossl_check_SRP_gN_cache_compfunc_type(cmp))) +#define sk_SRP_gN_cache_new_null() ((STACK_OF(SRP_gN_cache) *)OPENSSL_sk_new_null()) +#define sk_SRP_gN_cache_new_reserve(cmp, n) ((STACK_OF(SRP_gN_cache) *)OPENSSL_sk_new_reserve(ossl_check_SRP_gN_cache_compfunc_type(cmp), (n))) +#define sk_SRP_gN_cache_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SRP_gN_cache_sk_type(sk), (n)) +#define sk_SRP_gN_cache_free(sk) OPENSSL_sk_free(ossl_check_SRP_gN_cache_sk_type(sk)) +#define sk_SRP_gN_cache_zero(sk) OPENSSL_sk_zero(ossl_check_SRP_gN_cache_sk_type(sk)) +#define sk_SRP_gN_cache_delete(sk, i) ((SRP_gN_cache *)OPENSSL_sk_delete(ossl_check_SRP_gN_cache_sk_type(sk), (i))) +#define sk_SRP_gN_cache_delete_ptr(sk, ptr) ((SRP_gN_cache *)OPENSSL_sk_delete_ptr(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_type(ptr))) +#define sk_SRP_gN_cache_push(sk, ptr) OPENSSL_sk_push(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_type(ptr)) +#define sk_SRP_gN_cache_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_type(ptr)) +#define sk_SRP_gN_cache_pop(sk) ((SRP_gN_cache *)OPENSSL_sk_pop(ossl_check_SRP_gN_cache_sk_type(sk))) +#define sk_SRP_gN_cache_shift(sk) ((SRP_gN_cache *)OPENSSL_sk_shift(ossl_check_SRP_gN_cache_sk_type(sk))) +#define sk_SRP_gN_cache_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SRP_gN_cache_sk_type(sk),ossl_check_SRP_gN_cache_freefunc_type(freefunc)) +#define sk_SRP_gN_cache_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_type(ptr), (idx)) +#define sk_SRP_gN_cache_set(sk, idx, ptr) ((SRP_gN_cache *)OPENSSL_sk_set(ossl_check_SRP_gN_cache_sk_type(sk), (idx), ossl_check_SRP_gN_cache_type(ptr))) +#define sk_SRP_gN_cache_find(sk, ptr) OPENSSL_sk_find(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_type(ptr)) +#define sk_SRP_gN_cache_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_type(ptr)) +#define sk_SRP_gN_cache_sort(sk) OPENSSL_sk_sort(ossl_check_SRP_gN_cache_sk_type(sk)) +#define sk_SRP_gN_cache_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SRP_gN_cache_sk_type(sk)) +#define sk_SRP_gN_cache_dup(sk) ((STACK_OF(SRP_gN_cache) *)OPENSSL_sk_dup(ossl_check_const_SRP_gN_cache_sk_type(sk))) +#define sk_SRP_gN_cache_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SRP_gN_cache) *)OPENSSL_sk_deep_copy(ossl_check_const_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_copyfunc_type(copyfunc), ossl_check_SRP_gN_cache_freefunc_type(freefunc))) +#define sk_SRP_gN_cache_set_cmp_func(sk, cmp) ((sk_SRP_gN_cache_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SRP_gN_cache_sk_type(sk), ossl_check_SRP_gN_cache_compfunc_type(cmp))) + + typedef struct SRP_user_pwd_st { /* Owned by us. */ @@ -50,7 +81,32 @@ typedef struct SRP_user_pwd_st { /* Owned by us. */ char *info; } SRP_user_pwd; -DEFINE_OR_DECLARE_STACK_OF(SRP_user_pwd) +SKM_DEFINE_STACK_OF_INTERNAL(SRP_user_pwd, SRP_user_pwd, SRP_user_pwd) +#define sk_SRP_user_pwd_num(sk) OPENSSL_sk_num(ossl_check_const_SRP_user_pwd_sk_type(sk)) +#define sk_SRP_user_pwd_value(sk, idx) ((SRP_user_pwd *)OPENSSL_sk_value(ossl_check_const_SRP_user_pwd_sk_type(sk), (idx))) +#define sk_SRP_user_pwd_new(cmp) ((STACK_OF(SRP_user_pwd) *)OPENSSL_sk_new(ossl_check_SRP_user_pwd_compfunc_type(cmp))) +#define sk_SRP_user_pwd_new_null() ((STACK_OF(SRP_user_pwd) *)OPENSSL_sk_new_null()) +#define sk_SRP_user_pwd_new_reserve(cmp, n) ((STACK_OF(SRP_user_pwd) *)OPENSSL_sk_new_reserve(ossl_check_SRP_user_pwd_compfunc_type(cmp), (n))) +#define sk_SRP_user_pwd_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SRP_user_pwd_sk_type(sk), (n)) +#define sk_SRP_user_pwd_free(sk) OPENSSL_sk_free(ossl_check_SRP_user_pwd_sk_type(sk)) +#define sk_SRP_user_pwd_zero(sk) OPENSSL_sk_zero(ossl_check_SRP_user_pwd_sk_type(sk)) +#define sk_SRP_user_pwd_delete(sk, i) ((SRP_user_pwd *)OPENSSL_sk_delete(ossl_check_SRP_user_pwd_sk_type(sk), (i))) +#define sk_SRP_user_pwd_delete_ptr(sk, ptr) ((SRP_user_pwd *)OPENSSL_sk_delete_ptr(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_type(ptr))) +#define sk_SRP_user_pwd_push(sk, ptr) OPENSSL_sk_push(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_type(ptr)) +#define sk_SRP_user_pwd_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_type(ptr)) +#define sk_SRP_user_pwd_pop(sk) ((SRP_user_pwd *)OPENSSL_sk_pop(ossl_check_SRP_user_pwd_sk_type(sk))) +#define sk_SRP_user_pwd_shift(sk) ((SRP_user_pwd *)OPENSSL_sk_shift(ossl_check_SRP_user_pwd_sk_type(sk))) +#define sk_SRP_user_pwd_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SRP_user_pwd_sk_type(sk),ossl_check_SRP_user_pwd_freefunc_type(freefunc)) +#define sk_SRP_user_pwd_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_type(ptr), (idx)) +#define sk_SRP_user_pwd_set(sk, idx, ptr) ((SRP_user_pwd *)OPENSSL_sk_set(ossl_check_SRP_user_pwd_sk_type(sk), (idx), ossl_check_SRP_user_pwd_type(ptr))) +#define sk_SRP_user_pwd_find(sk, ptr) OPENSSL_sk_find(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_type(ptr)) +#define sk_SRP_user_pwd_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_type(ptr)) +#define sk_SRP_user_pwd_sort(sk) OPENSSL_sk_sort(ossl_check_SRP_user_pwd_sk_type(sk)) +#define sk_SRP_user_pwd_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SRP_user_pwd_sk_type(sk)) +#define sk_SRP_user_pwd_dup(sk) ((STACK_OF(SRP_user_pwd) *)OPENSSL_sk_dup(ossl_check_const_SRP_user_pwd_sk_type(sk))) +#define sk_SRP_user_pwd_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SRP_user_pwd) *)OPENSSL_sk_deep_copy(ossl_check_const_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_copyfunc_type(copyfunc), ossl_check_SRP_user_pwd_freefunc_type(freefunc))) +#define sk_SRP_user_pwd_set_cmp_func(sk, cmp) ((sk_SRP_user_pwd_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SRP_user_pwd_sk_type(sk), ossl_check_SRP_user_pwd_compfunc_type(cmp))) + SRP_user_pwd *SRP_user_pwd_new(void); void SRP_user_pwd_free(SRP_user_pwd *user_pwd); @@ -76,7 +132,33 @@ typedef struct SRP_gN_st { const BIGNUM *g; const BIGNUM *N; } SRP_gN; -DEFINE_OR_DECLARE_STACK_OF(SRP_gN) +SKM_DEFINE_STACK_OF_INTERNAL(SRP_gN, SRP_gN, SRP_gN) +#define sk_SRP_gN_num(sk) OPENSSL_sk_num(ossl_check_const_SRP_gN_sk_type(sk)) +#define sk_SRP_gN_value(sk, idx) ((SRP_gN *)OPENSSL_sk_value(ossl_check_const_SRP_gN_sk_type(sk), (idx))) +#define sk_SRP_gN_new(cmp) ((STACK_OF(SRP_gN) *)OPENSSL_sk_new(ossl_check_SRP_gN_compfunc_type(cmp))) +#define sk_SRP_gN_new_null() ((STACK_OF(SRP_gN) *)OPENSSL_sk_new_null()) +#define sk_SRP_gN_new_reserve(cmp, n) ((STACK_OF(SRP_gN) *)OPENSSL_sk_new_reserve(ossl_check_SRP_gN_compfunc_type(cmp), (n))) +#define sk_SRP_gN_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SRP_gN_sk_type(sk), (n)) +#define sk_SRP_gN_free(sk) OPENSSL_sk_free(ossl_check_SRP_gN_sk_type(sk)) +#define sk_SRP_gN_zero(sk) OPENSSL_sk_zero(ossl_check_SRP_gN_sk_type(sk)) +#define sk_SRP_gN_delete(sk, i) ((SRP_gN *)OPENSSL_sk_delete(ossl_check_SRP_gN_sk_type(sk), (i))) +#define sk_SRP_gN_delete_ptr(sk, ptr) ((SRP_gN *)OPENSSL_sk_delete_ptr(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_type(ptr))) +#define sk_SRP_gN_push(sk, ptr) OPENSSL_sk_push(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_type(ptr)) +#define sk_SRP_gN_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_type(ptr)) +#define sk_SRP_gN_pop(sk) ((SRP_gN *)OPENSSL_sk_pop(ossl_check_SRP_gN_sk_type(sk))) +#define sk_SRP_gN_shift(sk) ((SRP_gN *)OPENSSL_sk_shift(ossl_check_SRP_gN_sk_type(sk))) +#define sk_SRP_gN_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SRP_gN_sk_type(sk),ossl_check_SRP_gN_freefunc_type(freefunc)) +#define sk_SRP_gN_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_type(ptr), (idx)) +#define sk_SRP_gN_set(sk, idx, ptr) ((SRP_gN *)OPENSSL_sk_set(ossl_check_SRP_gN_sk_type(sk), (idx), ossl_check_SRP_gN_type(ptr))) +#define sk_SRP_gN_find(sk, ptr) OPENSSL_sk_find(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_type(ptr)) +#define sk_SRP_gN_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_type(ptr)) +#define sk_SRP_gN_sort(sk) OPENSSL_sk_sort(ossl_check_SRP_gN_sk_type(sk)) +#define sk_SRP_gN_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SRP_gN_sk_type(sk)) +#define sk_SRP_gN_dup(sk) ((STACK_OF(SRP_gN) *)OPENSSL_sk_dup(ossl_check_const_SRP_gN_sk_type(sk))) +#define sk_SRP_gN_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SRP_gN) *)OPENSSL_sk_deep_copy(ossl_check_const_SRP_gN_sk_type(sk), ossl_check_SRP_gN_copyfunc_type(copyfunc), ossl_check_SRP_gN_freefunc_type(freefunc))) +#define sk_SRP_gN_set_cmp_func(sk, cmp) ((sk_SRP_gN_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SRP_gN_sk_type(sk), ossl_check_SRP_gN_compfunc_type(cmp))) + + SRP_VBASE *SRP_VBASE_new(char *seed_key); void SRP_VBASE_free(SRP_VBASE *vb); @@ -90,12 +172,12 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt, char **verifier, const char *N, const char *g, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); char *SRP_create_verifier(const char *user, const char *pass, char **salt, char **verifier, const char *N, const char *g); int SRP_create_verifier_BN_ex(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, const BIGNUM *N, - const BIGNUM *g, OPENSSL_CTX *libctx, + const BIGNUM *g, OSSL_LIB_CTX *libctx, const char *propq); int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, const BIGNUM *N, @@ -129,22 +211,22 @@ SRP_gN *SRP_get_default_gN(const char *id); BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, const BIGNUM *b, const BIGNUM *N); BIGNUM *SRP_Calc_B_ex(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, - const BIGNUM *v, OPENSSL_CTX *libctx, const char *propq); + const BIGNUM *v, OSSL_LIB_CTX *libctx, const char *propq); BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, const BIGNUM *v); int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N); BIGNUM *SRP_Calc_u_ex(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N); /* client side .... */ BIGNUM *SRP_Calc_x_ex(const BIGNUM *s, const char *user, const char *pass, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass); BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g); BIGNUM *SRP_Calc_client_key_ex(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, const BIGNUM *x, const BIGNUM *a, const BIGNUM *u, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, const BIGNUM *x, const BIGNUM *a, const BIGNUM *u); int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N); diff --git a/include/openssl/srp.h.in b/include/openssl/srp.h.in new file mode 100644 index 0000000000..619816c65f --- /dev/null +++ b/include/openssl/srp.h.in @@ -0,0 +1,173 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2004-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2004, EdelKey Project. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * Originally written by Christophe Renou and Peter Sylvester, + * for the EdelKey project. + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_SRP_H +# define OPENSSL_SRP_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_SRP_H +# endif + +#include + +#ifndef OPENSSL_NO_SRP +# include +# include +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; +{- + generate_stack_macros("SRP_gN_cache"); +-} + + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; +{- + generate_stack_macros("SRP_user_pwd"); +-} + +SRP_user_pwd *SRP_user_pwd_new(void); +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +void SRP_user_pwd_set_gN(SRP_user_pwd *user_pwd, const BIGNUM *g, const BIGNUM *N); +int SRP_user_pwd_set1_ids(SRP_user_pwd *user_pwd, const char *id, const char *info); +int SRP_user_pwd_set0_sv(SRP_user_pwd *user_pwd, BIGNUM *s, BIGNUM *v); + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + const BIGNUM *default_g; + const BIGNUM *default_N; +} SRP_VBASE; + +/* + * Internal structure storing N and g pair + */ +typedef struct SRP_gN_st { + char *id; + const BIGNUM *g; + const BIGNUM *N; +} SRP_gN; +{- + generate_stack_macros("SRP_gN"); +-} + + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +void SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +int SRP_VBASE_add0_user(SRP_VBASE *vb, SRP_user_pwd *user_pwd); +/* This method ignores the configured seed and fails for an unknown user. */ +DEPRECATEDIN_1_1_0(SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)) +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g, + OSSL_LIB_CTX *libctx, const char *propq); +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN_ex(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g, OSSL_LIB_CTX *libctx, + const char *propq); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, const BIGNUM *N, + const BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u, + const BIGNUM *b, const BIGNUM *N); +BIGNUM *SRP_Calc_B_ex(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v, OSSL_LIB_CTX *libctx, const char *propq); +BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g, + const BIGNUM *v); +int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N); +BIGNUM *SRP_Calc_u_ex(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N, + OSSL_LIB_CTX *libctx, const char *propq); +BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x_ex(const BIGNUM *s, const char *user, const char *pass, + OSSL_LIB_CTX *libctx, const char *propq); +BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g); +BIGNUM *SRP_Calc_client_key_ex(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u, + OSSL_LIB_CTX *libctx, const char *propq); +BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g, + const BIGNUM *x, const BIGNUM *a, const BIGNUM *u); +int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +# ifdef __cplusplus +} +# endif +# endif + +#endif diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index bc003bc4fa..4e454366e7 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/ssl.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * Copyright 2005 Nokia. All rights reserved. @@ -9,6 +12,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_SSL_H # define OPENSSL_SSL_H # pragma once @@ -240,7 +245,32 @@ typedef struct srtp_protection_profile_st { const char *name; unsigned long id; } SRTP_PROTECTION_PROFILE; -DEFINE_OR_DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) +SKM_DEFINE_STACK_OF_INTERNAL(SRTP_PROTECTION_PROFILE, SRTP_PROTECTION_PROFILE, SRTP_PROTECTION_PROFILE) +#define sk_SRTP_PROTECTION_PROFILE_num(sk) OPENSSL_sk_num(ossl_check_const_SRTP_PROTECTION_PROFILE_sk_type(sk)) +#define sk_SRTP_PROTECTION_PROFILE_value(sk, idx) ((SRTP_PROTECTION_PROFILE *)OPENSSL_sk_value(ossl_check_const_SRTP_PROTECTION_PROFILE_sk_type(sk), (idx))) +#define sk_SRTP_PROTECTION_PROFILE_new(cmp) ((STACK_OF(SRTP_PROTECTION_PROFILE) *)OPENSSL_sk_new(ossl_check_SRTP_PROTECTION_PROFILE_compfunc_type(cmp))) +#define sk_SRTP_PROTECTION_PROFILE_new_null() ((STACK_OF(SRTP_PROTECTION_PROFILE) *)OPENSSL_sk_new_null()) +#define sk_SRTP_PROTECTION_PROFILE_new_reserve(cmp, n) ((STACK_OF(SRTP_PROTECTION_PROFILE) *)OPENSSL_sk_new_reserve(ossl_check_SRTP_PROTECTION_PROFILE_compfunc_type(cmp), (n))) +#define sk_SRTP_PROTECTION_PROFILE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), (n)) +#define sk_SRTP_PROTECTION_PROFILE_free(sk) OPENSSL_sk_free(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk)) +#define sk_SRTP_PROTECTION_PROFILE_zero(sk) OPENSSL_sk_zero(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk)) +#define sk_SRTP_PROTECTION_PROFILE_delete(sk, i) ((SRTP_PROTECTION_PROFILE *)OPENSSL_sk_delete(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), (i))) +#define sk_SRTP_PROTECTION_PROFILE_delete_ptr(sk, ptr) ((SRTP_PROTECTION_PROFILE *)OPENSSL_sk_delete_ptr(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr))) +#define sk_SRTP_PROTECTION_PROFILE_push(sk, ptr) OPENSSL_sk_push(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr)) +#define sk_SRTP_PROTECTION_PROFILE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr)) +#define sk_SRTP_PROTECTION_PROFILE_pop(sk) ((SRTP_PROTECTION_PROFILE *)OPENSSL_sk_pop(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk))) +#define sk_SRTP_PROTECTION_PROFILE_shift(sk) ((SRTP_PROTECTION_PROFILE *)OPENSSL_sk_shift(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk))) +#define sk_SRTP_PROTECTION_PROFILE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk),ossl_check_SRTP_PROTECTION_PROFILE_freefunc_type(freefunc)) +#define sk_SRTP_PROTECTION_PROFILE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr), (idx)) +#define sk_SRTP_PROTECTION_PROFILE_set(sk, idx, ptr) ((SRTP_PROTECTION_PROFILE *)OPENSSL_sk_set(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), (idx), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr))) +#define sk_SRTP_PROTECTION_PROFILE_find(sk, ptr) OPENSSL_sk_find(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr)) +#define sk_SRTP_PROTECTION_PROFILE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_type(ptr)) +#define sk_SRTP_PROTECTION_PROFILE_sort(sk) OPENSSL_sk_sort(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk)) +#define sk_SRTP_PROTECTION_PROFILE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SRTP_PROTECTION_PROFILE_sk_type(sk)) +#define sk_SRTP_PROTECTION_PROFILE_dup(sk) ((STACK_OF(SRTP_PROTECTION_PROFILE) *)OPENSSL_sk_dup(ossl_check_const_SRTP_PROTECTION_PROFILE_sk_type(sk))) +#define sk_SRTP_PROTECTION_PROFILE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SRTP_PROTECTION_PROFILE) *)OPENSSL_sk_deep_copy(ossl_check_const_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_copyfunc_type(copyfunc), ossl_check_SRTP_PROTECTION_PROFILE_freefunc_type(freefunc))) +#define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(sk, cmp) ((sk_SRTP_PROTECTION_PROFILE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SRTP_PROTECTION_PROFILE_sk_type(sk), ossl_check_SRTP_PROTECTION_PROFILE_compfunc_type(cmp))) + typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, @@ -841,8 +871,8 @@ void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, * the maximum length of the buffer given to callbacks containing the * resulting identity/psk */ -# define PSK_MAX_IDENTITY_LEN 128 -# define PSK_MAX_PSK_LEN 256 +# define PSK_MAX_IDENTITY_LEN 256 +# define PSK_MAX_PSK_LEN 512 typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, const char *hint, char *identity, @@ -980,8 +1010,57 @@ extern "C" { * These need to be after the above set of includes due to a compiler bug * in VisualStudio 2015 */ -DEFINE_OR_DECLARE_STACK_OF(SSL_CIPHER) -DEFINE_OR_DECLARE_STACK_OF(SSL_COMP) +SKM_DEFINE_STACK_OF_INTERNAL(SSL_CIPHER, const SSL_CIPHER, SSL_CIPHER) +#define sk_SSL_CIPHER_num(sk) OPENSSL_sk_num(ossl_check_const_SSL_CIPHER_sk_type(sk)) +#define sk_SSL_CIPHER_value(sk, idx) ((const SSL_CIPHER *)OPENSSL_sk_value(ossl_check_const_SSL_CIPHER_sk_type(sk), (idx))) +#define sk_SSL_CIPHER_new(cmp) ((STACK_OF(SSL_CIPHER) *)OPENSSL_sk_new(ossl_check_SSL_CIPHER_compfunc_type(cmp))) +#define sk_SSL_CIPHER_new_null() ((STACK_OF(SSL_CIPHER) *)OPENSSL_sk_new_null()) +#define sk_SSL_CIPHER_new_reserve(cmp, n) ((STACK_OF(SSL_CIPHER) *)OPENSSL_sk_new_reserve(ossl_check_SSL_CIPHER_compfunc_type(cmp), (n))) +#define sk_SSL_CIPHER_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SSL_CIPHER_sk_type(sk), (n)) +#define sk_SSL_CIPHER_free(sk) OPENSSL_sk_free(ossl_check_SSL_CIPHER_sk_type(sk)) +#define sk_SSL_CIPHER_zero(sk) OPENSSL_sk_zero(ossl_check_SSL_CIPHER_sk_type(sk)) +#define sk_SSL_CIPHER_delete(sk, i) ((const SSL_CIPHER *)OPENSSL_sk_delete(ossl_check_SSL_CIPHER_sk_type(sk), (i))) +#define sk_SSL_CIPHER_delete_ptr(sk, ptr) ((const SSL_CIPHER *)OPENSSL_sk_delete_ptr(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_type(ptr))) +#define sk_SSL_CIPHER_push(sk, ptr) OPENSSL_sk_push(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_type(ptr)) +#define sk_SSL_CIPHER_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_type(ptr)) +#define sk_SSL_CIPHER_pop(sk) ((const SSL_CIPHER *)OPENSSL_sk_pop(ossl_check_SSL_CIPHER_sk_type(sk))) +#define sk_SSL_CIPHER_shift(sk) ((const SSL_CIPHER *)OPENSSL_sk_shift(ossl_check_SSL_CIPHER_sk_type(sk))) +#define sk_SSL_CIPHER_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SSL_CIPHER_sk_type(sk),ossl_check_SSL_CIPHER_freefunc_type(freefunc)) +#define sk_SSL_CIPHER_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_type(ptr), (idx)) +#define sk_SSL_CIPHER_set(sk, idx, ptr) ((const SSL_CIPHER *)OPENSSL_sk_set(ossl_check_SSL_CIPHER_sk_type(sk), (idx), ossl_check_SSL_CIPHER_type(ptr))) +#define sk_SSL_CIPHER_find(sk, ptr) OPENSSL_sk_find(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_type(ptr)) +#define sk_SSL_CIPHER_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_type(ptr)) +#define sk_SSL_CIPHER_sort(sk) OPENSSL_sk_sort(ossl_check_SSL_CIPHER_sk_type(sk)) +#define sk_SSL_CIPHER_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SSL_CIPHER_sk_type(sk)) +#define sk_SSL_CIPHER_dup(sk) ((STACK_OF(SSL_CIPHER) *)OPENSSL_sk_dup(ossl_check_const_SSL_CIPHER_sk_type(sk))) +#define sk_SSL_CIPHER_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SSL_CIPHER) *)OPENSSL_sk_deep_copy(ossl_check_const_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_copyfunc_type(copyfunc), ossl_check_SSL_CIPHER_freefunc_type(freefunc))) +#define sk_SSL_CIPHER_set_cmp_func(sk, cmp) ((sk_SSL_CIPHER_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SSL_CIPHER_sk_type(sk), ossl_check_SSL_CIPHER_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(SSL_COMP, SSL_COMP, SSL_COMP) +#define sk_SSL_COMP_num(sk) OPENSSL_sk_num(ossl_check_const_SSL_COMP_sk_type(sk)) +#define sk_SSL_COMP_value(sk, idx) ((SSL_COMP *)OPENSSL_sk_value(ossl_check_const_SSL_COMP_sk_type(sk), (idx))) +#define sk_SSL_COMP_new(cmp) ((STACK_OF(SSL_COMP) *)OPENSSL_sk_new(ossl_check_SSL_COMP_compfunc_type(cmp))) +#define sk_SSL_COMP_new_null() ((STACK_OF(SSL_COMP) *)OPENSSL_sk_new_null()) +#define sk_SSL_COMP_new_reserve(cmp, n) ((STACK_OF(SSL_COMP) *)OPENSSL_sk_new_reserve(ossl_check_SSL_COMP_compfunc_type(cmp), (n))) +#define sk_SSL_COMP_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SSL_COMP_sk_type(sk), (n)) +#define sk_SSL_COMP_free(sk) OPENSSL_sk_free(ossl_check_SSL_COMP_sk_type(sk)) +#define sk_SSL_COMP_zero(sk) OPENSSL_sk_zero(ossl_check_SSL_COMP_sk_type(sk)) +#define sk_SSL_COMP_delete(sk, i) ((SSL_COMP *)OPENSSL_sk_delete(ossl_check_SSL_COMP_sk_type(sk), (i))) +#define sk_SSL_COMP_delete_ptr(sk, ptr) ((SSL_COMP *)OPENSSL_sk_delete_ptr(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_type(ptr))) +#define sk_SSL_COMP_push(sk, ptr) OPENSSL_sk_push(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_type(ptr)) +#define sk_SSL_COMP_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_type(ptr)) +#define sk_SSL_COMP_pop(sk) ((SSL_COMP *)OPENSSL_sk_pop(ossl_check_SSL_COMP_sk_type(sk))) +#define sk_SSL_COMP_shift(sk) ((SSL_COMP *)OPENSSL_sk_shift(ossl_check_SSL_COMP_sk_type(sk))) +#define sk_SSL_COMP_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SSL_COMP_sk_type(sk),ossl_check_SSL_COMP_freefunc_type(freefunc)) +#define sk_SSL_COMP_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_type(ptr), (idx)) +#define sk_SSL_COMP_set(sk, idx, ptr) ((SSL_COMP *)OPENSSL_sk_set(ossl_check_SSL_COMP_sk_type(sk), (idx), ossl_check_SSL_COMP_type(ptr))) +#define sk_SSL_COMP_find(sk, ptr) OPENSSL_sk_find(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_type(ptr)) +#define sk_SSL_COMP_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_type(ptr)) +#define sk_SSL_COMP_sort(sk) OPENSSL_sk_sort(ossl_check_SSL_COMP_sk_type(sk)) +#define sk_SSL_COMP_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SSL_COMP_sk_type(sk)) +#define sk_SSL_COMP_dup(sk) ((STACK_OF(SSL_COMP) *)OPENSSL_sk_dup(ossl_check_const_SSL_COMP_sk_type(sk))) +#define sk_SSL_COMP_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SSL_COMP) *)OPENSSL_sk_deep_copy(ossl_check_const_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_copyfunc_type(copyfunc), ossl_check_SSL_COMP_freefunc_type(freefunc))) +#define sk_SSL_COMP_set_cmp_func(sk, cmp) ((sk_SSL_COMP_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SSL_COMP_sk_type(sk), ossl_check_SSL_COMP_compfunc_type(cmp))) + /* compatibility */ # define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)(arg))) @@ -1528,8 +1607,8 @@ void BIO_ssl_shutdown(BIO *ssl_bio); __owur int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); __owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); -__owur SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, - const SSL_METHOD *meth); +__owur SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const SSL_METHOD *meth); int SSL_CTX_up_ref(SSL_CTX *ctx); void SSL_CTX_free(SSL_CTX *); __owur long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); @@ -1630,8 +1709,8 @@ __owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); __owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file); __owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); __owur STACK_OF(X509_NAME) -*SSL_load_client_CA_file_with_libctx(const char *file, - OPENSSL_CTX *libctx, const char *propq); +*SSL_load_client_CA_file_ex(const char *file, OSSL_LIB_CTX *libctx, + const char *propq); __owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, const char *file); int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, @@ -1903,7 +1982,7 @@ __owur int SSL_get_error(const SSL *s, int ret_code); __owur const char *SSL_get_version(const SSL *s); /* This sets the 'default' SSL version that SSL_new() will create */ -__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); +DEPRECATEDIN_3_0(__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)) # ifndef OPENSSL_NO_SSL3_METHOD DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_method(void)) /* SSLv3 */ diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in new file mode 100644 index 0000000000..edcd9819fa --- /dev/null +++ b/include/openssl/ssl.h.in @@ -0,0 +1,2503 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * Copyright 2005 Nokia. All rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros generate_const_stack_macros); +-} + +#ifndef OPENSSL_SSL_H +# define OPENSSL_SSL_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_SSL_H +# endif + +# include +# include +# include +# include +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# include +# include +# include +# endif +# include +# include +# include +# include + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* OpenSSL version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* The maximum number of encrypt/decrypt pipelines we can support */ +# define SSL_MAX_PIPELINES 32 + +/* text strings for the ciphers */ + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr"/* this cipher class has been removed */ +# define SSL_TXT_kDHd "kDHd"/* this cipher class has been removed */ +# define SSL_TXT_kDH "kDH"/* this cipher class has been removed */ +# define SSL_TXT_kEDH "kEDH"/* alias for kDHE */ +# define SSL_TXT_kDHE "kDHE" +# define SSL_TXT_kECDHr "kECDHr"/* this cipher class has been removed */ +# define SSL_TXT_kECDHe "kECDHe"/* this cipher class has been removed */ +# define SSL_TXT_kECDH "kECDH"/* this cipher class has been removed */ +# define SSL_TXT_kEECDH "kEECDH"/* alias for kECDHE */ +# define SSL_TXT_kECDHE "kECDHE" +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kRSAPSK "kRSAPSK" +# define SSL_TXT_kECDHEPSK "kECDHEPSK" +# define SSL_TXT_kDHEPSK "kDHEPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kGOST18 "kGOST18" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDH "aECDH"/* this cipher class has been removed */ +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST12 "aGOST12" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_DHE "DHE"/* same as "kDHE:-ADH" */ +# define SSL_TXT_EDH "EDH"/* alias for DHE */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* alias for ECDHE" */ +# define SSL_TXT_ECDHE "ECDHE"/* same as "kECDHE:-AECDH" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_AES_CCM "AESCCM" +# define SSL_TXT_AES_CCM_8 "AESCCM8" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" +# define SSL_TXT_CHACHA20 "CHACHA20" +# define SSL_TXT_GOST "GOST89" +# define SSL_TXT_ARIA "ARIA" +# define SSL_TXT_ARIA_GCM "ARIAGCM" +# define SSL_TXT_ARIA128 "ARIA128" +# define SSL_TXT_ARIA256 "ARIA256" +# define SSL_TXT_GOST2012_GOST8912_GOST8912 "GOST2012-GOST8912-GOST8912" +# define SSL_TXT_CBC "CBC" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_GOST12 "GOST12" +# define SSL_TXT_GOST89MAC12 "GOST89MAC12" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + * This applies to ciphersuites for TLSv1.2 and below. + * DEPRECATED IN 3.0.0, in favor of OSSL_default_cipher_list() + * Update both macro and function simultaneously + */ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL" +/* + * This is the default set of TLSv1.3 ciphersuites + * DEPRECATED IN 3.0.0, in favor of OSSL_default_ciphersuites() + * Update both macro and function simultaneously + */ +# if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_CHACHA20_POLY1305_SHA256:" \ + "TLS_AES_128_GCM_SHA256" +# else +# define TLS_DEFAULT_CIPHERSUITES "TLS_AES_256_GCM_SHA384:" \ + "TLS_AES_128_GCM_SHA256" +# endif +# endif +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; +typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; +typedef struct ssl_comp_st SSL_COMP; + +STACK_OF(SSL_CIPHER); +STACK_OF(SSL_COMP); + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; +{- + generate_stack_macros("SRTP_PROTECTION_PROFILE"); +-} + + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + const SSL_CIPHER **cipher, void *arg); + +/* Extension context codes */ +/* This extension is only allowed in TLS */ +#define SSL_EXT_TLS_ONLY 0x0001 +/* This extension is only allowed in DTLS */ +#define SSL_EXT_DTLS_ONLY 0x0002 +/* Some extensions may be allowed in DTLS but we don't implement them for it */ +#define SSL_EXT_TLS_IMPLEMENTATION_ONLY 0x0004 +/* Most extensions are not defined for SSLv3 but EXT_TYPE_renegotiate is */ +#define SSL_EXT_SSL3_ALLOWED 0x0008 +/* Extension is only defined for TLS1.2 and below */ +#define SSL_EXT_TLS1_2_AND_BELOW_ONLY 0x0010 +/* Extension is only defined for TLS1.3 and above */ +#define SSL_EXT_TLS1_3_ONLY 0x0020 +/* Ignore this extension during parsing if we are resuming */ +#define SSL_EXT_IGNORE_ON_RESUMPTION 0x0040 +#define SSL_EXT_CLIENT_HELLO 0x0080 +/* Really means TLS1.2 or below */ +#define SSL_EXT_TLS1_2_SERVER_HELLO 0x0100 +#define SSL_EXT_TLS1_3_SERVER_HELLO 0x0200 +#define SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS 0x0400 +#define SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST 0x0800 +#define SSL_EXT_TLS1_3_CERTIFICATE 0x1000 +#define SSL_EXT_TLS1_3_NEW_SESSION_TICKET 0x2000 +#define SSL_EXT_TLS1_3_CERTIFICATE_REQUEST 0x4000 + +/* Typedefs for handling custom extensions */ + +typedef int (*custom_ext_add_cb)(SSL *s, unsigned int ext_type, + const unsigned char **out, size_t *outlen, + int *al, void *add_arg); + +typedef void (*custom_ext_free_cb)(SSL *s, unsigned int ext_type, + const unsigned char *out, void *add_arg); + +typedef int (*custom_ext_parse_cb)(SSL *s, unsigned int ext_type, + const unsigned char *in, size_t inlen, + int *al, void *parse_arg); + + +typedef int (*SSL_custom_ext_add_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char **out, + size_t *outlen, X509 *x, + size_t chainidx, + int *al, void *add_arg); + +typedef void (*SSL_custom_ext_free_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *out, + void *add_arg); + +typedef int (*SSL_custom_ext_parse_cb_ex)(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char *in, + size_t inlen, X509 *x, + size_t chainidx, + int *al, void *parse_arg); + +/* Typedef for verification callback */ +typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx); + +/* Typedef for SSL async callback */ +typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); + +/* + * Some values are reserved until OpenSSL 3.0.0 because they were previously + * included in SSL_OP_ALL in a 1.1.x release. + */ + +/* Disable Extended master secret */ +# define SSL_OP_NO_EXTENDED_MASTER_SECRET 0x00000001U + +/* Cleanse plaintext copies of data delivered to the application */ +# define SSL_OP_CLEANSE_PLAINTEXT 0x00000002U + +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U + +# define SSL_OP_TLSEXT_PADDING 0x00000010U +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040U +# define SSL_OP_IGNORE_UNEXPECTED_EOF 0x00000080U + +# define SSL_OP_DISABLE_TLSEXT_CA_NAMES 0x00000200U + +/* In TLSv1.3 allow a non-(ec)dhe based kex_mode */ +# define SSL_OP_ALLOW_NO_DHE_KEX 0x00000400U + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. Added in 0.9.6e + */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800U + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000U +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000U +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000U +# ifndef OPENSSL_NO_DTLS1_METHOD +/* Use Cisco's "speshul" version of DTLS_BAD_VER + * (only with deprecated DTLSv1_client_method()) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000U +# endif + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000U +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000U +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000U +/* Disable encrypt-then-mac */ +# define SSL_OP_NO_ENCRYPT_THEN_MAC 0x00080000U + +/* + * Enable TLSv1.3 Compatibility mode. This is on by default. A future version + * of OpenSSL may have this disabled by default. + */ +# define SSL_OP_ENABLE_MIDDLEBOX_COMPAT 0x00100000U + +/* Prioritize Chacha20Poly1305 when client does. + * Modifies SSL_OP_CIPHER_SERVER_PREFERENCE */ +# define SSL_OP_PRIORITIZE_CHACHA 0x00200000U + +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000U +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000U + +/* + * Switches off automatic TLSv1.3 anti-replay protection for early data. This + * is a server-side option only (no effect on the client). + */ +# define SSL_OP_NO_ANTI_REPLAY 0x01000000U + +# define SSL_OP_NO_SSLv3 0x02000000U +# define SSL_OP_NO_TLSv1 0x04000000U +# define SSL_OP_NO_TLSv1_2 0x08000000U +# define SSL_OP_NO_TLSv1_1 0x10000000U +# define SSL_OP_NO_TLSv1_3 0x20000000U + +# define SSL_OP_NO_DTLSv1 0x04000000U +# define SSL_OP_NO_DTLSv1_2 0x08000000U + +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2|SSL_OP_NO_TLSv1_3) +# define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2) + +/* Disallow all renegotiation */ +# define SSL_OP_NO_RENEGOTIATION 0x40000000U + +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000U + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. + * This used to be 0x80000BFFU before 1.1.1. + */ +# define SSL_OP_ALL (SSL_OP_CRYPTOPRO_TLSEXT_BUG|\ + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS|\ + SSL_OP_LEGACY_SERVER_CONNECT|\ + SSL_OP_TLSEXT_PADDING|\ + SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + +/* OBSOLETE OPTIONS: retained for compatibility */ + +/* Removed from OpenSSL 1.1.0. Was 0x00000001L */ +/* Related to removed SSLv2. */ +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000002L */ +/* Related to removed SSLv2. */ +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x0 +/* Removed from OpenSSL 0.9.8q and 1.0.0c. Was 0x00000008L */ +/* Dead forever, see CVE-2010-4180 */ +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x0 +/* Removed from OpenSSL 1.0.1h and 1.0.2. Was 0x00000010L */ +/* Refers to ancient SSLREF and SSLv2. */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000020 */ +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x0 +/* Removed from OpenSSL 0.9.7h and 0.9.8b. Was 0x00000040L */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000080 */ +/* Ancient SSLeay version. */ +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000100L */ +# define SSL_OP_TLS_D5_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00000200L */ +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00080000L */ +# define SSL_OP_SINGLE_ECDH_USE 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x00100000L */ +# define SSL_OP_SINGLE_DH_USE 0x0 +/* Removed from OpenSSL 1.0.1k and 1.0.2. Was 0x00200000L */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x01000000L */ +# define SSL_OP_NO_SSLv2 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x08000000L */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +/* Removed from OpenSSL 1.0.1. Was 0x10000000L */ +# define SSL_OP_PKCS1_CHECK_2 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x20000000L */ +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 +/* Removed from OpenSSL 1.1.0. Was 0x40000000L */ +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001U +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004U +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008U +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) Released buffers are freed. + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010U +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020U +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040U +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080U +/* + * Support Asynchronous operation + */ +# define SSL_MODE_ASYNC 0x00000100U +/* + * Don't use the kernel TLS data-path for sending. + */ +# define SSL_MODE_NO_KTLS_TX 0x00000200U +/* + * When using DTLS/SCTP, include the terminating zero in the label + * used for computing the endpoint-pair shared secret. Required for + * interoperability with implementations having this bug like these + * older version of OpenSSL: + * - OpenSSL 1.0.0 series + * - OpenSSL 1.0.1 series + * - OpenSSL 1.0.2 series + * - OpenSSL 1.1.0 series + * - OpenSSL 1.1.1 and 1.1.1a + */ +# define SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG 0x00000400U +/* + * Don't use the kernel TLS data-path for receiving. + */ +# define SSL_MODE_NO_KTLS_RX 0x00000800U + +/* Cert related flags */ +/* + * Many implementations ignore some aspects of the TLS standards such as + * enforcing certificate chain algorithms. When this is set we enforce them. + */ +# define SSL_CERT_FLAG_TLS_STRICT 0x00000001U + +/* Suite B modes, takes same values as certificate verify flags */ +# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 + +/* Perform all sorts of protocol violations for testing purposes */ +# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 + +/* Flags for building certificate chains */ +/* Treat any existing certificates as untrusted CAs */ +# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 +/* Don't include root CA in chain */ +# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 +/* Just check certificates already there */ +# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 +/* Ignore verification errors */ +# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 + +/* Flags returned by SSL_check_chain */ +/* Certificate can be used with this session */ +# define CERT_PKEY_VALID 0x1 +/* Certificate can also be used for signing */ +# define CERT_PKEY_SIGN 0x2 +/* EE certificate signing algorithm OK */ +# define CERT_PKEY_EE_SIGNATURE 0x10 +/* CA signature algorithms OK */ +# define CERT_PKEY_CA_SIGNATURE 0x20 +/* EE certificate parameters OK */ +# define CERT_PKEY_EE_PARAM 0x40 +/* CA certificate parameters OK */ +# define CERT_PKEY_CA_PARAM 0x80 +/* Signing explicitly allowed as opposed to SHA1 fallback */ +# define CERT_PKEY_EXPLICIT_SIGN 0x100 +/* Client CA issuer names match (always set for server cert) */ +# define CERT_PKEY_ISSUER_NAME 0x200 +/* Cert type matches client types (always set for server cert) */ +# define CERT_PKEY_CERT_TYPE 0x400 +/* Cert chain suitable to Suite B */ +# define CERT_PKEY_SUITEB 0x800 + +# define SSL_CONF_FLAG_CMDLINE 0x1 +# define SSL_CONF_FLAG_FILE 0x2 +# define SSL_CONF_FLAG_CLIENT 0x4 +# define SSL_CONF_FLAG_SERVER 0x8 +# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 +# define SSL_CONF_FLAG_CERTIFICATE 0x20 +# define SSL_CONF_FLAG_REQUIRE_PRIVATE 0x40 +/* Configuration value types */ +# define SSL_CONF_TYPE_UNKNOWN 0x0 +# define SSL_CONF_TYPE_STRING 0x1 +# define SSL_CONF_TYPE_FILE 0x2 +# define SSL_CONF_TYPE_DIR 0x3 +# define SSL_CONF_TYPE_NONE 0x4 +# define SSL_CONF_TYPE_STORE 0x5 + +/* Maximum length of the application-controlled segment of a a TLSv1.3 cookie */ +# define SSL_COOKIE_LENGTH 4096 + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +unsigned long SSL_CTX_get_options(const SSL_CTX *ctx); +unsigned long SSL_get_options(const SSL *s); +unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_clear_options(SSL *s, unsigned long op); +unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op); +unsigned long SSL_set_options(SSL *s, unsigned long op); + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# define SSL_CTX_set_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_set_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_CTX_clear_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) +# define SSL_clear_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# define SSL_get_extms_support(s) \ + SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL) + +# ifndef OPENSSL_NO_SRP + +/* see tls_srp.c */ +__owur int SSL_SRP_CTX_init(SSL *s); +__owur int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +__owur int SSL_srp_server_param_with_username(SSL *s, int *ad); +__owur int SRP_Calc_A_param(SSL *s); + +# endif + +/* 100k max cert list */ +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv3/TLSv1 it is 32 + * bytes. The callback can alter this length to be less if desired. It is + * also an error for the callback to set the size to zero. + */ +typedef int (*GEN_SESSION_CB) (SSL *ssl, unsigned char *id, + unsigned int *id_len); + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + const unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + const unsigned char *data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +__owur int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + const unsigned + char *cookie, + unsigned int + cookie_len)); + +void SSL_CTX_set_stateless_cookie_generate_cb( + SSL_CTX *ctx, + int (*gen_stateless_cookie_cb) (SSL *ssl, + unsigned char *cookie, + size_t *cookie_len)); +void SSL_CTX_set_stateless_cookie_verify_cb( + SSL_CTX *ctx, + int (*verify_stateless_cookie_cb) (SSL *ssl, + const unsigned char *cookie, + size_t cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG + +typedef int (*SSL_CTX_npn_advertised_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned int *outlen, + void *arg); +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + SSL_CTX_npn_advertised_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_advertised_cb SSL_CTX_set_next_protos_advertised_cb + +typedef int (*SSL_CTX_npn_select_cb_func)(SSL *s, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + SSL_CTX_npn_select_cb_func cb, + void *arg); +# define SSL_CTX_set_npn_select_cb SSL_CTX_set_next_proto_select_cb + +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); +# define SSL_get0_npn_negotiated SSL_get0_next_proto_negotiated +# endif + +__owur int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 + +__owur int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned int protos_len); +__owur int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned int protos_len); +typedef int (*SSL_CTX_alpn_select_cb_func)(SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + SSL_CTX_alpn_select_cb_func cb, + void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 256 +# define PSK_MAX_PSK_LEN 512 +typedef unsigned int (*SSL_psk_client_cb_func)(SSL *ssl, + const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, SSL_psk_client_cb_func cb); +void SSL_set_psk_client_callback(SSL *ssl, SSL_psk_client_cb_func cb); + +typedef unsigned int (*SSL_psk_server_cb_func)(SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, SSL_psk_server_cb_func cb); +void SSL_set_psk_server_callback(SSL *ssl, SSL_psk_server_cb_func cb); + +__owur int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +__owur int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +typedef int (*SSL_psk_find_session_cb_func)(SSL *ssl, + const unsigned char *identity, + size_t identity_len, + SSL_SESSION **sess); +typedef int (*SSL_psk_use_session_cb_func)(SSL *ssl, const EVP_MD *md, + const unsigned char **id, + size_t *idlen, + SSL_SESSION **sess); + +void SSL_set_psk_find_session_callback(SSL *s, SSL_psk_find_session_cb_func cb); +void SSL_CTX_set_psk_find_session_callback(SSL_CTX *ctx, + SSL_psk_find_session_cb_func cb); +void SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb); +void SSL_CTX_set_psk_use_session_callback(SSL_CTX *ctx, + SSL_psk_use_session_cb_func cb); + +/* Register callbacks to handle custom TLS Extensions for client or server. */ + +__owur int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, + unsigned int ext_type); + +__owur int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +__owur int SSL_CTX_add_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + unsigned int context, + SSL_custom_ext_add_cb_ex add_cb, + SSL_custom_ext_free_cb_ex free_cb, + void *add_arg, + SSL_custom_ext_parse_cb_ex parse_cb, + void *parse_arg); + +__owur int SSL_extension_supported(unsigned int ext_type); + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 +# define SSL_ASYNC_PAUSED 5 +# define SSL_ASYNC_NO_JOBS 6 +# define SSL_CLIENT_HELLO_CB 7 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) +# define SSL_want_async(s) (SSL_want(s) == SSL_ASYNC_PAUSED) +# define SSL_want_async_job(s) (SSL_want(s) == SSL_ASYNC_NO_JOBS) +# define SSL_want_client_hello_cb(s) (SSL_want(s) == SSL_CLIENT_HELLO_CB) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 +# define SSL_MAC_FLAG_READ_MAC_TLSTREE 4 +# define SSL_MAC_FLAG_WRITE_MAC_TLSTREE 8 + +/* + * A callback for logging out TLS key material. This callback should log out + * |line| followed by a newline. + */ +typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line); + +/* + * SSL_CTX_set_keylog_callback configures a callback to log key material. This + * is intended for debugging use with tools like Wireshark. The cb function + * should log line followed by a newline. + */ +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb); + +/* + * SSL_CTX_get_keylog_callback returns the callback configured by + * SSL_CTX_set_keylog_callback. + */ +SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx); + +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data); +uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx); +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data); +uint32_t SSL_get_max_early_data(const SSL *s); +int SSL_CTX_set_recv_max_early_data(SSL_CTX *ctx, uint32_t recv_max_early_data); +uint32_t SSL_CTX_get_recv_max_early_data(const SSL_CTX *ctx); +int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data); +uint32_t SSL_get_recv_max_early_data(const SSL *s); + +#ifdef __cplusplus +} +#endif + +# include +# include +# include /* This is mostly sslv3 with a few tweaks */ +# include /* Datagram TLS */ +# include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These need to be after the above set of includes due to a compiler bug + * in VisualStudio 2015 + */ +{- + generate_const_stack_macros("SSL_CIPHER") + .generate_stack_macros("SSL_COMP"); +-} + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)(arg))) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0, \ + (char *)(a))) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0, \ + (char *)(arg))) +DEPRECATEDIN_1_1_0(void SSL_set_debug(SSL *s, int debug)) + +/* TLSv1.3 KeyUpdate message types */ +/* -1 used so that this is an invalid value for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NONE -1 +/* Values as defined for the on-the-wire protocol */ +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 +#define SSL_KEY_UPDATE_REQUESTED 1 + +/* + * The valid handshake states (one for each type message sent and one for each + * type of message received). There are also two "special" states: + * TLS = TLS or DTLS state + * DTLS = DTLS specific state + * CR/SR = Client Read/Server Read + * CW/SW = Client Write/Server Write + * + * The "special" states are: + * TLS_ST_BEFORE = No handshake has been initiated yet + * TLS_ST_OK = A handshake has been successfully completed + */ +typedef enum { + TLS_ST_BEFORE, + TLS_ST_OK, + DTLS_ST_CR_HELLO_VERIFY_REQUEST, + TLS_ST_CR_SRVR_HELLO, + TLS_ST_CR_CERT, + TLS_ST_CR_CERT_STATUS, + TLS_ST_CR_KEY_EXCH, + TLS_ST_CR_CERT_REQ, + TLS_ST_CR_SRVR_DONE, + TLS_ST_CR_SESSION_TICKET, + TLS_ST_CR_CHANGE, + TLS_ST_CR_FINISHED, + TLS_ST_CW_CLNT_HELLO, + TLS_ST_CW_CERT, + TLS_ST_CW_KEY_EXCH, + TLS_ST_CW_CERT_VRFY, + TLS_ST_CW_CHANGE, + TLS_ST_CW_NEXT_PROTO, + TLS_ST_CW_FINISHED, + TLS_ST_SW_HELLO_REQ, + TLS_ST_SR_CLNT_HELLO, + DTLS_ST_SW_HELLO_VERIFY_REQUEST, + TLS_ST_SW_SRVR_HELLO, + TLS_ST_SW_CERT, + TLS_ST_SW_KEY_EXCH, + TLS_ST_SW_CERT_REQ, + TLS_ST_SW_SRVR_DONE, + TLS_ST_SR_CERT, + TLS_ST_SR_KEY_EXCH, + TLS_ST_SR_CERT_VRFY, + TLS_ST_SR_NEXT_PROTO, + TLS_ST_SR_CHANGE, + TLS_ST_SR_FINISHED, + TLS_ST_SW_SESSION_TICKET, + TLS_ST_SW_CERT_STATUS, + TLS_ST_SW_CHANGE, + TLS_ST_SW_FINISHED, + TLS_ST_SW_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_ENCRYPTED_EXTENSIONS, + TLS_ST_CR_CERT_VRFY, + TLS_ST_SW_CERT_VRFY, + TLS_ST_CR_HELLO_REQ, + TLS_ST_SW_KEY_UPDATE, + TLS_ST_CW_KEY_UPDATE, + TLS_ST_SR_KEY_UPDATE, + TLS_ST_CR_KEY_UPDATE, + TLS_ST_EARLY_DATA, + TLS_ST_PENDING_EARLY_DATA_END, + TLS_ST_CW_END_OF_EARLY_DATA, + TLS_ST_SR_END_OF_EARLY_DATA +} OSSL_HANDSHAKE_STATE; + +/* + * Most of the following state values are no longer used and are defined to be + * the closest equivalent value in the current state machine code. Not all + * defines have an equivalent and are set to a dummy value (-1). SSL_ST_CONNECT + * and SSL_ST_ACCEPT are still in use in the definition of SSL_CB_ACCEPT_LOOP, + * SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP and SSL_CB_CONNECT_EXIT. + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 + +# define SSL_ST_MASK 0x0FFF + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_in_connect_init(a) (SSL_in_init(a) && !SSL_is_server(a)) +# define SSL_in_accept_init(a) (SSL_in_init(a) && SSL_is_server(a)) +int SSL_in_init(const SSL *s); +int SSL_in_before(const SSL *s); +int SSL_is_init_finished(const SSL *s); + +/* + * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you + * should not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 +# define SSL_VERIFY_POST_HANDSHAKE 0x08 + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() +# endif + +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_MISSING_EXTENSION TLS13_AD_MISSING_EXTENSION +# define SSL_AD_CERTIFICATE_REQUIRED TLS13_AD_CERTIFICATE_REQUIRED +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_AD_NO_APPLICATION_PROTOCOL TLS1_AD_NO_APPLICATION_PROTOCOL +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_ERROR_WANT_ASYNC 9 +# define SSL_ERROR_WANT_ASYNC_JOB 10 +# define SSL_ERROR_WANT_CLIENT_HELLO_CB 11 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 */ +/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 */ +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# endif +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB 79 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHAIN 88 +# define SSL_CTRL_CHAIN_CERT 89 +# define SSL_CTRL_GET_GROUPS 90 +# define SSL_CTRL_SET_GROUPS 91 +# define SSL_CTRL_SET_GROUPS_LIST 92 +# define SSL_CTRL_GET_SHARED_GROUP 93 +# define SSL_CTRL_SET_SIGALGS 97 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_CERT_FLAGS 99 +# define SSL_CTRL_CLEAR_CERT_FLAGS 100 +# define SSL_CTRL_SET_CLIENT_SIGALGS 101 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 +# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 +# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 +# define SSL_CTRL_BUILD_CERT_CHAIN 105 +# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 +# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 +# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +# define SSL_CTRL_GET_PEER_TMP_KEY 109 +# define SSL_CTRL_GET_RAW_CIPHERLIST 110 +# define SSL_CTRL_GET_EC_POINT_FORMATS 111 +# define SSL_CTRL_GET_CHAIN_CERTS 115 +# define SSL_CTRL_SELECT_CURRENT_CERT 116 +# define SSL_CTRL_SET_CURRENT_CERT 117 +# define SSL_CTRL_SET_DH_AUTO 118 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define SSL_CTRL_GET_EXTMS_SUPPORT 122 +# define SSL_CTRL_SET_MIN_PROTO_VERSION 123 +# define SSL_CTRL_SET_MAX_PROTO_VERSION 124 +# define SSL_CTRL_SET_SPLIT_SEND_FRAGMENT 125 +# define SSL_CTRL_SET_MAX_PIPELINES 126 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE 127 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB 128 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG 129 +# define SSL_CTRL_GET_MIN_PROTO_VERSION 130 +# define SSL_CTRL_GET_MAX_PROTO_VERSION 131 +# define SSL_CTRL_GET_SIGNATURE_NID 132 +# define SSL_CTRL_GET_TMP_KEY 133 +# define SSL_CTRL_GET_NEGOTIATED_GROUP 134 +# define SSL_CERT_SET_FIRST 1 +# define SSL_CERT_SET_NEXT 2 +# define SSL_CERT_SET_SERVER 3 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)(arg)) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# define SSL_CTX_set_dh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_dh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)(dh)) +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)(ecdh)) +# endif +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# define SSL_CTX_set0_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_CTX_set1_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_CTX_add0_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_CTX_add1_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_CTX_get0_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_chain_certs(ctx) \ + SSL_CTX_set0_chain(ctx,NULL) +# define SSL_CTX_build_cert_chain(ctx, flags) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_CTX_select_current_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_CTX_set_current_cert(ctx, op) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_CTX_set0_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_CTX_set0_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_CTX_set1_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk)) +# define SSL_set1_chain(s,sk) \ + SSL_ctrl(s,SSL_CTRL_CHAIN,1,(char *)(sk)) +# define SSL_add0_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,0,(char *)(x509)) +# define SSL_add1_chain_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,1,(char *)(x509)) +# define SSL_get0_chain_certs(s,px509) \ + SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_clear_chain_certs(s) \ + SSL_set0_chain(s,NULL) +# define SSL_build_cert_chain(s, flags) \ + SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_select_current_cert(s,x509) \ + SSL_ctrl(s,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509)) +# define SSL_set_current_cert(s,op) \ + SSL_ctrl(s,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_set0_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st)) +# define SSL_set1_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st)) +# define SSL_set0_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st)) +# define SSL_set1_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st)) +# define SSL_get1_groups(s, glist) \ + SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist)) +# define SSL_CTX_set1_groups(ctx, glist, glistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(int *)(glist)) +# define SSL_CTX_set1_groups_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s)) +# define SSL_set1_groups(s, glist, glistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist)) +# define SSL_set1_groups_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(str)) +# define SSL_get_shared_group(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_GROUP,n,NULL) +# define SSL_get_negotiated_group(s) \ + SSL_ctrl(s,SSL_CTRL_GET_NEGOTIATED_GROUP,0,NULL) +# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(str)) +# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s)) +# define SSL_set1_client_sigalgs(s, slist, slistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist)) +# define SSL_set1_client_sigalgs_list(s, str) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(str)) +# define SSL_get0_certificate_types(s, clist) \ + SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)(clist)) +# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen, \ + (char *)(clist)) +# define SSL_set1_client_certificate_types(s, clist, clistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)(clist)) +# define SSL_get_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_SIGNATURE_NID,0,pn) +# define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) +# define SSL_get_peer_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_TMP_KEY,0,pk) +# define SSL_get_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_TMP_KEY,0,pk) +# define SSL_get0_raw_cipherlist(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst) +# define SSL_get0_ec_point_formats(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,plst) +# define SSL_CTX_set_min_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_CTX_set_max_proto_version(ctx, version) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_CTX_get_min_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_CTX_get_max_proto_version(ctx) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) +# define SSL_set_min_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL) +# define SSL_set_max_proto_version(s, version) \ + SSL_ctrl(s, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL) +# define SSL_get_min_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL) +# define SSL_get_max_proto_version(s) \ + SSL_ctrl(s, SSL_CTRL_GET_MAX_PROTO_VERSION, 0, NULL) + +/* Backwards compatibility, original 1.1.0 names */ +# define SSL_CTRL_GET_SERVER_TMP_KEY \ + SSL_CTRL_GET_PEER_TMP_KEY +# define SSL_get_server_tmp_key(s, pk) \ + SSL_get_peer_tmp_key(s, pk) + +/* + * The following symbol names are old and obsolete. They are kept + * for compatibility reasons only and should not be used anymore. + */ +# define SSL_CTRL_GET_CURVES SSL_CTRL_GET_GROUPS +# define SSL_CTRL_SET_CURVES SSL_CTRL_SET_GROUPS +# define SSL_CTRL_SET_CURVES_LIST SSL_CTRL_SET_GROUPS_LIST +# define SSL_CTRL_GET_SHARED_CURVE SSL_CTRL_GET_SHARED_GROUP + +# define SSL_get1_curves SSL_get1_groups +# define SSL_CTX_set1_curves SSL_CTX_set1_groups +# define SSL_CTX_set1_curves_list SSL_CTX_set1_groups_list +# define SSL_set1_curves SSL_set1_groups +# define SSL_set1_curves_list SSL_set1_groups_list +# define SSL_get_shared_curve SSL_get_shared_group + + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +/* Provide some compatibility macros for removed functionality. */ +# define SSL_CTX_need_tmp_RSA(ctx) 0 +# define SSL_CTX_set_tmp_rsa(ctx,rsa) 1 +# define SSL_need_tmp_RSA(ssl) 0 +# define SSL_set_tmp_rsa(ssl,rsa) 1 +# define SSL_CTX_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +# define SSL_set_ecdh_auto(dummy, onoff) ((onoff) != 0) +/* + * We "pretend" to call the callback to avoid warnings about unused static + * functions. + */ +# define SSL_CTX_set_tmp_rsa_callback(ctx, cb) while(0) (cb)(NULL, 0, 0) +# define SSL_set_tmp_rsa_callback(ssl, cb) while(0) (cb)(NULL, 0, 0) +# endif +__owur const BIO_METHOD *BIO_f_ssl(void); +__owur BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +__owur BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +__owur BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +__owur int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +__owur int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +__owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +__owur SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const SSL_METHOD *meth); +int SSL_CTX_up_ref(SSL_CTX *ctx); +void SSL_CTX_free(SSL_CTX *); +__owur long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +__owur long SSL_CTX_get_timeout(const SSL_CTX *ctx); +__owur X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +void SSL_CTX_set1_cert_store(SSL_CTX *, X509_STORE *); +__owur int SSL_want(const SSL *s); +__owur int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +__owur const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +__owur const SSL_CIPHER *SSL_get_pending_cipher(const SSL *s); +__owur int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +__owur const char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +__owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); +__owur const char *OPENSSL_cipher_name(const char *rfc_name); +__owur uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); +__owur uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); +__owur int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); +__owur const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c); +__owur int SSL_CIPHER_is_aead(const SSL_CIPHER *c); + +__owur int SSL_get_fd(const SSL *s); +__owur int SSL_get_rfd(const SSL *s); +__owur int SSL_get_wfd(const SSL *s); +__owur const char *SSL_get_cipher_list(const SSL *s, int n); +__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); +__owur int SSL_get_read_ahead(const SSL *s); +__owur int SSL_pending(const SSL *s); +__owur int SSL_has_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +__owur int SSL_set_fd(SSL *s, int fd); +__owur int SSL_set_rfd(SSL *s, int fd); +__owur int SSL_set_wfd(SSL *s, int fd); +# endif +void SSL_set0_rbio(SSL *s, BIO *rbio); +void SSL_set0_wbio(SSL *s, BIO *wbio); +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +__owur BIO *SSL_get_rbio(const SSL *s); +__owur BIO *SSL_get_wbio(const SSL *s); +__owur int SSL_set_cipher_list(SSL *s, const char *str); +__owur int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +__owur int SSL_set_ciphersuites(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +__owur int SSL_get_verify_mode(const SSL *s); +__owur int SSL_get_verify_depth(const SSL *s); +__owur SSL_verify_cb SSL_get_verify_callback(const SSL *s); +void SSL_set_verify(SSL *s, int mode, SSL_verify_cb callback); +void SSL_set_verify_depth(SSL *s, int depth); +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +__owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, + long len); +# endif +__owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +__owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +__owur int SSL_use_certificate(SSL *ssl, X509 *x); +__owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); +__owur int SSL_use_cert_and_key(SSL *ssl, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + + +/* serverinfo file format versions */ +# define SSL_SERVERINFOV1 1 +# define SSL_SERVERINFOV2 2 + +/* Set serverinfo data for the current active cert. */ +__owur int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_ex(SSL_CTX *ctx, unsigned int version, + const unsigned char *serverinfo, + size_t serverinfo_length); +__owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +#endif + +__owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +__owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type); + +#ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +#endif +__owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +__owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +/* PEM type */ +__owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file); +__owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +__owur STACK_OF(X509_NAME) +*SSL_load_client_CA_file_ex(const char *file, OSSL_LIB_CTX *libctx, + const char *propq); +__owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); +int SSL_add_store_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *uri); + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define SSL_load_error_strings() \ + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \ + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) +# endif + +__owur const char *SSL_state_string(const SSL *s); +__owur const char *SSL_rstate_string(const SSL *s); +__owur const char *SSL_state_string_long(const SSL *s); +__owur const char *SSL_rstate_string_long(const SSL *s); +__owur long SSL_SESSION_get_time(const SSL_SESSION *s); +__owur long SSL_SESSION_set_time(SSL_SESSION *s, long t); +__owur long SSL_SESSION_get_timeout(const SSL_SESSION *s); +__owur long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +__owur int SSL_SESSION_get_protocol_version(const SSL_SESSION *s); +__owur int SSL_SESSION_set_protocol_version(SSL_SESSION *s, int version); + +__owur const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s); +__owur int SSL_SESSION_set1_hostname(SSL_SESSION *s, const char *hostname); +void SSL_SESSION_get0_alpn_selected(const SSL_SESSION *s, + const unsigned char **alpn, + size_t *len); +__owur int SSL_SESSION_set1_alpn_selected(SSL_SESSION *s, + const unsigned char *alpn, + size_t len); +__owur const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s); +__owur int SSL_SESSION_set_cipher(SSL_SESSION *s, const SSL_CIPHER *cipher); +__owur int SSL_SESSION_has_ticket(const SSL_SESSION *s); +__owur unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s); +void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick, + size_t *len); +__owur uint32_t SSL_SESSION_get_max_early_data(const SSL_SESSION *s); +__owur int SSL_SESSION_set_max_early_data(SSL_SESSION *s, + uint32_t max_early_data); +__owur int SSL_copy_session_id(SSL *to, const SSL *from); +__owur X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +__owur int SSL_SESSION_set1_id_context(SSL_SESSION *s, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); +__owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid, + unsigned int sid_len); +__owur int SSL_SESSION_is_resumable(const SSL_SESSION *s); + +__owur SSL_SESSION *SSL_SESSION_new(void); +__owur SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s, + unsigned int *len); +__owur unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_STDIO +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x); +int SSL_SESSION_up_ref(SSL_SESSION *ses); +void SSL_SESSION_free(SSL_SESSION *ses); +__owur int i2d_SSL_SESSION(const SSL_SESSION *in, unsigned char **pp); +__owur int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); +__owur int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb); +__owur int SSL_set_generate_session_id(SSL *s, GEN_SESSION_CB cb); +__owur int SSL_has_matching_session_id(const SSL *s, + const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef OPENSSL_X509_H +__owur X509 *SSL_get0_peer_certificate(const SSL *s); +__owur X509 *SSL_get1_peer_certificate(const SSL *s); +/* Deprecated in 3.0.0 */ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define SSL_get_peer_certificate SSL_get1_peer_certificate +# endif +# endif + +__owur STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +__owur int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +__owur int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +__owur SSL_verify_cb SSL_CTX_get_verify_callback(const SSL_CTX *ctx); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg); +# ifndef OPENSSL_NO_RSA +__owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +__owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +# endif +__owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +__owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +__owur int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +__owur int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); +__owur int SSL_CTX_use_cert_and_key(SSL_CTX *ctx, X509 *x509, EVP_PKEY *privatekey, + STACK_OF(X509) *chain, int override); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); +pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx); +void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx); +void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb); +void SSL_set_default_passwd_cb_userdata(SSL *s, void *u); +pem_password_cb *SSL_get_default_passwd_cb(SSL *s); +void *SSL_get_default_passwd_cb_userdata(SSL *s); + +__owur int SSL_CTX_check_private_key(const SSL_CTX *ctx); +__owur int SSL_check_private_key(const SSL *ctx); + +__owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_up_ref(SSL *s); +int SSL_is_dtls(const SSL *s); +__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +__owur int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); +__owur int SSL_set_purpose(SSL *ssl, int purpose); +__owur int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); +__owur int SSL_set_trust(SSL *ssl, int trust); + +__owur int SSL_set1_host(SSL *s, const char *hostname); +__owur int SSL_add1_host(SSL *s, const char *hostname); +__owur const char *SSL_get0_peername(SSL *s); +void SSL_set_hostflags(SSL *s, unsigned int flags); + +__owur int SSL_CTX_dane_enable(SSL_CTX *ctx); +__owur int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, + uint8_t mtype, uint8_t ord); +__owur int SSL_dane_enable(SSL *s, const char *basedomain); +__owur int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector, + uint8_t mtype, unsigned const char *data, size_t dlen); +__owur int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki); +__owur int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector, + uint8_t *mtype, unsigned const char **data, + size_t *dlen); +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +SSL_DANE *SSL_get0_dane(SSL *ssl); +/* + * DANE flags + */ +unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags); +unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags); +unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags); + +__owur int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +__owur int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +__owur X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +__owur X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +__owur BIGNUM *SSL_get_srp_g(SSL *s); +__owur BIGNUM *SSL_get_srp_N(SSL *s); + +__owur char *SSL_get_srp_username(SSL *s); +__owur char *SSL_get_srp_userinfo(SSL *s); +# endif + +/* + * ClientHello callback and helpers. + */ + +# define SSL_CLIENT_HELLO_SUCCESS 1 +# define SSL_CLIENT_HELLO_ERROR 0 +# define SSL_CLIENT_HELLO_RETRY (-1) + +typedef int (*SSL_client_hello_cb_fn) (SSL *s, int *al, void *arg); +void SSL_CTX_set_client_hello_cb(SSL_CTX *c, SSL_client_hello_cb_fn cb, + void *arg); +int SSL_client_hello_isv2(SSL *s); +unsigned int SSL_client_hello_get0_legacy_version(SSL *s); +size_t SSL_client_hello_get0_random(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_session_id(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_ciphers(SSL *s, const unsigned char **out); +size_t SSL_client_hello_get0_compression_methods(SSL *s, + const unsigned char **out); +int SSL_client_hello_get1_extensions_present(SSL *s, int **out, size_t *outlen); +int SSL_client_hello_get0_ext(SSL *s, unsigned int type, + const unsigned char **out, size_t *outlen); + +void SSL_certs_clear(SSL *s); +void SSL_free(SSL *ssl); +# ifdef OSSL_ASYNC_FD +/* + * Windows application developer has to include windows.h to use these. + */ +__owur int SSL_waiting_for_async(SSL *s); +__owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds); +__owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, + size_t *numaddfds, OSSL_ASYNC_FD *delfd, + size_t *numdelfds); +__owur int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback); +__owur int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg); +__owur int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback); +__owur int SSL_set_async_callback_arg(SSL *s, void *arg); +__owur int SSL_get_async_status(SSL *s, int *status); + +# endif +__owur int SSL_accept(SSL *ssl); +__owur int SSL_stateless(SSL *s); +__owur int SSL_connect(SSL *ssl); +__owur int SSL_read(SSL *ssl, void *buf, int num); +__owur int SSL_read_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); + +# define SSL_READ_EARLY_DATA_ERROR 0 +# define SSL_READ_EARLY_DATA_SUCCESS 1 +# define SSL_READ_EARLY_DATA_FINISH 2 + +__owur int SSL_read_early_data(SSL *s, void *buf, size_t num, + size_t *readbytes); +__owur int SSL_peek(SSL *ssl, void *buf, int num); +__owur int SSL_peek_ex(SSL *ssl, void *buf, size_t num, size_t *readbytes); +__owur ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, + int flags); +__owur int SSL_write(SSL *ssl, const void *buf, int num); +__owur int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); +__owur int SSL_write_early_data(SSL *s, const void *buf, size_t num, + size_t *written); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +# define SSL_EARLY_DATA_NOT_SENT 0 +# define SSL_EARLY_DATA_REJECTED 1 +# define SSL_EARLY_DATA_ACCEPTED 2 + +__owur int SSL_get_early_data_status(const SSL *s); + +__owur int SSL_get_error(const SSL *s, int ret_code); +__owur const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +DEPRECATEDIN_3_0(__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)) + +# ifndef OPENSSL_NO_SSL3_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_method(void)) /* SSLv3 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_client_method(void)) +# endif + +#define SSLv23_method TLS_method +#define SSLv23_server_method TLS_server_method +#define SSLv23_client_method TLS_client_method + +/* Negotiate highest available SSL/TLS version */ +__owur const SSL_METHOD *TLS_method(void); +__owur const SSL_METHOD *TLS_server_method(void); +__owur const SSL_METHOD *TLS_client_method(void); + +# ifndef OPENSSL_NO_TLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_method(void)) /* TLSv1.1 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_TLS1_2_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_method(void)) /* TLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_METHOD +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_client_method(void)) +# endif + +# ifndef OPENSSL_NO_DTLS1_2_METHOD +/* DTLSv1.2 */ +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_server_method(void)) +DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_client_method(void)) +# endif + +__owur const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ +__owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ + +__owur size_t DTLS_get_data_mtu(const SSL *s); + +__owur STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); +__owur STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s); +__owur STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s); + +__owur int SSL_do_handshake(SSL *s); +int SSL_key_update(SSL *s, int updatetype); +int SSL_get_key_update_type(const SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +__owur int SSL_renegotiate_pending(const SSL *s); +int SSL_new_session_ticket(SSL *s); +int SSL_shutdown(SSL *s); +__owur int SSL_verify_client_post_handshake(SSL *s); +void SSL_CTX_set_post_handshake_auth(SSL_CTX *ctx, int val); +void SSL_set_post_handshake_auth(SSL *s, int val); + +__owur const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx); +__owur const SSL_METHOD *SSL_get_ssl_method(const SSL *s); +__owur int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +__owur const char *SSL_alert_type_string_long(int value); +__owur const char *SSL_alert_type_string(int value); +__owur const char *SSL_alert_desc_string_long(int value); +__owur const char *SSL_alert_desc_string(int value); + +void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s); +__owur const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx); +__owur int SSL_add1_to_CA_list(SSL *ssl, const X509 *x); +__owur int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x); +__owur const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +__owur STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +__owur STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +__owur int SSL_add_client_CA(SSL *ssl, X509 *x); +__owur int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +__owur long SSL_get_default_timeout(const SSL *s); + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define SSL_library_init() OPENSSL_init_ssl(0, NULL) +# endif + +__owur char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk); + +__owur SSL *SSL_dup(SSL *ssl); + +__owur X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ +struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +__owur X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +__owur EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +__owur int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +__owur int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +__owur int SSL_get_shutdown(const SSL *ssl); +__owur int SSL_version(const SSL *ssl); +__owur int SSL_client_version(const SSL *s); +__owur int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); +__owur int SSL_CTX_set_default_verify_store(SSL_CTX *ctx); +__owur int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile); +__owur int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath); +__owur int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore); +__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, + const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +__owur SSL_SESSION *SSL_get_session(const SSL *ssl); +__owur SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +__owur SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +__owur OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); + +void SSL_set_verify_result(SSL *ssl, long v); +__owur long SSL_get_verify_result(const SSL *ssl); +__owur STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s); + +__owur size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, + size_t outlen); +__owur size_t SSL_SESSION_get_master_key(const SSL_SESSION *sess, + unsigned char *out, size_t outlen); +__owur int SSL_SESSION_set1_master_key(SSL_SESSION *sess, + const unsigned char *in, size_t len); +uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *sess); + +#define SSL_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, l, p, newf, dupf, freef) +__owur int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +#define SSL_SESSION_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, l, p, newf, dupf, freef) +__owur int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +#define SSL_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef) +__owur int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); + +__owur int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_split_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_set_split_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL) +# define SSL_CTX_set_max_pipelines(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) +# define SSL_set_max_pipelines(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_PIPELINES,m,NULL) + +void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); +void SSL_set_default_read_buffer_len(SSL *s, size_t len); + +# ifndef OPENSSL_NO_DH +/* NB: the |keylength| is only applicable when is_export is true */ +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif + +__owur const COMP_METHOD *SSL_get_current_compression(const SSL *s); +__owur const COMP_METHOD *SSL_get_current_expansion(const SSL *s); +__owur const char *SSL_COMP_get_name(const COMP_METHOD *comp); +__owur const char *SSL_COMP_get0_name(const SSL_COMP *comp); +__owur int SSL_COMP_get_id(const SSL_COMP *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +__owur STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths); +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define SSL_COMP_free_compression_methods() while(0) continue +# endif +__owur int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c); +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c); +int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, + int isv2format, STACK_OF(SSL_CIPHER) **sk, + STACK_OF(SSL_CIPHER) **scsvs); + +/* TLS extensions functions */ +__owur int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +__owur int SSL_set_session_ticket_ext_cb(SSL *s, + tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +__owur int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn session_secret_cb, + void *arg); + +void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + int + is_forward_secure)); + +void SSL_set_not_resumable_session_callback(SSL *ssl, + int (*cb) (SSL *ssl, + int is_forward_secure)); + +void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); +void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); +int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); + +int SSL_set_record_padding_callback(SSL *ssl, + size_t (*cb) (SSL *ssl, int type, + size_t len, void *arg)); +void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); +void *SSL_get_record_padding_callback_arg(const SSL *ssl); +int SSL_set_block_padding(SSL *ssl, size_t block_size); + +int SSL_set_num_tickets(SSL *s, size_t num_tickets); +size_t SSL_get_num_tickets(const SSL *s); +int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); +size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx); + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define SSL_cache_hit(s) SSL_session_reused(s) +# endif + +__owur int SSL_session_reused(const SSL *s); +__owur int SSL_is_server(const SSL *s); + +__owur __owur SSL_CONF_CTX *SSL_CONF_CTX_new(void); +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +__owur unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, + unsigned int flags); +__owur int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +__owur int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); +__owur int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); +__owur int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); + +void SSL_add_ssl_module(void); +int SSL_config(SSL *s, const char *name); +int SSL_CTX_config(SSL_CTX *ctx, const char *name); + +# ifndef OPENSSL_NO_SSL_TRACE +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); +# endif + +# ifndef OPENSSL_NO_SOCK +int DTLSv1_listen(SSL *s, BIO_ADDR *client); +# endif + +# ifndef OPENSSL_NO_CT + +/* + * A callback for verifying that the received SCTs are sufficient. + * Expected to return 1 if they are sufficient, otherwise 0. + * May return a negative integer if an error occurs. + * A connection should be aborted if the SCTs are deemed insufficient. + */ +typedef int (*ssl_ct_validation_cb)(const CT_POLICY_EVAL_CTX *ctx, + const STACK_OF(SCT) *scts, void *arg); + +/* + * Sets a |callback| that is invoked upon receipt of ServerHelloDone to validate + * the received SCTs. + * If the callback returns a non-positive result, the connection is terminated. + * Call this function before beginning a handshake. + * If a NULL |callback| is provided, SCT validation is disabled. + * |arg| is arbitrary userdata that will be passed to the callback whenever it + * is invoked. Ownership of |arg| remains with the caller. + * + * NOTE: A side-effect of setting a CT callback is that an OCSP stapled response + * will be requested. + */ +int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback, + void *arg); +int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx, + ssl_ct_validation_cb callback, + void *arg); +#define SSL_disable_ct(s) \ + ((void) SSL_set_validation_callback((s), NULL, NULL)) +#define SSL_CTX_disable_ct(ctx) \ + ((void) SSL_CTX_set_validation_callback((ctx), NULL, NULL)) + +/* + * The validation type enumerates the available behaviours of the built-in SSL + * CT validation callback selected via SSL_enable_ct() and SSL_CTX_enable_ct(). + * The underlying callback is a static function in libssl. + */ +enum { + SSL_CT_VALIDATION_PERMISSIVE = 0, + SSL_CT_VALIDATION_STRICT +}; + +/* + * Enable CT by setting up a callback that implements one of the built-in + * validation variants. The SSL_CT_VALIDATION_PERMISSIVE variant always + * continues the handshake, the application can make appropriate decisions at + * handshake completion. The SSL_CT_VALIDATION_STRICT variant requires at + * least one valid SCT, or else handshake termination will be requested. The + * handshake may continue anyway if SSL_VERIFY_NONE is in effect. + */ +int SSL_enable_ct(SSL *s, int validation_mode); +int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode); + +/* + * Report whether a non-NULL callback is enabled. + */ +int SSL_ct_is_enabled(const SSL *s); +int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx); + +/* Gets the SCTs received from a connection */ +const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s); + +/* + * Loads the CT log list from the default location. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx); + +/* + * Loads the CT log list from the specified file path. + * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store, + * the log information loaded from this file will be appended to the + * CTLOG_STORE. + * Returns 1 on success, 0 otherwise. + */ +int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path); + +/* + * Sets the CT log list used by all SSL connections created from this SSL_CTX. + * Ownership of the CTLOG_STORE is transferred to the SSL_CTX. + */ +void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs); + +/* + * Gets the CT log list used by all SSL connections created from this SSL_CTX. + * This will be NULL unless one of the following functions has been called: + * - SSL_CTX_set_default_ctlog_list_file + * - SSL_CTX_set_ctlog_list_file + * - SSL_CTX_set_ctlog_store + */ +const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx); + +# endif /* OPENSSL_NO_CT */ + +/* What the "other" parameter contains in security callback */ +/* Mask for type */ +# define SSL_SECOP_OTHER_TYPE 0xffff0000 +# define SSL_SECOP_OTHER_NONE 0 +# define SSL_SECOP_OTHER_CIPHER (1 << 16) +# define SSL_SECOP_OTHER_CURVE (2 << 16) +# define SSL_SECOP_OTHER_DH (3 << 16) +# define SSL_SECOP_OTHER_PKEY (4 << 16) +# define SSL_SECOP_OTHER_SIGALG (5 << 16) +# define SSL_SECOP_OTHER_CERT (6 << 16) + +/* Indicated operation refers to peer key or certificate */ +# define SSL_SECOP_PEER 0x1000 + +/* Values for "op" parameter in security callback */ + +/* Called to filter ciphers */ +/* Ciphers client supports */ +# define SSL_SECOP_CIPHER_SUPPORTED (1 | SSL_SECOP_OTHER_CIPHER) +/* Cipher shared by client/server */ +# define SSL_SECOP_CIPHER_SHARED (2 | SSL_SECOP_OTHER_CIPHER) +/* Sanity check of cipher server selects */ +# define SSL_SECOP_CIPHER_CHECK (3 | SSL_SECOP_OTHER_CIPHER) +/* Curves supported by client */ +# define SSL_SECOP_CURVE_SUPPORTED (4 | SSL_SECOP_OTHER_CURVE) +/* Curves shared by client/server */ +# define SSL_SECOP_CURVE_SHARED (5 | SSL_SECOP_OTHER_CURVE) +/* Sanity check of curve server selects */ +# define SSL_SECOP_CURVE_CHECK (6 | SSL_SECOP_OTHER_CURVE) +/* Temporary DH key */ +# define SSL_SECOP_TMP_DH (7 | SSL_SECOP_OTHER_PKEY) +/* SSL/TLS version */ +# define SSL_SECOP_VERSION (9 | SSL_SECOP_OTHER_NONE) +/* Session tickets */ +# define SSL_SECOP_TICKET (10 | SSL_SECOP_OTHER_NONE) +/* Supported signature algorithms sent to peer */ +# define SSL_SECOP_SIGALG_SUPPORTED (11 | SSL_SECOP_OTHER_SIGALG) +/* Shared signature algorithm */ +# define SSL_SECOP_SIGALG_SHARED (12 | SSL_SECOP_OTHER_SIGALG) +/* Sanity check signature algorithm allowed */ +# define SSL_SECOP_SIGALG_CHECK (13 | SSL_SECOP_OTHER_SIGALG) +/* Used to get mask of supported public key signature algorithms */ +# define SSL_SECOP_SIGALG_MASK (14 | SSL_SECOP_OTHER_SIGALG) +/* Use to see if compression is allowed */ +# define SSL_SECOP_COMPRESSION (15 | SSL_SECOP_OTHER_NONE) +/* EE key in certificate */ +# define SSL_SECOP_EE_KEY (16 | SSL_SECOP_OTHER_CERT) +/* CA key in certificate */ +# define SSL_SECOP_CA_KEY (17 | SSL_SECOP_OTHER_CERT) +/* CA digest algorithm in certificate */ +# define SSL_SECOP_CA_MD (18 | SSL_SECOP_OTHER_CERT) +/* Peer EE key in certificate */ +# define SSL_SECOP_PEER_EE_KEY (SSL_SECOP_EE_KEY | SSL_SECOP_PEER) +/* Peer CA key in certificate */ +# define SSL_SECOP_PEER_CA_KEY (SSL_SECOP_CA_KEY | SSL_SECOP_PEER) +/* Peer CA digest algorithm in certificate */ +# define SSL_SECOP_PEER_CA_MD (SSL_SECOP_CA_MD | SSL_SECOP_PEER) + +void SSL_set_security_level(SSL *s, int level); +__owur int SSL_get_security_level(const SSL *s); +void SSL_set_security_callback(SSL *s, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, + const SSL_CTX *ctx, int op, + int bits, int nid, void *other, + void *ex); +void SSL_set0_security_ex_data(SSL *s, void *ex); +__owur void *SSL_get0_security_ex_data(const SSL *s); + +void SSL_CTX_set_security_level(SSL_CTX *ctx, int level); +__owur int SSL_CTX_get_security_level(const SSL_CTX *ctx); +void SSL_CTX_set_security_callback(SSL_CTX *ctx, + int (*cb) (const SSL *s, const SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex)); +int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx)) (const SSL *s, + const SSL_CTX *ctx, + int op, int bits, + int nid, + void *other, + void *ex); +void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex); +__owur void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx); + +/* OPENSSL_INIT flag 0x010000 reserved for internal use */ +# define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0x00100000L +# define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L + +# define OPENSSL_INIT_SSL_DEFAULT \ + (OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS) + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); + +# ifndef OPENSSL_NO_UNIT_TEST +__owur const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +__owur int SSL_free_buffers(SSL *ssl); +__owur int SSL_alloc_buffers(SSL *ssl); + +/* Status codes passed to the decrypt session ticket callback. Some of these + * are for internal use only and are never passed to the callback. */ +typedef int SSL_TICKET_STATUS; + +/* Support for ticket appdata */ +/* fatal error, malloc failure */ +# define SSL_TICKET_FATAL_ERR_MALLOC 0 +/* fatal error, either from parsing or decrypting the ticket */ +# define SSL_TICKET_FATAL_ERR_OTHER 1 +/* No ticket present */ +# define SSL_TICKET_NONE 2 +/* Empty ticket present */ +# define SSL_TICKET_EMPTY 3 +/* the ticket couldn't be decrypted */ +# define SSL_TICKET_NO_DECRYPT 4 +/* a ticket was successfully decrypted */ +# define SSL_TICKET_SUCCESS 5 +/* same as above but the ticket needs to be renewed */ +# define SSL_TICKET_SUCCESS_RENEW 6 + +/* Return codes for the decrypt session ticket callback */ +typedef int SSL_TICKET_RETURN; + +/* An error occurred */ +#define SSL_TICKET_RETURN_ABORT 0 +/* Do not use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE 1 +/* Do not use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_IGNORE_RENEW 2 +/* Use the ticket, do not send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE 3 +/* Use the ticket, send a renewed ticket to the client */ +#define SSL_TICKET_RETURN_USE_RENEW 4 + +typedef int (*SSL_CTX_generate_session_ticket_fn)(SSL *s, void *arg); +typedef SSL_TICKET_RETURN (*SSL_CTX_decrypt_session_ticket_fn)(SSL *s, SSL_SESSION *ss, + const unsigned char *keyname, + size_t keyname_length, + SSL_TICKET_STATUS status, + void *arg); +int SSL_CTX_set_session_ticket_cb(SSL_CTX *ctx, + SSL_CTX_generate_session_ticket_fn gen_cb, + SSL_CTX_decrypt_session_ticket_fn dec_cb, + void *arg); +int SSL_SESSION_set1_ticket_appdata(SSL_SESSION *ss, const void *data, size_t len); +int SSL_SESSION_get0_ticket_appdata(SSL_SESSION *ss, void **data, size_t *len); + +typedef unsigned int (*DTLS_timer_cb)(SSL *s, unsigned int timer_us); + +void DTLS_set_timer_cb(SSL *s, DTLS_timer_cb cb); + + +typedef int (*SSL_allow_early_data_cb_fn)(SSL *s, void *arg); +void SSL_CTX_set_allow_early_data_cb(SSL_CTX *ctx, + SSL_allow_early_data_cb_fn cb, + void *arg); +void SSL_set_allow_early_data_cb(SSL *s, + SSL_allow_early_data_cb_fn cb, + void *arg); + +/* store the default cipher strings inside the library */ +const char *OSSL_default_cipher_list(void); +const char *OSSL_default_ciphersuites(void); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index c15a17f96f..56ece0d175 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -183,11 +183,13 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 0 # define SSL_F_SSL_DANE_DUP 0 # define SSL_F_SSL_DANE_ENABLE 0 +# define SSL_F_SSL_DECAPSULATE 0 # define SSL_F_SSL_DERIVE 0 # define SSL_F_SSL_DO_CONFIG 0 # define SSL_F_SSL_DO_HANDSHAKE 0 # define SSL_F_SSL_DUP_CA_LIST 0 # define SSL_F_SSL_ENABLE_CT 0 +# define SSL_F_SSL_ENCAPSULATE 0 # define SSL_F_SSL_GENERATE_PKEY_GROUP 0 # define SSL_F_SSL_GENERATE_SESSION_ID 0 # define SSL_F_SSL_GET_NEW_SESSION 0 @@ -634,6 +636,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_NO_SHARED_GROUPS 410 # define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS 376 # define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_SUITABLE_DIGEST_ALGORITHM 297 # define SSL_R_NO_SUITABLE_KEY_SHARE 101 # define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 # define SSL_R_NO_VALID_SCTS 216 diff --git a/include/openssl/store.h b/include/openssl/store.h index d5e72a0963..8be9f71bf3 100644 --- a/include/openssl/store.h +++ b/include/openssl/store.h @@ -52,15 +52,15 @@ typedef OSSL_STORE_INFO *(*OSSL_STORE_post_process_info_fn)(OSSL_STORE_INFO *, * Returns a context reference which represents the channel to communicate * through. */ -OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, - void *ui_data, - OSSL_STORE_post_process_info_fn post_process, - void *post_process_data); - -OSSL_STORE_CTX *OSSL_STORE_open_with_libctx - (const char *uri, OPENSSL_CTX *libctx, const char *propq, - const UI_METHOD *ui_method, void *ui_data, - OSSL_STORE_post_process_info_fn post_process, void *post_process_data); +OSSL_STORE_CTX * +OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data); +OSSL_STORE_CTX * +OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data); /* * Control / fine tune the OSSL_STORE channel. |cmd| determines what is to be @@ -68,8 +68,12 @@ OSSL_STORE_CTX *OSSL_STORE_open_with_libctx * determine which loader is used), except for common commands (see below). * Each command takes different arguments. */ -int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */); -int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args); +DEPRECATEDIN_3_0(int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, + ... /* args */)) +DEPRECATEDIN_3_0(int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, + va_list args)) + +# ifndef OPENSSL_NO_DEPRECATED_3_0 /* * Common ctrl commands that different loaders may choose to support. @@ -79,6 +83,8 @@ int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args); /* Where custom commands start */ # define OSSL_STORE_C_CUSTOM_START 100 +# endif + /* * Read one data item (a key, a cert, a CRL) that is supported by the OSSL_STORE * functionality, given a context. @@ -121,7 +127,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx); * BIO actually reads. */ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, const char *scheme, - OPENSSL_CTX *libctx, const char *propq, + OSSL_LIB_CTX *libctx, const char *propq, const UI_METHOD *ui_method, void *ui_data, OSSL_STORE_post_process_info_fn post_process, void *post_process_data); @@ -138,9 +144,10 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, const char *scheme, */ # define OSSL_STORE_INFO_NAME 1 /* char * */ # define OSSL_STORE_INFO_PARAMS 2 /* EVP_PKEY * */ -# define OSSL_STORE_INFO_PKEY 3 /* EVP_PKEY * */ -# define OSSL_STORE_INFO_CERT 4 /* X509 * */ -# define OSSL_STORE_INFO_CRL 5 /* X509_CRL * */ +# define OSSL_STORE_INFO_PUBKEY 3 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_PKEY 4 /* EVP_PKEY * */ +# define OSSL_STORE_INFO_CERT 5 /* X509 * */ +# define OSSL_STORE_INFO_CRL 6 /* X509_CRL * */ /* * Functions to generate OSSL_STORE_INFOs, one function for each type we @@ -149,9 +156,11 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, const char *scheme, * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO * and will therefore be freed when the OSSL_STORE_INFO is freed. */ +OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data); OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name); int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc); OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params); +OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pubkey); OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey); OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509); OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl); @@ -160,12 +169,15 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl); * Functions to try to extract data from a OSSL_STORE_INFO. */ int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info); +void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info); const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info); char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info); const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info); char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info); EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info); EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info); +EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info); EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info); EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info); X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info); @@ -230,6 +242,32 @@ int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type); int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search); +/*- + * Function to fetch a loader and extract data from it + * --------------------------------------------------- + */ + +typedef struct ossl_store_loader_st OSSL_STORE_LOADER; + +OSSL_STORE_LOADER *OSSL_STORE_LOADER_fetch(const char *scheme, + OSSL_LIB_CTX *libctx, + const char *properties); +int OSSL_STORE_LOADER_up_ref(OSSL_STORE_LOADER *loader); +void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader); +const OSSL_PROVIDER *OSSL_STORE_LOADER_provider(const OSSL_STORE_LOADER * + loader); +const char *OSSL_STORE_LOADER_properties(const OSSL_STORE_LOADER *loader); +int OSSL_STORE_LOADER_number(const OSSL_STORE_LOADER *loader); +int OSSL_STORE_LOADER_is_a(const OSSL_STORE_LOADER *loader, + const char *scheme); +void OSSL_STORE_LOADER_do_all_provided(OSSL_LIB_CTX *libctx, + void (*fn)(OSSL_STORE_LOADER *loader, + void *arg), + void *arg); +void OSSL_STORE_LOADER_names_do_all(const OSSL_STORE_LOADER *loader, + void (*fn)(const char *name, void *data), + void *data); + /*- * Function to register a loader for the given URI scheme. * ------------------------------------------------------- @@ -238,66 +276,86 @@ int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search); * scheme. */ -typedef struct ossl_store_loader_st OSSL_STORE_LOADER; -OSSL_STORE_LOADER *OSSL_STORE_LOADER_new(ENGINE *e, const char *scheme); -const ENGINE *OSSL_STORE_LOADER_get0_engine(const OSSL_STORE_LOADER *loader); -const char *OSSL_STORE_LOADER_get0_scheme(const OSSL_STORE_LOADER *loader); +# ifndef OPENSSL_NO_DEPRECATED_3_0 + /* struct ossl_store_loader_ctx_st is defined differently by each loader */ typedef struct ossl_store_loader_ctx_st OSSL_STORE_LOADER_CTX; typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn) (const OSSL_STORE_LOADER *loader, const char *uri, const UI_METHOD *ui_method, void *ui_data); -typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_with_libctx_fn) +typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_ex_fn) (const OSSL_STORE_LOADER *loader, - const char *uri, OPENSSL_CTX *libctx, const char *propq, + const char *uri, OSSL_LIB_CTX *libctx, const char *propq, const UI_METHOD *ui_method, void *ui_data); -int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, - OSSL_STORE_open_fn open_function); typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn) (const OSSL_STORE_LOADER *loader, BIO *bio, - OPENSSL_CTX *libctx, const char *propq, + OSSL_LIB_CTX *libctx, const char *propq, const UI_METHOD *ui_method, void *ui_data); -int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader, - OSSL_STORE_attach_fn attach_function); -typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd, - va_list args); -int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, - OSSL_STORE_ctrl_fn ctrl_function); -typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected); -int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader, - OSSL_STORE_expect_fn expect_function); -typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx, - const OSSL_STORE_SEARCH *criteria); -int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader, - OSSL_STORE_find_fn find_function); -typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx, - const UI_METHOD *ui_method, - void *ui_data); -int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader, - OSSL_STORE_load_fn load_function); - +typedef int (*OSSL_STORE_ctrl_fn) + (OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args); +typedef int (*OSSL_STORE_expect_fn) + (OSSL_STORE_LOADER_CTX *ctx, int expected); +typedef int (*OSSL_STORE_find_fn) + (OSSL_STORE_LOADER_CTX *ctx, const OSSL_STORE_SEARCH *criteria); +typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn) + (OSSL_STORE_LOADER_CTX *ctx, const UI_METHOD *ui_method, void *ui_data); typedef int (*OSSL_STORE_eof_fn)(OSSL_STORE_LOADER_CTX *ctx); -int OSSL_STORE_LOADER_set_eof(OSSL_STORE_LOADER *loader, - OSSL_STORE_eof_fn eof_function); typedef int (*OSSL_STORE_error_fn)(OSSL_STORE_LOADER_CTX *ctx); -int OSSL_STORE_LOADER_set_error(OSSL_STORE_LOADER *loader, - OSSL_STORE_error_fn error_function); typedef int (*OSSL_STORE_close_fn)(OSSL_STORE_LOADER_CTX *ctx); -int OSSL_STORE_LOADER_set_close(OSSL_STORE_LOADER *loader, - OSSL_STORE_close_fn close_function); -void OSSL_STORE_LOADER_free(OSSL_STORE_LOADER *loader); -int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader); -OSSL_STORE_LOADER *OSSL_STORE_unregister_loader(const char *scheme); +# endif + +DEPRECATEDIN_3_0(OSSL_STORE_LOADER *OSSL_STORE_LOADER_new + (ENGINE *e, const char *scheme)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_open + (OSSL_STORE_LOADER *loader, + OSSL_STORE_open_fn open_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_open_ex + (OSSL_STORE_LOADER *loader, + OSSL_STORE_open_ex_fn open_ex_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_attach + (OSSL_STORE_LOADER *loader, + OSSL_STORE_attach_fn attach_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_ctrl + (OSSL_STORE_LOADER *loader, + OSSL_STORE_ctrl_fn ctrl_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_expect + (OSSL_STORE_LOADER *loader, + OSSL_STORE_expect_fn expect_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_find + (OSSL_STORE_LOADER *loader, + OSSL_STORE_find_fn find_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_load + (OSSL_STORE_LOADER *loader, + OSSL_STORE_load_fn load_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_eof + (OSSL_STORE_LOADER *loader, + OSSL_STORE_eof_fn eof_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_error + (OSSL_STORE_LOADER *loader, + OSSL_STORE_error_fn error_function)) +DEPRECATEDIN_3_0(int OSSL_STORE_LOADER_set_close + (OSSL_STORE_LOADER *loader, + OSSL_STORE_close_fn close_function)) + +DEPRECATEDIN_3_0(const ENGINE *OSSL_STORE_LOADER_get0_engine + (const OSSL_STORE_LOADER *loader)) +DEPRECATEDIN_3_0(const char * OSSL_STORE_LOADER_get0_scheme + (const OSSL_STORE_LOADER *loader)) + +DEPRECATEDIN_3_0(int OSSL_STORE_register_loader(OSSL_STORE_LOADER *loader)) +DEPRECATEDIN_3_0(OSSL_STORE_LOADER *OSSL_STORE_unregister_loader + (const char *scheme)) /*- * Functions to list STORE loaders * ------------------------------- */ -int OSSL_STORE_do_all_loaders(void (*do_function) (const OSSL_STORE_LOADER - *loader, void *do_arg), - void *do_arg); +DEPRECATEDIN_3_0(int OSSL_STORE_do_all_loaders + (void (*do_function)(const OSSL_STORE_LOADER *loader, + void *do_arg), + void *do_arg)) # ifdef __cplusplus } diff --git a/include/openssl/storeerr.h b/include/openssl/storeerr.h index ed8f7988fe..5213a0b33c 100644 --- a/include/openssl/storeerr.h +++ b/include/openssl/storeerr.h @@ -78,8 +78,9 @@ int ERR_load_OSSL_STORE_strings(void); # define OSSL_STORE_R_LOADING_STARTED 117 # define OSSL_STORE_R_NOT_A_CERTIFICATE 100 # define OSSL_STORE_R_NOT_A_CRL 101 -# define OSSL_STORE_R_NOT_A_KEY 102 # define OSSL_STORE_R_NOT_A_NAME 103 +# define OSSL_STORE_R_NOT_A_PRIVATE_KEY 102 +# define OSSL_STORE_R_NOT_A_PUBLIC_KEY 122 # define OSSL_STORE_R_NOT_PARAMETERS 104 # define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114 # define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108 diff --git a/include/openssl/ts.h b/include/openssl/ts.h index 48cea0f503..e88ad44cfd 100644 --- a/include/openssl/ts.h +++ b/include/openssl/ts.h @@ -486,7 +486,7 @@ int TS_CONF_set_def_policy(CONF *conf, const char *section, int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); -int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, +int TS_CONF_set_clock_precision_digits(const CONF *conf, const char *section, TS_RESP_CTX *ctx); int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); diff --git a/include/openssl/types.h b/include/openssl/types.h index 496f42a101..8ca2d144c7 100644 --- a/include/openssl/types.h +++ b/include/openssl/types.h @@ -123,6 +123,8 @@ typedef struct evp_signature_st EVP_SIGNATURE; typedef struct evp_asym_cipher_st EVP_ASYM_CIPHER; +typedef struct evp_kem_st EVP_KEM; + typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX; typedef struct hmac_ctx_st HMAC_CTX; @@ -202,7 +204,7 @@ typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX; typedef struct ossl_store_info_st OSSL_STORE_INFO; typedef struct ossl_store_search_st OSSL_STORE_SEARCH; -typedef struct openssl_ctx_st OPENSSL_CTX; +typedef struct ossl_lib_ctx_st OSSL_LIB_CTX; typedef struct ossl_dispatch_st OSSL_DISPATCH; typedef struct ossl_item_st OSSL_ITEM; @@ -212,10 +214,10 @@ typedef struct ossl_param_bld_st OSSL_PARAM_BLD; typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); -typedef struct ossl_serializer_st OSSL_SERIALIZER; -typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX; -typedef struct ossl_deserializer_st OSSL_DESERIALIZER; -typedef struct ossl_deserializer_ctx_st OSSL_DESERIALIZER_CTX; +typedef struct ossl_encoder_st OSSL_ENCODER; +typedef struct ossl_encoder_ctx_st OSSL_ENCODER_CTX; +typedef struct ossl_decoder_st OSSL_DECODER; +typedef struct ossl_decoder_ctx_st OSSL_DECODER_CTX; typedef struct ossl_self_test_st OSSL_SELF_TEST; diff --git a/include/openssl/ui.h b/include/openssl/ui.h index fa55d92ac8..e702406eb8 100644 --- a/include/openssl/ui.h +++ b/include/openssl/ui.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/ui.h.in + * * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_UI_H # define OPENSSL_UI_H # pragma once @@ -138,25 +143,26 @@ int UI_dup_error_string(UI *ui, const char *text); # define UI_INPUT_FLAG_USER_BASE 16 /*- - * The following function helps construct a prompt. object_desc is a - * textual short description of the object, for example "pass phrase", - * and object_name is the name of the object (might be a card name or - * a file name. + * The following function helps construct a prompt. + * phrase_desc is a textual short description of the phrase to enter, + * for example "pass phrase", and + * object_name is the name of the object + * (which might be a card name or a file name) or NULL. * The returned string shall always be allocated on the heap with * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). * * If the ui_method doesn't contain a pointer to a user-defined prompt * constructor, a default string is built, looking like this: * - * "Enter {object_desc} for {object_name}:" + * "Enter {phrase_desc} for {object_name}:" * - * So, if object_desc has the value "pass phrase" and object_name has + * So, if phrase_desc has the value "pass phrase" and object_name has * the value "foo.key", the resulting string is: * * "Enter pass phrase for foo.key:" */ char *UI_construct_prompt(UI *ui_method, - const char *object_desc, const char *object_name); + const char *phrase_desc, const char *object_name); /* * The following function is used to store a pointer to user-specific data. @@ -284,7 +290,32 @@ const UI_METHOD *UI_null(void); */ typedef struct ui_string_st UI_STRING; -DEFINE_OR_DECLARE_STACK_OF(UI_STRING) +SKM_DEFINE_STACK_OF_INTERNAL(UI_STRING, UI_STRING, UI_STRING) +#define sk_UI_STRING_num(sk) OPENSSL_sk_num(ossl_check_const_UI_STRING_sk_type(sk)) +#define sk_UI_STRING_value(sk, idx) ((UI_STRING *)OPENSSL_sk_value(ossl_check_const_UI_STRING_sk_type(sk), (idx))) +#define sk_UI_STRING_new(cmp) ((STACK_OF(UI_STRING) *)OPENSSL_sk_new(ossl_check_UI_STRING_compfunc_type(cmp))) +#define sk_UI_STRING_new_null() ((STACK_OF(UI_STRING) *)OPENSSL_sk_new_null()) +#define sk_UI_STRING_new_reserve(cmp, n) ((STACK_OF(UI_STRING) *)OPENSSL_sk_new_reserve(ossl_check_UI_STRING_compfunc_type(cmp), (n))) +#define sk_UI_STRING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_UI_STRING_sk_type(sk), (n)) +#define sk_UI_STRING_free(sk) OPENSSL_sk_free(ossl_check_UI_STRING_sk_type(sk)) +#define sk_UI_STRING_zero(sk) OPENSSL_sk_zero(ossl_check_UI_STRING_sk_type(sk)) +#define sk_UI_STRING_delete(sk, i) ((UI_STRING *)OPENSSL_sk_delete(ossl_check_UI_STRING_sk_type(sk), (i))) +#define sk_UI_STRING_delete_ptr(sk, ptr) ((UI_STRING *)OPENSSL_sk_delete_ptr(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_type(ptr))) +#define sk_UI_STRING_push(sk, ptr) OPENSSL_sk_push(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_type(ptr)) +#define sk_UI_STRING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_type(ptr)) +#define sk_UI_STRING_pop(sk) ((UI_STRING *)OPENSSL_sk_pop(ossl_check_UI_STRING_sk_type(sk))) +#define sk_UI_STRING_shift(sk) ((UI_STRING *)OPENSSL_sk_shift(ossl_check_UI_STRING_sk_type(sk))) +#define sk_UI_STRING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_UI_STRING_sk_type(sk),ossl_check_UI_STRING_freefunc_type(freefunc)) +#define sk_UI_STRING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_type(ptr), (idx)) +#define sk_UI_STRING_set(sk, idx, ptr) ((UI_STRING *)OPENSSL_sk_set(ossl_check_UI_STRING_sk_type(sk), (idx), ossl_check_UI_STRING_type(ptr))) +#define sk_UI_STRING_find(sk, ptr) OPENSSL_sk_find(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_type(ptr)) +#define sk_UI_STRING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_type(ptr)) +#define sk_UI_STRING_sort(sk) OPENSSL_sk_sort(ossl_check_UI_STRING_sk_type(sk)) +#define sk_UI_STRING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_UI_STRING_sk_type(sk)) +#define sk_UI_STRING_dup(sk) ((STACK_OF(UI_STRING) *)OPENSSL_sk_dup(ossl_check_const_UI_STRING_sk_type(sk))) +#define sk_UI_STRING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(UI_STRING) *)OPENSSL_sk_deep_copy(ossl_check_const_UI_STRING_sk_type(sk), ossl_check_UI_STRING_copyfunc_type(copyfunc), ossl_check_UI_STRING_freefunc_type(freefunc))) +#define sk_UI_STRING_set_cmp_func(sk, cmp) ((sk_UI_STRING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_UI_STRING_sk_type(sk), ossl_check_UI_STRING_compfunc_type(cmp))) + /* * The different types of strings that are currently supported. This is only @@ -315,7 +346,7 @@ int UI_method_set_data_duplicator(UI_METHOD *method, int UI_method_set_prompt_constructor(UI_METHOD *method, char *(*prompt_constructor) (UI *ui, const char - *object_desc, + *phrase_desc, const char *object_name)); int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data); diff --git a/include/openssl/ui.h.in b/include/openssl/ui.h.in new file mode 100644 index 0000000000..eb9a580fa8 --- /dev/null +++ b/include/openssl/ui.h.in @@ -0,0 +1,384 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_UI_H +# define OPENSSL_UI_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_UI_H +# endif + +# include + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# include +# endif +# include +# include +# include +# include + +/* For compatibility reasons, the macro OPENSSL_NO_UI is currently retained */ +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifdef OPENSSL_NO_UI_CONSOLE +# define OPENSSL_NO_UI +# endif +# endif + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is useful when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. + * phrase_desc is a textual short description of the phrase to enter, + * for example "pass phrase", and + * object_name is the name of the object + * (which might be a card name or a file name) or NULL. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {phrase_desc} for {object_name}:" + * + * So, if phrase_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *phrase_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* + * Alternatively, this function is used to duplicate the user data. + * This uses the duplicator method function. The destroy function will + * be used to free the user data in this case. + */ +int UI_dup_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); +int UI_get_result_length(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parameterised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) + +# define UI_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, l, p, newf, dupf, freef) +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(const UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +# ifndef OPENSSL_NO_UI_CONSOLE + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +# endif + +/* + * NULL method. Literally does nothing, but may serve as a placeholder + * to avoid internal default. + */ +const UI_METHOD *UI_null(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called with all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; + +{- + generate_stack_macros("UI_STRING"); +-} + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(const char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_data_duplicator(UI_METHOD *method, + void *(*duplicator) (UI *ui, void *ui_data), + void (*destructor)(UI *ui, void *ui_data)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *phrase_desc, + const char + *object_name)); +int UI_method_set_ex_data(UI_METHOD *method, int idx, void *data); +int (*UI_method_get_opener(const UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(const UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(const UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(const UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(const UI_METHOD *method)) + (UI *, const char *, const char *); +void *(*UI_method_get_data_duplicator(const UI_METHOD *method)) (UI *, void *); +void (*UI_method_get_data_destructor(const UI_METHOD *method)) (UI *, void *); +const void *UI_method_get_ex_data(const UI_METHOD *method, int idx); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean prompt + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +int UI_get_result_string_length(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); +int UI_set_result_ex(UI *ui, UI_STRING *uis, const char *result, int len); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); +UI_METHOD *UI_UTIL_wrap_read_pem_callback(pem_password_cb *cb, int rwflag); + + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 935699a55a..2c46066259 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/x509.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * @@ -8,6 +11,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_X509_H # define OPENSSL_X509_H # pragma once @@ -41,10 +46,107 @@ extern "C" { #endif /* Needed stacks for types defined in other headers */ -DEFINE_OR_DECLARE_STACK_OF(X509_NAME) -DEFINE_OR_DECLARE_STACK_OF(X509) -DEFINE_OR_DECLARE_STACK_OF(X509_REVOKED) -DEFINE_OR_DECLARE_STACK_OF(X509_CRL) +SKM_DEFINE_STACK_OF_INTERNAL(X509_NAME, X509_NAME, X509_NAME) +#define sk_X509_NAME_num(sk) OPENSSL_sk_num(ossl_check_const_X509_NAME_sk_type(sk)) +#define sk_X509_NAME_value(sk, idx) ((X509_NAME *)OPENSSL_sk_value(ossl_check_const_X509_NAME_sk_type(sk), (idx))) +#define sk_X509_NAME_new(cmp) ((STACK_OF(X509_NAME) *)OPENSSL_sk_new(ossl_check_X509_NAME_compfunc_type(cmp))) +#define sk_X509_NAME_new_null() ((STACK_OF(X509_NAME) *)OPENSSL_sk_new_null()) +#define sk_X509_NAME_new_reserve(cmp, n) ((STACK_OF(X509_NAME) *)OPENSSL_sk_new_reserve(ossl_check_X509_NAME_compfunc_type(cmp), (n))) +#define sk_X509_NAME_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_NAME_sk_type(sk), (n)) +#define sk_X509_NAME_free(sk) OPENSSL_sk_free(ossl_check_X509_NAME_sk_type(sk)) +#define sk_X509_NAME_zero(sk) OPENSSL_sk_zero(ossl_check_X509_NAME_sk_type(sk)) +#define sk_X509_NAME_delete(sk, i) ((X509_NAME *)OPENSSL_sk_delete(ossl_check_X509_NAME_sk_type(sk), (i))) +#define sk_X509_NAME_delete_ptr(sk, ptr) ((X509_NAME *)OPENSSL_sk_delete_ptr(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr))) +#define sk_X509_NAME_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr)) +#define sk_X509_NAME_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr)) +#define sk_X509_NAME_pop(sk) ((X509_NAME *)OPENSSL_sk_pop(ossl_check_X509_NAME_sk_type(sk))) +#define sk_X509_NAME_shift(sk) ((X509_NAME *)OPENSSL_sk_shift(ossl_check_X509_NAME_sk_type(sk))) +#define sk_X509_NAME_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_NAME_sk_type(sk),ossl_check_X509_NAME_freefunc_type(freefunc)) +#define sk_X509_NAME_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr), (idx)) +#define sk_X509_NAME_set(sk, idx, ptr) ((X509_NAME *)OPENSSL_sk_set(ossl_check_X509_NAME_sk_type(sk), (idx), ossl_check_X509_NAME_type(ptr))) +#define sk_X509_NAME_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr)) +#define sk_X509_NAME_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_type(ptr)) +#define sk_X509_NAME_sort(sk) OPENSSL_sk_sort(ossl_check_X509_NAME_sk_type(sk)) +#define sk_X509_NAME_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_NAME_sk_type(sk)) +#define sk_X509_NAME_dup(sk) ((STACK_OF(X509_NAME) *)OPENSSL_sk_dup(ossl_check_const_X509_NAME_sk_type(sk))) +#define sk_X509_NAME_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_NAME) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_NAME_sk_type(sk), ossl_check_X509_NAME_copyfunc_type(copyfunc), ossl_check_X509_NAME_freefunc_type(freefunc))) +#define sk_X509_NAME_set_cmp_func(sk, cmp) ((sk_X509_NAME_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_NAME_sk_type(sk), ossl_check_X509_NAME_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(X509, X509, X509) +#define sk_X509_num(sk) OPENSSL_sk_num(ossl_check_const_X509_sk_type(sk)) +#define sk_X509_value(sk, idx) ((X509 *)OPENSSL_sk_value(ossl_check_const_X509_sk_type(sk), (idx))) +#define sk_X509_new(cmp) ((STACK_OF(X509) *)OPENSSL_sk_new(ossl_check_X509_compfunc_type(cmp))) +#define sk_X509_new_null() ((STACK_OF(X509) *)OPENSSL_sk_new_null()) +#define sk_X509_new_reserve(cmp, n) ((STACK_OF(X509) *)OPENSSL_sk_new_reserve(ossl_check_X509_compfunc_type(cmp), (n))) +#define sk_X509_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_sk_type(sk), (n)) +#define sk_X509_free(sk) OPENSSL_sk_free(ossl_check_X509_sk_type(sk)) +#define sk_X509_zero(sk) OPENSSL_sk_zero(ossl_check_X509_sk_type(sk)) +#define sk_X509_delete(sk, i) ((X509 *)OPENSSL_sk_delete(ossl_check_X509_sk_type(sk), (i))) +#define sk_X509_delete_ptr(sk, ptr) ((X509 *)OPENSSL_sk_delete_ptr(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr))) +#define sk_X509_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr)) +#define sk_X509_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr)) +#define sk_X509_pop(sk) ((X509 *)OPENSSL_sk_pop(ossl_check_X509_sk_type(sk))) +#define sk_X509_shift(sk) ((X509 *)OPENSSL_sk_shift(ossl_check_X509_sk_type(sk))) +#define sk_X509_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_sk_type(sk),ossl_check_X509_freefunc_type(freefunc)) +#define sk_X509_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr), (idx)) +#define sk_X509_set(sk, idx, ptr) ((X509 *)OPENSSL_sk_set(ossl_check_X509_sk_type(sk), (idx), ossl_check_X509_type(ptr))) +#define sk_X509_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr)) +#define sk_X509_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_sk_type(sk), ossl_check_X509_type(ptr)) +#define sk_X509_sort(sk) OPENSSL_sk_sort(ossl_check_X509_sk_type(sk)) +#define sk_X509_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_sk_type(sk)) +#define sk_X509_dup(sk) ((STACK_OF(X509) *)OPENSSL_sk_dup(ossl_check_const_X509_sk_type(sk))) +#define sk_X509_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_sk_type(sk), ossl_check_X509_copyfunc_type(copyfunc), ossl_check_X509_freefunc_type(freefunc))) +#define sk_X509_set_cmp_func(sk, cmp) ((sk_X509_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_sk_type(sk), ossl_check_X509_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(X509_REVOKED, X509_REVOKED, X509_REVOKED) +#define sk_X509_REVOKED_num(sk) OPENSSL_sk_num(ossl_check_const_X509_REVOKED_sk_type(sk)) +#define sk_X509_REVOKED_value(sk, idx) ((X509_REVOKED *)OPENSSL_sk_value(ossl_check_const_X509_REVOKED_sk_type(sk), (idx))) +#define sk_X509_REVOKED_new(cmp) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new(ossl_check_X509_REVOKED_compfunc_type(cmp))) +#define sk_X509_REVOKED_new_null() ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new_null()) +#define sk_X509_REVOKED_new_reserve(cmp, n) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_new_reserve(ossl_check_X509_REVOKED_compfunc_type(cmp), (n))) +#define sk_X509_REVOKED_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_REVOKED_sk_type(sk), (n)) +#define sk_X509_REVOKED_free(sk) OPENSSL_sk_free(ossl_check_X509_REVOKED_sk_type(sk)) +#define sk_X509_REVOKED_zero(sk) OPENSSL_sk_zero(ossl_check_X509_REVOKED_sk_type(sk)) +#define sk_X509_REVOKED_delete(sk, i) ((X509_REVOKED *)OPENSSL_sk_delete(ossl_check_X509_REVOKED_sk_type(sk), (i))) +#define sk_X509_REVOKED_delete_ptr(sk, ptr) ((X509_REVOKED *)OPENSSL_sk_delete_ptr(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr))) +#define sk_X509_REVOKED_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr)) +#define sk_X509_REVOKED_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr)) +#define sk_X509_REVOKED_pop(sk) ((X509_REVOKED *)OPENSSL_sk_pop(ossl_check_X509_REVOKED_sk_type(sk))) +#define sk_X509_REVOKED_shift(sk) ((X509_REVOKED *)OPENSSL_sk_shift(ossl_check_X509_REVOKED_sk_type(sk))) +#define sk_X509_REVOKED_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_REVOKED_sk_type(sk),ossl_check_X509_REVOKED_freefunc_type(freefunc)) +#define sk_X509_REVOKED_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr), (idx)) +#define sk_X509_REVOKED_set(sk, idx, ptr) ((X509_REVOKED *)OPENSSL_sk_set(ossl_check_X509_REVOKED_sk_type(sk), (idx), ossl_check_X509_REVOKED_type(ptr))) +#define sk_X509_REVOKED_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr)) +#define sk_X509_REVOKED_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_type(ptr)) +#define sk_X509_REVOKED_sort(sk) OPENSSL_sk_sort(ossl_check_X509_REVOKED_sk_type(sk)) +#define sk_X509_REVOKED_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_REVOKED_sk_type(sk)) +#define sk_X509_REVOKED_dup(sk) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_dup(ossl_check_const_X509_REVOKED_sk_type(sk))) +#define sk_X509_REVOKED_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_REVOKED) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_copyfunc_type(copyfunc), ossl_check_X509_REVOKED_freefunc_type(freefunc))) +#define sk_X509_REVOKED_set_cmp_func(sk, cmp) ((sk_X509_REVOKED_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_REVOKED_sk_type(sk), ossl_check_X509_REVOKED_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(X509_CRL, X509_CRL, X509_CRL) +#define sk_X509_CRL_num(sk) OPENSSL_sk_num(ossl_check_const_X509_CRL_sk_type(sk)) +#define sk_X509_CRL_value(sk, idx) ((X509_CRL *)OPENSSL_sk_value(ossl_check_const_X509_CRL_sk_type(sk), (idx))) +#define sk_X509_CRL_new(cmp) ((STACK_OF(X509_CRL) *)OPENSSL_sk_new(ossl_check_X509_CRL_compfunc_type(cmp))) +#define sk_X509_CRL_new_null() ((STACK_OF(X509_CRL) *)OPENSSL_sk_new_null()) +#define sk_X509_CRL_new_reserve(cmp, n) ((STACK_OF(X509_CRL) *)OPENSSL_sk_new_reserve(ossl_check_X509_CRL_compfunc_type(cmp), (n))) +#define sk_X509_CRL_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_CRL_sk_type(sk), (n)) +#define sk_X509_CRL_free(sk) OPENSSL_sk_free(ossl_check_X509_CRL_sk_type(sk)) +#define sk_X509_CRL_zero(sk) OPENSSL_sk_zero(ossl_check_X509_CRL_sk_type(sk)) +#define sk_X509_CRL_delete(sk, i) ((X509_CRL *)OPENSSL_sk_delete(ossl_check_X509_CRL_sk_type(sk), (i))) +#define sk_X509_CRL_delete_ptr(sk, ptr) ((X509_CRL *)OPENSSL_sk_delete_ptr(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr))) +#define sk_X509_CRL_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr)) +#define sk_X509_CRL_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr)) +#define sk_X509_CRL_pop(sk) ((X509_CRL *)OPENSSL_sk_pop(ossl_check_X509_CRL_sk_type(sk))) +#define sk_X509_CRL_shift(sk) ((X509_CRL *)OPENSSL_sk_shift(ossl_check_X509_CRL_sk_type(sk))) +#define sk_X509_CRL_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_CRL_sk_type(sk),ossl_check_X509_CRL_freefunc_type(freefunc)) +#define sk_X509_CRL_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr), (idx)) +#define sk_X509_CRL_set(sk, idx, ptr) ((X509_CRL *)OPENSSL_sk_set(ossl_check_X509_CRL_sk_type(sk), (idx), ossl_check_X509_CRL_type(ptr))) +#define sk_X509_CRL_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr)) +#define sk_X509_CRL_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_type(ptr)) +#define sk_X509_CRL_sort(sk) OPENSSL_sk_sort(ossl_check_X509_CRL_sk_type(sk)) +#define sk_X509_CRL_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_CRL_sk_type(sk)) +#define sk_X509_CRL_dup(sk) ((STACK_OF(X509_CRL) *)OPENSSL_sk_dup(ossl_check_const_X509_CRL_sk_type(sk))) +#define sk_X509_CRL_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_CRL) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_CRL_sk_type(sk), ossl_check_X509_CRL_copyfunc_type(copyfunc), ossl_check_X509_CRL_freefunc_type(freefunc))) +#define sk_X509_CRL_set_cmp_func(sk, cmp) ((sk_X509_CRL_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_CRL_sk_type(sk), ossl_check_X509_CRL_compfunc_type(cmp))) + /* Flags for X509_get_signature_info() */ /* Signature info is valid */ @@ -82,16 +184,91 @@ typedef struct X509_val_st { typedef struct X509_sig_st X509_SIG; typedef struct X509_name_entry_st X509_NAME_ENTRY; -DEFINE_OR_DECLARE_STACK_OF(X509_NAME_ENTRY) + +SKM_DEFINE_STACK_OF_INTERNAL(X509_NAME_ENTRY, X509_NAME_ENTRY, X509_NAME_ENTRY) +#define sk_X509_NAME_ENTRY_num(sk) OPENSSL_sk_num(ossl_check_const_X509_NAME_ENTRY_sk_type(sk)) +#define sk_X509_NAME_ENTRY_value(sk, idx) ((X509_NAME_ENTRY *)OPENSSL_sk_value(ossl_check_const_X509_NAME_ENTRY_sk_type(sk), (idx))) +#define sk_X509_NAME_ENTRY_new(cmp) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new(ossl_check_X509_NAME_ENTRY_compfunc_type(cmp))) +#define sk_X509_NAME_ENTRY_new_null() ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new_null()) +#define sk_X509_NAME_ENTRY_new_reserve(cmp, n) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_new_reserve(ossl_check_X509_NAME_ENTRY_compfunc_type(cmp), (n))) +#define sk_X509_NAME_ENTRY_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_NAME_ENTRY_sk_type(sk), (n)) +#define sk_X509_NAME_ENTRY_free(sk) OPENSSL_sk_free(ossl_check_X509_NAME_ENTRY_sk_type(sk)) +#define sk_X509_NAME_ENTRY_zero(sk) OPENSSL_sk_zero(ossl_check_X509_NAME_ENTRY_sk_type(sk)) +#define sk_X509_NAME_ENTRY_delete(sk, i) ((X509_NAME_ENTRY *)OPENSSL_sk_delete(ossl_check_X509_NAME_ENTRY_sk_type(sk), (i))) +#define sk_X509_NAME_ENTRY_delete_ptr(sk, ptr) ((X509_NAME_ENTRY *)OPENSSL_sk_delete_ptr(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr))) +#define sk_X509_NAME_ENTRY_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr)) +#define sk_X509_NAME_ENTRY_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr)) +#define sk_X509_NAME_ENTRY_pop(sk) ((X509_NAME_ENTRY *)OPENSSL_sk_pop(ossl_check_X509_NAME_ENTRY_sk_type(sk))) +#define sk_X509_NAME_ENTRY_shift(sk) ((X509_NAME_ENTRY *)OPENSSL_sk_shift(ossl_check_X509_NAME_ENTRY_sk_type(sk))) +#define sk_X509_NAME_ENTRY_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_NAME_ENTRY_sk_type(sk),ossl_check_X509_NAME_ENTRY_freefunc_type(freefunc)) +#define sk_X509_NAME_ENTRY_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr), (idx)) +#define sk_X509_NAME_ENTRY_set(sk, idx, ptr) ((X509_NAME_ENTRY *)OPENSSL_sk_set(ossl_check_X509_NAME_ENTRY_sk_type(sk), (idx), ossl_check_X509_NAME_ENTRY_type(ptr))) +#define sk_X509_NAME_ENTRY_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr)) +#define sk_X509_NAME_ENTRY_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_type(ptr)) +#define sk_X509_NAME_ENTRY_sort(sk) OPENSSL_sk_sort(ossl_check_X509_NAME_ENTRY_sk_type(sk)) +#define sk_X509_NAME_ENTRY_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_NAME_ENTRY_sk_type(sk)) +#define sk_X509_NAME_ENTRY_dup(sk) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_dup(ossl_check_const_X509_NAME_ENTRY_sk_type(sk))) +#define sk_X509_NAME_ENTRY_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_NAME_ENTRY) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_copyfunc_type(copyfunc), ossl_check_X509_NAME_ENTRY_freefunc_type(freefunc))) +#define sk_X509_NAME_ENTRY_set_cmp_func(sk, cmp) ((sk_X509_NAME_ENTRY_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_NAME_ENTRY_sk_type(sk), ossl_check_X509_NAME_ENTRY_compfunc_type(cmp))) # define X509_EX_V_NETSCAPE_HACK 0x8000 # define X509_EX_V_INIT 0x0001 typedef struct X509_extension_st X509_EXTENSION; -DEFINE_OR_DECLARE_STACK_OF(X509_EXTENSION) +SKM_DEFINE_STACK_OF_INTERNAL(X509_EXTENSION, X509_EXTENSION, X509_EXTENSION) +#define sk_X509_EXTENSION_num(sk) OPENSSL_sk_num(ossl_check_const_X509_EXTENSION_sk_type(sk)) +#define sk_X509_EXTENSION_value(sk, idx) ((X509_EXTENSION *)OPENSSL_sk_value(ossl_check_const_X509_EXTENSION_sk_type(sk), (idx))) +#define sk_X509_EXTENSION_new(cmp) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new(ossl_check_X509_EXTENSION_compfunc_type(cmp))) +#define sk_X509_EXTENSION_new_null() ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new_null()) +#define sk_X509_EXTENSION_new_reserve(cmp, n) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_new_reserve(ossl_check_X509_EXTENSION_compfunc_type(cmp), (n))) +#define sk_X509_EXTENSION_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_EXTENSION_sk_type(sk), (n)) +#define sk_X509_EXTENSION_free(sk) OPENSSL_sk_free(ossl_check_X509_EXTENSION_sk_type(sk)) +#define sk_X509_EXTENSION_zero(sk) OPENSSL_sk_zero(ossl_check_X509_EXTENSION_sk_type(sk)) +#define sk_X509_EXTENSION_delete(sk, i) ((X509_EXTENSION *)OPENSSL_sk_delete(ossl_check_X509_EXTENSION_sk_type(sk), (i))) +#define sk_X509_EXTENSION_delete_ptr(sk, ptr) ((X509_EXTENSION *)OPENSSL_sk_delete_ptr(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr))) +#define sk_X509_EXTENSION_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr)) +#define sk_X509_EXTENSION_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr)) +#define sk_X509_EXTENSION_pop(sk) ((X509_EXTENSION *)OPENSSL_sk_pop(ossl_check_X509_EXTENSION_sk_type(sk))) +#define sk_X509_EXTENSION_shift(sk) ((X509_EXTENSION *)OPENSSL_sk_shift(ossl_check_X509_EXTENSION_sk_type(sk))) +#define sk_X509_EXTENSION_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_EXTENSION_sk_type(sk),ossl_check_X509_EXTENSION_freefunc_type(freefunc)) +#define sk_X509_EXTENSION_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr), (idx)) +#define sk_X509_EXTENSION_set(sk, idx, ptr) ((X509_EXTENSION *)OPENSSL_sk_set(ossl_check_X509_EXTENSION_sk_type(sk), (idx), ossl_check_X509_EXTENSION_type(ptr))) +#define sk_X509_EXTENSION_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr)) +#define sk_X509_EXTENSION_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_type(ptr)) +#define sk_X509_EXTENSION_sort(sk) OPENSSL_sk_sort(ossl_check_X509_EXTENSION_sk_type(sk)) +#define sk_X509_EXTENSION_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_EXTENSION_sk_type(sk)) +#define sk_X509_EXTENSION_dup(sk) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_dup(ossl_check_const_X509_EXTENSION_sk_type(sk))) +#define sk_X509_EXTENSION_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_EXTENSION) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_copyfunc_type(copyfunc), ossl_check_X509_EXTENSION_freefunc_type(freefunc))) +#define sk_X509_EXTENSION_set_cmp_func(sk, cmp) ((sk_X509_EXTENSION_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_EXTENSION_sk_type(sk), ossl_check_X509_EXTENSION_compfunc_type(cmp))) + typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; typedef struct x509_attributes_st X509_ATTRIBUTE; -DEFINE_OR_DECLARE_STACK_OF(X509_ATTRIBUTE) +SKM_DEFINE_STACK_OF_INTERNAL(X509_ATTRIBUTE, X509_ATTRIBUTE, X509_ATTRIBUTE) +#define sk_X509_ATTRIBUTE_num(sk) OPENSSL_sk_num(ossl_check_const_X509_ATTRIBUTE_sk_type(sk)) +#define sk_X509_ATTRIBUTE_value(sk, idx) ((X509_ATTRIBUTE *)OPENSSL_sk_value(ossl_check_const_X509_ATTRIBUTE_sk_type(sk), (idx))) +#define sk_X509_ATTRIBUTE_new(cmp) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new(ossl_check_X509_ATTRIBUTE_compfunc_type(cmp))) +#define sk_X509_ATTRIBUTE_new_null() ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new_null()) +#define sk_X509_ATTRIBUTE_new_reserve(cmp, n) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_new_reserve(ossl_check_X509_ATTRIBUTE_compfunc_type(cmp), (n))) +#define sk_X509_ATTRIBUTE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_ATTRIBUTE_sk_type(sk), (n)) +#define sk_X509_ATTRIBUTE_free(sk) OPENSSL_sk_free(ossl_check_X509_ATTRIBUTE_sk_type(sk)) +#define sk_X509_ATTRIBUTE_zero(sk) OPENSSL_sk_zero(ossl_check_X509_ATTRIBUTE_sk_type(sk)) +#define sk_X509_ATTRIBUTE_delete(sk, i) ((X509_ATTRIBUTE *)OPENSSL_sk_delete(ossl_check_X509_ATTRIBUTE_sk_type(sk), (i))) +#define sk_X509_ATTRIBUTE_delete_ptr(sk, ptr) ((X509_ATTRIBUTE *)OPENSSL_sk_delete_ptr(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr))) +#define sk_X509_ATTRIBUTE_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr)) +#define sk_X509_ATTRIBUTE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr)) +#define sk_X509_ATTRIBUTE_pop(sk) ((X509_ATTRIBUTE *)OPENSSL_sk_pop(ossl_check_X509_ATTRIBUTE_sk_type(sk))) +#define sk_X509_ATTRIBUTE_shift(sk) ((X509_ATTRIBUTE *)OPENSSL_sk_shift(ossl_check_X509_ATTRIBUTE_sk_type(sk))) +#define sk_X509_ATTRIBUTE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_ATTRIBUTE_sk_type(sk),ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc)) +#define sk_X509_ATTRIBUTE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr), (idx)) +#define sk_X509_ATTRIBUTE_set(sk, idx, ptr) ((X509_ATTRIBUTE *)OPENSSL_sk_set(ossl_check_X509_ATTRIBUTE_sk_type(sk), (idx), ossl_check_X509_ATTRIBUTE_type(ptr))) +#define sk_X509_ATTRIBUTE_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr)) +#define sk_X509_ATTRIBUTE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_type(ptr)) +#define sk_X509_ATTRIBUTE_sort(sk) OPENSSL_sk_sort(ossl_check_X509_ATTRIBUTE_sk_type(sk)) +#define sk_X509_ATTRIBUTE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_ATTRIBUTE_sk_type(sk)) +#define sk_X509_ATTRIBUTE_dup(sk) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_dup(ossl_check_const_X509_ATTRIBUTE_sk_type(sk))) +#define sk_X509_ATTRIBUTE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_ATTRIBUTE) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_copyfunc_type(copyfunc), ossl_check_X509_ATTRIBUTE_freefunc_type(freefunc))) +#define sk_X509_ATTRIBUTE_set_cmp_func(sk, cmp) ((sk_X509_ATTRIBUTE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_ATTRIBUTE_sk_type(sk), ossl_check_X509_ATTRIBUTE_compfunc_type(cmp))) + typedef struct X509_req_info_st X509_REQ_INFO; typedef struct X509_req_st X509_REQ; typedef struct x509_cert_aux_st X509_CERT_AUX; @@ -107,7 +284,32 @@ typedef struct x509_trust_st { int arg1; void *arg2; } X509_TRUST; -DEFINE_OR_DECLARE_STACK_OF(X509_TRUST) +SKM_DEFINE_STACK_OF_INTERNAL(X509_TRUST, X509_TRUST, X509_TRUST) +#define sk_X509_TRUST_num(sk) OPENSSL_sk_num(ossl_check_const_X509_TRUST_sk_type(sk)) +#define sk_X509_TRUST_value(sk, idx) ((X509_TRUST *)OPENSSL_sk_value(ossl_check_const_X509_TRUST_sk_type(sk), (idx))) +#define sk_X509_TRUST_new(cmp) ((STACK_OF(X509_TRUST) *)OPENSSL_sk_new(ossl_check_X509_TRUST_compfunc_type(cmp))) +#define sk_X509_TRUST_new_null() ((STACK_OF(X509_TRUST) *)OPENSSL_sk_new_null()) +#define sk_X509_TRUST_new_reserve(cmp, n) ((STACK_OF(X509_TRUST) *)OPENSSL_sk_new_reserve(ossl_check_X509_TRUST_compfunc_type(cmp), (n))) +#define sk_X509_TRUST_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_TRUST_sk_type(sk), (n)) +#define sk_X509_TRUST_free(sk) OPENSSL_sk_free(ossl_check_X509_TRUST_sk_type(sk)) +#define sk_X509_TRUST_zero(sk) OPENSSL_sk_zero(ossl_check_X509_TRUST_sk_type(sk)) +#define sk_X509_TRUST_delete(sk, i) ((X509_TRUST *)OPENSSL_sk_delete(ossl_check_X509_TRUST_sk_type(sk), (i))) +#define sk_X509_TRUST_delete_ptr(sk, ptr) ((X509_TRUST *)OPENSSL_sk_delete_ptr(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_type(ptr))) +#define sk_X509_TRUST_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_type(ptr)) +#define sk_X509_TRUST_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_type(ptr)) +#define sk_X509_TRUST_pop(sk) ((X509_TRUST *)OPENSSL_sk_pop(ossl_check_X509_TRUST_sk_type(sk))) +#define sk_X509_TRUST_shift(sk) ((X509_TRUST *)OPENSSL_sk_shift(ossl_check_X509_TRUST_sk_type(sk))) +#define sk_X509_TRUST_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_TRUST_sk_type(sk),ossl_check_X509_TRUST_freefunc_type(freefunc)) +#define sk_X509_TRUST_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_type(ptr), (idx)) +#define sk_X509_TRUST_set(sk, idx, ptr) ((X509_TRUST *)OPENSSL_sk_set(ossl_check_X509_TRUST_sk_type(sk), (idx), ossl_check_X509_TRUST_type(ptr))) +#define sk_X509_TRUST_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_type(ptr)) +#define sk_X509_TRUST_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_type(ptr)) +#define sk_X509_TRUST_sort(sk) OPENSSL_sk_sort(ossl_check_X509_TRUST_sk_type(sk)) +#define sk_X509_TRUST_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_TRUST_sk_type(sk)) +#define sk_X509_TRUST_dup(sk) ((STACK_OF(X509_TRUST) *)OPENSSL_sk_dup(ossl_check_const_X509_TRUST_sk_type(sk))) +#define sk_X509_TRUST_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_TRUST) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_copyfunc_type(copyfunc), ossl_check_X509_TRUST_freefunc_type(freefunc))) +#define sk_X509_TRUST_set_cmp_func(sk, cmp) ((sk_X509_TRUST_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_TRUST_sk_type(sk), ossl_check_X509_TRUST_compfunc_type(cmp))) + /* standard trust ids */ @@ -159,6 +361,7 @@ DEFINE_OR_DECLARE_STACK_OF(X509_TRUST) # define X509_FLAG_NO_AUX (1L << 10) # define X509_FLAG_NO_ATTRIBUTES (1L << 11) # define X509_FLAG_NO_IDS (1L << 12) +# define X509_FLAG_EXTENSIONS_ONLY_KID (1L << 13) /* Flags specific to X509_NAME_print_ex() */ @@ -245,7 +448,32 @@ typedef struct X509_info_st { int enc_len; char *enc_data; } X509_INFO; -DEFINE_OR_DECLARE_STACK_OF(X509_INFO) +SKM_DEFINE_STACK_OF_INTERNAL(X509_INFO, X509_INFO, X509_INFO) +#define sk_X509_INFO_num(sk) OPENSSL_sk_num(ossl_check_const_X509_INFO_sk_type(sk)) +#define sk_X509_INFO_value(sk, idx) ((X509_INFO *)OPENSSL_sk_value(ossl_check_const_X509_INFO_sk_type(sk), (idx))) +#define sk_X509_INFO_new(cmp) ((STACK_OF(X509_INFO) *)OPENSSL_sk_new(ossl_check_X509_INFO_compfunc_type(cmp))) +#define sk_X509_INFO_new_null() ((STACK_OF(X509_INFO) *)OPENSSL_sk_new_null()) +#define sk_X509_INFO_new_reserve(cmp, n) ((STACK_OF(X509_INFO) *)OPENSSL_sk_new_reserve(ossl_check_X509_INFO_compfunc_type(cmp), (n))) +#define sk_X509_INFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_INFO_sk_type(sk), (n)) +#define sk_X509_INFO_free(sk) OPENSSL_sk_free(ossl_check_X509_INFO_sk_type(sk)) +#define sk_X509_INFO_zero(sk) OPENSSL_sk_zero(ossl_check_X509_INFO_sk_type(sk)) +#define sk_X509_INFO_delete(sk, i) ((X509_INFO *)OPENSSL_sk_delete(ossl_check_X509_INFO_sk_type(sk), (i))) +#define sk_X509_INFO_delete_ptr(sk, ptr) ((X509_INFO *)OPENSSL_sk_delete_ptr(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr))) +#define sk_X509_INFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr)) +#define sk_X509_INFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr)) +#define sk_X509_INFO_pop(sk) ((X509_INFO *)OPENSSL_sk_pop(ossl_check_X509_INFO_sk_type(sk))) +#define sk_X509_INFO_shift(sk) ((X509_INFO *)OPENSSL_sk_shift(ossl_check_X509_INFO_sk_type(sk))) +#define sk_X509_INFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_INFO_sk_type(sk),ossl_check_X509_INFO_freefunc_type(freefunc)) +#define sk_X509_INFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr), (idx)) +#define sk_X509_INFO_set(sk, idx, ptr) ((X509_INFO *)OPENSSL_sk_set(ossl_check_X509_INFO_sk_type(sk), (idx), ossl_check_X509_INFO_type(ptr))) +#define sk_X509_INFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr)) +#define sk_X509_INFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_type(ptr)) +#define sk_X509_INFO_sort(sk) OPENSSL_sk_sort(ossl_check_X509_INFO_sk_type(sk)) +#define sk_X509_INFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_INFO_sk_type(sk)) +#define sk_X509_INFO_dup(sk) ((STACK_OF(X509_INFO) *)OPENSSL_sk_dup(ossl_check_const_X509_INFO_sk_type(sk))) +#define sk_X509_INFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_INFO) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_INFO_sk_type(sk), ossl_check_X509_INFO_copyfunc_type(copyfunc), ossl_check_X509_INFO_freefunc_type(freefunc))) +#define sk_X509_INFO_set_cmp_func(sk, cmp) ((sk_X509_INFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_INFO_sk_type(sk), ossl_check_X509_INFO_compfunc_type(cmp))) + /* * The next 2 structures and their 8 routines are used to manipulate Netscape's @@ -346,8 +574,8 @@ const char *X509_verify_cert_error_string(long n); int X509_verify(X509 *a, EVP_PKEY *r); int X509_self_signed(X509 *cert, int verify_signature); -int X509_REQ_verify_with_libctx(X509_REQ *a, EVP_PKEY *r, OPENSSL_CTX *libctx, - const char *propq); +int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx, + const char *propq); int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); @@ -383,12 +611,10 @@ int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, unsigned int *len); -# if !defined(OPENSSL_NO_SOCK) X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); -# define X509_http_nbio(url) X509_load_http(url, NULL, NULL, 0) +# define X509_http_nbio(url) X509_load_http(url, NULL, NULL, 0) X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); -# define X509_CRL_http_nbio(url) X509_CRL_load_http(url, NULL, NULL, 0) -# endif +# define X509_CRL_http_nbio(url) X509_CRL_load_http(url, NULL, NULL, 0) # ifndef OPENSSL_NO_STDIO X509 *d2i_X509_fp(FILE *fp, X509 **x509); @@ -426,7 +652,7 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf); int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key); int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OPENSSL_CTX *libctx, +EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey); @@ -468,7 +694,7 @@ PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf); int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key); int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OPENSSL_CTX *libctx, +EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey); @@ -524,6 +750,8 @@ EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key); int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); long X509_get_pathlen(X509 *x); DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY) +EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length, + OSSL_LIB_CTX *libctx, const char *propq); # ifndef OPENSSL_NO_RSA DECLARE_ASN1_ENCODE_FUNCTIONS_only(RSA, RSA_PUBKEY) # endif @@ -557,7 +785,7 @@ int X509_NAME_set(X509_NAME **xn, const X509_NAME *name); DECLARE_ASN1_FUNCTIONS(X509_CINF) DECLARE_ASN1_FUNCTIONS(X509) -X509 *X509_new_with_libctx(OPENSSL_CTX *libctx, const char *propq); +X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq); DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) #define X509_get_ex_new_index(l, p, newf, dupf, freef) \ @@ -621,33 +849,30 @@ X509_INFO *X509_INFO_new(void); void X509_INFO_free(X509_INFO *a); char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); +/* TODO move this block of decls to asn1.h when 'breaking change' is possible */ DEPRECATEDIN_3_0(int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey)) - DEPRECATEDIN_3_0(int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, unsigned char *md, unsigned int *len)) - DEPRECATEDIN_3_0(int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, const EVP_MD *type)) - int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, unsigned char *md, unsigned int *len); - -int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, - ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); -int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, - ASN1_BIT_STRING *signature, void *data, +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey); +int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, EVP_MD_CTX *ctx); - -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, - EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey, const EVP_MD *md); int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, - void *asn, EVP_MD_CTX *ctx); + const void *data, EVP_MD_CTX *ctx); long X509_get_version(const X509 *x); int X509_set_version(X509 *x, long version); @@ -787,6 +1012,14 @@ unsigned long X509_issuer_name_hash_old(X509 *a); unsigned long X509_subject_name_hash_old(X509 *x); # endif +# define X509_ADD_FLAG_DEFAULT 0 +# define X509_ADD_FLAG_UP_REF 0x1 +# define X509_ADD_FLAG_PREPEND 0x2 +# define X509_ADD_FLAG_NO_DUP 0x4 +# define X509_ADD_FLAG_NO_SS 0x8 +int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags); +int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags); + int X509_cmp(const X509 *a, const X509 *b); int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); unsigned long X509_NAME_hash(const X509_NAME *x); @@ -951,7 +1184,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) int type, const unsigned char *bytes, int len); -void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, +void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x, const ASN1_OBJECT *obj, int lastpos, int type); X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, int atrtype, const void *data, @@ -1030,6 +1263,8 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); +EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, + const char *propq); PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey); int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, diff --git a/include/openssl/x509.h.in b/include/openssl/x509.h.in new file mode 100644 index 0000000000..eda5ee986f --- /dev/null +++ b/include/openssl/x509.h.in @@ -0,0 +1,1099 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_X509_H +# define OPENSSL_X509_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_X509_H +# endif + +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# include +# include +# include +# endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Needed stacks for types defined in other headers */ +{- + generate_stack_macros("X509_NAME") + .generate_stack_macros("X509") + .generate_stack_macros("X509_REVOKED") + .generate_stack_macros("X509_CRL"); +-} + +/* Flags for X509_get_signature_info() */ +/* Signature info is valid */ +# define X509_SIG_INFO_VALID 0x1 +/* Signature is suitable for TLS use */ +# define X509_SIG_INFO_TLS 0x2 + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +typedef struct X509_sig_st X509_SIG; + +typedef struct X509_name_entry_st X509_NAME_ENTRY; + +{- + generate_stack_macros("X509_NAME_ENTRY"); +-} + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st X509_EXTENSION; +{- + generate_stack_macros("X509_EXTENSION"); +-} +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; +typedef struct x509_attributes_st X509_ATTRIBUTE; +{- + generate_stack_macros("X509_ATTRIBUTE"); +-} +typedef struct X509_req_info_st X509_REQ_INFO; +typedef struct X509_req_st X509_REQ; +typedef struct x509_cert_aux_st X509_CERT_AUX; +typedef struct x509_cinf_st X509_CINF; + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; +{- + generate_stack_macros("X509_TRUST"); +-} + + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT 0 /* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC (1U << 0) +# define X509_TRUST_DYNAMIC_NAME (1U << 1) +/* No compat trust if self-signed, preempts "DO_SS" */ +# define X509_TRUST_NO_SS_COMPAT (1U << 2) +/* Compat trust if no explicit accepted trust EKUs */ +# define X509_TRUST_DO_SS_COMPAT (1U << 3) +/* Accept "anyEKU" as a wildcard trust OID */ +# define X509_TRUST_OK_ANY_EKU (1U << 4) + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) +# define X509_FLAG_NO_IDS (1L << 12) +# define X509_FLAG_EXTENSIONS_ONLY_KID (1L << 13) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional; use old X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +typedef struct X509_crl_info_st X509_CRL_INFO; + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; +} X509_PKEY; + +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; +} X509_INFO; +{- + generate_stack_macros("X509_INFO"); +-} + +/* + * The next 2 structures and their 8 routines are used to manipulate Netscape's + * spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +#ifndef OPENSSL_NO_SCRYPT +typedef struct SCRYPT_PARAMS_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *costParameter; + ASN1_INTEGER *blockSize; + ASN1_INTEGER *parallelizationParameter; + ASN1_INTEGER *keyLength; +} SCRYPT_PARAMS; +#endif + +#ifdef __cplusplus +} +#endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + const + ASN1_INTEGER *serial, + const + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +const char *X509_verify_cert_error_string(long n); + +int X509_verify(X509 *a, EVP_PKEY *r); +int X509_self_signed(X509 *cert, int verify_signature); + +int X509_REQ_verify_ex(X509_REQ *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx, + const char *propq); +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +ASN1_OCTET_STRING *X509_digest_sig(const X509 *cert); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); + +X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); +# define X509_http_nbio(url) X509_load_http(url, NULL, NULL, 0) +X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); +# define X509_CRL_http_nbio(url) X509_CRL_load_http(url, NULL, NULL, 0) + +# ifndef OPENSSL_NO_STDIO +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, const X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, const X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, const X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, const RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, const RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, const RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, const DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, const DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, const EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, const EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, const X509_SIG *p8); +X509_PUBKEY *d2i_X509_PUBKEY_fp(FILE *fp, X509_PUBKEY **xpk); +int i2d_X509_PUBKEY_fp(FILE *fp, const X509_PUBKEY *xpk); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, const PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, const EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, const X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, const X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, const X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, const RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, const RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, const RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, const DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, const DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, const EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, const EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, const X509_SIG *p8); +X509_PUBKEY *d2i_X509_PUBKEY_bio(BIO *bp, X509_PUBKEY **xpk); +int i2d_X509_PUBKEY_bio(BIO *bp, const X509_PUBKEY *xpk); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, const PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, const EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx, + const char *propq); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + +DECLARE_ASN1_DUP_FUNCTION(X509) +DECLARE_ASN1_DUP_FUNCTION(X509_ALGOR) +DECLARE_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) +DECLARE_ASN1_DUP_FUNCTION(X509_CRL) +DECLARE_ASN1_DUP_FUNCTION(X509_EXTENSION) +DECLARE_ASN1_DUP_FUNCTION(X509_PUBKEY) +DECLARE_ASN1_DUP_FUNCTION(X509_REQ) +DECLARE_ASN1_DUP_FUNCTION(X509_REVOKED) +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, + const void **ppval, const X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); +int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src); + +DECLARE_ASN1_DUP_FUNCTION(X509_NAME) +DECLARE_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +int X509_cmp_timeframe(const X509_VERIFY_PARAM *vpm, + const ASN1_TIME *start, const ASN1_TIME *end); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key); +EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +long X509_get_pathlen(X509 *x); +DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY) +EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length, + OSSL_LIB_CTX *libctx, const char *propq); +# ifndef OPENSSL_NO_RSA +DECLARE_ASN1_ENCODE_FUNCTIONS_only(RSA, RSA_PUBKEY) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_ASN1_ENCODE_FUNCTIONS_only(DSA, DSA_PUBKEY) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_ASN1_ENCODE_FUNCTIONS_only(EC_KEY, EC_PUBKEY) +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg, + const ASN1_OCTET_STRING **pdigest); +void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, + ASN1_OCTET_STRING **pdigest); + +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, const X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) +DECLARE_ASN1_FUNCTIONS(X509) +X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq); +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +#define X509_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef) +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(const X509 *r, int idx); +DECLARE_ASN1_ENCODE_FUNCTIONS_only(X509,X509_AUX) + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid, + int *secbits, uint32_t *flags); +void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid, + int secbits, uint32_t flags); + +int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits, + uint32_t *flags); + +void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +int X509_get_signature_nid(const X509 *x); + +void X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id); +ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x); +void X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id); +ASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x); + +int X509_trusted(const X509 *x); +int X509_alias_set1(X509 *x, const unsigned char *name, int len); +int X509_keyid_set1(X509 *x, const unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x); +STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, const ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size); + +/* TODO move this block of decls to asn1.h when 'breaking change' is possible */ +DEPRECATEDIN_3_0(int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, + EVP_PKEY *pkey)) +DEPRECATEDIN_3_0(int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, + char *data, + unsigned char *md, unsigned int *len)) +DEPRECATEDIN_3_0(int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type)) +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey); +int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg, + const ASN1_BIT_STRING *signature, const void *data, + EVP_MD_CTX *ctx); +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, const void *data, + EVP_PKEY *pkey, const EVP_MD *md); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + const void *data, EVP_MD_CTX *ctx); + +long X509_get_version(const X509 *x); +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x); +int X509_set_issuer_name(X509 *x, const X509_NAME *name); +X509_NAME *X509_get_issuer_name(const X509 *a); /* TODO change to get0_ */ +int X509_set_subject_name(X509 *x, const X509_NAME *name); +X509_NAME *X509_get_subject_name(const X509 *a); /* TODO change to get0_ */ +const ASN1_TIME * X509_get0_notBefore(const X509 *x); +ASN1_TIME *X509_getm_notBefore(const X509 *x); +int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm); +const ASN1_TIME *X509_get0_notAfter(const X509 *x); +ASN1_TIME *X509_getm_notAfter(const X509 *x); +int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +int X509_up_ref(X509 *x); +int X509_get_signature_type(const X509 *x); + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define X509_get_notBefore X509_getm_notBefore +# define X509_get_notAfter X509_getm_notAfter +# define X509_set_notBefore X509_set1_notBefore +# define X509_set_notAfter X509_set1_notAfter +#endif + + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &buf) + */ +X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x); +const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); +void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid, + const ASN1_BIT_STRING **psuid); +const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x); + +EVP_PKEY *X509_get0_pubkey(const X509 *x); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey); + +long X509_REQ_get_version(const X509_REQ *req); +int X509_REQ_set_version(X509_REQ *x, long version); +X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req); /* TODO change to get0_ */ +int X509_REQ_set_subject_name(X509_REQ *req, const X509_NAME *name); +void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig); +int X509_REQ_set1_signature_algo(X509_REQ *req, X509_ALGOR *palg); +int X509_REQ_get_signature_nid(const X509_REQ *req); +int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, const X509_NAME *name); +int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); +int X509_CRL_up_ref(X509_CRL *crl); + +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate +# define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate +#endif + +long X509_CRL_get_version(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl); +const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl); +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)) +DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)) +X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl); /* TODO change to get0_ */ +const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl); +STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl); +void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg); +int X509_CRL_get_signature_nid(const X509_CRL *crl); +int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp); + +const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x); +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); +const STACK_OF(X509_EXTENSION) * +X509_REVOKED_get0_extensions(const X509_REVOKED *r); + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey); +int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +# define X509_ADD_FLAG_DEFAULT 0 +# define X509_ADD_FLAG_UP_REF 0x1 +# define X509_ADD_FLAG_PREPEND 0x2 +# define X509_ADD_FLAG_NO_DUP 0x4 +# define X509_ADD_FLAG_NO_SS 0x8 +int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags); +int X509_add_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs, int flags); + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(const X509_NAME *x); +unsigned long X509_NAME_hash_old(const X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +int X509_aux_print(BIO *out, X509 *x, int indent); +# ifndef OPENSSL_NO_STDIO +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent, + unsigned long flags); +# endif + +int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CRL_print_ex(BIO *out, X509_CRL *x, unsigned long nmflag); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); + +int X509_NAME_entry_count(const X509_NAME *name); +int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, + char *buf, int len); +int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(const X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, + const unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne); +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +int X509_NAME_get0_der(const X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(const X509 *x); +int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(const X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(const X509_CRL *x); +int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(const X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, + int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, + int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(const X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + const ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x, + const ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, const X509_NAME *name, + const ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, const X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) +#ifndef OPENSSL_NO_SCRYPT +DECLARE_ASN1_FUNCTIONS(SCRYPT_PARAMS) +#endif + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +#ifndef OPENSSL_NO_SCRYPT +X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher, + const unsigned char *salt, int saltlen, + unsigned char *aiv, uint64_t N, uint64_t r, + uint64_t p); +#endif + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); +EVP_PKEY *EVP_PKCS82PKEY_ex(const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, + const char *propq); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8); + +const STACK_OF(X509_ATTRIBUTE) * +PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8); +int PKCS8_pkey_add1_attr(PKCS8_PRIV_KEY_INFO *p8, X509_ATTRIBUTE *attr); +int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type, + const unsigned char *bytes, int len); +int PKCS8_pkey_add1_attr_by_OBJ(PKCS8_PRIV_KEY_INFO *p8, const ASN1_OBJECT *obj, + int type, const unsigned char *bytes, int len); + + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, const X509_PUBKEY *pub); +int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + const char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(const X509_TRUST *xp); +char *X509_TRUST_get0_name(const X509_TRUST *xp); +int X509_TRUST_get_trust(const X509_TRUST *xp); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 2d3bd70ae2..afc53d81e9 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/x509_vfy.h.in + * * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_X509_VFY_H # define OPENSSL_X509_VFY_H # pragma once @@ -60,9 +65,82 @@ typedef enum { #define X509_LU_FAIL 0 #endif -DEFINE_OR_DECLARE_STACK_OF(X509_LOOKUP) -DEFINE_OR_DECLARE_STACK_OF(X509_OBJECT) -DEFINE_OR_DECLARE_STACK_OF(X509_VERIFY_PARAM) +SKM_DEFINE_STACK_OF_INTERNAL(X509_LOOKUP, X509_LOOKUP, X509_LOOKUP) +#define sk_X509_LOOKUP_num(sk) OPENSSL_sk_num(ossl_check_const_X509_LOOKUP_sk_type(sk)) +#define sk_X509_LOOKUP_value(sk, idx) ((X509_LOOKUP *)OPENSSL_sk_value(ossl_check_const_X509_LOOKUP_sk_type(sk), (idx))) +#define sk_X509_LOOKUP_new(cmp) ((STACK_OF(X509_LOOKUP) *)OPENSSL_sk_new(ossl_check_X509_LOOKUP_compfunc_type(cmp))) +#define sk_X509_LOOKUP_new_null() ((STACK_OF(X509_LOOKUP) *)OPENSSL_sk_new_null()) +#define sk_X509_LOOKUP_new_reserve(cmp, n) ((STACK_OF(X509_LOOKUP) *)OPENSSL_sk_new_reserve(ossl_check_X509_LOOKUP_compfunc_type(cmp), (n))) +#define sk_X509_LOOKUP_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_LOOKUP_sk_type(sk), (n)) +#define sk_X509_LOOKUP_free(sk) OPENSSL_sk_free(ossl_check_X509_LOOKUP_sk_type(sk)) +#define sk_X509_LOOKUP_zero(sk) OPENSSL_sk_zero(ossl_check_X509_LOOKUP_sk_type(sk)) +#define sk_X509_LOOKUP_delete(sk, i) ((X509_LOOKUP *)OPENSSL_sk_delete(ossl_check_X509_LOOKUP_sk_type(sk), (i))) +#define sk_X509_LOOKUP_delete_ptr(sk, ptr) ((X509_LOOKUP *)OPENSSL_sk_delete_ptr(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_type(ptr))) +#define sk_X509_LOOKUP_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_type(ptr)) +#define sk_X509_LOOKUP_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_type(ptr)) +#define sk_X509_LOOKUP_pop(sk) ((X509_LOOKUP *)OPENSSL_sk_pop(ossl_check_X509_LOOKUP_sk_type(sk))) +#define sk_X509_LOOKUP_shift(sk) ((X509_LOOKUP *)OPENSSL_sk_shift(ossl_check_X509_LOOKUP_sk_type(sk))) +#define sk_X509_LOOKUP_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_LOOKUP_sk_type(sk),ossl_check_X509_LOOKUP_freefunc_type(freefunc)) +#define sk_X509_LOOKUP_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_type(ptr), (idx)) +#define sk_X509_LOOKUP_set(sk, idx, ptr) ((X509_LOOKUP *)OPENSSL_sk_set(ossl_check_X509_LOOKUP_sk_type(sk), (idx), ossl_check_X509_LOOKUP_type(ptr))) +#define sk_X509_LOOKUP_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_type(ptr)) +#define sk_X509_LOOKUP_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_type(ptr)) +#define sk_X509_LOOKUP_sort(sk) OPENSSL_sk_sort(ossl_check_X509_LOOKUP_sk_type(sk)) +#define sk_X509_LOOKUP_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_LOOKUP_sk_type(sk)) +#define sk_X509_LOOKUP_dup(sk) ((STACK_OF(X509_LOOKUP) *)OPENSSL_sk_dup(ossl_check_const_X509_LOOKUP_sk_type(sk))) +#define sk_X509_LOOKUP_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_LOOKUP) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_copyfunc_type(copyfunc), ossl_check_X509_LOOKUP_freefunc_type(freefunc))) +#define sk_X509_LOOKUP_set_cmp_func(sk, cmp) ((sk_X509_LOOKUP_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_LOOKUP_sk_type(sk), ossl_check_X509_LOOKUP_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(X509_OBJECT, X509_OBJECT, X509_OBJECT) +#define sk_X509_OBJECT_num(sk) OPENSSL_sk_num(ossl_check_const_X509_OBJECT_sk_type(sk)) +#define sk_X509_OBJECT_value(sk, idx) ((X509_OBJECT *)OPENSSL_sk_value(ossl_check_const_X509_OBJECT_sk_type(sk), (idx))) +#define sk_X509_OBJECT_new(cmp) ((STACK_OF(X509_OBJECT) *)OPENSSL_sk_new(ossl_check_X509_OBJECT_compfunc_type(cmp))) +#define sk_X509_OBJECT_new_null() ((STACK_OF(X509_OBJECT) *)OPENSSL_sk_new_null()) +#define sk_X509_OBJECT_new_reserve(cmp, n) ((STACK_OF(X509_OBJECT) *)OPENSSL_sk_new_reserve(ossl_check_X509_OBJECT_compfunc_type(cmp), (n))) +#define sk_X509_OBJECT_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_OBJECT_sk_type(sk), (n)) +#define sk_X509_OBJECT_free(sk) OPENSSL_sk_free(ossl_check_X509_OBJECT_sk_type(sk)) +#define sk_X509_OBJECT_zero(sk) OPENSSL_sk_zero(ossl_check_X509_OBJECT_sk_type(sk)) +#define sk_X509_OBJECT_delete(sk, i) ((X509_OBJECT *)OPENSSL_sk_delete(ossl_check_X509_OBJECT_sk_type(sk), (i))) +#define sk_X509_OBJECT_delete_ptr(sk, ptr) ((X509_OBJECT *)OPENSSL_sk_delete_ptr(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_type(ptr))) +#define sk_X509_OBJECT_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_type(ptr)) +#define sk_X509_OBJECT_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_type(ptr)) +#define sk_X509_OBJECT_pop(sk) ((X509_OBJECT *)OPENSSL_sk_pop(ossl_check_X509_OBJECT_sk_type(sk))) +#define sk_X509_OBJECT_shift(sk) ((X509_OBJECT *)OPENSSL_sk_shift(ossl_check_X509_OBJECT_sk_type(sk))) +#define sk_X509_OBJECT_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_OBJECT_sk_type(sk),ossl_check_X509_OBJECT_freefunc_type(freefunc)) +#define sk_X509_OBJECT_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_type(ptr), (idx)) +#define sk_X509_OBJECT_set(sk, idx, ptr) ((X509_OBJECT *)OPENSSL_sk_set(ossl_check_X509_OBJECT_sk_type(sk), (idx), ossl_check_X509_OBJECT_type(ptr))) +#define sk_X509_OBJECT_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_type(ptr)) +#define sk_X509_OBJECT_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_type(ptr)) +#define sk_X509_OBJECT_sort(sk) OPENSSL_sk_sort(ossl_check_X509_OBJECT_sk_type(sk)) +#define sk_X509_OBJECT_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_OBJECT_sk_type(sk)) +#define sk_X509_OBJECT_dup(sk) ((STACK_OF(X509_OBJECT) *)OPENSSL_sk_dup(ossl_check_const_X509_OBJECT_sk_type(sk))) +#define sk_X509_OBJECT_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_OBJECT) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_copyfunc_type(copyfunc), ossl_check_X509_OBJECT_freefunc_type(freefunc))) +#define sk_X509_OBJECT_set_cmp_func(sk, cmp) ((sk_X509_OBJECT_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_OBJECT_sk_type(sk), ossl_check_X509_OBJECT_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(X509_VERIFY_PARAM, X509_VERIFY_PARAM, X509_VERIFY_PARAM) +#define sk_X509_VERIFY_PARAM_num(sk) OPENSSL_sk_num(ossl_check_const_X509_VERIFY_PARAM_sk_type(sk)) +#define sk_X509_VERIFY_PARAM_value(sk, idx) ((X509_VERIFY_PARAM *)OPENSSL_sk_value(ossl_check_const_X509_VERIFY_PARAM_sk_type(sk), (idx))) +#define sk_X509_VERIFY_PARAM_new(cmp) ((STACK_OF(X509_VERIFY_PARAM) *)OPENSSL_sk_new(ossl_check_X509_VERIFY_PARAM_compfunc_type(cmp))) +#define sk_X509_VERIFY_PARAM_new_null() ((STACK_OF(X509_VERIFY_PARAM) *)OPENSSL_sk_new_null()) +#define sk_X509_VERIFY_PARAM_new_reserve(cmp, n) ((STACK_OF(X509_VERIFY_PARAM) *)OPENSSL_sk_new_reserve(ossl_check_X509_VERIFY_PARAM_compfunc_type(cmp), (n))) +#define sk_X509_VERIFY_PARAM_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_VERIFY_PARAM_sk_type(sk), (n)) +#define sk_X509_VERIFY_PARAM_free(sk) OPENSSL_sk_free(ossl_check_X509_VERIFY_PARAM_sk_type(sk)) +#define sk_X509_VERIFY_PARAM_zero(sk) OPENSSL_sk_zero(ossl_check_X509_VERIFY_PARAM_sk_type(sk)) +#define sk_X509_VERIFY_PARAM_delete(sk, i) ((X509_VERIFY_PARAM *)OPENSSL_sk_delete(ossl_check_X509_VERIFY_PARAM_sk_type(sk), (i))) +#define sk_X509_VERIFY_PARAM_delete_ptr(sk, ptr) ((X509_VERIFY_PARAM *)OPENSSL_sk_delete_ptr(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_type(ptr))) +#define sk_X509_VERIFY_PARAM_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_type(ptr)) +#define sk_X509_VERIFY_PARAM_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_type(ptr)) +#define sk_X509_VERIFY_PARAM_pop(sk) ((X509_VERIFY_PARAM *)OPENSSL_sk_pop(ossl_check_X509_VERIFY_PARAM_sk_type(sk))) +#define sk_X509_VERIFY_PARAM_shift(sk) ((X509_VERIFY_PARAM *)OPENSSL_sk_shift(ossl_check_X509_VERIFY_PARAM_sk_type(sk))) +#define sk_X509_VERIFY_PARAM_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_VERIFY_PARAM_sk_type(sk),ossl_check_X509_VERIFY_PARAM_freefunc_type(freefunc)) +#define sk_X509_VERIFY_PARAM_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_type(ptr), (idx)) +#define sk_X509_VERIFY_PARAM_set(sk, idx, ptr) ((X509_VERIFY_PARAM *)OPENSSL_sk_set(ossl_check_X509_VERIFY_PARAM_sk_type(sk), (idx), ossl_check_X509_VERIFY_PARAM_type(ptr))) +#define sk_X509_VERIFY_PARAM_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_type(ptr)) +#define sk_X509_VERIFY_PARAM_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_type(ptr)) +#define sk_X509_VERIFY_PARAM_sort(sk) OPENSSL_sk_sort(ossl_check_X509_VERIFY_PARAM_sk_type(sk)) +#define sk_X509_VERIFY_PARAM_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_VERIFY_PARAM_sk_type(sk)) +#define sk_X509_VERIFY_PARAM_dup(sk) ((STACK_OF(X509_VERIFY_PARAM) *)OPENSSL_sk_dup(ossl_check_const_X509_VERIFY_PARAM_sk_type(sk))) +#define sk_X509_VERIFY_PARAM_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_VERIFY_PARAM) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_copyfunc_type(copyfunc), ossl_check_X509_VERIFY_PARAM_freefunc_type(freefunc))) +#define sk_X509_VERIFY_PARAM_set_cmp_func(sk, cmp) ((sk_X509_VERIFY_PARAM_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_VERIFY_PARAM_sk_type(sk), ossl_check_X509_VERIFY_PARAM_compfunc_type(cmp))) + int X509_STORE_set_depth(X509_STORE *store, int depth); @@ -112,115 +190,131 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); # define X509_LOOKUP_load_store(x,name) \ X509_LOOKUP_ctrl((x),X509_L_LOAD_STORE,(name),0,NULL) -# define X509_LOOKUP_load_file_with_libctx(x, name, type, libctx, propq) \ -X509_LOOKUP_ctrl_with_libctx((x), X509_L_FILE_LOAD, (name), (long)(type), NULL,\ - (libctx), (propq)) - -# define X509_LOOKUP_load_store_with_libctx(x, name, libctx, propq) \ -X509_LOOKUP_ctrl_with_libctx((x), X509_L_LOAD_STORE, (name), 0, NULL, \ - (libctx), (propq)) - -# define X509_LOOKUP_add_store_with_libctx(x, name, libctx, propq) \ -X509_LOOKUP_ctrl_with_libctx((x), X509_L_ADD_STORE, (name), 0, NULL, \ - (libctx), (propq)) - - -# define X509_V_OK 0 -# define X509_V_ERR_UNSPECIFIED 1 -# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 -# define X509_V_ERR_UNABLE_TO_GET_CRL 3 -# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 -# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 -# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 -# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 -# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 -# define X509_V_ERR_CERT_NOT_YET_VALID 9 -# define X509_V_ERR_CERT_HAS_EXPIRED 10 -# define X509_V_ERR_CRL_NOT_YET_VALID 11 -# define X509_V_ERR_CRL_HAS_EXPIRED 12 -# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 -# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 -# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 -# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 -# define X509_V_ERR_OUT_OF_MEM 17 -# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 -# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 -# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 -# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 -# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 -# define X509_V_ERR_CERT_REVOKED 23 -# define X509_V_ERR_INVALID_CA 24 -# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 -# define X509_V_ERR_INVALID_PURPOSE 26 -# define X509_V_ERR_CERT_UNTRUSTED 27 -# define X509_V_ERR_CERT_REJECTED 28 +# define X509_LOOKUP_load_file_ex(x, name, type, libctx, propq) \ +X509_LOOKUP_ctrl_ex((x), X509_L_FILE_LOAD, (name), (long)(type), NULL,\ + (libctx), (propq)) + +# define X509_LOOKUP_load_store_ex(x, name, libctx, propq) \ +X509_LOOKUP_ctrl_ex((x), X509_L_LOAD_STORE, (name), 0, NULL, \ + (libctx), (propq)) + +# define X509_LOOKUP_add_store_ex(x, name, libctx, propq) \ +X509_LOOKUP_ctrl_ex((x), X509_L_ADD_STORE, (name), 0, NULL, \ + (libctx), (propq)) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 + /* These are 'informational' when looking for issuer cert */ -# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 -# define X509_V_ERR_AKID_SKID_MISMATCH 30 -# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 -# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 -# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 -# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 -# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 -# define X509_V_ERR_INVALID_NON_CA 37 -# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 -# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 -# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 -# define X509_V_ERR_INVALID_EXTENSION 41 -# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 -# define X509_V_ERR_NO_EXPLICIT_POLICY 43 -# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 -# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 -# define X509_V_ERR_UNNESTED_RESOURCE 46 -# define X509_V_ERR_PERMITTED_VIOLATION 47 -# define X509_V_ERR_EXCLUDED_VIOLATION 48 -# define X509_V_ERR_SUBTREE_MINMAX 49 +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +# define X509_V_ERR_UNNESTED_RESOURCE 46 +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 /* The application is not happy */ -# define X509_V_ERR_APPLICATION_VERIFICATION 50 -# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 -# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 -# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 -# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +# define X509_V_ERR_APPLICATION_VERIFICATION 50 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 /* Another issuer check debug option */ -# define X509_V_ERR_PATH_LOOP 55 +# define X509_V_ERR_PATH_LOOP 55 /* Suite B mode algorithm violation */ -# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 -# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 -# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 -# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 -# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 -# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 /* Host, email and IP check errors */ -# define X509_V_ERR_HOSTNAME_MISMATCH 62 -# define X509_V_ERR_EMAIL_MISMATCH 63 -# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 /* DANE TLSA errors */ -# define X509_V_ERR_DANE_NO_MATCH 65 +# define X509_V_ERR_DANE_NO_MATCH 65 /* security level errors */ -# define X509_V_ERR_EE_KEY_TOO_SMALL 66 -# define X509_V_ERR_CA_KEY_TOO_SMALL 67 -# define X509_V_ERR_CA_MD_TOO_WEAK 68 +# define X509_V_ERR_EE_KEY_TOO_SMALL 66 +# define X509_V_ERR_CA_KEY_TOO_SMALL 67 +# define X509_V_ERR_CA_MD_TOO_WEAK 68 /* Caller error */ -# define X509_V_ERR_INVALID_CALL 69 +# define X509_V_ERR_INVALID_CALL 69 /* Issuer lookup error */ -# define X509_V_ERR_STORE_LOOKUP 70 +# define X509_V_ERR_STORE_LOOKUP 70 /* Certificate transparency */ -# define X509_V_ERR_NO_VALID_SCTS 71 +# define X509_V_ERR_NO_VALID_SCTS 71 -# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 /* OCSP status errors */ -# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ -# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ -# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ - -# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 76 -# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 77 -# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM 78 - +# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ +# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ +# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ + +# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM 76 +# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 77 + +/* Errors in case a check in X509_V_FLAG_X509_STRICT mode fails */ +# define X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY 78 +# define X509_V_ERR_INVALID_CA 79 +# define X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA 80 +# define X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN 81 +# define X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA 82 +# define X509_V_ERR_ISSUER_NAME_EMPTY 83 +# define X509_V_ERR_SUBJECT_NAME_EMPTY 84 +# define X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER 85 +# define X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER 86 +# define X509_V_ERR_EMPTY_SUBJECT_ALT_NAME 87 +# define X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL 88 +# define X509_V_ERR_CA_BCONS_NOT_CRITICAL 89 +# define X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL 90 +# define X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL 91 +# define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92 +# define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93 +# define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94 /* Certificate verify flags */ - # ifndef OPENSSL_NO_DEPRECATED_1_1_0 # define X509_V_FLAG_CB_ISSUER_CHECK 0x0 /* Deprecated */ # endif @@ -365,8 +459,7 @@ X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx); int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx); -X509_STORE_CTX *X509_STORE_CTX_new_with_libctx(OPENSSL_CTX *libctx, - const char *propq); +X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); X509_STORE_CTX *X509_STORE_CTX_new(void); int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); @@ -416,19 +509,19 @@ X509_LOOKUP_METHOD *X509_LOOKUP_store(void); typedef int (*X509_LOOKUP_ctrl_fn)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); -typedef int (*X509_LOOKUP_ctrl_with_libctx_fn)( +typedef int (*X509_LOOKUP_ctrl_ex_fn)( X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret, - OPENSSL_CTX *libctx, const char *propq); + OSSL_LIB_CTX *libctx, const char *propq); typedef int (*X509_LOOKUP_get_by_subject_fn)(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret); -typedef int (*X509_LOOKUP_get_by_subject_with_libctx_fn)(X509_LOOKUP *ctx, +typedef int (*X509_LOOKUP_get_by_subject_ex_fn)(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret, - OPENSSL_CTX *libctx, + OSSL_LIB_CTX *libctx, const char *propq); typedef int (*X509_LOOKUP_get_by_issuer_serial_fn)(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, @@ -506,27 +599,25 @@ X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); -int X509_LOOKUP_ctrl_with_libctx(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret, - OPENSSL_CTX *libctx, const char *propq); +int X509_LOOKUP_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret, OSSL_LIB_CTX *libctx, const char *propq); int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); -int X509_load_cert_file_with_libctx(X509_LOOKUP *ctx, const char *file, int type, - OPENSSL_CTX *libctx, const char *propq); +int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq); int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); -int X509_load_cert_crl_file_with_libctx(X509_LOOKUP *ctx, const char *file, - int type, OPENSSL_CTX *libctx, - const char *propq); +int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq); X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); void X509_LOOKUP_free(X509_LOOKUP *ctx); int X509_LOOKUP_init(X509_LOOKUP *ctx); int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, X509_OBJECT *ret); -int X509_LOOKUP_by_subject_with_libctx(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, - const X509_NAME *name, X509_OBJECT *ret, - OPENSSL_CTX *libctx, const char *propq); +int X509_LOOKUP_by_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq); int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, const X509_NAME *name, const ASN1_INTEGER *serial, @@ -549,16 +640,15 @@ int X509_STORE_load_locations(X509_STORE *ctx, const char *dir); int X509_STORE_set_default_paths(X509_STORE *ctx); -int X509_STORE_load_file_with_libctx(X509_STORE *ctx, const char *file, - OPENSSL_CTX *libctx, const char *propq); -int X509_STORE_load_store_with_libctx(X509_STORE *ctx, const char *store, - OPENSSL_CTX *libctx, const char *propq); -int X509_STORE_load_locations_with_libctx(X509_STORE *ctx, - const char *file, const char *dir, - OPENSSL_CTX *libctx, const char *propq); -int X509_STORE_set_default_paths_with_libctx(X509_STORE *ctx, - OPENSSL_CTX *libctx, - const char *propq); +int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_STORE_load_store_ex(X509_STORE *ctx, const char *store, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, + const char *dir, OSSL_LIB_CTX *libctx, + const char *propq); +int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, + const char *propq); #define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) diff --git a/include/openssl/x509_vfy.h.in b/include/openssl/x509_vfy.h.in new file mode 100644 index 0000000000..f4ab746f75 --- /dev/null +++ b/include/openssl/x509_vfy.h.in @@ -0,0 +1,726 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_X509_VFY_H +# define OPENSSL_X509_VFY_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_X509_VFY_H +# endif + +/* + * Protect against recursion, x509.h and x509_vfy.h each include the other. + */ +# ifndef OPENSSL_X509_H +# include +# endif + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +typedef enum { + X509_LU_NONE = 0, + X509_LU_X509, X509_LU_CRL +} X509_LOOKUP_TYPE; + +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#endif + +{- + generate_stack_macros("X509_LOOKUP") + .generate_stack_macros("X509_OBJECT") + .generate_stack_macros("X509_VERIFY_PARAM"); +-} + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); +int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); +typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, + X509_STORE_CTX *ctx, X509 *x); +typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, + X509 *x, X509 *issuer); +typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); +typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL **crl, X509 *x); +typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl); +typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx, + X509_CRL *crl, X509 *x); +typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx); +typedef STACK_OF(X509) + *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx, + const X509_NAME *nm); +typedef STACK_OF(X509_CRL) + *(*X509_STORE_CTX_lookup_crls_fn)(const X509_STORE_CTX *ctx, + const X509_NAME *nm); +typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx); + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 +# define X509_L_ADD_STORE 3 +# define X509_L_LOAD_STORE 4 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_store(x,name) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_STORE,(name),0,NULL) + +# define X509_LOOKUP_load_store(x,name) \ + X509_LOOKUP_ctrl((x),X509_L_LOAD_STORE,(name),0,NULL) + +# define X509_LOOKUP_load_file_ex(x, name, type, libctx, propq) \ +X509_LOOKUP_ctrl_ex((x), X509_L_FILE_LOAD, (name), (long)(type), NULL,\ + (libctx), (propq)) + +# define X509_LOOKUP_load_store_ex(x, name, libctx, propq) \ +X509_LOOKUP_ctrl_ex((x), X509_L_LOAD_STORE, (name), 0, NULL, \ + (libctx), (propq)) + +# define X509_LOOKUP_add_store_ex(x, name, libctx, propq) \ +X509_LOOKUP_ctrl_ex((x), X509_L_ADD_STORE, (name), 0, NULL, \ + (libctx), (propq)) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 + +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 +# define X509_V_ERR_UNNESTED_RESOURCE 46 +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +/* The application is not happy */ +# define X509_V_ERR_APPLICATION_VERIFICATION 50 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 +/* Another issuer check debug option */ +# define X509_V_ERR_PATH_LOOP 55 +/* Suite B mode algorithm violation */ +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 +/* Host, email and IP check errors */ +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 +/* DANE TLSA errors */ +# define X509_V_ERR_DANE_NO_MATCH 65 +/* security level errors */ +# define X509_V_ERR_EE_KEY_TOO_SMALL 66 +# define X509_V_ERR_CA_KEY_TOO_SMALL 67 +# define X509_V_ERR_CA_MD_TOO_WEAK 68 +/* Caller error */ +# define X509_V_ERR_INVALID_CALL 69 +/* Issuer lookup error */ +# define X509_V_ERR_STORE_LOOKUP 70 +/* Certificate transparency */ +# define X509_V_ERR_NO_VALID_SCTS 71 + +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 +/* OCSP status errors */ +# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */ +# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */ +# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */ + +# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM 76 +# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 77 + +/* Errors in case a check in X509_V_FLAG_X509_STRICT mode fails */ +# define X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY 78 +# define X509_V_ERR_INVALID_CA 79 +# define X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA 80 +# define X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN 81 +# define X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA 82 +# define X509_V_ERR_ISSUER_NAME_EMPTY 83 +# define X509_V_ERR_SUBJECT_NAME_EMPTY 84 +# define X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER 85 +# define X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER 86 +# define X509_V_ERR_EMPTY_SUBJECT_ALT_NAME 87 +# define X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL 88 +# define X509_V_ERR_CA_BCONS_NOT_CRITICAL 89 +# define X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL 90 +# define X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL 91 +# define X509_V_ERR_CA_CERT_MISSING_KEY_USAGE 92 +# define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93 +# define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94 + +/* Certificate verify flags */ +# ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define X509_V_FLAG_CB_ISSUER_CHECK 0x0 /* Deprecated */ +# endif +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check self-signed CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +# define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Suite B 128 bit only mode: not normally used */ +# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define X509_V_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define X509_V_FLAG_SUITEB_128_LOS 0x30000 +/* Allow partial chains if at least one certificate is in trusted store */ +# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.1.0. Setting this flag + * will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 +/* Do not check certificate/CRL validity against current time */ +# define X509_V_FLAG_NO_CHECK_TIME 0x200000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type, + const X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + X509_LOOKUP_TYPE type, + const X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +int X509_OBJECT_up_ref_count(X509_OBJECT *a); +X509_OBJECT *X509_OBJECT_new(void); +void X509_OBJECT_free(X509_OBJECT *a); +X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a); +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); +X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a); +int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); +int X509_STORE_lock(X509_STORE *ctx); +int X509_STORE_unlock(X509_STORE *ctx); +int X509_STORE_up_ref(X509_STORE *v); +STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *v); +STACK_OF(X509) *X509_STORE_get1_all_certs(X509_STORE *st); +STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, + const X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(const X509_STORE_CTX *st, + const X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, const X509_VERIFY_PARAM *pm); +X509_VERIFY_PARAM *X509_STORE_get0_param(const X509_STORE *ctx); + +void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify); +#define X509_STORE_set_verify_func(ctx, func) \ + X509_STORE_set_verify((ctx),(func)) +void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_fn verify); +X509_STORE_CTX_verify_fn X509_STORE_get_verify(const X509_STORE *ctx); +void X509_STORE_set_verify_cb(X509_STORE *ctx, + X509_STORE_CTX_verify_cb verify_cb); +# define X509_STORE_set_verify_cb_func(ctx,func) \ + X509_STORE_set_verify_cb((ctx),(func)) +X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(const X509_STORE *ctx); +void X509_STORE_set_get_issuer(X509_STORE *ctx, + X509_STORE_CTX_get_issuer_fn get_issuer); +X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(const X509_STORE *ctx); +void X509_STORE_set_check_issued(X509_STORE *ctx, + X509_STORE_CTX_check_issued_fn check_issued); +X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(const X509_STORE *ctx); +void X509_STORE_set_check_revocation(X509_STORE *ctx, + X509_STORE_CTX_check_revocation_fn check_revocation); +X509_STORE_CTX_check_revocation_fn + X509_STORE_get_check_revocation(const X509_STORE *ctx); +void X509_STORE_set_get_crl(X509_STORE *ctx, + X509_STORE_CTX_get_crl_fn get_crl); +X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(const X509_STORE *ctx); +void X509_STORE_set_check_crl(X509_STORE *ctx, + X509_STORE_CTX_check_crl_fn check_crl); +X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(const X509_STORE *ctx); +void X509_STORE_set_cert_crl(X509_STORE *ctx, + X509_STORE_CTX_cert_crl_fn cert_crl); +X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(const X509_STORE *ctx); +void X509_STORE_set_check_policy(X509_STORE *ctx, + X509_STORE_CTX_check_policy_fn check_policy); +X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(const X509_STORE *ctx); +void X509_STORE_set_lookup_certs(X509_STORE *ctx, + X509_STORE_CTX_lookup_certs_fn lookup_certs); +X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(const X509_STORE *ctx); +void X509_STORE_set_lookup_crls(X509_STORE *ctx, + X509_STORE_CTX_lookup_crls_fn lookup_crls); +#define X509_STORE_set_lookup_crls_cb(ctx, func) \ + X509_STORE_set_lookup_crls((ctx), (func)) +X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(const X509_STORE *ctx); +void X509_STORE_set_cleanup(X509_STORE *ctx, + X509_STORE_CTX_cleanup_fn cleanup); +X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(const X509_STORE *ctx); + +#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef) +int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data); +void *X509_STORE_get_ex_data(const X509_STORE *ctx, int idx); + +X509_STORE_CTX *X509_STORE_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq); +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_STORE *X509_STORE_CTX_get0_store(const X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_cert(const X509_STORE_CTX *ctx); +STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + X509_STORE_CTX_verify_cb verify); +X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(const X509_STORE_CTX *ctx); +X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(const X509_STORE_CTX *ctx); +X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(const X509_STORE_CTX *ctx); +X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(const X509_STORE_CTX *ctx); +X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(const X509_STORE_CTX *ctx); +X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(const X509_STORE_CTX *ctx); +X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(const X509_STORE_CTX *ctx); +X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(const X509_STORE_CTX *ctx); +X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(const X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(const X509_STORE_CTX *ctx); +X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(const X509_STORE_CTX *ctx); +X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(const X509_STORE_CTX *ctx); + +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +# define X509_STORE_CTX_get_chain X509_STORE_CTX_get0_chain +# define X509_STORE_CTX_set_chain X509_STORE_CTX_set0_untrusted +# define X509_STORE_CTX_trusted_stack X509_STORE_CTX_set0_trusted_stack +# define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject +# define X509_STORE_get1_certs X509_STORE_CTX_get1_certs +# define X509_STORE_get1_crls X509_STORE_CTX_get1_crls +/* the following macro is misspelled; use X509_STORE_get1_certs instead */ +# define X509_STORE_get1_cert X509_STORE_CTX_get1_certs +/* the following macro is misspelled; use X509_STORE_get1_crls instead */ +# define X509_STORE_get1_crl X509_STORE_CTX_get1_crls +#endif + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); +X509_LOOKUP_METHOD *X509_LOOKUP_store(void); + +typedef int (*X509_LOOKUP_ctrl_fn)(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +typedef int (*X509_LOOKUP_ctrl_ex_fn)( + X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret, + OSSL_LIB_CTX *libctx, const char *propq); + +typedef int (*X509_LOOKUP_get_by_subject_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const X509_NAME *name, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_subject_ex_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const X509_NAME *name, + X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, + const char *propq); +typedef int (*X509_LOOKUP_get_by_issuer_serial_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const X509_NAME *name, + const ASN1_INTEGER *serial, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_fingerprint_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const unsigned char* bytes, + int len, + X509_OBJECT *ret); +typedef int (*X509_LOOKUP_get_by_alias_fn)(X509_LOOKUP *ctx, + X509_LOOKUP_TYPE type, + const char *str, + int len, + X509_OBJECT *ret); + +X509_LOOKUP_METHOD *X509_LOOKUP_meth_new(const char *name); +void X509_LOOKUP_meth_free(X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_new_item(X509_LOOKUP_METHOD *method, + int (*new_item) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_new_item(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_free(X509_LOOKUP_METHOD *method, + void (*free_fn) (X509_LOOKUP *ctx)); +void (*X509_LOOKUP_meth_get_free(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_init(X509_LOOKUP_METHOD *method, + int (*init) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_init(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_shutdown(X509_LOOKUP_METHOD *method, + int (*shutdown) (X509_LOOKUP *ctx)); +int (*X509_LOOKUP_meth_get_shutdown(const X509_LOOKUP_METHOD* method)) + (X509_LOOKUP *ctx); + +int X509_LOOKUP_meth_set_ctrl(X509_LOOKUP_METHOD *method, + X509_LOOKUP_ctrl_fn ctrl_fn); +X509_LOOKUP_ctrl_fn X509_LOOKUP_meth_get_ctrl(const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_subject(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_subject_fn fn); +X509_LOOKUP_get_by_subject_fn X509_LOOKUP_meth_get_get_by_subject( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_issuer_serial(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_issuer_serial_fn fn); +X509_LOOKUP_get_by_issuer_serial_fn X509_LOOKUP_meth_get_get_by_issuer_serial( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_fingerprint(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_fingerprint_fn fn); +X509_LOOKUP_get_by_fingerprint_fn X509_LOOKUP_meth_get_get_by_fingerprint( + const X509_LOOKUP_METHOD *method); + +int X509_LOOKUP_meth_set_get_by_alias(X509_LOOKUP_METHOD *method, + X509_LOOKUP_get_by_alias_fn fn); +X509_LOOKUP_get_by_alias_fn X509_LOOKUP_meth_get_get_by_alias( + const X509_LOOKUP_METHOD *method); + + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_CTX_get_by_subject(const X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret); +X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs, + X509_LOOKUP_TYPE type, + const X509_NAME *name); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +int X509_LOOKUP_ctrl_ex(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret, OSSL_LIB_CTX *libctx, const char *propq); + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file_ex(X509_LOOKUP *ctx, const char *file, int type, + OSSL_LIB_CTX *libctx, const char *propq); + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret); +int X509_LOOKUP_by_subject_ex(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, X509_OBJECT *ret, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const X509_NAME *name, + const ASN1_INTEGER *serial, + X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type, + const char *str, int len, X509_OBJECT *ret); +int X509_LOOKUP_set_method_data(X509_LOOKUP *ctx, void *data); +void *X509_LOOKUP_get_method_data(const X509_LOOKUP *ctx); +X509_STORE *X509_LOOKUP_get_store(const X509_LOOKUP *ctx); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +int X509_STORE_load_file(X509_STORE *ctx, const char *file); +int X509_STORE_load_path(X509_STORE *ctx, const char *path); +int X509_STORE_load_store(X509_STORE *ctx, const char *store); +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, + const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); + +int X509_STORE_load_file_ex(X509_STORE *ctx, const char *file, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_STORE_load_store_ex(X509_STORE *ctx, const char *store, + OSSL_LIB_CTX *libctx, const char *propq); +int X509_STORE_load_locations_ex(X509_STORE *ctx, const char *file, + const char *dir, OSSL_LIB_CTX *libctx, + const char *propq); +int X509_STORE_set_default_paths_ex(X509_STORE *ctx, OSSL_LIB_CTX *libctx, + const char *propq); + +#define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef) +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(const X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth); +X509 *X509_STORE_CTX_get_current_cert(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x); +X509 *X509_STORE_CTX_get0_current_issuer(const X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(const X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(const X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get0_chain(const X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(const X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(const X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_num_untrusted(const X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(const X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* + * Bridge opacity barrier between libcrypt and libssl, also needed to support + * offline testing in test/danetest.c + */ +void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane); +#define DANE_FLAG_NO_DANE_EE_NAMECHECKS (1L << 0) + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(const X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level); +time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, + uint32_t flags); +uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param); + +char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx); +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param); +char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param); +void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *); +char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_count(void); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +/* Non positive return values are errors */ +#define X509_PCY_TREE_FAILURE -2 /* Failure to satisfy explicit policy */ +#define X509_PCY_TREE_INVALID -1 /* Inconsistent or invalid extensions */ +#define X509_PCY_TREE_INTERNAL 0 /* Internal error, most likely malloc */ + +/* + * Positive return values form a bit mask, all but the first are internal to + * the library and don't appear in results from X509_policy_check(). + */ +#define X509_PCY_TREE_VALID 1 /* The policy tree is valid */ +#define X509_PCY_TREE_EMPTY 2 /* The policy tree is empty */ +#define X509_PCY_TREE_EXPLICIT 4 /* Explicit policy required */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) + *X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree); + +STACK_OF(X509_POLICY_NODE) + *X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(const X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) + *X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node); +const X509_POLICY_NODE + *X509_policy_node_get0_parent(const X509_POLICY_NODE *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h index 19743b5987..94c5c5b75e 100644 --- a/include/openssl/x509err.h +++ b/include/openssl/x509err.h @@ -107,9 +107,12 @@ int ERR_load_X509_strings(void); # define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 # define X509_R_CRL_ALREADY_DELTA 127 # define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_ERROR_GETTING_MD_BY_NID 141 +# define X509_R_ERROR_USING_SIGINF_SET 142 # define X509_R_IDP_MISMATCH 128 # define X509_R_INVALID_ATTRIBUTES 138 # define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_DISTPOINT 143 # define X509_R_INVALID_FIELD_NAME 119 # define X509_R_INVALID_TRUST 123 # define X509_R_ISSUER_MISMATCH 129 @@ -133,6 +136,7 @@ int ERR_load_X509_strings(void); # define X509_R_UNKNOWN_KEY_TYPE 117 # define X509_R_UNKNOWN_NID 109 # define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_SIGID_ALGS 144 # define X509_R_UNKNOWN_TRUST_ID 120 # define X509_R_UNSUPPORTED_ALGORITHM 111 # define X509_R_WRONG_LOOKUP_TYPE 112 diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 24f5a361d0..45badef0b4 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -1,4 +1,7 @@ /* + * WARNING: do not edit! + * Generated by Makefile from include/openssl/x509v3.h.in + * * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -7,6 +10,8 @@ * https://www.openssl.org/source/license.html */ + + #ifndef OPENSSL_X509V3_H # define OPENSSL_X509V3_H # pragma once @@ -97,7 +102,32 @@ struct v3_ext_ctx { typedef struct v3_ext_method X509V3_EXT_METHOD; -DEFINE_OR_DECLARE_STACK_OF(X509V3_EXT_METHOD) +SKM_DEFINE_STACK_OF_INTERNAL(X509V3_EXT_METHOD, X509V3_EXT_METHOD, X509V3_EXT_METHOD) +#define sk_X509V3_EXT_METHOD_num(sk) OPENSSL_sk_num(ossl_check_const_X509V3_EXT_METHOD_sk_type(sk)) +#define sk_X509V3_EXT_METHOD_value(sk, idx) ((X509V3_EXT_METHOD *)OPENSSL_sk_value(ossl_check_const_X509V3_EXT_METHOD_sk_type(sk), (idx))) +#define sk_X509V3_EXT_METHOD_new(cmp) ((STACK_OF(X509V3_EXT_METHOD) *)OPENSSL_sk_new(ossl_check_X509V3_EXT_METHOD_compfunc_type(cmp))) +#define sk_X509V3_EXT_METHOD_new_null() ((STACK_OF(X509V3_EXT_METHOD) *)OPENSSL_sk_new_null()) +#define sk_X509V3_EXT_METHOD_new_reserve(cmp, n) ((STACK_OF(X509V3_EXT_METHOD) *)OPENSSL_sk_new_reserve(ossl_check_X509V3_EXT_METHOD_compfunc_type(cmp), (n))) +#define sk_X509V3_EXT_METHOD_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509V3_EXT_METHOD_sk_type(sk), (n)) +#define sk_X509V3_EXT_METHOD_free(sk) OPENSSL_sk_free(ossl_check_X509V3_EXT_METHOD_sk_type(sk)) +#define sk_X509V3_EXT_METHOD_zero(sk) OPENSSL_sk_zero(ossl_check_X509V3_EXT_METHOD_sk_type(sk)) +#define sk_X509V3_EXT_METHOD_delete(sk, i) ((X509V3_EXT_METHOD *)OPENSSL_sk_delete(ossl_check_X509V3_EXT_METHOD_sk_type(sk), (i))) +#define sk_X509V3_EXT_METHOD_delete_ptr(sk, ptr) ((X509V3_EXT_METHOD *)OPENSSL_sk_delete_ptr(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_type(ptr))) +#define sk_X509V3_EXT_METHOD_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_type(ptr)) +#define sk_X509V3_EXT_METHOD_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_type(ptr)) +#define sk_X509V3_EXT_METHOD_pop(sk) ((X509V3_EXT_METHOD *)OPENSSL_sk_pop(ossl_check_X509V3_EXT_METHOD_sk_type(sk))) +#define sk_X509V3_EXT_METHOD_shift(sk) ((X509V3_EXT_METHOD *)OPENSSL_sk_shift(ossl_check_X509V3_EXT_METHOD_sk_type(sk))) +#define sk_X509V3_EXT_METHOD_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509V3_EXT_METHOD_sk_type(sk),ossl_check_X509V3_EXT_METHOD_freefunc_type(freefunc)) +#define sk_X509V3_EXT_METHOD_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_type(ptr), (idx)) +#define sk_X509V3_EXT_METHOD_set(sk, idx, ptr) ((X509V3_EXT_METHOD *)OPENSSL_sk_set(ossl_check_X509V3_EXT_METHOD_sk_type(sk), (idx), ossl_check_X509V3_EXT_METHOD_type(ptr))) +#define sk_X509V3_EXT_METHOD_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_type(ptr)) +#define sk_X509V3_EXT_METHOD_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_type(ptr)) +#define sk_X509V3_EXT_METHOD_sort(sk) OPENSSL_sk_sort(ossl_check_X509V3_EXT_METHOD_sk_type(sk)) +#define sk_X509V3_EXT_METHOD_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509V3_EXT_METHOD_sk_type(sk)) +#define sk_X509V3_EXT_METHOD_dup(sk) ((STACK_OF(X509V3_EXT_METHOD) *)OPENSSL_sk_dup(ossl_check_const_X509V3_EXT_METHOD_sk_type(sk))) +#define sk_X509V3_EXT_METHOD_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509V3_EXT_METHOD) *)OPENSSL_sk_deep_copy(ossl_check_const_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_copyfunc_type(copyfunc), ossl_check_X509V3_EXT_METHOD_freefunc_type(freefunc))) +#define sk_X509V3_EXT_METHOD_set_cmp_func(sk, cmp) ((sk_X509V3_EXT_METHOD_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509V3_EXT_METHOD_sk_type(sk), ossl_check_X509V3_EXT_METHOD_compfunc_type(cmp))) + /* ext_flags values */ # define X509V3_EXT_DYNAMIC 0x1 @@ -163,15 +193,89 @@ typedef struct ACCESS_DESCRIPTION_st { GENERAL_NAME *location; } ACCESS_DESCRIPTION; -DEFINE_OR_DECLARE_STACK_OF(ACCESS_DESCRIPTION) -DEFINE_OR_DECLARE_STACK_OF(GENERAL_NAME) +SKM_DEFINE_STACK_OF_INTERNAL(ACCESS_DESCRIPTION, ACCESS_DESCRIPTION, ACCESS_DESCRIPTION) +#define sk_ACCESS_DESCRIPTION_num(sk) OPENSSL_sk_num(ossl_check_const_ACCESS_DESCRIPTION_sk_type(sk)) +#define sk_ACCESS_DESCRIPTION_value(sk, idx) ((ACCESS_DESCRIPTION *)OPENSSL_sk_value(ossl_check_const_ACCESS_DESCRIPTION_sk_type(sk), (idx))) +#define sk_ACCESS_DESCRIPTION_new(cmp) ((STACK_OF(ACCESS_DESCRIPTION) *)OPENSSL_sk_new(ossl_check_ACCESS_DESCRIPTION_compfunc_type(cmp))) +#define sk_ACCESS_DESCRIPTION_new_null() ((STACK_OF(ACCESS_DESCRIPTION) *)OPENSSL_sk_new_null()) +#define sk_ACCESS_DESCRIPTION_new_reserve(cmp, n) ((STACK_OF(ACCESS_DESCRIPTION) *)OPENSSL_sk_new_reserve(ossl_check_ACCESS_DESCRIPTION_compfunc_type(cmp), (n))) +#define sk_ACCESS_DESCRIPTION_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), (n)) +#define sk_ACCESS_DESCRIPTION_free(sk) OPENSSL_sk_free(ossl_check_ACCESS_DESCRIPTION_sk_type(sk)) +#define sk_ACCESS_DESCRIPTION_zero(sk) OPENSSL_sk_zero(ossl_check_ACCESS_DESCRIPTION_sk_type(sk)) +#define sk_ACCESS_DESCRIPTION_delete(sk, i) ((ACCESS_DESCRIPTION *)OPENSSL_sk_delete(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), (i))) +#define sk_ACCESS_DESCRIPTION_delete_ptr(sk, ptr) ((ACCESS_DESCRIPTION *)OPENSSL_sk_delete_ptr(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_type(ptr))) +#define sk_ACCESS_DESCRIPTION_push(sk, ptr) OPENSSL_sk_push(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_type(ptr)) +#define sk_ACCESS_DESCRIPTION_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_type(ptr)) +#define sk_ACCESS_DESCRIPTION_pop(sk) ((ACCESS_DESCRIPTION *)OPENSSL_sk_pop(ossl_check_ACCESS_DESCRIPTION_sk_type(sk))) +#define sk_ACCESS_DESCRIPTION_shift(sk) ((ACCESS_DESCRIPTION *)OPENSSL_sk_shift(ossl_check_ACCESS_DESCRIPTION_sk_type(sk))) +#define sk_ACCESS_DESCRIPTION_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ACCESS_DESCRIPTION_sk_type(sk),ossl_check_ACCESS_DESCRIPTION_freefunc_type(freefunc)) +#define sk_ACCESS_DESCRIPTION_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_type(ptr), (idx)) +#define sk_ACCESS_DESCRIPTION_set(sk, idx, ptr) ((ACCESS_DESCRIPTION *)OPENSSL_sk_set(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), (idx), ossl_check_ACCESS_DESCRIPTION_type(ptr))) +#define sk_ACCESS_DESCRIPTION_find(sk, ptr) OPENSSL_sk_find(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_type(ptr)) +#define sk_ACCESS_DESCRIPTION_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_type(ptr)) +#define sk_ACCESS_DESCRIPTION_sort(sk) OPENSSL_sk_sort(ossl_check_ACCESS_DESCRIPTION_sk_type(sk)) +#define sk_ACCESS_DESCRIPTION_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ACCESS_DESCRIPTION_sk_type(sk)) +#define sk_ACCESS_DESCRIPTION_dup(sk) ((STACK_OF(ACCESS_DESCRIPTION) *)OPENSSL_sk_dup(ossl_check_const_ACCESS_DESCRIPTION_sk_type(sk))) +#define sk_ACCESS_DESCRIPTION_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ACCESS_DESCRIPTION) *)OPENSSL_sk_deep_copy(ossl_check_const_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_copyfunc_type(copyfunc), ossl_check_ACCESS_DESCRIPTION_freefunc_type(freefunc))) +#define sk_ACCESS_DESCRIPTION_set_cmp_func(sk, cmp) ((sk_ACCESS_DESCRIPTION_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ACCESS_DESCRIPTION_sk_type(sk), ossl_check_ACCESS_DESCRIPTION_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(GENERAL_NAME, GENERAL_NAME, GENERAL_NAME) +#define sk_GENERAL_NAME_num(sk) OPENSSL_sk_num(ossl_check_const_GENERAL_NAME_sk_type(sk)) +#define sk_GENERAL_NAME_value(sk, idx) ((GENERAL_NAME *)OPENSSL_sk_value(ossl_check_const_GENERAL_NAME_sk_type(sk), (idx))) +#define sk_GENERAL_NAME_new(cmp) ((STACK_OF(GENERAL_NAME) *)OPENSSL_sk_new(ossl_check_GENERAL_NAME_compfunc_type(cmp))) +#define sk_GENERAL_NAME_new_null() ((STACK_OF(GENERAL_NAME) *)OPENSSL_sk_new_null()) +#define sk_GENERAL_NAME_new_reserve(cmp, n) ((STACK_OF(GENERAL_NAME) *)OPENSSL_sk_new_reserve(ossl_check_GENERAL_NAME_compfunc_type(cmp), (n))) +#define sk_GENERAL_NAME_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_GENERAL_NAME_sk_type(sk), (n)) +#define sk_GENERAL_NAME_free(sk) OPENSSL_sk_free(ossl_check_GENERAL_NAME_sk_type(sk)) +#define sk_GENERAL_NAME_zero(sk) OPENSSL_sk_zero(ossl_check_GENERAL_NAME_sk_type(sk)) +#define sk_GENERAL_NAME_delete(sk, i) ((GENERAL_NAME *)OPENSSL_sk_delete(ossl_check_GENERAL_NAME_sk_type(sk), (i))) +#define sk_GENERAL_NAME_delete_ptr(sk, ptr) ((GENERAL_NAME *)OPENSSL_sk_delete_ptr(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_type(ptr))) +#define sk_GENERAL_NAME_push(sk, ptr) OPENSSL_sk_push(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_type(ptr)) +#define sk_GENERAL_NAME_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_type(ptr)) +#define sk_GENERAL_NAME_pop(sk) ((GENERAL_NAME *)OPENSSL_sk_pop(ossl_check_GENERAL_NAME_sk_type(sk))) +#define sk_GENERAL_NAME_shift(sk) ((GENERAL_NAME *)OPENSSL_sk_shift(ossl_check_GENERAL_NAME_sk_type(sk))) +#define sk_GENERAL_NAME_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_GENERAL_NAME_sk_type(sk),ossl_check_GENERAL_NAME_freefunc_type(freefunc)) +#define sk_GENERAL_NAME_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_type(ptr), (idx)) +#define sk_GENERAL_NAME_set(sk, idx, ptr) ((GENERAL_NAME *)OPENSSL_sk_set(ossl_check_GENERAL_NAME_sk_type(sk), (idx), ossl_check_GENERAL_NAME_type(ptr))) +#define sk_GENERAL_NAME_find(sk, ptr) OPENSSL_sk_find(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_type(ptr)) +#define sk_GENERAL_NAME_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_type(ptr)) +#define sk_GENERAL_NAME_sort(sk) OPENSSL_sk_sort(ossl_check_GENERAL_NAME_sk_type(sk)) +#define sk_GENERAL_NAME_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_GENERAL_NAME_sk_type(sk)) +#define sk_GENERAL_NAME_dup(sk) ((STACK_OF(GENERAL_NAME) *)OPENSSL_sk_dup(ossl_check_const_GENERAL_NAME_sk_type(sk))) +#define sk_GENERAL_NAME_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(GENERAL_NAME) *)OPENSSL_sk_deep_copy(ossl_check_const_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_copyfunc_type(copyfunc), ossl_check_GENERAL_NAME_freefunc_type(freefunc))) +#define sk_GENERAL_NAME_set_cmp_func(sk, cmp) ((sk_GENERAL_NAME_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_GENERAL_NAME_sk_type(sk), ossl_check_GENERAL_NAME_compfunc_type(cmp))) + typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE; typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; -DEFINE_OR_DECLARE_STACK_OF(GENERAL_NAMES) +SKM_DEFINE_STACK_OF_INTERNAL(GENERAL_NAMES, GENERAL_NAMES, GENERAL_NAMES) +#define sk_GENERAL_NAMES_num(sk) OPENSSL_sk_num(ossl_check_const_GENERAL_NAMES_sk_type(sk)) +#define sk_GENERAL_NAMES_value(sk, idx) ((GENERAL_NAMES *)OPENSSL_sk_value(ossl_check_const_GENERAL_NAMES_sk_type(sk), (idx))) +#define sk_GENERAL_NAMES_new(cmp) ((STACK_OF(GENERAL_NAMES) *)OPENSSL_sk_new(ossl_check_GENERAL_NAMES_compfunc_type(cmp))) +#define sk_GENERAL_NAMES_new_null() ((STACK_OF(GENERAL_NAMES) *)OPENSSL_sk_new_null()) +#define sk_GENERAL_NAMES_new_reserve(cmp, n) ((STACK_OF(GENERAL_NAMES) *)OPENSSL_sk_new_reserve(ossl_check_GENERAL_NAMES_compfunc_type(cmp), (n))) +#define sk_GENERAL_NAMES_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_GENERAL_NAMES_sk_type(sk), (n)) +#define sk_GENERAL_NAMES_free(sk) OPENSSL_sk_free(ossl_check_GENERAL_NAMES_sk_type(sk)) +#define sk_GENERAL_NAMES_zero(sk) OPENSSL_sk_zero(ossl_check_GENERAL_NAMES_sk_type(sk)) +#define sk_GENERAL_NAMES_delete(sk, i) ((GENERAL_NAMES *)OPENSSL_sk_delete(ossl_check_GENERAL_NAMES_sk_type(sk), (i))) +#define sk_GENERAL_NAMES_delete_ptr(sk, ptr) ((GENERAL_NAMES *)OPENSSL_sk_delete_ptr(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_type(ptr))) +#define sk_GENERAL_NAMES_push(sk, ptr) OPENSSL_sk_push(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_type(ptr)) +#define sk_GENERAL_NAMES_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_type(ptr)) +#define sk_GENERAL_NAMES_pop(sk) ((GENERAL_NAMES *)OPENSSL_sk_pop(ossl_check_GENERAL_NAMES_sk_type(sk))) +#define sk_GENERAL_NAMES_shift(sk) ((GENERAL_NAMES *)OPENSSL_sk_shift(ossl_check_GENERAL_NAMES_sk_type(sk))) +#define sk_GENERAL_NAMES_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_GENERAL_NAMES_sk_type(sk),ossl_check_GENERAL_NAMES_freefunc_type(freefunc)) +#define sk_GENERAL_NAMES_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_type(ptr), (idx)) +#define sk_GENERAL_NAMES_set(sk, idx, ptr) ((GENERAL_NAMES *)OPENSSL_sk_set(ossl_check_GENERAL_NAMES_sk_type(sk), (idx), ossl_check_GENERAL_NAMES_type(ptr))) +#define sk_GENERAL_NAMES_find(sk, ptr) OPENSSL_sk_find(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_type(ptr)) +#define sk_GENERAL_NAMES_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_type(ptr)) +#define sk_GENERAL_NAMES_sort(sk) OPENSSL_sk_sort(ossl_check_GENERAL_NAMES_sk_type(sk)) +#define sk_GENERAL_NAMES_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_GENERAL_NAMES_sk_type(sk)) +#define sk_GENERAL_NAMES_dup(sk) ((STACK_OF(GENERAL_NAMES) *)OPENSSL_sk_dup(ossl_check_const_GENERAL_NAMES_sk_type(sk))) +#define sk_GENERAL_NAMES_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(GENERAL_NAMES) *)OPENSSL_sk_deep_copy(ossl_check_const_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_copyfunc_type(copyfunc), ossl_check_GENERAL_NAMES_freefunc_type(freefunc))) +#define sk_GENERAL_NAMES_set_cmp_func(sk, cmp) ((sk_GENERAL_NAMES_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_GENERAL_NAMES_sk_type(sk), ossl_check_GENERAL_NAMES_compfunc_type(cmp))) + typedef struct DIST_POINT_NAME_st { int type; @@ -204,7 +308,32 @@ struct DIST_POINT_st { int dp_reasons; }; -DEFINE_OR_DECLARE_STACK_OF(DIST_POINT) +SKM_DEFINE_STACK_OF_INTERNAL(DIST_POINT, DIST_POINT, DIST_POINT) +#define sk_DIST_POINT_num(sk) OPENSSL_sk_num(ossl_check_const_DIST_POINT_sk_type(sk)) +#define sk_DIST_POINT_value(sk, idx) ((DIST_POINT *)OPENSSL_sk_value(ossl_check_const_DIST_POINT_sk_type(sk), (idx))) +#define sk_DIST_POINT_new(cmp) ((STACK_OF(DIST_POINT) *)OPENSSL_sk_new(ossl_check_DIST_POINT_compfunc_type(cmp))) +#define sk_DIST_POINT_new_null() ((STACK_OF(DIST_POINT) *)OPENSSL_sk_new_null()) +#define sk_DIST_POINT_new_reserve(cmp, n) ((STACK_OF(DIST_POINT) *)OPENSSL_sk_new_reserve(ossl_check_DIST_POINT_compfunc_type(cmp), (n))) +#define sk_DIST_POINT_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_DIST_POINT_sk_type(sk), (n)) +#define sk_DIST_POINT_free(sk) OPENSSL_sk_free(ossl_check_DIST_POINT_sk_type(sk)) +#define sk_DIST_POINT_zero(sk) OPENSSL_sk_zero(ossl_check_DIST_POINT_sk_type(sk)) +#define sk_DIST_POINT_delete(sk, i) ((DIST_POINT *)OPENSSL_sk_delete(ossl_check_DIST_POINT_sk_type(sk), (i))) +#define sk_DIST_POINT_delete_ptr(sk, ptr) ((DIST_POINT *)OPENSSL_sk_delete_ptr(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_type(ptr))) +#define sk_DIST_POINT_push(sk, ptr) OPENSSL_sk_push(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_type(ptr)) +#define sk_DIST_POINT_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_type(ptr)) +#define sk_DIST_POINT_pop(sk) ((DIST_POINT *)OPENSSL_sk_pop(ossl_check_DIST_POINT_sk_type(sk))) +#define sk_DIST_POINT_shift(sk) ((DIST_POINT *)OPENSSL_sk_shift(ossl_check_DIST_POINT_sk_type(sk))) +#define sk_DIST_POINT_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_DIST_POINT_sk_type(sk),ossl_check_DIST_POINT_freefunc_type(freefunc)) +#define sk_DIST_POINT_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_type(ptr), (idx)) +#define sk_DIST_POINT_set(sk, idx, ptr) ((DIST_POINT *)OPENSSL_sk_set(ossl_check_DIST_POINT_sk_type(sk), (idx), ossl_check_DIST_POINT_type(ptr))) +#define sk_DIST_POINT_find(sk, ptr) OPENSSL_sk_find(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_type(ptr)) +#define sk_DIST_POINT_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_type(ptr)) +#define sk_DIST_POINT_sort(sk) OPENSSL_sk_sort(ossl_check_DIST_POINT_sk_type(sk)) +#define sk_DIST_POINT_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_DIST_POINT_sk_type(sk)) +#define sk_DIST_POINT_dup(sk) ((STACK_OF(DIST_POINT) *)OPENSSL_sk_dup(ossl_check_const_DIST_POINT_sk_type(sk))) +#define sk_DIST_POINT_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(DIST_POINT) *)OPENSSL_sk_deep_copy(ossl_check_const_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_copyfunc_type(copyfunc), ossl_check_DIST_POINT_freefunc_type(freefunc))) +#define sk_DIST_POINT_set_cmp_func(sk, cmp) ((sk_DIST_POINT_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_DIST_POINT_sk_type(sk), ossl_check_DIST_POINT_compfunc_type(cmp))) + typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; @@ -221,7 +350,33 @@ typedef struct SXNET_ID_st { ASN1_OCTET_STRING *user; } SXNETID; -DEFINE_OR_DECLARE_STACK_OF(SXNETID) +SKM_DEFINE_STACK_OF_INTERNAL(SXNETID, SXNETID, SXNETID) +#define sk_SXNETID_num(sk) OPENSSL_sk_num(ossl_check_const_SXNETID_sk_type(sk)) +#define sk_SXNETID_value(sk, idx) ((SXNETID *)OPENSSL_sk_value(ossl_check_const_SXNETID_sk_type(sk), (idx))) +#define sk_SXNETID_new(cmp) ((STACK_OF(SXNETID) *)OPENSSL_sk_new(ossl_check_SXNETID_compfunc_type(cmp))) +#define sk_SXNETID_new_null() ((STACK_OF(SXNETID) *)OPENSSL_sk_new_null()) +#define sk_SXNETID_new_reserve(cmp, n) ((STACK_OF(SXNETID) *)OPENSSL_sk_new_reserve(ossl_check_SXNETID_compfunc_type(cmp), (n))) +#define sk_SXNETID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_SXNETID_sk_type(sk), (n)) +#define sk_SXNETID_free(sk) OPENSSL_sk_free(ossl_check_SXNETID_sk_type(sk)) +#define sk_SXNETID_zero(sk) OPENSSL_sk_zero(ossl_check_SXNETID_sk_type(sk)) +#define sk_SXNETID_delete(sk, i) ((SXNETID *)OPENSSL_sk_delete(ossl_check_SXNETID_sk_type(sk), (i))) +#define sk_SXNETID_delete_ptr(sk, ptr) ((SXNETID *)OPENSSL_sk_delete_ptr(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_type(ptr))) +#define sk_SXNETID_push(sk, ptr) OPENSSL_sk_push(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_type(ptr)) +#define sk_SXNETID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_type(ptr)) +#define sk_SXNETID_pop(sk) ((SXNETID *)OPENSSL_sk_pop(ossl_check_SXNETID_sk_type(sk))) +#define sk_SXNETID_shift(sk) ((SXNETID *)OPENSSL_sk_shift(ossl_check_SXNETID_sk_type(sk))) +#define sk_SXNETID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_SXNETID_sk_type(sk),ossl_check_SXNETID_freefunc_type(freefunc)) +#define sk_SXNETID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_type(ptr), (idx)) +#define sk_SXNETID_set(sk, idx, ptr) ((SXNETID *)OPENSSL_sk_set(ossl_check_SXNETID_sk_type(sk), (idx), ossl_check_SXNETID_type(ptr))) +#define sk_SXNETID_find(sk, ptr) OPENSSL_sk_find(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_type(ptr)) +#define sk_SXNETID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_type(ptr)) +#define sk_SXNETID_sort(sk) OPENSSL_sk_sort(ossl_check_SXNETID_sk_type(sk)) +#define sk_SXNETID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_SXNETID_sk_type(sk)) +#define sk_SXNETID_dup(sk) ((STACK_OF(SXNETID) *)OPENSSL_sk_dup(ossl_check_const_SXNETID_sk_type(sk))) +#define sk_SXNETID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(SXNETID) *)OPENSSL_sk_deep_copy(ossl_check_const_SXNETID_sk_type(sk), ossl_check_SXNETID_copyfunc_type(copyfunc), ossl_check_SXNETID_freefunc_type(freefunc))) +#define sk_SXNETID_set_cmp_func(sk, cmp) ((sk_SXNETID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_SXNETID_sk_type(sk), ossl_check_SXNETID_compfunc_type(cmp))) + + typedef struct SXNET_st { ASN1_INTEGER *version; @@ -254,14 +409,65 @@ typedef struct POLICYQUALINFO_st { } d; } POLICYQUALINFO; -DEFINE_OR_DECLARE_STACK_OF(POLICYQUALINFO) +SKM_DEFINE_STACK_OF_INTERNAL(POLICYQUALINFO, POLICYQUALINFO, POLICYQUALINFO) +#define sk_POLICYQUALINFO_num(sk) OPENSSL_sk_num(ossl_check_const_POLICYQUALINFO_sk_type(sk)) +#define sk_POLICYQUALINFO_value(sk, idx) ((POLICYQUALINFO *)OPENSSL_sk_value(ossl_check_const_POLICYQUALINFO_sk_type(sk), (idx))) +#define sk_POLICYQUALINFO_new(cmp) ((STACK_OF(POLICYQUALINFO) *)OPENSSL_sk_new(ossl_check_POLICYQUALINFO_compfunc_type(cmp))) +#define sk_POLICYQUALINFO_new_null() ((STACK_OF(POLICYQUALINFO) *)OPENSSL_sk_new_null()) +#define sk_POLICYQUALINFO_new_reserve(cmp, n) ((STACK_OF(POLICYQUALINFO) *)OPENSSL_sk_new_reserve(ossl_check_POLICYQUALINFO_compfunc_type(cmp), (n))) +#define sk_POLICYQUALINFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_POLICYQUALINFO_sk_type(sk), (n)) +#define sk_POLICYQUALINFO_free(sk) OPENSSL_sk_free(ossl_check_POLICYQUALINFO_sk_type(sk)) +#define sk_POLICYQUALINFO_zero(sk) OPENSSL_sk_zero(ossl_check_POLICYQUALINFO_sk_type(sk)) +#define sk_POLICYQUALINFO_delete(sk, i) ((POLICYQUALINFO *)OPENSSL_sk_delete(ossl_check_POLICYQUALINFO_sk_type(sk), (i))) +#define sk_POLICYQUALINFO_delete_ptr(sk, ptr) ((POLICYQUALINFO *)OPENSSL_sk_delete_ptr(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_type(ptr))) +#define sk_POLICYQUALINFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_type(ptr)) +#define sk_POLICYQUALINFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_type(ptr)) +#define sk_POLICYQUALINFO_pop(sk) ((POLICYQUALINFO *)OPENSSL_sk_pop(ossl_check_POLICYQUALINFO_sk_type(sk))) +#define sk_POLICYQUALINFO_shift(sk) ((POLICYQUALINFO *)OPENSSL_sk_shift(ossl_check_POLICYQUALINFO_sk_type(sk))) +#define sk_POLICYQUALINFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_POLICYQUALINFO_sk_type(sk),ossl_check_POLICYQUALINFO_freefunc_type(freefunc)) +#define sk_POLICYQUALINFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_type(ptr), (idx)) +#define sk_POLICYQUALINFO_set(sk, idx, ptr) ((POLICYQUALINFO *)OPENSSL_sk_set(ossl_check_POLICYQUALINFO_sk_type(sk), (idx), ossl_check_POLICYQUALINFO_type(ptr))) +#define sk_POLICYQUALINFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_type(ptr)) +#define sk_POLICYQUALINFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_type(ptr)) +#define sk_POLICYQUALINFO_sort(sk) OPENSSL_sk_sort(ossl_check_POLICYQUALINFO_sk_type(sk)) +#define sk_POLICYQUALINFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_POLICYQUALINFO_sk_type(sk)) +#define sk_POLICYQUALINFO_dup(sk) ((STACK_OF(POLICYQUALINFO) *)OPENSSL_sk_dup(ossl_check_const_POLICYQUALINFO_sk_type(sk))) +#define sk_POLICYQUALINFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(POLICYQUALINFO) *)OPENSSL_sk_deep_copy(ossl_check_const_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_copyfunc_type(copyfunc), ossl_check_POLICYQUALINFO_freefunc_type(freefunc))) +#define sk_POLICYQUALINFO_set_cmp_func(sk, cmp) ((sk_POLICYQUALINFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_POLICYQUALINFO_sk_type(sk), ossl_check_POLICYQUALINFO_compfunc_type(cmp))) + + typedef struct POLICYINFO_st { ASN1_OBJECT *policyid; STACK_OF(POLICYQUALINFO) *qualifiers; } POLICYINFO; -DEFINE_OR_DECLARE_STACK_OF(POLICYINFO) +SKM_DEFINE_STACK_OF_INTERNAL(POLICYINFO, POLICYINFO, POLICYINFO) +#define sk_POLICYINFO_num(sk) OPENSSL_sk_num(ossl_check_const_POLICYINFO_sk_type(sk)) +#define sk_POLICYINFO_value(sk, idx) ((POLICYINFO *)OPENSSL_sk_value(ossl_check_const_POLICYINFO_sk_type(sk), (idx))) +#define sk_POLICYINFO_new(cmp) ((STACK_OF(POLICYINFO) *)OPENSSL_sk_new(ossl_check_POLICYINFO_compfunc_type(cmp))) +#define sk_POLICYINFO_new_null() ((STACK_OF(POLICYINFO) *)OPENSSL_sk_new_null()) +#define sk_POLICYINFO_new_reserve(cmp, n) ((STACK_OF(POLICYINFO) *)OPENSSL_sk_new_reserve(ossl_check_POLICYINFO_compfunc_type(cmp), (n))) +#define sk_POLICYINFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_POLICYINFO_sk_type(sk), (n)) +#define sk_POLICYINFO_free(sk) OPENSSL_sk_free(ossl_check_POLICYINFO_sk_type(sk)) +#define sk_POLICYINFO_zero(sk) OPENSSL_sk_zero(ossl_check_POLICYINFO_sk_type(sk)) +#define sk_POLICYINFO_delete(sk, i) ((POLICYINFO *)OPENSSL_sk_delete(ossl_check_POLICYINFO_sk_type(sk), (i))) +#define sk_POLICYINFO_delete_ptr(sk, ptr) ((POLICYINFO *)OPENSSL_sk_delete_ptr(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_type(ptr))) +#define sk_POLICYINFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_type(ptr)) +#define sk_POLICYINFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_type(ptr)) +#define sk_POLICYINFO_pop(sk) ((POLICYINFO *)OPENSSL_sk_pop(ossl_check_POLICYINFO_sk_type(sk))) +#define sk_POLICYINFO_shift(sk) ((POLICYINFO *)OPENSSL_sk_shift(ossl_check_POLICYINFO_sk_type(sk))) +#define sk_POLICYINFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_POLICYINFO_sk_type(sk),ossl_check_POLICYINFO_freefunc_type(freefunc)) +#define sk_POLICYINFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_type(ptr), (idx)) +#define sk_POLICYINFO_set(sk, idx, ptr) ((POLICYINFO *)OPENSSL_sk_set(ossl_check_POLICYINFO_sk_type(sk), (idx), ossl_check_POLICYINFO_type(ptr))) +#define sk_POLICYINFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_type(ptr)) +#define sk_POLICYINFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_type(ptr)) +#define sk_POLICYINFO_sort(sk) OPENSSL_sk_sort(ossl_check_POLICYINFO_sk_type(sk)) +#define sk_POLICYINFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_POLICYINFO_sk_type(sk)) +#define sk_POLICYINFO_dup(sk) ((STACK_OF(POLICYINFO) *)OPENSSL_sk_dup(ossl_check_const_POLICYINFO_sk_type(sk))) +#define sk_POLICYINFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(POLICYINFO) *)OPENSSL_sk_deep_copy(ossl_check_const_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_copyfunc_type(copyfunc), ossl_check_POLICYINFO_freefunc_type(freefunc))) +#define sk_POLICYINFO_set_cmp_func(sk, cmp) ((sk_POLICYINFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_POLICYINFO_sk_type(sk), ossl_check_POLICYINFO_compfunc_type(cmp))) + typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; @@ -270,7 +476,32 @@ typedef struct POLICY_MAPPING_st { ASN1_OBJECT *subjectDomainPolicy; } POLICY_MAPPING; -DEFINE_OR_DECLARE_STACK_OF(POLICY_MAPPING) +SKM_DEFINE_STACK_OF_INTERNAL(POLICY_MAPPING, POLICY_MAPPING, POLICY_MAPPING) +#define sk_POLICY_MAPPING_num(sk) OPENSSL_sk_num(ossl_check_const_POLICY_MAPPING_sk_type(sk)) +#define sk_POLICY_MAPPING_value(sk, idx) ((POLICY_MAPPING *)OPENSSL_sk_value(ossl_check_const_POLICY_MAPPING_sk_type(sk), (idx))) +#define sk_POLICY_MAPPING_new(cmp) ((STACK_OF(POLICY_MAPPING) *)OPENSSL_sk_new(ossl_check_POLICY_MAPPING_compfunc_type(cmp))) +#define sk_POLICY_MAPPING_new_null() ((STACK_OF(POLICY_MAPPING) *)OPENSSL_sk_new_null()) +#define sk_POLICY_MAPPING_new_reserve(cmp, n) ((STACK_OF(POLICY_MAPPING) *)OPENSSL_sk_new_reserve(ossl_check_POLICY_MAPPING_compfunc_type(cmp), (n))) +#define sk_POLICY_MAPPING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_POLICY_MAPPING_sk_type(sk), (n)) +#define sk_POLICY_MAPPING_free(sk) OPENSSL_sk_free(ossl_check_POLICY_MAPPING_sk_type(sk)) +#define sk_POLICY_MAPPING_zero(sk) OPENSSL_sk_zero(ossl_check_POLICY_MAPPING_sk_type(sk)) +#define sk_POLICY_MAPPING_delete(sk, i) ((POLICY_MAPPING *)OPENSSL_sk_delete(ossl_check_POLICY_MAPPING_sk_type(sk), (i))) +#define sk_POLICY_MAPPING_delete_ptr(sk, ptr) ((POLICY_MAPPING *)OPENSSL_sk_delete_ptr(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_type(ptr))) +#define sk_POLICY_MAPPING_push(sk, ptr) OPENSSL_sk_push(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_type(ptr)) +#define sk_POLICY_MAPPING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_type(ptr)) +#define sk_POLICY_MAPPING_pop(sk) ((POLICY_MAPPING *)OPENSSL_sk_pop(ossl_check_POLICY_MAPPING_sk_type(sk))) +#define sk_POLICY_MAPPING_shift(sk) ((POLICY_MAPPING *)OPENSSL_sk_shift(ossl_check_POLICY_MAPPING_sk_type(sk))) +#define sk_POLICY_MAPPING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_POLICY_MAPPING_sk_type(sk),ossl_check_POLICY_MAPPING_freefunc_type(freefunc)) +#define sk_POLICY_MAPPING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_type(ptr), (idx)) +#define sk_POLICY_MAPPING_set(sk, idx, ptr) ((POLICY_MAPPING *)OPENSSL_sk_set(ossl_check_POLICY_MAPPING_sk_type(sk), (idx), ossl_check_POLICY_MAPPING_type(ptr))) +#define sk_POLICY_MAPPING_find(sk, ptr) OPENSSL_sk_find(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_type(ptr)) +#define sk_POLICY_MAPPING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_type(ptr)) +#define sk_POLICY_MAPPING_sort(sk) OPENSSL_sk_sort(ossl_check_POLICY_MAPPING_sk_type(sk)) +#define sk_POLICY_MAPPING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_POLICY_MAPPING_sk_type(sk)) +#define sk_POLICY_MAPPING_dup(sk) ((STACK_OF(POLICY_MAPPING) *)OPENSSL_sk_dup(ossl_check_const_POLICY_MAPPING_sk_type(sk))) +#define sk_POLICY_MAPPING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(POLICY_MAPPING) *)OPENSSL_sk_deep_copy(ossl_check_const_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_copyfunc_type(copyfunc), ossl_check_POLICY_MAPPING_freefunc_type(freefunc))) +#define sk_POLICY_MAPPING_set_cmp_func(sk, cmp) ((sk_POLICY_MAPPING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_POLICY_MAPPING_sk_type(sk), ossl_check_POLICY_MAPPING_compfunc_type(cmp))) + typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; @@ -280,7 +511,32 @@ typedef struct GENERAL_SUBTREE_st { ASN1_INTEGER *maximum; } GENERAL_SUBTREE; -DEFINE_OR_DECLARE_STACK_OF(GENERAL_SUBTREE) +SKM_DEFINE_STACK_OF_INTERNAL(GENERAL_SUBTREE, GENERAL_SUBTREE, GENERAL_SUBTREE) +#define sk_GENERAL_SUBTREE_num(sk) OPENSSL_sk_num(ossl_check_const_GENERAL_SUBTREE_sk_type(sk)) +#define sk_GENERAL_SUBTREE_value(sk, idx) ((GENERAL_SUBTREE *)OPENSSL_sk_value(ossl_check_const_GENERAL_SUBTREE_sk_type(sk), (idx))) +#define sk_GENERAL_SUBTREE_new(cmp) ((STACK_OF(GENERAL_SUBTREE) *)OPENSSL_sk_new(ossl_check_GENERAL_SUBTREE_compfunc_type(cmp))) +#define sk_GENERAL_SUBTREE_new_null() ((STACK_OF(GENERAL_SUBTREE) *)OPENSSL_sk_new_null()) +#define sk_GENERAL_SUBTREE_new_reserve(cmp, n) ((STACK_OF(GENERAL_SUBTREE) *)OPENSSL_sk_new_reserve(ossl_check_GENERAL_SUBTREE_compfunc_type(cmp), (n))) +#define sk_GENERAL_SUBTREE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_GENERAL_SUBTREE_sk_type(sk), (n)) +#define sk_GENERAL_SUBTREE_free(sk) OPENSSL_sk_free(ossl_check_GENERAL_SUBTREE_sk_type(sk)) +#define sk_GENERAL_SUBTREE_zero(sk) OPENSSL_sk_zero(ossl_check_GENERAL_SUBTREE_sk_type(sk)) +#define sk_GENERAL_SUBTREE_delete(sk, i) ((GENERAL_SUBTREE *)OPENSSL_sk_delete(ossl_check_GENERAL_SUBTREE_sk_type(sk), (i))) +#define sk_GENERAL_SUBTREE_delete_ptr(sk, ptr) ((GENERAL_SUBTREE *)OPENSSL_sk_delete_ptr(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_type(ptr))) +#define sk_GENERAL_SUBTREE_push(sk, ptr) OPENSSL_sk_push(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_type(ptr)) +#define sk_GENERAL_SUBTREE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_type(ptr)) +#define sk_GENERAL_SUBTREE_pop(sk) ((GENERAL_SUBTREE *)OPENSSL_sk_pop(ossl_check_GENERAL_SUBTREE_sk_type(sk))) +#define sk_GENERAL_SUBTREE_shift(sk) ((GENERAL_SUBTREE *)OPENSSL_sk_shift(ossl_check_GENERAL_SUBTREE_sk_type(sk))) +#define sk_GENERAL_SUBTREE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_GENERAL_SUBTREE_sk_type(sk),ossl_check_GENERAL_SUBTREE_freefunc_type(freefunc)) +#define sk_GENERAL_SUBTREE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_type(ptr), (idx)) +#define sk_GENERAL_SUBTREE_set(sk, idx, ptr) ((GENERAL_SUBTREE *)OPENSSL_sk_set(ossl_check_GENERAL_SUBTREE_sk_type(sk), (idx), ossl_check_GENERAL_SUBTREE_type(ptr))) +#define sk_GENERAL_SUBTREE_find(sk, ptr) OPENSSL_sk_find(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_type(ptr)) +#define sk_GENERAL_SUBTREE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_type(ptr)) +#define sk_GENERAL_SUBTREE_sort(sk) OPENSSL_sk_sort(ossl_check_GENERAL_SUBTREE_sk_type(sk)) +#define sk_GENERAL_SUBTREE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_GENERAL_SUBTREE_sk_type(sk)) +#define sk_GENERAL_SUBTREE_dup(sk) ((STACK_OF(GENERAL_SUBTREE) *)OPENSSL_sk_dup(ossl_check_const_GENERAL_SUBTREE_sk_type(sk))) +#define sk_GENERAL_SUBTREE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(GENERAL_SUBTREE) *)OPENSSL_sk_deep_copy(ossl_check_const_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_copyfunc_type(copyfunc), ossl_check_GENERAL_SUBTREE_freefunc_type(freefunc))) +#define sk_GENERAL_SUBTREE_set_cmp_func(sk, cmp) ((sk_GENERAL_SUBTREE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_GENERAL_SUBTREE_sk_type(sk), ossl_check_GENERAL_SUBTREE_compfunc_type(cmp))) + struct NAME_CONSTRAINTS_st { STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; @@ -364,8 +620,7 @@ struct ISSUING_DIST_POINT_st { # define EXFLAG_NSCERT 0x8 # define EXFLAG_CA 0x10 -/* Really self issued not necessarily self signed */ -# define EXFLAG_SI 0x20 +# define EXFLAG_SI 0x20 /* self-issued, maybe not self-signed */ # define EXFLAG_V1 0x40 # define EXFLAG_INVALID 0x80 /* EXFLAG_SET is set to indicate that some values have been precomputed */ @@ -375,8 +630,12 @@ struct ISSUING_DIST_POINT_st { # define EXFLAG_INVALID_POLICY 0x800 # define EXFLAG_FRESHEST 0x1000 -/* Self signed */ -# define EXFLAG_SS 0x2000 +# define EXFLAG_SS 0x2000 /* cert is apparently self-signed */ + +# define EXFLAG_BCONS_CRITICAL 0x10000 +# define EXFLAG_AKID_CRITICAL 0x20000 +# define EXFLAG_SKID_CRITICAL 0x40000 +# define EXFLAG_SAN_CRITICAL 0x80000 # define KU_DIGITAL_SIGNATURE 0x0080 # define KU_NON_REPUDIATION 0x0040 @@ -420,7 +679,33 @@ typedef struct x509_purpose_st { void *usr_data; } X509_PURPOSE; -DEFINE_OR_DECLARE_STACK_OF(X509_PURPOSE) +SKM_DEFINE_STACK_OF_INTERNAL(X509_PURPOSE, X509_PURPOSE, X509_PURPOSE) +#define sk_X509_PURPOSE_num(sk) OPENSSL_sk_num(ossl_check_const_X509_PURPOSE_sk_type(sk)) +#define sk_X509_PURPOSE_value(sk, idx) ((X509_PURPOSE *)OPENSSL_sk_value(ossl_check_const_X509_PURPOSE_sk_type(sk), (idx))) +#define sk_X509_PURPOSE_new(cmp) ((STACK_OF(X509_PURPOSE) *)OPENSSL_sk_new(ossl_check_X509_PURPOSE_compfunc_type(cmp))) +#define sk_X509_PURPOSE_new_null() ((STACK_OF(X509_PURPOSE) *)OPENSSL_sk_new_null()) +#define sk_X509_PURPOSE_new_reserve(cmp, n) ((STACK_OF(X509_PURPOSE) *)OPENSSL_sk_new_reserve(ossl_check_X509_PURPOSE_compfunc_type(cmp), (n))) +#define sk_X509_PURPOSE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_PURPOSE_sk_type(sk), (n)) +#define sk_X509_PURPOSE_free(sk) OPENSSL_sk_free(ossl_check_X509_PURPOSE_sk_type(sk)) +#define sk_X509_PURPOSE_zero(sk) OPENSSL_sk_zero(ossl_check_X509_PURPOSE_sk_type(sk)) +#define sk_X509_PURPOSE_delete(sk, i) ((X509_PURPOSE *)OPENSSL_sk_delete(ossl_check_X509_PURPOSE_sk_type(sk), (i))) +#define sk_X509_PURPOSE_delete_ptr(sk, ptr) ((X509_PURPOSE *)OPENSSL_sk_delete_ptr(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_type(ptr))) +#define sk_X509_PURPOSE_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_type(ptr)) +#define sk_X509_PURPOSE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_type(ptr)) +#define sk_X509_PURPOSE_pop(sk) ((X509_PURPOSE *)OPENSSL_sk_pop(ossl_check_X509_PURPOSE_sk_type(sk))) +#define sk_X509_PURPOSE_shift(sk) ((X509_PURPOSE *)OPENSSL_sk_shift(ossl_check_X509_PURPOSE_sk_type(sk))) +#define sk_X509_PURPOSE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_PURPOSE_sk_type(sk),ossl_check_X509_PURPOSE_freefunc_type(freefunc)) +#define sk_X509_PURPOSE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_type(ptr), (idx)) +#define sk_X509_PURPOSE_set(sk, idx, ptr) ((X509_PURPOSE *)OPENSSL_sk_set(ossl_check_X509_PURPOSE_sk_type(sk), (idx), ossl_check_X509_PURPOSE_type(ptr))) +#define sk_X509_PURPOSE_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_type(ptr)) +#define sk_X509_PURPOSE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_type(ptr)) +#define sk_X509_PURPOSE_sort(sk) OPENSSL_sk_sort(ossl_check_X509_PURPOSE_sk_type(sk)) +#define sk_X509_PURPOSE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_PURPOSE_sk_type(sk)) +#define sk_X509_PURPOSE_dup(sk) ((STACK_OF(X509_PURPOSE) *)OPENSSL_sk_dup(ossl_check_const_X509_PURPOSE_sk_type(sk))) +#define sk_X509_PURPOSE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_PURPOSE) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_copyfunc_type(copyfunc), ossl_check_X509_PURPOSE_freefunc_type(freefunc))) +#define sk_X509_PURPOSE_set_cmp_func(sk, cmp) ((sk_X509_PURPOSE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_PURPOSE_sk_type(sk), ossl_check_X509_PURPOSE_compfunc_type(cmp))) + + # define X509_PURPOSE_SSL_CLIENT 1 # define X509_PURPOSE_SSL_SERVER 2 @@ -732,7 +1017,33 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, unsigned long chtype); void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); -DEFINE_OR_DECLARE_STACK_OF(X509_POLICY_NODE) +SKM_DEFINE_STACK_OF_INTERNAL(X509_POLICY_NODE, X509_POLICY_NODE, X509_POLICY_NODE) +#define sk_X509_POLICY_NODE_num(sk) OPENSSL_sk_num(ossl_check_const_X509_POLICY_NODE_sk_type(sk)) +#define sk_X509_POLICY_NODE_value(sk, idx) ((X509_POLICY_NODE *)OPENSSL_sk_value(ossl_check_const_X509_POLICY_NODE_sk_type(sk), (idx))) +#define sk_X509_POLICY_NODE_new(cmp) ((STACK_OF(X509_POLICY_NODE) *)OPENSSL_sk_new(ossl_check_X509_POLICY_NODE_compfunc_type(cmp))) +#define sk_X509_POLICY_NODE_new_null() ((STACK_OF(X509_POLICY_NODE) *)OPENSSL_sk_new_null()) +#define sk_X509_POLICY_NODE_new_reserve(cmp, n) ((STACK_OF(X509_POLICY_NODE) *)OPENSSL_sk_new_reserve(ossl_check_X509_POLICY_NODE_compfunc_type(cmp), (n))) +#define sk_X509_POLICY_NODE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_X509_POLICY_NODE_sk_type(sk), (n)) +#define sk_X509_POLICY_NODE_free(sk) OPENSSL_sk_free(ossl_check_X509_POLICY_NODE_sk_type(sk)) +#define sk_X509_POLICY_NODE_zero(sk) OPENSSL_sk_zero(ossl_check_X509_POLICY_NODE_sk_type(sk)) +#define sk_X509_POLICY_NODE_delete(sk, i) ((X509_POLICY_NODE *)OPENSSL_sk_delete(ossl_check_X509_POLICY_NODE_sk_type(sk), (i))) +#define sk_X509_POLICY_NODE_delete_ptr(sk, ptr) ((X509_POLICY_NODE *)OPENSSL_sk_delete_ptr(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_type(ptr))) +#define sk_X509_POLICY_NODE_push(sk, ptr) OPENSSL_sk_push(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_type(ptr)) +#define sk_X509_POLICY_NODE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_type(ptr)) +#define sk_X509_POLICY_NODE_pop(sk) ((X509_POLICY_NODE *)OPENSSL_sk_pop(ossl_check_X509_POLICY_NODE_sk_type(sk))) +#define sk_X509_POLICY_NODE_shift(sk) ((X509_POLICY_NODE *)OPENSSL_sk_shift(ossl_check_X509_POLICY_NODE_sk_type(sk))) +#define sk_X509_POLICY_NODE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_X509_POLICY_NODE_sk_type(sk),ossl_check_X509_POLICY_NODE_freefunc_type(freefunc)) +#define sk_X509_POLICY_NODE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_type(ptr), (idx)) +#define sk_X509_POLICY_NODE_set(sk, idx, ptr) ((X509_POLICY_NODE *)OPENSSL_sk_set(ossl_check_X509_POLICY_NODE_sk_type(sk), (idx), ossl_check_X509_POLICY_NODE_type(ptr))) +#define sk_X509_POLICY_NODE_find(sk, ptr) OPENSSL_sk_find(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_type(ptr)) +#define sk_X509_POLICY_NODE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_type(ptr)) +#define sk_X509_POLICY_NODE_sort(sk) OPENSSL_sk_sort(ossl_check_X509_POLICY_NODE_sk_type(sk)) +#define sk_X509_POLICY_NODE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_X509_POLICY_NODE_sk_type(sk)) +#define sk_X509_POLICY_NODE_dup(sk) ((STACK_OF(X509_POLICY_NODE) *)OPENSSL_sk_dup(ossl_check_const_X509_POLICY_NODE_sk_type(sk))) +#define sk_X509_POLICY_NODE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(X509_POLICY_NODE) *)OPENSSL_sk_deep_copy(ossl_check_const_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_copyfunc_type(copyfunc), ossl_check_X509_POLICY_NODE_freefunc_type(freefunc))) +#define sk_X509_POLICY_NODE_set_cmp_func(sk, cmp) ((sk_X509_POLICY_NODE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_X509_POLICY_NODE_sk_type(sk), ossl_check_X509_POLICY_NODE_compfunc_type(cmp))) + + #ifndef OPENSSL_NO_RFC3779 typedef struct ASRange_st { @@ -750,7 +1061,32 @@ typedef struct ASIdOrRange_st { } u; } ASIdOrRange; -DEFINE_OR_DECLARE_STACK_OF(ASIdOrRange) +SKM_DEFINE_STACK_OF_INTERNAL(ASIdOrRange, ASIdOrRange, ASIdOrRange) +#define sk_ASIdOrRange_num(sk) OPENSSL_sk_num(ossl_check_const_ASIdOrRange_sk_type(sk)) +#define sk_ASIdOrRange_value(sk, idx) ((ASIdOrRange *)OPENSSL_sk_value(ossl_check_const_ASIdOrRange_sk_type(sk), (idx))) +#define sk_ASIdOrRange_new(cmp) ((STACK_OF(ASIdOrRange) *)OPENSSL_sk_new(ossl_check_ASIdOrRange_compfunc_type(cmp))) +#define sk_ASIdOrRange_new_null() ((STACK_OF(ASIdOrRange) *)OPENSSL_sk_new_null()) +#define sk_ASIdOrRange_new_reserve(cmp, n) ((STACK_OF(ASIdOrRange) *)OPENSSL_sk_new_reserve(ossl_check_ASIdOrRange_compfunc_type(cmp), (n))) +#define sk_ASIdOrRange_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASIdOrRange_sk_type(sk), (n)) +#define sk_ASIdOrRange_free(sk) OPENSSL_sk_free(ossl_check_ASIdOrRange_sk_type(sk)) +#define sk_ASIdOrRange_zero(sk) OPENSSL_sk_zero(ossl_check_ASIdOrRange_sk_type(sk)) +#define sk_ASIdOrRange_delete(sk, i) ((ASIdOrRange *)OPENSSL_sk_delete(ossl_check_ASIdOrRange_sk_type(sk), (i))) +#define sk_ASIdOrRange_delete_ptr(sk, ptr) ((ASIdOrRange *)OPENSSL_sk_delete_ptr(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_type(ptr))) +#define sk_ASIdOrRange_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_type(ptr)) +#define sk_ASIdOrRange_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_type(ptr)) +#define sk_ASIdOrRange_pop(sk) ((ASIdOrRange *)OPENSSL_sk_pop(ossl_check_ASIdOrRange_sk_type(sk))) +#define sk_ASIdOrRange_shift(sk) ((ASIdOrRange *)OPENSSL_sk_shift(ossl_check_ASIdOrRange_sk_type(sk))) +#define sk_ASIdOrRange_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASIdOrRange_sk_type(sk),ossl_check_ASIdOrRange_freefunc_type(freefunc)) +#define sk_ASIdOrRange_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_type(ptr), (idx)) +#define sk_ASIdOrRange_set(sk, idx, ptr) ((ASIdOrRange *)OPENSSL_sk_set(ossl_check_ASIdOrRange_sk_type(sk), (idx), ossl_check_ASIdOrRange_type(ptr))) +#define sk_ASIdOrRange_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_type(ptr)) +#define sk_ASIdOrRange_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_type(ptr)) +#define sk_ASIdOrRange_sort(sk) OPENSSL_sk_sort(ossl_check_ASIdOrRange_sk_type(sk)) +#define sk_ASIdOrRange_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASIdOrRange_sk_type(sk)) +#define sk_ASIdOrRange_dup(sk) ((STACK_OF(ASIdOrRange) *)OPENSSL_sk_dup(ossl_check_const_ASIdOrRange_sk_type(sk))) +#define sk_ASIdOrRange_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASIdOrRange) *)OPENSSL_sk_deep_copy(ossl_check_const_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_copyfunc_type(copyfunc), ossl_check_ASIdOrRange_freefunc_type(freefunc))) +#define sk_ASIdOrRange_set_cmp_func(sk, cmp) ((sk_ASIdOrRange_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASIdOrRange_sk_type(sk), ossl_check_ASIdOrRange_compfunc_type(cmp))) + typedef STACK_OF(ASIdOrRange) ASIdOrRanges; @@ -789,7 +1125,32 @@ typedef struct IPAddressOrRange_st { } u; } IPAddressOrRange; -DEFINE_OR_DECLARE_STACK_OF(IPAddressOrRange) +SKM_DEFINE_STACK_OF_INTERNAL(IPAddressOrRange, IPAddressOrRange, IPAddressOrRange) +#define sk_IPAddressOrRange_num(sk) OPENSSL_sk_num(ossl_check_const_IPAddressOrRange_sk_type(sk)) +#define sk_IPAddressOrRange_value(sk, idx) ((IPAddressOrRange *)OPENSSL_sk_value(ossl_check_const_IPAddressOrRange_sk_type(sk), (idx))) +#define sk_IPAddressOrRange_new(cmp) ((STACK_OF(IPAddressOrRange) *)OPENSSL_sk_new(ossl_check_IPAddressOrRange_compfunc_type(cmp))) +#define sk_IPAddressOrRange_new_null() ((STACK_OF(IPAddressOrRange) *)OPENSSL_sk_new_null()) +#define sk_IPAddressOrRange_new_reserve(cmp, n) ((STACK_OF(IPAddressOrRange) *)OPENSSL_sk_new_reserve(ossl_check_IPAddressOrRange_compfunc_type(cmp), (n))) +#define sk_IPAddressOrRange_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_IPAddressOrRange_sk_type(sk), (n)) +#define sk_IPAddressOrRange_free(sk) OPENSSL_sk_free(ossl_check_IPAddressOrRange_sk_type(sk)) +#define sk_IPAddressOrRange_zero(sk) OPENSSL_sk_zero(ossl_check_IPAddressOrRange_sk_type(sk)) +#define sk_IPAddressOrRange_delete(sk, i) ((IPAddressOrRange *)OPENSSL_sk_delete(ossl_check_IPAddressOrRange_sk_type(sk), (i))) +#define sk_IPAddressOrRange_delete_ptr(sk, ptr) ((IPAddressOrRange *)OPENSSL_sk_delete_ptr(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_type(ptr))) +#define sk_IPAddressOrRange_push(sk, ptr) OPENSSL_sk_push(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_type(ptr)) +#define sk_IPAddressOrRange_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_type(ptr)) +#define sk_IPAddressOrRange_pop(sk) ((IPAddressOrRange *)OPENSSL_sk_pop(ossl_check_IPAddressOrRange_sk_type(sk))) +#define sk_IPAddressOrRange_shift(sk) ((IPAddressOrRange *)OPENSSL_sk_shift(ossl_check_IPAddressOrRange_sk_type(sk))) +#define sk_IPAddressOrRange_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_IPAddressOrRange_sk_type(sk),ossl_check_IPAddressOrRange_freefunc_type(freefunc)) +#define sk_IPAddressOrRange_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_type(ptr), (idx)) +#define sk_IPAddressOrRange_set(sk, idx, ptr) ((IPAddressOrRange *)OPENSSL_sk_set(ossl_check_IPAddressOrRange_sk_type(sk), (idx), ossl_check_IPAddressOrRange_type(ptr))) +#define sk_IPAddressOrRange_find(sk, ptr) OPENSSL_sk_find(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_type(ptr)) +#define sk_IPAddressOrRange_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_type(ptr)) +#define sk_IPAddressOrRange_sort(sk) OPENSSL_sk_sort(ossl_check_IPAddressOrRange_sk_type(sk)) +#define sk_IPAddressOrRange_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_IPAddressOrRange_sk_type(sk)) +#define sk_IPAddressOrRange_dup(sk) ((STACK_OF(IPAddressOrRange) *)OPENSSL_sk_dup(ossl_check_const_IPAddressOrRange_sk_type(sk))) +#define sk_IPAddressOrRange_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(IPAddressOrRange) *)OPENSSL_sk_deep_copy(ossl_check_const_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_copyfunc_type(copyfunc), ossl_check_IPAddressOrRange_freefunc_type(freefunc))) +#define sk_IPAddressOrRange_set_cmp_func(sk, cmp) ((sk_IPAddressOrRange_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_IPAddressOrRange_sk_type(sk), ossl_check_IPAddressOrRange_compfunc_type(cmp))) + typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; @@ -809,7 +1170,33 @@ typedef struct IPAddressFamily_st { IPAddressChoice *ipAddressChoice; } IPAddressFamily; -DEFINE_OR_DECLARE_STACK_OF(IPAddressFamily) +SKM_DEFINE_STACK_OF_INTERNAL(IPAddressFamily, IPAddressFamily, IPAddressFamily) +#define sk_IPAddressFamily_num(sk) OPENSSL_sk_num(ossl_check_const_IPAddressFamily_sk_type(sk)) +#define sk_IPAddressFamily_value(sk, idx) ((IPAddressFamily *)OPENSSL_sk_value(ossl_check_const_IPAddressFamily_sk_type(sk), (idx))) +#define sk_IPAddressFamily_new(cmp) ((STACK_OF(IPAddressFamily) *)OPENSSL_sk_new(ossl_check_IPAddressFamily_compfunc_type(cmp))) +#define sk_IPAddressFamily_new_null() ((STACK_OF(IPAddressFamily) *)OPENSSL_sk_new_null()) +#define sk_IPAddressFamily_new_reserve(cmp, n) ((STACK_OF(IPAddressFamily) *)OPENSSL_sk_new_reserve(ossl_check_IPAddressFamily_compfunc_type(cmp), (n))) +#define sk_IPAddressFamily_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_IPAddressFamily_sk_type(sk), (n)) +#define sk_IPAddressFamily_free(sk) OPENSSL_sk_free(ossl_check_IPAddressFamily_sk_type(sk)) +#define sk_IPAddressFamily_zero(sk) OPENSSL_sk_zero(ossl_check_IPAddressFamily_sk_type(sk)) +#define sk_IPAddressFamily_delete(sk, i) ((IPAddressFamily *)OPENSSL_sk_delete(ossl_check_IPAddressFamily_sk_type(sk), (i))) +#define sk_IPAddressFamily_delete_ptr(sk, ptr) ((IPAddressFamily *)OPENSSL_sk_delete_ptr(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_type(ptr))) +#define sk_IPAddressFamily_push(sk, ptr) OPENSSL_sk_push(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_type(ptr)) +#define sk_IPAddressFamily_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_type(ptr)) +#define sk_IPAddressFamily_pop(sk) ((IPAddressFamily *)OPENSSL_sk_pop(ossl_check_IPAddressFamily_sk_type(sk))) +#define sk_IPAddressFamily_shift(sk) ((IPAddressFamily *)OPENSSL_sk_shift(ossl_check_IPAddressFamily_sk_type(sk))) +#define sk_IPAddressFamily_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_IPAddressFamily_sk_type(sk),ossl_check_IPAddressFamily_freefunc_type(freefunc)) +#define sk_IPAddressFamily_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_type(ptr), (idx)) +#define sk_IPAddressFamily_set(sk, idx, ptr) ((IPAddressFamily *)OPENSSL_sk_set(ossl_check_IPAddressFamily_sk_type(sk), (idx), ossl_check_IPAddressFamily_type(ptr))) +#define sk_IPAddressFamily_find(sk, ptr) OPENSSL_sk_find(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_type(ptr)) +#define sk_IPAddressFamily_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_type(ptr)) +#define sk_IPAddressFamily_sort(sk) OPENSSL_sk_sort(ossl_check_IPAddressFamily_sk_type(sk)) +#define sk_IPAddressFamily_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_IPAddressFamily_sk_type(sk)) +#define sk_IPAddressFamily_dup(sk) ((STACK_OF(IPAddressFamily) *)OPENSSL_sk_dup(ossl_check_const_IPAddressFamily_sk_type(sk))) +#define sk_IPAddressFamily_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(IPAddressFamily) *)OPENSSL_sk_deep_copy(ossl_check_const_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_copyfunc_type(copyfunc), ossl_check_IPAddressFamily_freefunc_type(freefunc))) +#define sk_IPAddressFamily_set_cmp_func(sk, cmp) ((sk_IPAddressFamily_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_IPAddressFamily_sk_type(sk), ossl_check_IPAddressFamily_compfunc_type(cmp))) + + typedef STACK_OF(IPAddressFamily) IPAddrBlocks; @@ -883,7 +1270,32 @@ int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, #endif /* OPENSSL_NO_RFC3779 */ -DEFINE_OR_DECLARE_STACK_OF(ASN1_STRING) +SKM_DEFINE_STACK_OF_INTERNAL(ASN1_STRING, ASN1_STRING, ASN1_STRING) +#define sk_ASN1_STRING_num(sk) OPENSSL_sk_num(ossl_check_const_ASN1_STRING_sk_type(sk)) +#define sk_ASN1_STRING_value(sk, idx) ((ASN1_STRING *)OPENSSL_sk_value(ossl_check_const_ASN1_STRING_sk_type(sk), (idx))) +#define sk_ASN1_STRING_new(cmp) ((STACK_OF(ASN1_STRING) *)OPENSSL_sk_new(ossl_check_ASN1_STRING_compfunc_type(cmp))) +#define sk_ASN1_STRING_new_null() ((STACK_OF(ASN1_STRING) *)OPENSSL_sk_new_null()) +#define sk_ASN1_STRING_new_reserve(cmp, n) ((STACK_OF(ASN1_STRING) *)OPENSSL_sk_new_reserve(ossl_check_ASN1_STRING_compfunc_type(cmp), (n))) +#define sk_ASN1_STRING_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ASN1_STRING_sk_type(sk), (n)) +#define sk_ASN1_STRING_free(sk) OPENSSL_sk_free(ossl_check_ASN1_STRING_sk_type(sk)) +#define sk_ASN1_STRING_zero(sk) OPENSSL_sk_zero(ossl_check_ASN1_STRING_sk_type(sk)) +#define sk_ASN1_STRING_delete(sk, i) ((ASN1_STRING *)OPENSSL_sk_delete(ossl_check_ASN1_STRING_sk_type(sk), (i))) +#define sk_ASN1_STRING_delete_ptr(sk, ptr) ((ASN1_STRING *)OPENSSL_sk_delete_ptr(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_type(ptr))) +#define sk_ASN1_STRING_push(sk, ptr) OPENSSL_sk_push(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_type(ptr)) +#define sk_ASN1_STRING_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_type(ptr)) +#define sk_ASN1_STRING_pop(sk) ((ASN1_STRING *)OPENSSL_sk_pop(ossl_check_ASN1_STRING_sk_type(sk))) +#define sk_ASN1_STRING_shift(sk) ((ASN1_STRING *)OPENSSL_sk_shift(ossl_check_ASN1_STRING_sk_type(sk))) +#define sk_ASN1_STRING_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ASN1_STRING_sk_type(sk),ossl_check_ASN1_STRING_freefunc_type(freefunc)) +#define sk_ASN1_STRING_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_type(ptr), (idx)) +#define sk_ASN1_STRING_set(sk, idx, ptr) ((ASN1_STRING *)OPENSSL_sk_set(ossl_check_ASN1_STRING_sk_type(sk), (idx), ossl_check_ASN1_STRING_type(ptr))) +#define sk_ASN1_STRING_find(sk, ptr) OPENSSL_sk_find(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_type(ptr)) +#define sk_ASN1_STRING_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_type(ptr)) +#define sk_ASN1_STRING_sort(sk) OPENSSL_sk_sort(ossl_check_ASN1_STRING_sk_type(sk)) +#define sk_ASN1_STRING_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ASN1_STRING_sk_type(sk)) +#define sk_ASN1_STRING_dup(sk) ((STACK_OF(ASN1_STRING) *)OPENSSL_sk_dup(ossl_check_const_ASN1_STRING_sk_type(sk))) +#define sk_ASN1_STRING_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ASN1_STRING) *)OPENSSL_sk_deep_copy(ossl_check_const_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_copyfunc_type(copyfunc), ossl_check_ASN1_STRING_freefunc_type(freefunc))) +#define sk_ASN1_STRING_set_cmp_func(sk, cmp) ((sk_ASN1_STRING_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ASN1_STRING_sk_type(sk), ossl_check_ASN1_STRING_compfunc_type(cmp))) + /* * Admission Syntax @@ -896,8 +1308,57 @@ DECLARE_ASN1_FUNCTIONS(NAMING_AUTHORITY) DECLARE_ASN1_FUNCTIONS(PROFESSION_INFO) DECLARE_ASN1_FUNCTIONS(ADMISSIONS) DECLARE_ASN1_FUNCTIONS(ADMISSION_SYNTAX) -DEFINE_OR_DECLARE_STACK_OF(PROFESSION_INFO) -DEFINE_OR_DECLARE_STACK_OF(ADMISSIONS) +SKM_DEFINE_STACK_OF_INTERNAL(PROFESSION_INFO, PROFESSION_INFO, PROFESSION_INFO) +#define sk_PROFESSION_INFO_num(sk) OPENSSL_sk_num(ossl_check_const_PROFESSION_INFO_sk_type(sk)) +#define sk_PROFESSION_INFO_value(sk, idx) ((PROFESSION_INFO *)OPENSSL_sk_value(ossl_check_const_PROFESSION_INFO_sk_type(sk), (idx))) +#define sk_PROFESSION_INFO_new(cmp) ((STACK_OF(PROFESSION_INFO) *)OPENSSL_sk_new(ossl_check_PROFESSION_INFO_compfunc_type(cmp))) +#define sk_PROFESSION_INFO_new_null() ((STACK_OF(PROFESSION_INFO) *)OPENSSL_sk_new_null()) +#define sk_PROFESSION_INFO_new_reserve(cmp, n) ((STACK_OF(PROFESSION_INFO) *)OPENSSL_sk_new_reserve(ossl_check_PROFESSION_INFO_compfunc_type(cmp), (n))) +#define sk_PROFESSION_INFO_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_PROFESSION_INFO_sk_type(sk), (n)) +#define sk_PROFESSION_INFO_free(sk) OPENSSL_sk_free(ossl_check_PROFESSION_INFO_sk_type(sk)) +#define sk_PROFESSION_INFO_zero(sk) OPENSSL_sk_zero(ossl_check_PROFESSION_INFO_sk_type(sk)) +#define sk_PROFESSION_INFO_delete(sk, i) ((PROFESSION_INFO *)OPENSSL_sk_delete(ossl_check_PROFESSION_INFO_sk_type(sk), (i))) +#define sk_PROFESSION_INFO_delete_ptr(sk, ptr) ((PROFESSION_INFO *)OPENSSL_sk_delete_ptr(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_type(ptr))) +#define sk_PROFESSION_INFO_push(sk, ptr) OPENSSL_sk_push(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_type(ptr)) +#define sk_PROFESSION_INFO_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_type(ptr)) +#define sk_PROFESSION_INFO_pop(sk) ((PROFESSION_INFO *)OPENSSL_sk_pop(ossl_check_PROFESSION_INFO_sk_type(sk))) +#define sk_PROFESSION_INFO_shift(sk) ((PROFESSION_INFO *)OPENSSL_sk_shift(ossl_check_PROFESSION_INFO_sk_type(sk))) +#define sk_PROFESSION_INFO_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_PROFESSION_INFO_sk_type(sk),ossl_check_PROFESSION_INFO_freefunc_type(freefunc)) +#define sk_PROFESSION_INFO_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_type(ptr), (idx)) +#define sk_PROFESSION_INFO_set(sk, idx, ptr) ((PROFESSION_INFO *)OPENSSL_sk_set(ossl_check_PROFESSION_INFO_sk_type(sk), (idx), ossl_check_PROFESSION_INFO_type(ptr))) +#define sk_PROFESSION_INFO_find(sk, ptr) OPENSSL_sk_find(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_type(ptr)) +#define sk_PROFESSION_INFO_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_type(ptr)) +#define sk_PROFESSION_INFO_sort(sk) OPENSSL_sk_sort(ossl_check_PROFESSION_INFO_sk_type(sk)) +#define sk_PROFESSION_INFO_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_PROFESSION_INFO_sk_type(sk)) +#define sk_PROFESSION_INFO_dup(sk) ((STACK_OF(PROFESSION_INFO) *)OPENSSL_sk_dup(ossl_check_const_PROFESSION_INFO_sk_type(sk))) +#define sk_PROFESSION_INFO_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(PROFESSION_INFO) *)OPENSSL_sk_deep_copy(ossl_check_const_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_copyfunc_type(copyfunc), ossl_check_PROFESSION_INFO_freefunc_type(freefunc))) +#define sk_PROFESSION_INFO_set_cmp_func(sk, cmp) ((sk_PROFESSION_INFO_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_PROFESSION_INFO_sk_type(sk), ossl_check_PROFESSION_INFO_compfunc_type(cmp))) +SKM_DEFINE_STACK_OF_INTERNAL(ADMISSIONS, ADMISSIONS, ADMISSIONS) +#define sk_ADMISSIONS_num(sk) OPENSSL_sk_num(ossl_check_const_ADMISSIONS_sk_type(sk)) +#define sk_ADMISSIONS_value(sk, idx) ((ADMISSIONS *)OPENSSL_sk_value(ossl_check_const_ADMISSIONS_sk_type(sk), (idx))) +#define sk_ADMISSIONS_new(cmp) ((STACK_OF(ADMISSIONS) *)OPENSSL_sk_new(ossl_check_ADMISSIONS_compfunc_type(cmp))) +#define sk_ADMISSIONS_new_null() ((STACK_OF(ADMISSIONS) *)OPENSSL_sk_new_null()) +#define sk_ADMISSIONS_new_reserve(cmp, n) ((STACK_OF(ADMISSIONS) *)OPENSSL_sk_new_reserve(ossl_check_ADMISSIONS_compfunc_type(cmp), (n))) +#define sk_ADMISSIONS_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ADMISSIONS_sk_type(sk), (n)) +#define sk_ADMISSIONS_free(sk) OPENSSL_sk_free(ossl_check_ADMISSIONS_sk_type(sk)) +#define sk_ADMISSIONS_zero(sk) OPENSSL_sk_zero(ossl_check_ADMISSIONS_sk_type(sk)) +#define sk_ADMISSIONS_delete(sk, i) ((ADMISSIONS *)OPENSSL_sk_delete(ossl_check_ADMISSIONS_sk_type(sk), (i))) +#define sk_ADMISSIONS_delete_ptr(sk, ptr) ((ADMISSIONS *)OPENSSL_sk_delete_ptr(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_type(ptr))) +#define sk_ADMISSIONS_push(sk, ptr) OPENSSL_sk_push(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_type(ptr)) +#define sk_ADMISSIONS_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_type(ptr)) +#define sk_ADMISSIONS_pop(sk) ((ADMISSIONS *)OPENSSL_sk_pop(ossl_check_ADMISSIONS_sk_type(sk))) +#define sk_ADMISSIONS_shift(sk) ((ADMISSIONS *)OPENSSL_sk_shift(ossl_check_ADMISSIONS_sk_type(sk))) +#define sk_ADMISSIONS_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ADMISSIONS_sk_type(sk),ossl_check_ADMISSIONS_freefunc_type(freefunc)) +#define sk_ADMISSIONS_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_type(ptr), (idx)) +#define sk_ADMISSIONS_set(sk, idx, ptr) ((ADMISSIONS *)OPENSSL_sk_set(ossl_check_ADMISSIONS_sk_type(sk), (idx), ossl_check_ADMISSIONS_type(ptr))) +#define sk_ADMISSIONS_find(sk, ptr) OPENSSL_sk_find(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_type(ptr)) +#define sk_ADMISSIONS_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_type(ptr)) +#define sk_ADMISSIONS_sort(sk) OPENSSL_sk_sort(ossl_check_ADMISSIONS_sk_type(sk)) +#define sk_ADMISSIONS_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ADMISSIONS_sk_type(sk)) +#define sk_ADMISSIONS_dup(sk) ((STACK_OF(ADMISSIONS) *)OPENSSL_sk_dup(ossl_check_const_ADMISSIONS_sk_type(sk))) +#define sk_ADMISSIONS_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ADMISSIONS) *)OPENSSL_sk_deep_copy(ossl_check_const_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_copyfunc_type(copyfunc), ossl_check_ADMISSIONS_freefunc_type(freefunc))) +#define sk_ADMISSIONS_set_cmp_func(sk, cmp) ((sk_ADMISSIONS_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ADMISSIONS_sk_type(sk), ossl_check_ADMISSIONS_compfunc_type(cmp))) + typedef STACK_OF(PROFESSION_INFO) PROFESSION_INFOS; const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId( diff --git a/include/openssl/x509v3.h.in b/include/openssl/x509v3.h.in new file mode 100644 index 0000000000..7234aa2c62 --- /dev/null +++ b/include/openssl/x509v3.h.in @@ -0,0 +1,1000 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} + +#ifndef OPENSSL_X509V3_H +# define OPENSSL_X509V3_H +# pragma once + +# include +# ifndef OPENSSL_NO_DEPRECATED_3_0 +# define HEADER_X509V3_H +# endif + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (const void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, const char *section, const char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, const char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 +# define X509V3_CTX_REPLACE 0x2 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +{- + generate_stack_macros("X509V3_EXT_METHOD"); +-} + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +{- + generate_stack_macros("ACCESS_DESCRIPTION") + .generate_stack_macros("GENERAL_NAME"); +-} + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; +typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE; +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +{- + generate_stack_macros("GENERAL_NAMES"); +-} + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +{- + generate_stack_macros("DIST_POINT"); +-} + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +{- + generate_stack_macros("SXNETID"); +-} + + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct ISSUER_SIGN_TOOL_st { + ASN1_UTF8STRING *signTool; + ASN1_UTF8STRING *cATool; + ASN1_UTF8STRING *signToolCert; + ASN1_UTF8STRING *cAToolCert; +} ISSUER_SIGN_TOOL; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +{- + generate_stack_macros("POLICYQUALINFO"); +-} + + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +{- + generate_stack_macros("POLICYINFO"); +-} + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +{- + generate_stack_macros("POLICY_MAPPING"); +-} + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +{- + generate_stack_macros("GENERAL_SUBTREE"); +-} + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, \ + "section:", (val)->section, \ + ",name:", (val)->name, ",value:", (val)->value) + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +# define EXFLAG_SI 0x20 /* self-issued, maybe not self-signed */ +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +/* EXFLAG_SET is set to indicate that some values have been precomputed */ +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 +# define EXFLAG_SS 0x2000 /* cert is apparently self-signed */ + +# define EXFLAG_BCONS_CRITICAL 0x10000 +# define EXFLAG_AKID_CRITICAL 0x20000 +# define EXFLAG_SKID_CRITICAL 0x40000 +# define EXFLAG_SAN_CRITICAL 0x80000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 +# define XKU_ANYEKU 0x100 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +{- + generate_stack_macros("X509_PURPOSE"); +-} + + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +DECLARE_ASN1_FUNCTIONS(ISSUER_SIGN_TOOL) + +int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, const char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +DECLARE_ASN1_DUP_FUNCTION(GENERAL_NAME) +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); +char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); +ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); +int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc); + +# ifdef OPENSSL_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); + +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + const char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *name, const char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +#ifndef OPENSSL_NO_DEPRECATED_1_1_0 +/* The new declarations are in crypto.h, but the old ones were here. */ +# define hex_to_string OPENSSL_buf2hexstr +# define string_to_hex OPENSSL_hexstr2buf +#endif + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +#ifndef OPENSSL_NO_STDIO +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); +#endif +int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(const X509 *issuer, const AUTHORITY_KEYID *akid); +void X509_set_proxy_flag(X509 *x); +void X509_set_proxy_pathlen(X509 *x, long l); +long X509_get_proxy_pathlen(X509 *x); + +uint32_t X509_get_extension_flags(X509 *x); +uint32_t X509_get_key_usage(X509 *x); +uint32_t X509_get_extended_key_usage(X509 *x); +const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x); +const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x); +const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x); +const ASN1_INTEGER *X509_get0_authority_serial(X509 *x); + +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(const char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + const char *name, const char *sname, void *arg); +char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(const X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +/* Flags for X509_check_* functions */ + +/* + * Always check subject name for host match even if subject alt names present + */ +# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* Never check the subject CN */ +# define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +{- + generate_stack_macros("X509_POLICY_NODE"); +-} + + +#ifndef OPENSSL_NO_RFC3779 +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +{- + generate_stack_macros("ASIdOrRange"); +-} + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +{- + generate_stack_macros("IPAddressOrRange"); +-} + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +{- + generate_stack_macros("IPAddressFamily"); +-} + + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int X509v3_asid_add_inherit(ASIdentifiers *asid, int which); +int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int X509v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int X509v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int X509v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned X509v3_addr_get_afi(const IPAddressFamily *f); +int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int X509v3_asid_is_canonical(ASIdentifiers *asid); +int X509v3_addr_is_canonical(IPAddrBlocks *addr); +int X509v3_asid_canonize(ASIdentifiers *asid); +int X509v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int X509v3_asid_inherits(ASIdentifiers *asid); +int X509v3_addr_inherits(IPAddrBlocks *addr); +int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int X509v3_asid_validate_path(X509_STORE_CTX *); +int X509v3_addr_validate_path(X509_STORE_CTX *); +int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, + int allow_inheritance); +int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +#endif /* OPENSSL_NO_RFC3779 */ + +{- + generate_stack_macros("ASN1_STRING"); +-} + +/* + * Admission Syntax + */ +typedef struct NamingAuthority_st NAMING_AUTHORITY; +typedef struct ProfessionInfo_st PROFESSION_INFO; +typedef struct Admissions_st ADMISSIONS; +typedef struct AdmissionSyntax_st ADMISSION_SYNTAX; +DECLARE_ASN1_FUNCTIONS(NAMING_AUTHORITY) +DECLARE_ASN1_FUNCTIONS(PROFESSION_INFO) +DECLARE_ASN1_FUNCTIONS(ADMISSIONS) +DECLARE_ASN1_FUNCTIONS(ADMISSION_SYNTAX) +{- + generate_stack_macros("PROFESSION_INFO") + .generate_stack_macros("ADMISSIONS"); +-} +typedef STACK_OF(PROFESSION_INFO) PROFESSION_INFOS; + +const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId( + const NAMING_AUTHORITY *n); +const ASN1_IA5STRING *NAMING_AUTHORITY_get0_authorityURL( + const NAMING_AUTHORITY *n); +const ASN1_STRING *NAMING_AUTHORITY_get0_authorityText( + const NAMING_AUTHORITY *n); +void NAMING_AUTHORITY_set0_authorityId(NAMING_AUTHORITY *n, + ASN1_OBJECT* namingAuthorityId); +void NAMING_AUTHORITY_set0_authorityURL(NAMING_AUTHORITY *n, + ASN1_IA5STRING* namingAuthorityUrl); +void NAMING_AUTHORITY_set0_authorityText(NAMING_AUTHORITY *n, + ASN1_STRING* namingAuthorityText); + +const GENERAL_NAME *ADMISSION_SYNTAX_get0_admissionAuthority( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_admissionAuthority( + ADMISSION_SYNTAX *as, GENERAL_NAME *aa); +const STACK_OF(ADMISSIONS) *ADMISSION_SYNTAX_get0_contentsOfAdmissions( + const ADMISSION_SYNTAX *as); +void ADMISSION_SYNTAX_set0_contentsOfAdmissions( + ADMISSION_SYNTAX *as, STACK_OF(ADMISSIONS) *a); +const GENERAL_NAME *ADMISSIONS_get0_admissionAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_admissionAuthority(ADMISSIONS *a, GENERAL_NAME *aa); +const NAMING_AUTHORITY *ADMISSIONS_get0_namingAuthority(const ADMISSIONS *a); +void ADMISSIONS_set0_namingAuthority(ADMISSIONS *a, NAMING_AUTHORITY *na); +const PROFESSION_INFOS *ADMISSIONS_get0_professionInfos(const ADMISSIONS *a); +void ADMISSIONS_set0_professionInfos(ADMISSIONS *a, PROFESSION_INFOS *pi); +const ASN1_OCTET_STRING *PROFESSION_INFO_get0_addProfessionInfo( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_addProfessionInfo( + PROFESSION_INFO *pi, ASN1_OCTET_STRING *aos); +const NAMING_AUTHORITY *PROFESSION_INFO_get0_namingAuthority( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_namingAuthority( + PROFESSION_INFO *pi, NAMING_AUTHORITY *na); +const STACK_OF(ASN1_STRING) *PROFESSION_INFO_get0_professionItems( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionItems( + PROFESSION_INFO *pi, STACK_OF(ASN1_STRING) *as); +const STACK_OF(ASN1_OBJECT) *PROFESSION_INFO_get0_professionOIDs( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_professionOIDs( + PROFESSION_INFO *pi, STACK_OF(ASN1_OBJECT) *po); +const ASN1_PRINTABLESTRING *PROFESSION_INFO_get0_registrationNumber( + const PROFESSION_INFO *pi); +void PROFESSION_INFO_set0_registrationNumber( + PROFESSION_INFO *pi, ASN1_PRINTABLESTRING *rn); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/x509v3err.h b/include/openssl/x509v3err.h index d7aa5da6ac..b245a63902 100644 --- a/include/openssl/x509v3err.h +++ b/include/openssl/x509v3err.h @@ -107,6 +107,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_R_DIRNAME_ERROR 149 # define X509V3_R_DISTPOINT_ALREADY_SET 160 # define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_EMPTY_KEY_USAGE 169 # define X509V3_R_ERROR_CONVERTING_ZONE 131 # define X509V3_R_ERROR_CREATING_EXTENSION 144 # define X509V3_R_ERROR_IN_EXTENSION 128 @@ -121,6 +122,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_R_INVALID_ASNUMBER 162 # define X509V3_R_INVALID_ASRANGE 163 # define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_CERTIFICATE 158 # define X509V3_R_INVALID_EXTENSION_STRING 105 # define X509V3_R_INVALID_INHERITANCE 165 # define X509V3_R_INVALID_IPADDRESS 166 @@ -142,6 +144,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_R_ISSUER_DECODE_ERROR 126 # define X509V3_R_MISSING_VALUE 124 # define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NEGATIVE_PATHLEN 168 # define X509V3_R_NO_CONFIG_DATABASE 136 # define X509V3_R_NO_ISSUER_CERTIFICATE 121 # define X509V3_R_NO_ISSUER_DETAILS 127 diff --git a/openssl.cmake b/openssl.cmake index 7b3fdd6035..2db3efd81b 100644 --- a/openssl.cmake +++ b/openssl.cmake @@ -143,7 +143,6 @@ set(crypto_srcs crypto/buffer/buf_err.c crypto/buffer/buffer.c crypto/chacha/chacha_enc.c - crypto/cmac/cm_ameth.c crypto/cmac/cmac.c crypto/cms/cms_asn1.c crypto/cms/cms_att.c @@ -217,6 +216,7 @@ set(crypto_srcs crypto/dh/dh_asn1.c crypto/dh/dh_backend.c crypto/dh/dh_check.c + crypto/dh/dh_ctrl.c crypto/dh/dh_depr.c crypto/dh/dh_err.c crypto/dh/dh_gen.c @@ -287,6 +287,14 @@ set(crypto_srcs crypto/ec/ecx_backend.c crypto/ec/ecx_meth.c crypto/ec/ecx_key.c + crypto/encode_decode/decoder_err.c + crypto/encode_decode/decoder_lib.c + crypto/encode_decode/decoder_meth.c + crypto/encode_decode/decoder_pkey.c + crypto/encode_decode/encoder_err.c + crypto/encode_decode/encoder_lib.c + crypto/encode_decode/encoder_meth.c + crypto/encode_decode/encoder_pkey.c crypto/engine/eng_all.c crypto/engine/eng_cnf.c crypto/engine/eng_ctrl.c @@ -315,6 +323,7 @@ set(crypto_srcs crypto/ess/ess_asn1.c crypto/ess/ess_err.c crypto/ess/ess_lib.c + crypto/evp/asymcipher.c crypto/evp/bio_b64.c crypto/evp/bio_enc.c crypto/evp/bio_md.c @@ -352,6 +361,7 @@ set(crypto_srcs crypto/evp/exchange.c crypto/evp/kdf_lib.c crypto/evp/kdf_meth.c + crypto/evp/kem.c crypto/evp/keymgmt_lib.c crypto/evp/keymgmt_meth.c crypto/evp/legacy_blake2.c @@ -367,8 +377,6 @@ set(crypto_srcs crypto/evp/p5_crpt.c crypto/evp/p5_crpt2.c crypto/evp/pbe_scrypt.c - crypto/evp/pkey_kdf.c - crypto/evp/pkey_mac.c crypto/evp/p_dec.c crypto/evp/p_enc.c crypto/evp/p_lib.c @@ -376,7 +384,6 @@ set(crypto_srcs crypto/evp/p_seal.c crypto/evp/p_sign.c crypto/evp/p_verify.c - crypto/evp/pmeth_fn.c crypto/evp/pmeth_gn.c crypto/evp/pmeth_lib.c crypto/evp/evp_rand.c @@ -389,7 +396,6 @@ set(crypto_srcs crypto/ffc/ffc_params_generate.c crypto/ffc/ffc_params_validate.c crypto/getenv.c - crypto/hmac/hm_ameth.c crypto/hmac/hmac.c crypto/http/http_client.c crypto/http/http_err.c @@ -441,6 +447,7 @@ set(crypto_srcs crypto/param_build.c crypto/param_build_set.c crypto/params_from_text.c + crypto/passphrase.c crypto/pem/pem_all.c crypto/pem/pem_err.c crypto/pem/pem_info.c @@ -476,7 +483,6 @@ set(crypto_srcs crypto/pkcs7/pk7_smime.c crypto/pkcs7/pkcs7err.c crypto/poly1305/poly1305.c - crypto/poly1305/poly1305_ameth.c crypto/provider.c crypto/provider_core.c crypto/provider_conf.c @@ -486,10 +492,11 @@ set(crypto_srcs crypto/property/property_err.c crypto/property/property_parse.c crypto/property/property_string.c - crypto/rand/drbg_lib.c + crypto/punycode.c crypto/rand/rand_egd.c crypto/rand/rand_err.c crypto/rand/rand_lib.c + crypto/rand/rand_meth.c crypto/rand/randfile.c crypto/rc2/rc2_cbc.c crypto/rc2/rc2_ecb.c @@ -525,26 +532,15 @@ set(crypto_srcs crypto/rsa/rsa_x931.c crypto/rsa/rsa_x931g.c crypto/self_test_core.c - crypto/serializer/deserializer_err.c - crypto/serializer/deserializer_lib.c - crypto/serializer/deserializer_meth.c - crypto/serializer/deserializer_pkey.c - crypto/serializer/serdes_pass.c - crypto/serializer/serializer_err.c - crypto/serializer/serializer_lib.c - crypto/serializer/serializer_meth.c - crypto/serializer/serializer_pkey.c crypto/sha/sha1_one.c crypto/sha/sha1dgst.c crypto/sha/sha256.c crypto/sha/sha3.c crypto/sha/sha512.c crypto/siphash/siphash.c - crypto/siphash/siphash_ameth.c crypto/sm2/sm2_err.c crypto/sm2/sm2_crypt.c crypto/sm2/sm2_sign.c - crypto/sm2/sm2_pmeth.c crypto/sm3/sm3.c crypto/sm3/legacy_sm3.c crypto/sm4/sm4.c @@ -554,9 +550,10 @@ set(crypto_srcs crypto/store/store_init.c crypto/store/store_err.c crypto/store/store_register.c + crypto/store/store_result.c crypto/store/store_lib.c + crypto/store/store_meth.c crypto/store/store_strings.c - crypto/store/loader_file.c crypto/stack/stack.c crypto/threads_none.c crypto/threads_pthread.c @@ -761,76 +758,28 @@ set(provider_srcs providers/common/der/der_dsa_gen.c providers/common/der/der_dsa_sig.c providers/common/der/der_ec_gen.c + providers/common/der/der_ecx_gen.c + providers/common/der/der_ecx_key.c providers/common/der/der_ec_sig.c providers/common/der/der_rsa_gen.c providers/common/der/der_rsa_key.c providers/common/der/der_rsa_sig.c + providers/common/der/der_sm2_gen.c + providers/common/der/der_sm2_sig.c providers/common/der/der_wrap_gen.c + providers/common/digest_to_nid.c + providers/common/nid_to_name.c providers/common/provider_ctx.c providers/common/provider_util.c providers/common/provider_err.c - providers/common/nid_to_name.c + providers/common/securitycheck.c + providers/common/securitycheck_default.c providers/baseprov.c providers/defltprov.c providers/implementations/asymciphers/rsa_enc.c + providers/implementations/asymciphers/sm2_enc.c providers/implementations/ciphers/cipher_aes_cts_fips.c providers/implementations/ciphers/ciphercommon_block.c - providers/implementations/exchange/ecx_exch.c - providers/implementations/exchange/ecdh_exch.c - providers/implementations/exchange/dh_exch.c - providers/implementations/serializers/deserialize_common.c - providers/implementations/serializers/deserialize_der2key.c - providers/implementations/serializers/deserialize_pem2der.c - providers/implementations/signature/dsa.c - providers/implementations/signature/rsa.c - providers/implementations/signature/eddsa.c - providers/implementations/signature/ecdsa.c - providers/implementations/keymgmt/dh_kmgmt.c - providers/implementations/keymgmt/ec_kmgmt.c - providers/implementations/keymgmt/rsa_kmgmt.c - providers/implementations/keymgmt/dsa_kmgmt.c - providers/implementations/keymgmt/ecx_kmgmt.c - providers/implementations/kdfs/x942kdf.c - providers/implementations/kdfs/sskdf.c - providers/implementations/kdfs/tls1_prf.c - providers/implementations/kdfs/sshkdf.c - providers/implementations/kdfs/scrypt.c - providers/implementations/kdfs/krb5kdf.c - providers/implementations/kdfs/hkdf.c - providers/implementations/kdfs/pbkdf2_fips.c - providers/implementations/kdfs/kbkdf.c - providers/implementations/kdfs/pbkdf2.c - providers/implementations/rands/drbg.c - providers/implementations/rands/drbg_ctr.c - providers/implementations/rands/drbg_hash.c - providers/implementations/rands/drbg_hmac.c - providers/implementations/rands/rand_pool.c - providers/implementations/rands/seeding/rand_unix.c - providers/implementations/rands/test_rng.c - providers/implementations/serializers/serializer_common.c - providers/implementations/serializers/serializer_dsa_priv.c - providers/implementations/serializers/serializer_dh.c - providers/implementations/serializers/serializer_ec_param.c - providers/implementations/serializers/serializer_dsa_pub.c - providers/implementations/serializers/serializer_dh_priv.c - providers/implementations/serializers/serializer_ffc_params.c - providers/implementations/serializers/serializer_ecx_pub.c - providers/implementations/serializers/serializer_dsa_param.c - providers/implementations/serializers/serializer_ecx_priv.c - providers/implementations/serializers/serializer_dh_param.c - providers/implementations/serializers/serializer_rsa_pub.c - providers/implementations/serializers/serializer_rsa_priv.c - providers/implementations/serializers/serializer_dh_pub.c - providers/implementations/serializers/serializer_rsa.c - providers/implementations/serializers/serializer_ec_pub.c - providers/implementations/serializers/serializer_ec_priv.c - providers/implementations/serializers/serializer_dsa.c - providers/implementations/serializers/serializer_ecx.c - providers/implementations/serializers/serializer_ec.c - providers/implementations/signature/dsa.c - providers/implementations/signature/ecdsa.c - providers/implementations/signature/eddsa.c - providers/implementations/signature/rsa.c providers/implementations/ciphers/cipher_chacha20.c providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c @@ -895,14 +844,59 @@ set(provider_srcs providers/implementations/digests/blake2b_prov.c providers/implementations/digests/sha3_prov.c providers/implementations/digests/md4_prov.c - providers/implementations/macs/gmac_prov.c - providers/implementations/macs/blake2s_mac.c - providers/implementations/macs/poly1305_prov.c - providers/implementations/macs/kmac_prov.c + providers/implementations/encode_decode/decode_der2key.c + providers/implementations/encode_decode/encode_key2any.c + providers/implementations/encode_decode/decode_ms2key.c + providers/implementations/encode_decode/encode_key2text.c + providers/implementations/encode_decode/decode_pem2der.c + providers/implementations/encode_decode/endecoder_common.c + providers/implementations/exchange/ecx_exch.c + providers/implementations/exchange/ecdh_exch.c + providers/implementations/exchange/dh_exch.c + providers/implementations/exchange/kdf_exch.c + providers/implementations/kem/rsa_kem.c + providers/implementations/keymgmt/dh_kmgmt.c + providers/implementations/keymgmt/ec_kmgmt.c + providers/implementations/keymgmt/dsa_kmgmt.c + providers/implementations/keymgmt/ecx_kmgmt.c + providers/implementations/keymgmt/kdf_legacy_kmgmt.c + providers/implementations/keymgmt/mac_legacy_kmgmt.c + providers/implementations/keymgmt/rsa_kmgmt.c + providers/implementations/kdfs/x942kdf.c + providers/implementations/kdfs/sskdf.c + providers/implementations/kdfs/tls1_prf.c + providers/implementations/kdfs/sshkdf.c + providers/implementations/kdfs/scrypt.c + providers/implementations/kdfs/krb5kdf.c + providers/implementations/kdfs/hkdf.c + providers/implementations/kdfs/pbkdf2_fips.c + providers/implementations/kdfs/kbkdf.c + providers/implementations/kdfs/pbkdf2.c + providers/implementations/kdfs/pkcs12kdf.c providers/implementations/macs/blake2b_mac.c + providers/implementations/macs/blake2s_mac.c providers/implementations/macs/cmac_prov.c + providers/implementations/macs/gmac_prov.c providers/implementations/macs/hmac_prov.c + providers/implementations/macs/kmac_prov.c + providers/implementations/macs/poly1305_prov.c providers/implementations/macs/siphash_prov.c + providers/implementations/rands/drbg.c + providers/implementations/rands/drbg_ctr.c + providers/implementations/rands/drbg_hash.c + providers/implementations/rands/drbg_hmac.c + providers/implementations/rands/rand_pool.c + providers/implementations/rands/seeding/rand_unix.c + providers/implementations/rands/test_rng.c + providers/implementations/signature/dsa.c + providers/implementations/signature/ecdsa.c + providers/implementations/signature/eddsa.c + providers/implementations/signature/mac_legacy.c + providers/implementations/signature/rsa.c + providers/implementations/signature/sm2sig.c + providers/implementations/storemgmt/file_store.c + providers/implementations/storemgmt/file_store_der2obj.c + providers/prov_running.c ) PREPEND(crypto_srcs_with_path ${OPENSSL_PATH} ${provider_srcs} ${crypto_srcs}) @@ -936,7 +930,7 @@ target_compile_options(crypto PRIVATE -Wno-missing-field-initializers -Wno-unuse -DOPENSSL_PIC -DOPENSSL_THREADS -DOPENSSL_CPUID_OBJ - + -DL_ENDIAN ) if (${ANDROID_ABI} STREQUAL "armeabi-v7a") diff --git a/openssl.version b/openssl.version index 6b2f50cba5..59cf3bf4bb 100644 --- a/openssl.version +++ b/openssl.version @@ -1 +1 @@ -OPENSSL_VERSION=3.0.0-alpha6 +OPENSSL_VERSION=3.0.0-alpha7 diff --git a/providers/baseprov.c b/providers/baseprov.c index 917bf680d4..019caf10d6 100644 --- a/providers/baseprov.c +++ b/providers/baseprov.c @@ -38,6 +38,7 @@ static const OSSL_PARAM base_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END }; @@ -60,49 +61,63 @@ static int base_get_params(void *provctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR)) return 0; + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); + if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) + return 0; return 1; } -static const OSSL_ALGORITHM base_serializer[] = { -#define SER(name, fips, format, type, func_table) \ +static const OSSL_ALGORITHM base_encoder[] = { +#define ENCODER(name, _fips, _output, func_table) \ { name, \ - "provider=base,fips=" fips ",format=" format ",type=" type, \ + "provider=base,fips=" _fips ",output=" _output, \ (func_table) } -#include "serializers.inc" +#include "encoders.inc" { NULL, NULL, NULL } }; -#undef SER +#undef ENCODER -static const OSSL_ALGORITHM base_deserializer[] = { -#define DESER(name, fips, input, func_table) \ +static const OSSL_ALGORITHM base_decoder[] = { +#define DECODER(name, _fips, _input, func_table) \ { name, \ - "provider=base,fips=" fips ",input=" input, \ + "provider=base,fips=" _fips ",input=" _input, \ (func_table) } -#include "deserializers.inc" +#include "decoders.inc" + { NULL, NULL, NULL } +}; +#undef DECODER + +static const OSSL_ALGORITHM base_store[] = { +#define STORE(name, _fips, func_table) \ + { name, "provider=base,fips=" _fips, (func_table) }, + +#include "stores.inc" { NULL, NULL, NULL } +#undef STORE }; -#undef DESER static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, int *no_cache) { *no_cache = 0; switch (operation_id) { - case OSSL_OP_SERIALIZER: - return base_serializer; - case OSSL_OP_DESERIALIZER: - return base_deserializer; + case OSSL_OP_ENCODER: + return base_encoder; + case OSSL_OP_DECODER: + return base_decoder; + case OSSL_OP_STORE: + return base_store; } return NULL; } static void base_teardown(void *provctx) { - BIO_meth_free(PROV_CTX_get0_core_bio_method(provctx)); - PROV_CTX_free(provctx); + BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(provctx)); + ossl_prov_ctx_free(provctx); } /* Functions we provide to the core */ @@ -121,7 +136,7 @@ int ossl_base_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, void **provctx) { - OSSL_FUNC_core_get_library_context_fn *c_get_libctx = NULL; + OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; BIO_METHOD *corebiometh; if (!ossl_prov_bio_from_dispatch(in)) @@ -134,8 +149,8 @@ int ossl_base_provider_init(const OSSL_CORE_HANDLE *handle, case OSSL_FUNC_CORE_GET_PARAMS: c_get_params = OSSL_FUNC_core_get_params(in); break; - case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT: - c_get_libctx = OSSL_FUNC_core_get_library_context(in); + case OSSL_FUNC_CORE_GET_LIBCTX: + c_get_libctx = OSSL_FUNC_core_get_libctx(in); break; default: /* Just ignore anything we don't understand */ @@ -154,15 +169,16 @@ int ossl_base_provider_init(const OSSL_CORE_HANDLE *handle, * This only works for built-in providers. Most providers should * create their own library context. */ - if ((*provctx = PROV_CTX_new()) == NULL + if ((*provctx = ossl_prov_ctx_new()) == NULL || (corebiometh = bio_prov_init_bio_method()) == NULL) { - PROV_CTX_free(*provctx); + ossl_prov_ctx_free(*provctx); *provctx = NULL; return 0; } - PROV_CTX_set0_library_context(*provctx, (OPENSSL_CTX *)c_get_libctx(handle)); - PROV_CTX_set0_handle(*provctx, handle); - PROV_CTX_set0_core_bio_method(*provctx, corebiometh); + ossl_prov_ctx_set0_libctx(*provctx, + (OSSL_LIB_CTX *)c_get_libctx(handle)); + ossl_prov_ctx_set0_handle(*provctx, handle); + ossl_prov_ctx_set0_core_bio_method(*provctx, corebiometh); *out = base_dispatch_table; diff --git a/providers/build.info b/providers/build.info index 8d82d3f911..b365bda0ec 100644 --- a/providers/build.info +++ b/providers/build.info @@ -140,7 +140,7 @@ ENDIF IF[{- !$disabled{fips} -}] # This is the trigger to actually build the FIPS module. Without these # statements, the final build file will not have a trace of it. - MODULES=$FIPSGOAL + MODULES{fips}=$FIPSGOAL LIBS{noinst}=$LIBFIPS ENDIF @@ -188,6 +188,6 @@ ENDIF # Because the null provider is built in, it means that libcrypto must # include all the object files that are needed. $NULLGOAL=../libcrypto -SOURCE[$NULLGOAL]=nullprov.c - +SOURCE[$NULLGOAL]=nullprov.c prov_running.c +SOURCE[$LIBNONFIPS]=prov_running.c diff --git a/providers/common/bio_prov.c b/providers/common/bio_prov.c index fc1f8b2b26..afdeb80d80 100644 --- a/providers/common/bio_prov.c +++ b/providers/common/bio_prov.c @@ -18,6 +18,7 @@ static OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex = NULL; static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex = NULL; static OSSL_FUNC_BIO_gets_fn *c_bio_gets = NULL; static OSSL_FUNC_BIO_puts_fn *c_bio_puts = NULL; +static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl = NULL; static OSSL_FUNC_BIO_free_fn *c_bio_free = NULL; static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf = NULL; @@ -49,6 +50,10 @@ int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) if (c_bio_puts == NULL) c_bio_puts = OSSL_FUNC_BIO_puts(fns); break; + case OSSL_FUNC_BIO_CTRL: + if (c_bio_ctrl == NULL) + c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns); + break; case OSSL_FUNC_BIO_FREE: if (c_bio_free == NULL) c_bio_free = OSSL_FUNC_BIO_free(fns); @@ -107,6 +112,13 @@ int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str) return c_bio_puts(bio, str); } +int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr) +{ + if (c_bio_ctrl == NULL) + return -1; + return c_bio_ctrl(bio, cmd, num, ptr); +} + int ossl_prov_bio_free(OSSL_CORE_BIO *bio) { if (c_bio_free == NULL) @@ -151,9 +163,7 @@ static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len, static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr) { - /* We don't support this */ - assert(0); - return 0; + return ossl_prov_bio_ctrl(BIO_get_data(bio), cmd, num, ptr); } static int bio_core_gets(BIO *bio, char *buf, int size) @@ -203,7 +213,7 @@ BIO_METHOD *bio_prov_init_bio_method(void) BIO *bio_new_from_core_bio(PROV_CTX *provctx, OSSL_CORE_BIO *corebio) { BIO *outbio; - BIO_METHOD *corebiometh = PROV_CTX_get0_core_bio_method(provctx); + BIO_METHOD *corebiometh = ossl_prov_ctx_get0_core_bio_method(provctx); if (corebiometh == NULL) return NULL; diff --git a/providers/common/build.info b/providers/common/build.info index fb04883507..2179b2a0f8 100644 --- a/providers/common/build.info +++ b/providers/common/build.info @@ -1,6 +1,7 @@ SUBDIRS=der SOURCE[../libcommon.a]=provider_err.c provider_ctx.c -$FIPSCOMMON=provider_util.c capabilities.c bio_prov.c -SOURCE[../libnonfips.a]=$FIPSCOMMON nid_to_name.c -SOURCE[../libfips.a]=$FIPSCOMMON +$FIPSCOMMON=provider_util.c capabilities.c bio_prov.c digest_to_nid.c\ + securitycheck.c +SOURCE[../libnonfips.a]=$FIPSCOMMON nid_to_name.c securitycheck_default.c +SOURCE[../libfips.a]=$FIPSCOMMON securitycheck_fips.c diff --git a/providers/common/der/ECX.asn1 b/providers/common/der/ECX.asn1 new file mode 100644 index 0000000000..72d1b451ae --- /dev/null +++ b/providers/common/der/ECX.asn1 @@ -0,0 +1,11 @@ + +-- ------------------------------------------------------------------- +-- Taken from RFC 8410, 9 ASN.1 Module +-- (https://tools.ietf.org/html/rfc8410#section-9) + +id-edwards-curve-algs OBJECT IDENTIFIER ::= { 1 3 101 } + +id-X25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 110 } +id-X448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 111 } +id-Ed25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 112 } +id-Ed448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 113 } diff --git a/providers/common/der/SM2.asn1 b/providers/common/der/SM2.asn1 new file mode 100644 index 0000000000..f90e11f04a --- /dev/null +++ b/providers/common/der/SM2.asn1 @@ -0,0 +1,11 @@ +oscca OBJECT IDENTIFIER ::= { iso(1) member-body(2) cn(156) 10197 } + +sm-scheme OBJECT IDENTIFIER ::= { oscca 1 } + +-- OID for SM2 signatures with SM3 + +sm2-with-SM3 OBJECT IDENTIFIER ::= { sm-scheme 501 } + +-- Named Elliptic Curves of SM2 + +curveSM2 OBJECT IDENTIFIER ::= { sm-scheme 301 } diff --git a/providers/common/der/build.info b/providers/common/der/build.info index f7eb86fdfb..ae5f1612ee 100644 --- a/providers/common/der/build.info +++ b/providers/common/der/build.info @@ -50,6 +50,19 @@ DEPEND[${DER_EC_GEN/.c/.o}]=$DER_EC_H GENERATE[$DER_EC_H]=der_ec.h.in DEPEND[$DER_EC_H]=oids_to_c.pm +#----- ECX +$DER_ECX_H=../include/prov/der_ecx.h +$DER_ECX_GEN=der_ecx_gen.c +$DER_ECX_AUX=der_ecx_key.c + +GENERATE[$DER_ECX_GEN]=der_ecx_gen.c.in +DEPEND[$DER_ECX_GEN]=oids_to_c.pm + +DEPEND[${DER_ECX_AUX/.c/.o}]=$DER_ECX_H +DEPEND[${DER_ECX_GEN/.c/.o}]=$DER_ECX_H +GENERATE[$DER_ECX_H]=der_ecx.h.in +DEPEND[$DER_ECX_H]=oids_to_c.pm + #----- KEY WRAP $DER_WRAP_H=../include/prov/der_wrap.h $DER_WRAP_GEN=der_wrap_gen.c @@ -61,6 +74,19 @@ DEPEND[${DER_WRAP_GEN/.c/.o}]=$DER_WRAP_H GENERATE[$DER_WRAP_H]=der_wrap.h.in DEPEND[$DER_WRAP_H]=oids_to_c.pm +#----- SM2 +$DER_SM2_H=../include/prov/der_sm2.h +$DER_SM2_GEN=der_sm2_gen.c +$DER_SM2_AUX=der_sm2_key.c der_sm2_sig.c + +GENERATE[$DER_SM2_GEN]=der_sm2_gen.c.in +DEPEND[$DER_SM2_GEN]=oids_to_c.pm + +DEPEND[${DER_SM2_AUX/.c/.o}]=$DER_SM2_H $DER_EC_H +DEPEND[${DER_SM2_GEN/.c/.o}]=$DER_SM2_H +GENERATE[$DER_SM2_H]=der_sm2.h.in +DEPEND[$DER_SM2_H]=oids_to_c.pm + #----- Conclusion # TODO(3.0) $COMMON should go to libcommon.a, but this currently leads @@ -71,7 +97,12 @@ $COMMON=\ $DER_DSA_GEN $DER_DSA_AUX \ $DER_EC_GEN $DER_EC_AUX \ $DER_DIGESTS_GEN \ - $DER_WRAP_GEN + $DER_WRAP_GEN \ + $DER_SM2_GEN $DER_SM2_AUX + +IF[{- !$disabled{ec} -}] + $COMMON = $COMMON $DER_ECX_GEN $DER_ECX_AUX +ENDIF SOURCE[../../libfips.a]=$COMMON $DER_RSA_FIPSABLE SOURCE[../../libnonfips.a]=$COMMON $DER_RSA_FIPSABLE diff --git a/providers/common/der/der_digests_gen.c b/providers/common/der/der_digests_gen.c index 27d230a031..a70bbe30ca 100644 --- a/providers/common/der/der_digests_gen.c +++ b/providers/common/der/der_digests_gen.c @@ -14,7 +14,7 @@ /* * sigAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 3 } */ -const unsigned char der_oid_sigAlgs[DER_OID_SZ_sigAlgs] = { +const unsigned char ossl_der_oid_sigAlgs[DER_OID_SZ_sigAlgs] = { DER_OID_V_sigAlgs }; @@ -23,7 +23,7 @@ const unsigned char der_oid_sigAlgs[DER_OID_SZ_sigAlgs] = { * identified-organization(3) oiw(14) * secsig(3) algorithms(2) 26 } */ -const unsigned char der_oid_id_sha1[DER_OID_SZ_id_sha1] = { +const unsigned char ossl_der_oid_id_sha1[DER_OID_SZ_id_sha1] = { DER_OID_V_id_sha1 }; @@ -31,7 +31,7 @@ const unsigned char der_oid_id_sha1[DER_OID_SZ_id_sha1] = { * id-md2 OBJECT IDENTIFIER ::= { * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */ -const unsigned char der_oid_id_md2[DER_OID_SZ_id_md2] = { +const unsigned char ossl_der_oid_id_md2[DER_OID_SZ_id_md2] = { DER_OID_V_id_md2 }; @@ -39,119 +39,119 @@ const unsigned char der_oid_id_md2[DER_OID_SZ_id_md2] = { * id-md5 OBJECT IDENTIFIER ::= { * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ -const unsigned char der_oid_id_md5[DER_OID_SZ_id_md5] = { +const unsigned char ossl_der_oid_id_md5[DER_OID_SZ_id_md5] = { DER_OID_V_id_md5 }; /* * id-sha256 OBJECT IDENTIFIER ::= { hashAlgs 1 } */ -const unsigned char der_oid_id_sha256[DER_OID_SZ_id_sha256] = { +const unsigned char ossl_der_oid_id_sha256[DER_OID_SZ_id_sha256] = { DER_OID_V_id_sha256 }; /* * id-sha384 OBJECT IDENTIFIER ::= { hashAlgs 2 } */ -const unsigned char der_oid_id_sha384[DER_OID_SZ_id_sha384] = { +const unsigned char ossl_der_oid_id_sha384[DER_OID_SZ_id_sha384] = { DER_OID_V_id_sha384 }; /* * id-sha512 OBJECT IDENTIFIER ::= { hashAlgs 3 } */ -const unsigned char der_oid_id_sha512[DER_OID_SZ_id_sha512] = { +const unsigned char ossl_der_oid_id_sha512[DER_OID_SZ_id_sha512] = { DER_OID_V_id_sha512 }; /* * id-sha224 OBJECT IDENTIFIER ::= { hashAlgs 4 } */ -const unsigned char der_oid_id_sha224[DER_OID_SZ_id_sha224] = { +const unsigned char ossl_der_oid_id_sha224[DER_OID_SZ_id_sha224] = { DER_OID_V_id_sha224 }; /* * id-sha512-224 OBJECT IDENTIFIER ::= { hashAlgs 5 } */ -const unsigned char der_oid_id_sha512_224[DER_OID_SZ_id_sha512_224] = { +const unsigned char ossl_der_oid_id_sha512_224[DER_OID_SZ_id_sha512_224] = { DER_OID_V_id_sha512_224 }; /* * id-sha512-256 OBJECT IDENTIFIER ::= { hashAlgs 6 } */ -const unsigned char der_oid_id_sha512_256[DER_OID_SZ_id_sha512_256] = { +const unsigned char ossl_der_oid_id_sha512_256[DER_OID_SZ_id_sha512_256] = { DER_OID_V_id_sha512_256 }; /* * id-sha3-224 OBJECT IDENTIFIER ::= { hashAlgs 7 } */ -const unsigned char der_oid_id_sha3_224[DER_OID_SZ_id_sha3_224] = { +const unsigned char ossl_der_oid_id_sha3_224[DER_OID_SZ_id_sha3_224] = { DER_OID_V_id_sha3_224 }; /* * id-sha3-256 OBJECT IDENTIFIER ::= { hashAlgs 8 } */ -const unsigned char der_oid_id_sha3_256[DER_OID_SZ_id_sha3_256] = { +const unsigned char ossl_der_oid_id_sha3_256[DER_OID_SZ_id_sha3_256] = { DER_OID_V_id_sha3_256 }; /* * id-sha3-384 OBJECT IDENTIFIER ::= { hashAlgs 9 } */ -const unsigned char der_oid_id_sha3_384[DER_OID_SZ_id_sha3_384] = { +const unsigned char ossl_der_oid_id_sha3_384[DER_OID_SZ_id_sha3_384] = { DER_OID_V_id_sha3_384 }; /* * id-sha3-512 OBJECT IDENTIFIER ::= { hashAlgs 10 } */ -const unsigned char der_oid_id_sha3_512[DER_OID_SZ_id_sha3_512] = { +const unsigned char ossl_der_oid_id_sha3_512[DER_OID_SZ_id_sha3_512] = { DER_OID_V_id_sha3_512 }; /* * id-shake128 OBJECT IDENTIFIER ::= { hashAlgs 11 } */ -const unsigned char der_oid_id_shake128[DER_OID_SZ_id_shake128] = { +const unsigned char ossl_der_oid_id_shake128[DER_OID_SZ_id_shake128] = { DER_OID_V_id_shake128 }; /* * id-shake256 OBJECT IDENTIFIER ::= { hashAlgs 12 } */ -const unsigned char der_oid_id_shake256[DER_OID_SZ_id_shake256] = { +const unsigned char ossl_der_oid_id_shake256[DER_OID_SZ_id_shake256] = { DER_OID_V_id_shake256 }; /* * id-shake128-len OBJECT IDENTIFIER ::= { hashAlgs 17 } */ -const unsigned char der_oid_id_shake128_len[DER_OID_SZ_id_shake128_len] = { +const unsigned char ossl_der_oid_id_shake128_len[DER_OID_SZ_id_shake128_len] = { DER_OID_V_id_shake128_len }; /* * id-shake256-len OBJECT IDENTIFIER ::= { hashAlgs 18 } */ -const unsigned char der_oid_id_shake256_len[DER_OID_SZ_id_shake256_len] = { +const unsigned char ossl_der_oid_id_shake256_len[DER_OID_SZ_id_shake256_len] = { DER_OID_V_id_shake256_len }; /* * id-KMACWithSHAKE128 OBJECT IDENTIFIER ::={hashAlgs 19} */ -const unsigned char der_oid_id_KMACWithSHAKE128[DER_OID_SZ_id_KMACWithSHAKE128] = { +const unsigned char ossl_der_oid_id_KMACWithSHAKE128[DER_OID_SZ_id_KMACWithSHAKE128] = { DER_OID_V_id_KMACWithSHAKE128 }; /* * id-KMACWithSHAKE256 OBJECT IDENTIFIER ::={ hashAlgs 20} */ -const unsigned char der_oid_id_KMACWithSHAKE256[DER_OID_SZ_id_KMACWithSHAKE256] = { +const unsigned char ossl_der_oid_id_KMACWithSHAKE256[DER_OID_SZ_id_KMACWithSHAKE256] = { DER_OID_V_id_KMACWithSHAKE256 }; diff --git a/providers/common/der/der_dsa.h.in b/providers/common/der/der_dsa.h.in index e9a8718fc6..e24c9845a9 100644 --- a/providers/common/der/der_dsa.h.in +++ b/providers/common/der/der_dsa.h.in @@ -17,7 +17,7 @@ -} /* Subject Public Key Info */ -int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa); +int ossl_DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa); /* Signature */ -int DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, - DSA *dsa, int mdnid); +int ossl_DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, + DSA *dsa, int mdnid); diff --git a/providers/common/der/der_dsa_gen.c b/providers/common/der/der_dsa_gen.c index 6effdc06a2..cae4c55561 100644 --- a/providers/common/der/der_dsa_gen.c +++ b/providers/common/der/der_dsa_gen.c @@ -15,7 +15,7 @@ * id-dsa OBJECT IDENTIFIER ::= { * iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 } */ -const unsigned char der_oid_id_dsa[DER_OID_SZ_id_dsa] = { +const unsigned char ossl_der_oid_id_dsa[DER_OID_SZ_id_dsa] = { DER_OID_V_id_dsa }; @@ -23,63 +23,63 @@ const unsigned char der_oid_id_dsa[DER_OID_SZ_id_dsa] = { * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { * iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 } */ -const unsigned char der_oid_id_dsa_with_sha1[DER_OID_SZ_id_dsa_with_sha1] = { +const unsigned char ossl_der_oid_id_dsa_with_sha1[DER_OID_SZ_id_dsa_with_sha1] = { DER_OID_V_id_dsa_with_sha1 }; /* * id-dsa-with-sha224 OBJECT IDENTIFIER ::= { sigAlgs 1 } */ -const unsigned char der_oid_id_dsa_with_sha224[DER_OID_SZ_id_dsa_with_sha224] = { +const unsigned char ossl_der_oid_id_dsa_with_sha224[DER_OID_SZ_id_dsa_with_sha224] = { DER_OID_V_id_dsa_with_sha224 }; /* * id-dsa-with-sha256 OBJECT IDENTIFIER ::= { sigAlgs 2 } */ -const unsigned char der_oid_id_dsa_with_sha256[DER_OID_SZ_id_dsa_with_sha256] = { +const unsigned char ossl_der_oid_id_dsa_with_sha256[DER_OID_SZ_id_dsa_with_sha256] = { DER_OID_V_id_dsa_with_sha256 }; /* * id-dsa-with-sha384 OBJECT IDENTIFIER ::= { sigAlgs 3 } */ -const unsigned char der_oid_id_dsa_with_sha384[DER_OID_SZ_id_dsa_with_sha384] = { +const unsigned char ossl_der_oid_id_dsa_with_sha384[DER_OID_SZ_id_dsa_with_sha384] = { DER_OID_V_id_dsa_with_sha384 }; /* * id-dsa-with-sha512 OBJECT IDENTIFIER ::= { sigAlgs 4 } */ -const unsigned char der_oid_id_dsa_with_sha512[DER_OID_SZ_id_dsa_with_sha512] = { +const unsigned char ossl_der_oid_id_dsa_with_sha512[DER_OID_SZ_id_dsa_with_sha512] = { DER_OID_V_id_dsa_with_sha512 }; /* * id-dsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 5 } */ -const unsigned char der_oid_id_dsa_with_sha3_224[DER_OID_SZ_id_dsa_with_sha3_224] = { +const unsigned char ossl_der_oid_id_dsa_with_sha3_224[DER_OID_SZ_id_dsa_with_sha3_224] = { DER_OID_V_id_dsa_with_sha3_224 }; /* * id-dsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 6 } */ -const unsigned char der_oid_id_dsa_with_sha3_256[DER_OID_SZ_id_dsa_with_sha3_256] = { +const unsigned char ossl_der_oid_id_dsa_with_sha3_256[DER_OID_SZ_id_dsa_with_sha3_256] = { DER_OID_V_id_dsa_with_sha3_256 }; /* * id-dsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 7 } */ -const unsigned char der_oid_id_dsa_with_sha3_384[DER_OID_SZ_id_dsa_with_sha3_384] = { +const unsigned char ossl_der_oid_id_dsa_with_sha3_384[DER_OID_SZ_id_dsa_with_sha3_384] = { DER_OID_V_id_dsa_with_sha3_384 }; /* * id-dsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 8 } */ -const unsigned char der_oid_id_dsa_with_sha3_512[DER_OID_SZ_id_dsa_with_sha3_512] = { +const unsigned char ossl_der_oid_id_dsa_with_sha3_512[DER_OID_SZ_id_dsa_with_sha3_512] = { DER_OID_V_id_dsa_with_sha3_512 }; diff --git a/providers/common/der/der_dsa_key.c b/providers/common/der/der_dsa_key.c index 6118b275fb..1a369faa81 100644 --- a/providers/common/der/der_dsa_key.c +++ b/providers/common/der/der_dsa_key.c @@ -11,10 +11,11 @@ #include "internal/packet.h" #include "prov/der_dsa.h" -int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa) +int ossl_DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa) { - return DER_w_begin_sequence(pkt, tag) + return ossl_DER_w_begin_sequence(pkt, tag) /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, der_oid_id_dsa, sizeof(der_oid_id_dsa)) - && DER_w_end_sequence(pkt, tag); + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_dsa, + sizeof(ossl_der_oid_id_dsa)) + && ossl_DER_w_end_sequence(pkt, tag); } diff --git a/providers/common/der/der_dsa_sig.c b/providers/common/der/der_dsa_sig.c index c96a617dad..37ee5f459d 100644 --- a/providers/common/der/der_dsa_sig.c +++ b/providers/common/der/der_dsa_sig.c @@ -13,12 +13,12 @@ #define MD_CASE(name) \ case NID_##name: \ - precompiled = der_oid_id_dsa_with_##name; \ - precompiled_sz = sizeof(der_oid_id_dsa_with_##name); \ + precompiled = ossl_der_oid_id_dsa_with_##name; \ + precompiled_sz = sizeof(ossl_der_oid_id_dsa_with_##name); \ break; -int DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, - DSA *dsa, int mdnid) +int ossl_DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, + DSA *dsa, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; @@ -37,8 +37,8 @@ int DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, return 0; } - return DER_w_begin_sequence(pkt, tag) + return ossl_DER_w_begin_sequence(pkt, tag) /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) - && DER_w_end_sequence(pkt, tag); + && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) + && ossl_DER_w_end_sequence(pkt, tag); } diff --git a/providers/common/der/der_ec.h.in b/providers/common/der/der_ec.h.in index 86a754e4ff..2d56119ba1 100644 --- a/providers/common/der/der_ec.h.in +++ b/providers/common/der/der_ec.h.in @@ -17,7 +17,7 @@ -} /* Subject Public Key Info */ -int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec); +int ossl_DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec); /* Signature */ -int DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, - EC_KEY *ec, int mdnid); +int ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid); diff --git a/providers/common/der/der_ec_gen.c b/providers/common/der/der_ec_gen.c index e22c508a59..73f835744d 100644 --- a/providers/common/der/der_ec_gen.c +++ b/providers/common/der/der_ec_gen.c @@ -14,203 +14,203 @@ /* * ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { id-ecSigType 1 } */ -const unsigned char der_oid_ecdsa_with_SHA1[DER_OID_SZ_ecdsa_with_SHA1] = { +const unsigned char ossl_der_oid_ecdsa_with_SHA1[DER_OID_SZ_ecdsa_with_SHA1] = { DER_OID_V_ecdsa_with_SHA1 }; /* * id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 } */ -const unsigned char der_oid_id_ecPublicKey[DER_OID_SZ_id_ecPublicKey] = { +const unsigned char ossl_der_oid_id_ecPublicKey[DER_OID_SZ_id_ecPublicKey] = { DER_OID_V_id_ecPublicKey }; /* * c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } */ -const unsigned char der_oid_c2pnb163v1[DER_OID_SZ_c2pnb163v1] = { +const unsigned char ossl_der_oid_c2pnb163v1[DER_OID_SZ_c2pnb163v1] = { DER_OID_V_c2pnb163v1 }; /* * c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } */ -const unsigned char der_oid_c2pnb163v2[DER_OID_SZ_c2pnb163v2] = { +const unsigned char ossl_der_oid_c2pnb163v2[DER_OID_SZ_c2pnb163v2] = { DER_OID_V_c2pnb163v2 }; /* * c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } */ -const unsigned char der_oid_c2pnb163v3[DER_OID_SZ_c2pnb163v3] = { +const unsigned char ossl_der_oid_c2pnb163v3[DER_OID_SZ_c2pnb163v3] = { DER_OID_V_c2pnb163v3 }; /* * c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } */ -const unsigned char der_oid_c2pnb176w1[DER_OID_SZ_c2pnb176w1] = { +const unsigned char ossl_der_oid_c2pnb176w1[DER_OID_SZ_c2pnb176w1] = { DER_OID_V_c2pnb176w1 }; /* * c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } */ -const unsigned char der_oid_c2tnb191v1[DER_OID_SZ_c2tnb191v1] = { +const unsigned char ossl_der_oid_c2tnb191v1[DER_OID_SZ_c2tnb191v1] = { DER_OID_V_c2tnb191v1 }; /* * c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } */ -const unsigned char der_oid_c2tnb191v2[DER_OID_SZ_c2tnb191v2] = { +const unsigned char ossl_der_oid_c2tnb191v2[DER_OID_SZ_c2tnb191v2] = { DER_OID_V_c2tnb191v2 }; /* * c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } */ -const unsigned char der_oid_c2tnb191v3[DER_OID_SZ_c2tnb191v3] = { +const unsigned char ossl_der_oid_c2tnb191v3[DER_OID_SZ_c2tnb191v3] = { DER_OID_V_c2tnb191v3 }; /* * c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } */ -const unsigned char der_oid_c2onb191v4[DER_OID_SZ_c2onb191v4] = { +const unsigned char ossl_der_oid_c2onb191v4[DER_OID_SZ_c2onb191v4] = { DER_OID_V_c2onb191v4 }; /* * c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } */ -const unsigned char der_oid_c2onb191v5[DER_OID_SZ_c2onb191v5] = { +const unsigned char ossl_der_oid_c2onb191v5[DER_OID_SZ_c2onb191v5] = { DER_OID_V_c2onb191v5 }; /* * c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } */ -const unsigned char der_oid_c2pnb208w1[DER_OID_SZ_c2pnb208w1] = { +const unsigned char ossl_der_oid_c2pnb208w1[DER_OID_SZ_c2pnb208w1] = { DER_OID_V_c2pnb208w1 }; /* * c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } */ -const unsigned char der_oid_c2tnb239v1[DER_OID_SZ_c2tnb239v1] = { +const unsigned char ossl_der_oid_c2tnb239v1[DER_OID_SZ_c2tnb239v1] = { DER_OID_V_c2tnb239v1 }; /* * c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } */ -const unsigned char der_oid_c2tnb239v2[DER_OID_SZ_c2tnb239v2] = { +const unsigned char ossl_der_oid_c2tnb239v2[DER_OID_SZ_c2tnb239v2] = { DER_OID_V_c2tnb239v2 }; /* * c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } */ -const unsigned char der_oid_c2tnb239v3[DER_OID_SZ_c2tnb239v3] = { +const unsigned char ossl_der_oid_c2tnb239v3[DER_OID_SZ_c2tnb239v3] = { DER_OID_V_c2tnb239v3 }; /* * c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } */ -const unsigned char der_oid_c2onb239v4[DER_OID_SZ_c2onb239v4] = { +const unsigned char ossl_der_oid_c2onb239v4[DER_OID_SZ_c2onb239v4] = { DER_OID_V_c2onb239v4 }; /* * c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } */ -const unsigned char der_oid_c2onb239v5[DER_OID_SZ_c2onb239v5] = { +const unsigned char ossl_der_oid_c2onb239v5[DER_OID_SZ_c2onb239v5] = { DER_OID_V_c2onb239v5 }; /* * c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } */ -const unsigned char der_oid_c2pnb272w1[DER_OID_SZ_c2pnb272w1] = { +const unsigned char ossl_der_oid_c2pnb272w1[DER_OID_SZ_c2pnb272w1] = { DER_OID_V_c2pnb272w1 }; /* * c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } */ -const unsigned char der_oid_c2pnb304w1[DER_OID_SZ_c2pnb304w1] = { +const unsigned char ossl_der_oid_c2pnb304w1[DER_OID_SZ_c2pnb304w1] = { DER_OID_V_c2pnb304w1 }; /* * c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } */ -const unsigned char der_oid_c2tnb359v1[DER_OID_SZ_c2tnb359v1] = { +const unsigned char ossl_der_oid_c2tnb359v1[DER_OID_SZ_c2tnb359v1] = { DER_OID_V_c2tnb359v1 }; /* * c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } */ -const unsigned char der_oid_c2pnb368w1[DER_OID_SZ_c2pnb368w1] = { +const unsigned char ossl_der_oid_c2pnb368w1[DER_OID_SZ_c2pnb368w1] = { DER_OID_V_c2pnb368w1 }; /* * c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } */ -const unsigned char der_oid_c2tnb431r1[DER_OID_SZ_c2tnb431r1] = { +const unsigned char ossl_der_oid_c2tnb431r1[DER_OID_SZ_c2tnb431r1] = { DER_OID_V_c2tnb431r1 }; /* * prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } */ -const unsigned char der_oid_prime192v1[DER_OID_SZ_prime192v1] = { +const unsigned char ossl_der_oid_prime192v1[DER_OID_SZ_prime192v1] = { DER_OID_V_prime192v1 }; /* * prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } */ -const unsigned char der_oid_prime192v2[DER_OID_SZ_prime192v2] = { +const unsigned char ossl_der_oid_prime192v2[DER_OID_SZ_prime192v2] = { DER_OID_V_prime192v2 }; /* * prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } */ -const unsigned char der_oid_prime192v3[DER_OID_SZ_prime192v3] = { +const unsigned char ossl_der_oid_prime192v3[DER_OID_SZ_prime192v3] = { DER_OID_V_prime192v3 }; /* * prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } */ -const unsigned char der_oid_prime239v1[DER_OID_SZ_prime239v1] = { +const unsigned char ossl_der_oid_prime239v1[DER_OID_SZ_prime239v1] = { DER_OID_V_prime239v1 }; /* * prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } */ -const unsigned char der_oid_prime239v2[DER_OID_SZ_prime239v2] = { +const unsigned char ossl_der_oid_prime239v2[DER_OID_SZ_prime239v2] = { DER_OID_V_prime239v2 }; /* * prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } */ -const unsigned char der_oid_prime239v3[DER_OID_SZ_prime239v3] = { +const unsigned char ossl_der_oid_prime239v3[DER_OID_SZ_prime239v3] = { DER_OID_V_prime239v3 }; /* * prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } */ -const unsigned char der_oid_prime256v1[DER_OID_SZ_prime256v1] = { +const unsigned char ossl_der_oid_prime256v1[DER_OID_SZ_prime256v1] = { DER_OID_V_prime256v1 }; @@ -218,7 +218,7 @@ const unsigned char der_oid_prime256v1[DER_OID_SZ_prime256v1] = { * ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) * us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 1 } */ -const unsigned char der_oid_ecdsa_with_SHA224[DER_OID_SZ_ecdsa_with_SHA224] = { +const unsigned char ossl_der_oid_ecdsa_with_SHA224[DER_OID_SZ_ecdsa_with_SHA224] = { DER_OID_V_ecdsa_with_SHA224 }; @@ -226,7 +226,7 @@ const unsigned char der_oid_ecdsa_with_SHA224[DER_OID_SZ_ecdsa_with_SHA224] = { * ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) * us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 } */ -const unsigned char der_oid_ecdsa_with_SHA256[DER_OID_SZ_ecdsa_with_SHA256] = { +const unsigned char ossl_der_oid_ecdsa_with_SHA256[DER_OID_SZ_ecdsa_with_SHA256] = { DER_OID_V_ecdsa_with_SHA256 }; @@ -234,7 +234,7 @@ const unsigned char der_oid_ecdsa_with_SHA256[DER_OID_SZ_ecdsa_with_SHA256] = { * ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) * us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 } */ -const unsigned char der_oid_ecdsa_with_SHA384[DER_OID_SZ_ecdsa_with_SHA384] = { +const unsigned char ossl_der_oid_ecdsa_with_SHA384[DER_OID_SZ_ecdsa_with_SHA384] = { DER_OID_V_ecdsa_with_SHA384 }; @@ -242,35 +242,35 @@ const unsigned char der_oid_ecdsa_with_SHA384[DER_OID_SZ_ecdsa_with_SHA384] = { * ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) * us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 } */ -const unsigned char der_oid_ecdsa_with_SHA512[DER_OID_SZ_ecdsa_with_SHA512] = { +const unsigned char ossl_der_oid_ecdsa_with_SHA512[DER_OID_SZ_ecdsa_with_SHA512] = { DER_OID_V_ecdsa_with_SHA512 }; /* * id-ecdsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 9 } */ -const unsigned char der_oid_id_ecdsa_with_sha3_224[DER_OID_SZ_id_ecdsa_with_sha3_224] = { +const unsigned char ossl_der_oid_id_ecdsa_with_sha3_224[DER_OID_SZ_id_ecdsa_with_sha3_224] = { DER_OID_V_id_ecdsa_with_sha3_224 }; /* * id-ecdsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 10 } */ -const unsigned char der_oid_id_ecdsa_with_sha3_256[DER_OID_SZ_id_ecdsa_with_sha3_256] = { +const unsigned char ossl_der_oid_id_ecdsa_with_sha3_256[DER_OID_SZ_id_ecdsa_with_sha3_256] = { DER_OID_V_id_ecdsa_with_sha3_256 }; /* * id-ecdsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 11 } */ -const unsigned char der_oid_id_ecdsa_with_sha3_384[DER_OID_SZ_id_ecdsa_with_sha3_384] = { +const unsigned char ossl_der_oid_id_ecdsa_with_sha3_384[DER_OID_SZ_id_ecdsa_with_sha3_384] = { DER_OID_V_id_ecdsa_with_sha3_384 }; /* * id-ecdsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 12 } */ -const unsigned char der_oid_id_ecdsa_with_sha3_512[DER_OID_SZ_id_ecdsa_with_sha3_512] = { +const unsigned char ossl_der_oid_id_ecdsa_with_sha3_512[DER_OID_SZ_id_ecdsa_with_sha3_512] = { DER_OID_V_id_ecdsa_with_sha3_512 }; diff --git a/providers/common/der/der_ec_key.c b/providers/common/der/der_ec_key.c index 058596a96e..ae0775af53 100644 --- a/providers/common/der/der_ec_key.c +++ b/providers/common/der/der_ec_key.c @@ -11,11 +11,11 @@ #include "internal/packet.h" #include "prov/der_ec.h" -int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec) +int ossl_DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec) { - return DER_w_begin_sequence(pkt, cont) + return ossl_DER_w_begin_sequence(pkt, cont) /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, der_oid_id_ecPublicKey, - sizeof(der_oid_id_ecPublicKey)) - && DER_w_end_sequence(pkt, cont); + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_ecPublicKey, + sizeof(ossl_der_oid_id_ecPublicKey)) + && ossl_DER_w_end_sequence(pkt, cont); } diff --git a/providers/common/der/der_ec_sig.c b/providers/common/der/der_ec_sig.c index 687ec49c1f..25b672dab2 100644 --- a/providers/common/der/der_ec_sig.c +++ b/providers/common/der/der_ec_sig.c @@ -12,20 +12,20 @@ #include "prov/der_ec.h" /* Aliases so we can have a uniform MD_CASE */ -#define der_oid_id_ecdsa_with_sha1 der_oid_ecdsa_with_SHA1 -#define der_oid_id_ecdsa_with_sha224 der_oid_ecdsa_with_SHA224 -#define der_oid_id_ecdsa_with_sha256 der_oid_ecdsa_with_SHA256 -#define der_oid_id_ecdsa_with_sha384 der_oid_ecdsa_with_SHA384 -#define der_oid_id_ecdsa_with_sha512 der_oid_ecdsa_with_SHA512 +#define ossl_der_oid_id_ecdsa_with_sha1 ossl_der_oid_ecdsa_with_SHA1 +#define ossl_der_oid_id_ecdsa_with_sha224 ossl_der_oid_ecdsa_with_SHA224 +#define ossl_der_oid_id_ecdsa_with_sha256 ossl_der_oid_ecdsa_with_SHA256 +#define ossl_der_oid_id_ecdsa_with_sha384 ossl_der_oid_ecdsa_with_SHA384 +#define ossl_der_oid_id_ecdsa_with_sha512 ossl_der_oid_ecdsa_with_SHA512 #define MD_CASE(name) \ case NID_##name: \ - precompiled = der_oid_id_ecdsa_with_##name; \ - precompiled_sz = sizeof(der_oid_id_ecdsa_with_##name); \ + precompiled = ossl_der_oid_id_ecdsa_with_##name; \ + precompiled_sz = sizeof(ossl_der_oid_id_ecdsa_with_##name); \ break; -int DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, - EC_KEY *ec, int mdnid) +int ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; @@ -44,8 +44,8 @@ int DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, return 0; } - return DER_w_begin_sequence(pkt, cont) + return ossl_DER_w_begin_sequence(pkt, cont) /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) - && DER_w_end_sequence(pkt, cont); + && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) + && ossl_DER_w_end_sequence(pkt, cont); } diff --git a/providers/common/der/der_ecx.h.in b/providers/common/der/der_ecx.h.in new file mode 100644 index 0000000000..ae2310c829 --- /dev/null +++ b/providers/common/der/der_ecx.h.in @@ -0,0 +1,23 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/der.h" +#include "crypto/ecx.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/ECX.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_H }); +-} + +int ossl_DER_w_algorithmIdentifier_ED25519(WPACKET *pkt, int cont, ECX_KEY *ec); +int ossl_DER_w_algorithmIdentifier_ED448(WPACKET *pkt, int cont, ECX_KEY *ec); +int ossl_DER_w_algorithmIdentifier_X25519(WPACKET *pkt, int cont, ECX_KEY *ec); +int ossl_DER_w_algorithmIdentifier_X448(WPACKET *pkt, int cont, ECX_KEY *ec); diff --git a/providers/common/der/der_ecx_gen.c b/providers/common/der/der_ecx_gen.c new file mode 100644 index 0000000000..effcd465c6 --- /dev/null +++ b/providers/common/der/der_ecx_gen.c @@ -0,0 +1,41 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_ecx.h" + +/* Well known OIDs precompiled */ + +/* + * id-X25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 110 } + */ +const unsigned char ossl_der_oid_id_X25519[DER_OID_SZ_id_X25519] = { + DER_OID_V_id_X25519 +}; + +/* + * id-X448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 111 } + */ +const unsigned char ossl_der_oid_id_X448[DER_OID_SZ_id_X448] = { + DER_OID_V_id_X448 +}; + +/* + * id-Ed25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 112 } + */ +const unsigned char ossl_der_oid_id_Ed25519[DER_OID_SZ_id_Ed25519] = { + DER_OID_V_id_Ed25519 +}; + +/* + * id-Ed448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 113 } + */ +const unsigned char ossl_der_oid_id_Ed448[DER_OID_SZ_id_Ed448] = { + DER_OID_V_id_Ed448 +}; + diff --git a/providers/common/der/der_ecx_gen.c.in b/providers/common/der/der_ecx_gen.c.in new file mode 100644 index 0000000000..a0ed9dd0b2 --- /dev/null +++ b/providers/common/der/der_ecx_gen.c.in @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_ecx.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/ECX.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} diff --git a/providers/common/der/der_ecx_key.c b/providers/common/der/der_ecx_key.c new file mode 100644 index 0000000000..c00a11cac8 --- /dev/null +++ b/providers/common/der/der_ecx_key.c @@ -0,0 +1,48 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/packet.h" +#include "prov/der_ecx.h" + +int ossl_DER_w_algorithmIdentifier_X25519(WPACKET *pkt, int cont, ECX_KEY *ec) +{ + return ossl_DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_X25519, + sizeof(ossl_der_oid_id_X25519)) + && ossl_DER_w_end_sequence(pkt, cont); +} + +int ossl_DER_w_algorithmIdentifier_X448(WPACKET *pkt, int cont, ECX_KEY *ec) +{ + return ossl_DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_X448, + sizeof(ossl_der_oid_id_X448)) + && ossl_DER_w_end_sequence(pkt, cont); +} + +int ossl_DER_w_algorithmIdentifier_ED25519(WPACKET *pkt, int cont, ECX_KEY *ec) +{ + return ossl_DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_Ed25519, + sizeof(ossl_der_oid_id_Ed25519)) + && ossl_DER_w_end_sequence(pkt, cont); +} + +int ossl_DER_w_algorithmIdentifier_ED448(WPACKET *pkt, int cont, ECX_KEY *ec) +{ + return ossl_DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_Ed448, + sizeof(ossl_der_oid_id_Ed448)) + && ossl_DER_w_end_sequence(pkt, cont); +} diff --git a/providers/common/der/der_rsa.h.in b/providers/common/der/der_rsa.h.in index c744fc25c5..412d5bbe7f 100644 --- a/providers/common/der/der_rsa.h.in +++ b/providers/common/der/der_rsa.h.in @@ -19,10 +19,10 @@ -} /* PSS parameters */ -int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, - const RSA_PSS_PARAMS_30 *pss); +int ossl_DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, + const RSA_PSS_PARAMS_30 *pss); /* Subject Public Key Info */ -int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa); +int ossl_DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa); /* Signature */ -int DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, - RSA *rsa, int mdnid); +int ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, + RSA *rsa, int mdnid); diff --git a/providers/common/der/der_rsa_gen.c b/providers/common/der/der_rsa_gen.c index 67be225d66..6bfd75023e 100644 --- a/providers/common/der/der_rsa_gen.c +++ b/providers/common/der/der_rsa_gen.c @@ -14,140 +14,140 @@ /* * hashAlgs OBJECT IDENTIFIER ::= { nistAlgorithms 2 } */ -const unsigned char der_oid_hashAlgs[DER_OID_SZ_hashAlgs] = { +const unsigned char ossl_der_oid_hashAlgs[DER_OID_SZ_hashAlgs] = { DER_OID_V_hashAlgs }; /* * rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ -const unsigned char der_oid_rsaEncryption[DER_OID_SZ_rsaEncryption] = { +const unsigned char ossl_der_oid_rsaEncryption[DER_OID_SZ_rsaEncryption] = { DER_OID_V_rsaEncryption }; /* * id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 } */ -const unsigned char der_oid_id_RSAES_OAEP[DER_OID_SZ_id_RSAES_OAEP] = { +const unsigned char ossl_der_oid_id_RSAES_OAEP[DER_OID_SZ_id_RSAES_OAEP] = { DER_OID_V_id_RSAES_OAEP }; /* * id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 } */ -const unsigned char der_oid_id_pSpecified[DER_OID_SZ_id_pSpecified] = { +const unsigned char ossl_der_oid_id_pSpecified[DER_OID_SZ_id_pSpecified] = { DER_OID_V_id_pSpecified }; /* * id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 } */ -const unsigned char der_oid_id_RSASSA_PSS[DER_OID_SZ_id_RSASSA_PSS] = { +const unsigned char ossl_der_oid_id_RSASSA_PSS[DER_OID_SZ_id_RSASSA_PSS] = { DER_OID_V_id_RSASSA_PSS }; /* * md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } */ -const unsigned char der_oid_md2WithRSAEncryption[DER_OID_SZ_md2WithRSAEncryption] = { +const unsigned char ossl_der_oid_md2WithRSAEncryption[DER_OID_SZ_md2WithRSAEncryption] = { DER_OID_V_md2WithRSAEncryption }; /* * md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } */ -const unsigned char der_oid_md5WithRSAEncryption[DER_OID_SZ_md5WithRSAEncryption] = { +const unsigned char ossl_der_oid_md5WithRSAEncryption[DER_OID_SZ_md5WithRSAEncryption] = { DER_OID_V_md5WithRSAEncryption }; /* * sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } */ -const unsigned char der_oid_sha1WithRSAEncryption[DER_OID_SZ_sha1WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha1WithRSAEncryption[DER_OID_SZ_sha1WithRSAEncryption] = { DER_OID_V_sha1WithRSAEncryption }; /* * sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 } */ -const unsigned char der_oid_sha224WithRSAEncryption[DER_OID_SZ_sha224WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha224WithRSAEncryption[DER_OID_SZ_sha224WithRSAEncryption] = { DER_OID_V_sha224WithRSAEncryption }; /* * sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } */ -const unsigned char der_oid_sha256WithRSAEncryption[DER_OID_SZ_sha256WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha256WithRSAEncryption[DER_OID_SZ_sha256WithRSAEncryption] = { DER_OID_V_sha256WithRSAEncryption }; /* * sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } */ -const unsigned char der_oid_sha384WithRSAEncryption[DER_OID_SZ_sha384WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha384WithRSAEncryption[DER_OID_SZ_sha384WithRSAEncryption] = { DER_OID_V_sha384WithRSAEncryption }; /* * sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } */ -const unsigned char der_oid_sha512WithRSAEncryption[DER_OID_SZ_sha512WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha512WithRSAEncryption[DER_OID_SZ_sha512WithRSAEncryption] = { DER_OID_V_sha512WithRSAEncryption }; /* * sha512-224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 15 } */ -const unsigned char der_oid_sha512_224WithRSAEncryption[DER_OID_SZ_sha512_224WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha512_224WithRSAEncryption[DER_OID_SZ_sha512_224WithRSAEncryption] = { DER_OID_V_sha512_224WithRSAEncryption }; /* * sha512-256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 16 } */ -const unsigned char der_oid_sha512_256WithRSAEncryption[DER_OID_SZ_sha512_256WithRSAEncryption] = { +const unsigned char ossl_der_oid_sha512_256WithRSAEncryption[DER_OID_SZ_sha512_256WithRSAEncryption] = { DER_OID_V_sha512_256WithRSAEncryption }; /* * id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 } */ -const unsigned char der_oid_id_mgf1[DER_OID_SZ_id_mgf1] = { +const unsigned char ossl_der_oid_id_mgf1[DER_OID_SZ_id_mgf1] = { DER_OID_V_id_mgf1 }; /* * id-rsassa-pkcs1-v1_5-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 13 } */ -const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_224] = { +const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_224] = { DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_224 }; /* * id-rsassa-pkcs1-v1_5-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 14 } */ -const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_256] = { +const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_256] = { DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_256 }; /* * id-rsassa-pkcs1-v1_5-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 15 } */ -const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_384] = { +const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_384] = { DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_384 }; /* * id-rsassa-pkcs1-v1_5-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 16 } */ -const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_512] = { +const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_512] = { DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_512 }; /* * md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 } */ -const unsigned char der_oid_md4WithRSAEncryption[DER_OID_SZ_md4WithRSAEncryption] = { +const unsigned char ossl_der_oid_md4WithRSAEncryption[DER_OID_SZ_md4WithRSAEncryption] = { DER_OID_V_md4WithRSAEncryption }; @@ -156,7 +156,7 @@ const unsigned char der_oid_md4WithRSAEncryption[DER_OID_SZ_md4WithRSAEncryption * iso(1) identified-organization(3) teletrust(36) algorithm(3) signatureAlgorithm(3) rsaSignature(1) 2 * } */ -const unsigned char der_oid_ripemd160WithRSAEncryption[DER_OID_SZ_ripemd160WithRSAEncryption] = { +const unsigned char ossl_der_oid_ripemd160WithRSAEncryption[DER_OID_SZ_ripemd160WithRSAEncryption] = { DER_OID_V_ripemd160WithRSAEncryption }; diff --git a/providers/common/der/der_rsa_key.c b/providers/common/der/der_rsa_key.c index bd2de4a6c3..a20c334b23 100644 --- a/providers/common/der/der_rsa_key.c +++ b/providers/common/der/der_rsa_key.c @@ -64,66 +64,66 @@ const unsigned char der_aid_sha1Identifier[] = { DER_OID_SZ_id_sha224 + DER_SZ_NULL, \ DER_OID_V_id_sha224, \ DER_V_NULL -extern const unsigned char der_aid_sha224Identifier[]; -const unsigned char der_aid_sha224Identifier[] = { +extern const unsigned char ossl_der_aid_sha224Identifier[]; +const unsigned char ossl_der_aid_sha224Identifier[] = { DER_AID_V_sha224Identifier }; -#define DER_AID_SZ_sha224Identifier sizeof(der_aid_sha224Identifier) +#define DER_AID_SZ_sha224Identifier sizeof(ossl_der_aid_sha224Identifier) #define DER_AID_V_sha256Identifier \ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ DER_OID_SZ_id_sha256 + DER_SZ_NULL, \ DER_OID_V_id_sha256, \ DER_V_NULL -extern const unsigned char der_aid_sha256Identifier[]; -const unsigned char der_aid_sha256Identifier[] = { +extern const unsigned char ossl_der_aid_sha256Identifier[]; +const unsigned char ossl_der_aid_sha256Identifier[] = { DER_AID_V_sha256Identifier }; -#define DER_AID_SZ_sha256Identifier sizeof(der_aid_sha256Identifier) +#define DER_AID_SZ_sha256Identifier sizeof(ossl_der_aid_sha256Identifier) #define DER_AID_V_sha384Identifier \ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ DER_OID_SZ_id_sha384 + DER_SZ_NULL, \ DER_OID_V_id_sha384, \ DER_V_NULL -extern const unsigned char der_aid_sha384Identifier[]; -const unsigned char der_aid_sha384Identifier[] = { +extern const unsigned char ossl_der_aid_sha384Identifier[]; +const unsigned char ossl_der_aid_sha384Identifier[] = { DER_AID_V_sha384Identifier }; -#define DER_AID_SZ_sha384Identifier sizeof(der_aid_sha384Identifier) +#define DER_AID_SZ_sha384Identifier sizeof(ossl_der_aid_sha384Identifier) #define DER_AID_V_sha512Identifier \ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ DER_OID_SZ_id_sha512 + DER_SZ_NULL, \ DER_OID_V_id_sha512, \ DER_V_NULL -extern const unsigned char der_aid_sha512Identifier[]; -const unsigned char der_aid_sha512Identifier[] = { +extern const unsigned char ossl_der_aid_sha512Identifier[]; +const unsigned char ossl_der_aid_sha512Identifier[] = { DER_AID_V_sha512Identifier }; -#define DER_AID_SZ_sha512Identifier sizeof(der_aid_sha512Identifier) +#define DER_AID_SZ_sha512Identifier sizeof(ossl_der_aid_sha512Identifier) #define DER_AID_V_sha512_224Identifier \ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ DER_OID_SZ_id_sha512_224 + DER_SZ_NULL, \ DER_OID_V_id_sha512_224, \ DER_V_NULL -extern const unsigned char der_aid_sha512_224Identifier[]; -const unsigned char der_aid_sha512_224Identifier[] = { +extern const unsigned char ossl_der_aid_sha512_224Identifier[]; +const unsigned char ossl_der_aid_sha512_224Identifier[] = { DER_AID_V_sha512_224Identifier }; -#define DER_AID_SZ_sha512_224Identifier sizeof(der_aid_sha512_224Identifier) +#define DER_AID_SZ_sha512_224Identifier sizeof(ossl_der_aid_sha512_224Identifier) #define DER_AID_V_sha512_256Identifier \ DER_P_SEQUENCE|DER_F_CONSTRUCTED, \ DER_OID_SZ_id_sha512_256 + DER_SZ_NULL, \ DER_OID_V_id_sha512_256, \ DER_V_NULL -extern const unsigned char der_aid_sha512_256Identifier[]; -const unsigned char der_aid_sha512_256Identifier[] = { +extern const unsigned char ossl_der_aid_sha512_256Identifier[]; +const unsigned char ossl_der_aid_sha512_256Identifier[] = { DER_AID_V_sha512_256Identifier }; -#define DER_AID_SZ_sha512_256Identifier sizeof(der_aid_sha512_256Identifier) +#define DER_AID_SZ_sha512_256Identifier sizeof(ossl_der_aid_sha512_256Identifier) /*- * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1 @@ -242,8 +242,8 @@ static const unsigned char der_aid_mgf1SHA512_256Identifier[] = { static int DER_w_MaskGenAlgorithm(WPACKET *pkt, int tag, const RSA_PSS_PARAMS_30 *pss) { - if (pss != NULL && rsa_pss_params_30_maskgenalg(pss) == NID_mgf1) { - int maskgenhashalg_nid = rsa_pss_params_30_maskgenhashalg(pss); + if (pss != NULL && ossl_rsa_pss_params_30_maskgenalg(pss) == NID_mgf1) { + int maskgenhashalg_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); const unsigned char *maskgenalg = NULL; size_t maskgenalg_sz = 0; @@ -264,18 +264,19 @@ static int DER_w_MaskGenAlgorithm(WPACKET *pkt, int tag, if (maskgenalg == NULL) return 1; - return DER_w_precompiled(pkt, tag, maskgenalg, maskgenalg_sz); + return ossl_DER_w_precompiled(pkt, tag, maskgenalg, maskgenalg_sz); } return 0; } #define OAEP_PSS_MD_CASE(name, var) \ case NID_##name: \ - var = der_oid_id_##name; \ - var##_sz = sizeof(der_oid_id_##name); \ + var = ossl_der_oid_id_##name; \ + var##_sz = sizeof(ossl_der_oid_id_##name); \ break; -int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, const RSA_PSS_PARAMS_30 *pss) +int ossl_DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, + const RSA_PSS_PARAMS_30 *pss) { int hashalg_nid, default_hashalg_nid; int saltlen, default_saltlen; @@ -291,17 +292,18 @@ int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, const RSA_PSS_PARAMS_30 *pss) * intent. Therefore, we assert that here, the PSS parameters must show * that the key is restricted. */ - if (!ossl_assert(pss != NULL && !rsa_pss_params_30_is_unrestricted(pss))) + if (!ossl_assert(pss != NULL + && !ossl_rsa_pss_params_30_is_unrestricted(pss))) return 0; - hashalg_nid = rsa_pss_params_30_hashalg(pss); - saltlen = rsa_pss_params_30_saltlen(pss); - trailerfield = rsa_pss_params_30_trailerfield(pss); + hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss); + saltlen = ossl_rsa_pss_params_30_saltlen(pss); + trailerfield = ossl_rsa_pss_params_30_trailerfield(pss); /* Getting default values */ - default_hashalg_nid = rsa_pss_params_30_hashalg(NULL); - default_saltlen = rsa_pss_params_30_saltlen(NULL); - default_trailerfield = rsa_pss_params_30_trailerfield(NULL); + default_hashalg_nid = ossl_rsa_pss_params_30_hashalg(NULL); + default_saltlen = ossl_rsa_pss_params_30_saltlen(NULL); + default_trailerfield = ossl_rsa_pss_params_30_trailerfield(NULL); /* * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1: @@ -329,31 +331,31 @@ int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, const RSA_PSS_PARAMS_30 *pss) return 0; } - return DER_w_begin_sequence(pkt, tag) + return ossl_DER_w_begin_sequence(pkt, tag) && (trailerfield == default_trailerfield - || DER_w_ulong(pkt, 3, trailerfield)) - && (saltlen == default_saltlen || DER_w_ulong(pkt, 2, saltlen)) + || ossl_DER_w_ulong(pkt, 3, trailerfield)) + && (saltlen == default_saltlen || ossl_DER_w_ulong(pkt, 2, saltlen)) && DER_w_MaskGenAlgorithm(pkt, 1, pss) && (hashalg_nid == default_hashalg_nid - || DER_w_precompiled(pkt, 0, hashalg, hashalg_sz)) - && DER_w_end_sequence(pkt, tag); + || ossl_DER_w_precompiled(pkt, 0, hashalg, hashalg_sz)) + && ossl_DER_w_end_sequence(pkt, tag); } /* Aliases so we can have a uniform RSA_CASE */ -#define der_oid_rsassaPss der_oid_id_RSASSA_PSS +#define ossl_der_oid_rsassaPss ossl_der_oid_id_RSASSA_PSS #define RSA_CASE(name, var) \ var##_nid = NID_##name; \ - var##_oid = der_oid_##name; \ - var##_oid_sz = sizeof(der_oid_##name); \ + var##_oid = ossl_der_oid_##name; \ + var##_oid_sz = sizeof(ossl_der_oid_##name); \ break; -int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa) +int ossl_DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa) { int rsa_nid = NID_undef; const unsigned char *rsa_oid = NULL; size_t rsa_oid_sz = 0; - RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa); + RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa); switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: @@ -365,10 +367,10 @@ int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa) if (rsa_oid == NULL) return 0; - return DER_w_begin_sequence(pkt, tag) + return ossl_DER_w_begin_sequence(pkt, tag) && (rsa_nid != NID_rsassaPss - || rsa_pss_params_30_is_unrestricted(pss_params) - || DER_w_RSASSA_PSS_params(pkt, -1, pss_params)) - && DER_w_precompiled(pkt, -1, rsa_oid, rsa_oid_sz) - && DER_w_end_sequence(pkt, tag); + || ossl_rsa_pss_params_30_is_unrestricted(pss_params) + || ossl_DER_w_RSASSA_PSS_params(pkt, -1, pss_params)) + && ossl_DER_w_precompiled(pkt, -1, rsa_oid, rsa_oid_sz) + && ossl_DER_w_end_sequence(pkt, tag); } diff --git a/providers/common/der/der_rsa_sig.c b/providers/common/der/der_rsa_sig.c index a1ab263dc1..1ff9bf789b 100644 --- a/providers/common/der/der_rsa_sig.c +++ b/providers/common/der/der_rsa_sig.c @@ -13,23 +13,23 @@ #include "prov/der_digests.h" /* Aliases so we can have a uniform MD_with_RSA_CASE */ -#define der_oid_sha3_224WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224 -#define der_oid_sha3_256WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256 -#define der_oid_sha3_384WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384 -#define der_oid_sha3_512WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512 +#define ossl_der_oid_sha3_224WithRSAEncryption \ + ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224 +#define ossl_der_oid_sha3_256WithRSAEncryption \ + ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256 +#define ossl_der_oid_sha3_384WithRSAEncryption \ + ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384 +#define ossl_der_oid_sha3_512WithRSAEncryption \ + ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512 #define MD_with_RSA_CASE(name, var) \ case NID_##name: \ - var = der_oid_##name##WithRSAEncryption; \ - var##_sz = sizeof(der_oid_##name##WithRSAEncryption); \ + var = ossl_der_oid_##name##WithRSAEncryption; \ + var##_sz = sizeof(ossl_der_oid_##name##WithRSAEncryption); \ break; -int DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, - RSA *rsa, int mdnid) +int ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, + RSA *rsa, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; @@ -57,8 +57,8 @@ int DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, return 0; } - return DER_w_begin_sequence(pkt, tag) + return ossl_DER_w_begin_sequence(pkt, tag) /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) - && DER_w_end_sequence(pkt, tag); + && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) + && ossl_DER_w_end_sequence(pkt, tag); } diff --git a/providers/common/der/der_sm2.h.in b/providers/common/der/der_sm2.h.in new file mode 100644 index 0000000000..406ddf2b16 --- /dev/null +++ b/providers/common/der/der_sm2.h.in @@ -0,0 +1,23 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/der.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/SM2.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_H }); +-} + +/* Subject Public Key Info */ +int DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec); +/* Signature */ +int DER_w_algorithmIdentifier_SM2_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid); diff --git a/providers/common/der/der_sm2_gen.c b/providers/common/der/der_sm2_gen.c new file mode 100644 index 0000000000..c142012089 --- /dev/null +++ b/providers/common/der/der_sm2_gen.c @@ -0,0 +1,27 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_sm2.h" + +/* Well known OIDs precompiled */ + +/* + * sm2-with-SM3 OBJECT IDENTIFIER ::= { sm-scheme 501 } + */ +const unsigned char ossl_der_oid_sm2_with_SM3[DER_OID_SZ_sm2_with_SM3] = { + DER_OID_V_sm2_with_SM3 +}; + +/* + * curveSM2 OBJECT IDENTIFIER ::= { sm-scheme 301 } + */ +const unsigned char ossl_der_oid_curveSM2[DER_OID_SZ_curveSM2] = { + DER_OID_V_curveSM2 +}; + diff --git a/providers/common/der/der_sm2_gen.c.in b/providers/common/der/der_sm2_gen.c.in new file mode 100644 index 0000000000..fc3c4461df --- /dev/null +++ b/providers/common/der/der_sm2_gen.c.in @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_sm2.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/SM2.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} diff --git a/providers/common/der/der_sm2_key.c b/providers/common/der/der_sm2_key.c new file mode 100644 index 0000000000..a766bb4f3d --- /dev/null +++ b/providers/common/der/der_sm2_key.c @@ -0,0 +1,23 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/packet.h" +#include "prov/der_ec.h" +#include "prov/der_sm2.h" + +int DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec) +{ + return ossl_DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + /* It seems SM2 identifier is the same as id_ecPublidKey */ + && ossl_DER_w_precompiled(pkt, -1, ossl_der_oid_id_ecPublicKey, + sizeof(ossl_der_oid_id_ecPublicKey)) + && ossl_DER_w_end_sequence(pkt, cont); +} diff --git a/providers/common/der/der_sm2_sig.c b/providers/common/der/der_sm2_sig.c new file mode 100644 index 0000000000..7b710cfa53 --- /dev/null +++ b/providers/common/der/der_sm2_sig.c @@ -0,0 +1,39 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/packet.h" +#include "prov/der_sm2.h" + +/* Aliases so we can have a uniform MD_CASE */ +#define ossl_der_oid_id_sm2_with_sm3 ossl_der_oid_sm2_with_SM3 + +#define MD_CASE(name) \ + case NID_##name: \ + precompiled = ossl_der_oid_id_sm2_with_##name; \ + precompiled_sz = sizeof(ossl_der_oid_id_sm2_with_##name); \ + break; + +int DER_w_algorithmIdentifier_SM2_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid) +{ + const unsigned char *precompiled = NULL; + size_t precompiled_sz = 0; + + switch (mdnid) { + MD_CASE(sm3); + default: + return 0; + } + + return ossl_DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + && ossl_DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) + && ossl_DER_w_end_sequence(pkt, cont); +} diff --git a/providers/common/der/der_wrap_gen.c b/providers/common/der/der_wrap_gen.c index a8bd725c63..85b433a6c8 100644 --- a/providers/common/der/der_wrap_gen.c +++ b/providers/common/der/der_wrap_gen.c @@ -16,28 +16,28 @@ * iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) alg(3) 6 * } */ -const unsigned char der_oid_id_alg_CMS3DESwrap[DER_OID_SZ_id_alg_CMS3DESwrap] = { +const unsigned char ossl_der_oid_id_alg_CMS3DESwrap[DER_OID_SZ_id_alg_CMS3DESwrap] = { DER_OID_V_id_alg_CMS3DESwrap }; /* * id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ -const unsigned char der_oid_id_aes128_wrap[DER_OID_SZ_id_aes128_wrap] = { +const unsigned char ossl_der_oid_id_aes128_wrap[DER_OID_SZ_id_aes128_wrap] = { DER_OID_V_id_aes128_wrap }; /* * id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ -const unsigned char der_oid_id_aes192_wrap[DER_OID_SZ_id_aes192_wrap] = { +const unsigned char ossl_der_oid_id_aes192_wrap[DER_OID_SZ_id_aes192_wrap] = { DER_OID_V_id_aes192_wrap }; /* * id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ -const unsigned char der_oid_id_aes256_wrap[DER_OID_SZ_id_aes256_wrap] = { +const unsigned char ossl_der_oid_id_aes256_wrap[DER_OID_SZ_id_aes256_wrap] = { DER_OID_V_id_aes256_wrap }; diff --git a/providers/common/der/oids_to_c.pm b/providers/common/der/oids_to_c.pm index dee326316b..aa5b80cc12 100644 --- a/providers/common/der/oids_to_c.pm +++ b/providers/common/der/oids_to_c.pm @@ -40,7 +40,7 @@ sub filter_to_H { $C_comment #define DER_OID_V_${C_name} DER_P_OBJECT, $oid_size, ${C_bytes} #define DER_OID_SZ_${C_name} ${C_bytes_size} -extern const unsigned char der_oid_${C_name}[DER_OID_SZ_${C_name}]; +extern const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}]; _____ } @@ -58,7 +58,7 @@ sub filter_to_C { return <<"_____"; $C_comment -const unsigned char der_oid_${C_name}[DER_OID_SZ_${C_name}] = { +const unsigned char ossl_der_oid_${C_name}[DER_OID_SZ_${C_name}] = { DER_OID_V_${C_name} }; _____ diff --git a/providers/common/digest_to_nid.c b/providers/common/digest_to_nid.c new file mode 100644 index 0000000000..99633c150c --- /dev/null +++ b/providers/common/digest_to_nid.c @@ -0,0 +1,55 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "prov/securitycheck.h" +#include "internal/nelem.h" + +/* + * Internal library code deals with NIDs, so we need to translate from a name. + * We do so using EVP_MD_is_a(), and therefore need a name to NID map. + */ +int digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len) +{ + size_t i; + + if (md == NULL) + return NID_undef; + + for (i = 0; i < it_len; i++) + if (EVP_MD_is_a(md, it[i].ptr)) + return (int)it[i].id; + return NID_undef; +} + +/* + * Retrieve one of the FIPs approved hash algorithms by nid. + * See FIPS 180-4 "Secure Hash Standard" and FIPS 202 - SHA-3. + */ +int digest_get_approved_nid(const EVP_MD *md) +{ + static const OSSL_ITEM name_to_nid[] = { + { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, + { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, + { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, + { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, + { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, + { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 }, + { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 }, + { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, + { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, + { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, + { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, + }; + + return digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid)); +} diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h index 3cef89ce18..9dd9f44bad 100644 --- a/providers/common/include/prov/bio.h +++ b/providers/common/include/prov/bio.h @@ -22,6 +22,7 @@ int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len size_t *written); int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size); int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str); +int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr); int ossl_prov_bio_free(OSSL_CORE_BIO *bio); int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap); int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...); diff --git a/providers/common/include/prov/der_digests.h b/providers/common/include/prov/der_digests.h index fe201a6c58..9136a3a6c9 100644 --- a/providers/common/include/prov/der_digests.h +++ b/providers/common/include/prov/der_digests.h @@ -16,7 +16,7 @@ */ #define DER_OID_V_sigAlgs DER_P_OBJECT, 8, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03 #define DER_OID_SZ_sigAlgs 10 -extern const unsigned char der_oid_sigAlgs[DER_OID_SZ_sigAlgs]; +extern const unsigned char ossl_der_oid_sigAlgs[DER_OID_SZ_sigAlgs]; /* * id-sha1 OBJECT IDENTIFIER ::= { iso(1) @@ -25,7 +25,7 @@ extern const unsigned char der_oid_sigAlgs[DER_OID_SZ_sigAlgs]; */ #define DER_OID_V_id_sha1 DER_P_OBJECT, 5, 0x2B, 0x0E, 0x03, 0x02, 0x1A #define DER_OID_SZ_id_sha1 7 -extern const unsigned char der_oid_id_sha1[DER_OID_SZ_id_sha1]; +extern const unsigned char ossl_der_oid_id_sha1[DER_OID_SZ_id_sha1]; /* * id-md2 OBJECT IDENTIFIER ::= { @@ -33,7 +33,7 @@ extern const unsigned char der_oid_id_sha1[DER_OID_SZ_id_sha1]; */ #define DER_OID_V_id_md2 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02 #define DER_OID_SZ_id_md2 10 -extern const unsigned char der_oid_id_md2[DER_OID_SZ_id_md2]; +extern const unsigned char ossl_der_oid_id_md2[DER_OID_SZ_id_md2]; /* * id-md5 OBJECT IDENTIFIER ::= { @@ -41,117 +41,117 @@ extern const unsigned char der_oid_id_md2[DER_OID_SZ_id_md2]; */ #define DER_OID_V_id_md5 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05 #define DER_OID_SZ_id_md5 10 -extern const unsigned char der_oid_id_md5[DER_OID_SZ_id_md5]; +extern const unsigned char ossl_der_oid_id_md5[DER_OID_SZ_id_md5]; /* * id-sha256 OBJECT IDENTIFIER ::= { hashAlgs 1 } */ #define DER_OID_V_id_sha256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01 #define DER_OID_SZ_id_sha256 11 -extern const unsigned char der_oid_id_sha256[DER_OID_SZ_id_sha256]; +extern const unsigned char ossl_der_oid_id_sha256[DER_OID_SZ_id_sha256]; /* * id-sha384 OBJECT IDENTIFIER ::= { hashAlgs 2 } */ #define DER_OID_V_id_sha384 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02 #define DER_OID_SZ_id_sha384 11 -extern const unsigned char der_oid_id_sha384[DER_OID_SZ_id_sha384]; +extern const unsigned char ossl_der_oid_id_sha384[DER_OID_SZ_id_sha384]; /* * id-sha512 OBJECT IDENTIFIER ::= { hashAlgs 3 } */ #define DER_OID_V_id_sha512 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03 #define DER_OID_SZ_id_sha512 11 -extern const unsigned char der_oid_id_sha512[DER_OID_SZ_id_sha512]; +extern const unsigned char ossl_der_oid_id_sha512[DER_OID_SZ_id_sha512]; /* * id-sha224 OBJECT IDENTIFIER ::= { hashAlgs 4 } */ #define DER_OID_V_id_sha224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04 #define DER_OID_SZ_id_sha224 11 -extern const unsigned char der_oid_id_sha224[DER_OID_SZ_id_sha224]; +extern const unsigned char ossl_der_oid_id_sha224[DER_OID_SZ_id_sha224]; /* * id-sha512-224 OBJECT IDENTIFIER ::= { hashAlgs 5 } */ #define DER_OID_V_id_sha512_224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05 #define DER_OID_SZ_id_sha512_224 11 -extern const unsigned char der_oid_id_sha512_224[DER_OID_SZ_id_sha512_224]; +extern const unsigned char ossl_der_oid_id_sha512_224[DER_OID_SZ_id_sha512_224]; /* * id-sha512-256 OBJECT IDENTIFIER ::= { hashAlgs 6 } */ #define DER_OID_V_id_sha512_256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06 #define DER_OID_SZ_id_sha512_256 11 -extern const unsigned char der_oid_id_sha512_256[DER_OID_SZ_id_sha512_256]; +extern const unsigned char ossl_der_oid_id_sha512_256[DER_OID_SZ_id_sha512_256]; /* * id-sha3-224 OBJECT IDENTIFIER ::= { hashAlgs 7 } */ #define DER_OID_V_id_sha3_224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x07 #define DER_OID_SZ_id_sha3_224 11 -extern const unsigned char der_oid_id_sha3_224[DER_OID_SZ_id_sha3_224]; +extern const unsigned char ossl_der_oid_id_sha3_224[DER_OID_SZ_id_sha3_224]; /* * id-sha3-256 OBJECT IDENTIFIER ::= { hashAlgs 8 } */ #define DER_OID_V_id_sha3_256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08 #define DER_OID_SZ_id_sha3_256 11 -extern const unsigned char der_oid_id_sha3_256[DER_OID_SZ_id_sha3_256]; +extern const unsigned char ossl_der_oid_id_sha3_256[DER_OID_SZ_id_sha3_256]; /* * id-sha3-384 OBJECT IDENTIFIER ::= { hashAlgs 9 } */ #define DER_OID_V_id_sha3_384 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09 #define DER_OID_SZ_id_sha3_384 11 -extern const unsigned char der_oid_id_sha3_384[DER_OID_SZ_id_sha3_384]; +extern const unsigned char ossl_der_oid_id_sha3_384[DER_OID_SZ_id_sha3_384]; /* * id-sha3-512 OBJECT IDENTIFIER ::= { hashAlgs 10 } */ #define DER_OID_V_id_sha3_512 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A #define DER_OID_SZ_id_sha3_512 11 -extern const unsigned char der_oid_id_sha3_512[DER_OID_SZ_id_sha3_512]; +extern const unsigned char ossl_der_oid_id_sha3_512[DER_OID_SZ_id_sha3_512]; /* * id-shake128 OBJECT IDENTIFIER ::= { hashAlgs 11 } */ #define DER_OID_V_id_shake128 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0B #define DER_OID_SZ_id_shake128 11 -extern const unsigned char der_oid_id_shake128[DER_OID_SZ_id_shake128]; +extern const unsigned char ossl_der_oid_id_shake128[DER_OID_SZ_id_shake128]; /* * id-shake256 OBJECT IDENTIFIER ::= { hashAlgs 12 } */ #define DER_OID_V_id_shake256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0C #define DER_OID_SZ_id_shake256 11 -extern const unsigned char der_oid_id_shake256[DER_OID_SZ_id_shake256]; +extern const unsigned char ossl_der_oid_id_shake256[DER_OID_SZ_id_shake256]; /* * id-shake128-len OBJECT IDENTIFIER ::= { hashAlgs 17 } */ #define DER_OID_V_id_shake128_len DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x11 #define DER_OID_SZ_id_shake128_len 11 -extern const unsigned char der_oid_id_shake128_len[DER_OID_SZ_id_shake128_len]; +extern const unsigned char ossl_der_oid_id_shake128_len[DER_OID_SZ_id_shake128_len]; /* * id-shake256-len OBJECT IDENTIFIER ::= { hashAlgs 18 } */ #define DER_OID_V_id_shake256_len DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x12 #define DER_OID_SZ_id_shake256_len 11 -extern const unsigned char der_oid_id_shake256_len[DER_OID_SZ_id_shake256_len]; +extern const unsigned char ossl_der_oid_id_shake256_len[DER_OID_SZ_id_shake256_len]; /* * id-KMACWithSHAKE128 OBJECT IDENTIFIER ::={hashAlgs 19} */ #define DER_OID_V_id_KMACWithSHAKE128 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x13 #define DER_OID_SZ_id_KMACWithSHAKE128 11 -extern const unsigned char der_oid_id_KMACWithSHAKE128[DER_OID_SZ_id_KMACWithSHAKE128]; +extern const unsigned char ossl_der_oid_id_KMACWithSHAKE128[DER_OID_SZ_id_KMACWithSHAKE128]; /* * id-KMACWithSHAKE256 OBJECT IDENTIFIER ::={ hashAlgs 20} */ #define DER_OID_V_id_KMACWithSHAKE256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x14 #define DER_OID_SZ_id_KMACWithSHAKE256 11 -extern const unsigned char der_oid_id_KMACWithSHAKE256[DER_OID_SZ_id_KMACWithSHAKE256]; +extern const unsigned char ossl_der_oid_id_KMACWithSHAKE256[DER_OID_SZ_id_KMACWithSHAKE256]; diff --git a/providers/common/include/prov/der_dsa.h b/providers/common/include/prov/der_dsa.h index 543f70af0a..a327219e66 100644 --- a/providers/common/include/prov/der_dsa.h +++ b/providers/common/include/prov/der_dsa.h @@ -17,7 +17,7 @@ */ #define DER_OID_V_id_dsa DER_P_OBJECT, 7, 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01 #define DER_OID_SZ_id_dsa 9 -extern const unsigned char der_oid_id_dsa[DER_OID_SZ_id_dsa]; +extern const unsigned char ossl_der_oid_id_dsa[DER_OID_SZ_id_dsa]; /* * id-dsa-with-sha1 OBJECT IDENTIFIER ::= { @@ -25,67 +25,67 @@ extern const unsigned char der_oid_id_dsa[DER_OID_SZ_id_dsa]; */ #define DER_OID_V_id_dsa_with_sha1 DER_P_OBJECT, 7, 0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x03 #define DER_OID_SZ_id_dsa_with_sha1 9 -extern const unsigned char der_oid_id_dsa_with_sha1[DER_OID_SZ_id_dsa_with_sha1]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha1[DER_OID_SZ_id_dsa_with_sha1]; /* * id-dsa-with-sha224 OBJECT IDENTIFIER ::= { sigAlgs 1 } */ #define DER_OID_V_id_dsa_with_sha224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x01 #define DER_OID_SZ_id_dsa_with_sha224 11 -extern const unsigned char der_oid_id_dsa_with_sha224[DER_OID_SZ_id_dsa_with_sha224]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha224[DER_OID_SZ_id_dsa_with_sha224]; /* * id-dsa-with-sha256 OBJECT IDENTIFIER ::= { sigAlgs 2 } */ #define DER_OID_V_id_dsa_with_sha256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x02 #define DER_OID_SZ_id_dsa_with_sha256 11 -extern const unsigned char der_oid_id_dsa_with_sha256[DER_OID_SZ_id_dsa_with_sha256]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha256[DER_OID_SZ_id_dsa_with_sha256]; /* * id-dsa-with-sha384 OBJECT IDENTIFIER ::= { sigAlgs 3 } */ #define DER_OID_V_id_dsa_with_sha384 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x03 #define DER_OID_SZ_id_dsa_with_sha384 11 -extern const unsigned char der_oid_id_dsa_with_sha384[DER_OID_SZ_id_dsa_with_sha384]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha384[DER_OID_SZ_id_dsa_with_sha384]; /* * id-dsa-with-sha512 OBJECT IDENTIFIER ::= { sigAlgs 4 } */ #define DER_OID_V_id_dsa_with_sha512 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x04 #define DER_OID_SZ_id_dsa_with_sha512 11 -extern const unsigned char der_oid_id_dsa_with_sha512[DER_OID_SZ_id_dsa_with_sha512]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha512[DER_OID_SZ_id_dsa_with_sha512]; /* * id-dsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 5 } */ #define DER_OID_V_id_dsa_with_sha3_224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x05 #define DER_OID_SZ_id_dsa_with_sha3_224 11 -extern const unsigned char der_oid_id_dsa_with_sha3_224[DER_OID_SZ_id_dsa_with_sha3_224]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha3_224[DER_OID_SZ_id_dsa_with_sha3_224]; /* * id-dsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 6 } */ #define DER_OID_V_id_dsa_with_sha3_256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x06 #define DER_OID_SZ_id_dsa_with_sha3_256 11 -extern const unsigned char der_oid_id_dsa_with_sha3_256[DER_OID_SZ_id_dsa_with_sha3_256]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha3_256[DER_OID_SZ_id_dsa_with_sha3_256]; /* * id-dsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 7 } */ #define DER_OID_V_id_dsa_with_sha3_384 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x07 #define DER_OID_SZ_id_dsa_with_sha3_384 11 -extern const unsigned char der_oid_id_dsa_with_sha3_384[DER_OID_SZ_id_dsa_with_sha3_384]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha3_384[DER_OID_SZ_id_dsa_with_sha3_384]; /* * id-dsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 8 } */ #define DER_OID_V_id_dsa_with_sha3_512 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x08 #define DER_OID_SZ_id_dsa_with_sha3_512 11 -extern const unsigned char der_oid_id_dsa_with_sha3_512[DER_OID_SZ_id_dsa_with_sha3_512]; +extern const unsigned char ossl_der_oid_id_dsa_with_sha3_512[DER_OID_SZ_id_dsa_with_sha3_512]; /* Subject Public Key Info */ -int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa); +int ossl_DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa); /* Signature */ -int DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, - DSA *dsa, int mdnid); +int ossl_DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, + DSA *dsa, int mdnid); diff --git a/providers/common/include/prov/der_ec.h b/providers/common/include/prov/der_ec.h index ecca728f3c..72f214896d 100644 --- a/providers/common/include/prov/der_ec.h +++ b/providers/common/include/prov/der_ec.h @@ -16,203 +16,203 @@ */ #define DER_OID_V_ecdsa_with_SHA1 DER_P_OBJECT, 7, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01 #define DER_OID_SZ_ecdsa_with_SHA1 9 -extern const unsigned char der_oid_ecdsa_with_SHA1[DER_OID_SZ_ecdsa_with_SHA1]; +extern const unsigned char ossl_der_oid_ecdsa_with_SHA1[DER_OID_SZ_ecdsa_with_SHA1]; /* * id-ecPublicKey OBJECT IDENTIFIER ::= { id-publicKeyType 1 } */ #define DER_OID_V_id_ecPublicKey DER_P_OBJECT, 7, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01 #define DER_OID_SZ_id_ecPublicKey 9 -extern const unsigned char der_oid_id_ecPublicKey[DER_OID_SZ_id_ecPublicKey]; +extern const unsigned char ossl_der_oid_id_ecPublicKey[DER_OID_SZ_id_ecPublicKey]; /* * c2pnb163v1 OBJECT IDENTIFIER ::= { c-TwoCurve 1 } */ #define DER_OID_V_c2pnb163v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x01 #define DER_OID_SZ_c2pnb163v1 10 -extern const unsigned char der_oid_c2pnb163v1[DER_OID_SZ_c2pnb163v1]; +extern const unsigned char ossl_der_oid_c2pnb163v1[DER_OID_SZ_c2pnb163v1]; /* * c2pnb163v2 OBJECT IDENTIFIER ::= { c-TwoCurve 2 } */ #define DER_OID_V_c2pnb163v2 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x02 #define DER_OID_SZ_c2pnb163v2 10 -extern const unsigned char der_oid_c2pnb163v2[DER_OID_SZ_c2pnb163v2]; +extern const unsigned char ossl_der_oid_c2pnb163v2[DER_OID_SZ_c2pnb163v2]; /* * c2pnb163v3 OBJECT IDENTIFIER ::= { c-TwoCurve 3 } */ #define DER_OID_V_c2pnb163v3 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x03 #define DER_OID_SZ_c2pnb163v3 10 -extern const unsigned char der_oid_c2pnb163v3[DER_OID_SZ_c2pnb163v3]; +extern const unsigned char ossl_der_oid_c2pnb163v3[DER_OID_SZ_c2pnb163v3]; /* * c2pnb176w1 OBJECT IDENTIFIER ::= { c-TwoCurve 4 } */ #define DER_OID_V_c2pnb176w1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x04 #define DER_OID_SZ_c2pnb176w1 10 -extern const unsigned char der_oid_c2pnb176w1[DER_OID_SZ_c2pnb176w1]; +extern const unsigned char ossl_der_oid_c2pnb176w1[DER_OID_SZ_c2pnb176w1]; /* * c2tnb191v1 OBJECT IDENTIFIER ::= { c-TwoCurve 5 } */ #define DER_OID_V_c2tnb191v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x05 #define DER_OID_SZ_c2tnb191v1 10 -extern const unsigned char der_oid_c2tnb191v1[DER_OID_SZ_c2tnb191v1]; +extern const unsigned char ossl_der_oid_c2tnb191v1[DER_OID_SZ_c2tnb191v1]; /* * c2tnb191v2 OBJECT IDENTIFIER ::= { c-TwoCurve 6 } */ #define DER_OID_V_c2tnb191v2 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x06 #define DER_OID_SZ_c2tnb191v2 10 -extern const unsigned char der_oid_c2tnb191v2[DER_OID_SZ_c2tnb191v2]; +extern const unsigned char ossl_der_oid_c2tnb191v2[DER_OID_SZ_c2tnb191v2]; /* * c2tnb191v3 OBJECT IDENTIFIER ::= { c-TwoCurve 7 } */ #define DER_OID_V_c2tnb191v3 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x07 #define DER_OID_SZ_c2tnb191v3 10 -extern const unsigned char der_oid_c2tnb191v3[DER_OID_SZ_c2tnb191v3]; +extern const unsigned char ossl_der_oid_c2tnb191v3[DER_OID_SZ_c2tnb191v3]; /* * c2onb191v4 OBJECT IDENTIFIER ::= { c-TwoCurve 8 } */ #define DER_OID_V_c2onb191v4 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x08 #define DER_OID_SZ_c2onb191v4 10 -extern const unsigned char der_oid_c2onb191v4[DER_OID_SZ_c2onb191v4]; +extern const unsigned char ossl_der_oid_c2onb191v4[DER_OID_SZ_c2onb191v4]; /* * c2onb191v5 OBJECT IDENTIFIER ::= { c-TwoCurve 9 } */ #define DER_OID_V_c2onb191v5 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x09 #define DER_OID_SZ_c2onb191v5 10 -extern const unsigned char der_oid_c2onb191v5[DER_OID_SZ_c2onb191v5]; +extern const unsigned char ossl_der_oid_c2onb191v5[DER_OID_SZ_c2onb191v5]; /* * c2pnb208w1 OBJECT IDENTIFIER ::= { c-TwoCurve 10 } */ #define DER_OID_V_c2pnb208w1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x0A #define DER_OID_SZ_c2pnb208w1 10 -extern const unsigned char der_oid_c2pnb208w1[DER_OID_SZ_c2pnb208w1]; +extern const unsigned char ossl_der_oid_c2pnb208w1[DER_OID_SZ_c2pnb208w1]; /* * c2tnb239v1 OBJECT IDENTIFIER ::= { c-TwoCurve 11 } */ #define DER_OID_V_c2tnb239v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x0B #define DER_OID_SZ_c2tnb239v1 10 -extern const unsigned char der_oid_c2tnb239v1[DER_OID_SZ_c2tnb239v1]; +extern const unsigned char ossl_der_oid_c2tnb239v1[DER_OID_SZ_c2tnb239v1]; /* * c2tnb239v2 OBJECT IDENTIFIER ::= { c-TwoCurve 12 } */ #define DER_OID_V_c2tnb239v2 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x0C #define DER_OID_SZ_c2tnb239v2 10 -extern const unsigned char der_oid_c2tnb239v2[DER_OID_SZ_c2tnb239v2]; +extern const unsigned char ossl_der_oid_c2tnb239v2[DER_OID_SZ_c2tnb239v2]; /* * c2tnb239v3 OBJECT IDENTIFIER ::= { c-TwoCurve 13 } */ #define DER_OID_V_c2tnb239v3 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x0D #define DER_OID_SZ_c2tnb239v3 10 -extern const unsigned char der_oid_c2tnb239v3[DER_OID_SZ_c2tnb239v3]; +extern const unsigned char ossl_der_oid_c2tnb239v3[DER_OID_SZ_c2tnb239v3]; /* * c2onb239v4 OBJECT IDENTIFIER ::= { c-TwoCurve 14 } */ #define DER_OID_V_c2onb239v4 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x0E #define DER_OID_SZ_c2onb239v4 10 -extern const unsigned char der_oid_c2onb239v4[DER_OID_SZ_c2onb239v4]; +extern const unsigned char ossl_der_oid_c2onb239v4[DER_OID_SZ_c2onb239v4]; /* * c2onb239v5 OBJECT IDENTIFIER ::= { c-TwoCurve 15 } */ #define DER_OID_V_c2onb239v5 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x0F #define DER_OID_SZ_c2onb239v5 10 -extern const unsigned char der_oid_c2onb239v5[DER_OID_SZ_c2onb239v5]; +extern const unsigned char ossl_der_oid_c2onb239v5[DER_OID_SZ_c2onb239v5]; /* * c2pnb272w1 OBJECT IDENTIFIER ::= { c-TwoCurve 16 } */ #define DER_OID_V_c2pnb272w1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x10 #define DER_OID_SZ_c2pnb272w1 10 -extern const unsigned char der_oid_c2pnb272w1[DER_OID_SZ_c2pnb272w1]; +extern const unsigned char ossl_der_oid_c2pnb272w1[DER_OID_SZ_c2pnb272w1]; /* * c2pnb304w1 OBJECT IDENTIFIER ::= { c-TwoCurve 17 } */ #define DER_OID_V_c2pnb304w1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x11 #define DER_OID_SZ_c2pnb304w1 10 -extern const unsigned char der_oid_c2pnb304w1[DER_OID_SZ_c2pnb304w1]; +extern const unsigned char ossl_der_oid_c2pnb304w1[DER_OID_SZ_c2pnb304w1]; /* * c2tnb359v1 OBJECT IDENTIFIER ::= { c-TwoCurve 18 } */ #define DER_OID_V_c2tnb359v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x12 #define DER_OID_SZ_c2tnb359v1 10 -extern const unsigned char der_oid_c2tnb359v1[DER_OID_SZ_c2tnb359v1]; +extern const unsigned char ossl_der_oid_c2tnb359v1[DER_OID_SZ_c2tnb359v1]; /* * c2pnb368w1 OBJECT IDENTIFIER ::= { c-TwoCurve 19 } */ #define DER_OID_V_c2pnb368w1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x13 #define DER_OID_SZ_c2pnb368w1 10 -extern const unsigned char der_oid_c2pnb368w1[DER_OID_SZ_c2pnb368w1]; +extern const unsigned char ossl_der_oid_c2pnb368w1[DER_OID_SZ_c2pnb368w1]; /* * c2tnb431r1 OBJECT IDENTIFIER ::= { c-TwoCurve 20 } */ #define DER_OID_V_c2tnb431r1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x00, 0x14 #define DER_OID_SZ_c2tnb431r1 10 -extern const unsigned char der_oid_c2tnb431r1[DER_OID_SZ_c2tnb431r1]; +extern const unsigned char ossl_der_oid_c2tnb431r1[DER_OID_SZ_c2tnb431r1]; /* * prime192v1 OBJECT IDENTIFIER ::= { primeCurve 1 } */ #define DER_OID_V_prime192v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x01 #define DER_OID_SZ_prime192v1 10 -extern const unsigned char der_oid_prime192v1[DER_OID_SZ_prime192v1]; +extern const unsigned char ossl_der_oid_prime192v1[DER_OID_SZ_prime192v1]; /* * prime192v2 OBJECT IDENTIFIER ::= { primeCurve 2 } */ #define DER_OID_V_prime192v2 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x02 #define DER_OID_SZ_prime192v2 10 -extern const unsigned char der_oid_prime192v2[DER_OID_SZ_prime192v2]; +extern const unsigned char ossl_der_oid_prime192v2[DER_OID_SZ_prime192v2]; /* * prime192v3 OBJECT IDENTIFIER ::= { primeCurve 3 } */ #define DER_OID_V_prime192v3 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x03 #define DER_OID_SZ_prime192v3 10 -extern const unsigned char der_oid_prime192v3[DER_OID_SZ_prime192v3]; +extern const unsigned char ossl_der_oid_prime192v3[DER_OID_SZ_prime192v3]; /* * prime239v1 OBJECT IDENTIFIER ::= { primeCurve 4 } */ #define DER_OID_V_prime239v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x04 #define DER_OID_SZ_prime239v1 10 -extern const unsigned char der_oid_prime239v1[DER_OID_SZ_prime239v1]; +extern const unsigned char ossl_der_oid_prime239v1[DER_OID_SZ_prime239v1]; /* * prime239v2 OBJECT IDENTIFIER ::= { primeCurve 5 } */ #define DER_OID_V_prime239v2 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x05 #define DER_OID_SZ_prime239v2 10 -extern const unsigned char der_oid_prime239v2[DER_OID_SZ_prime239v2]; +extern const unsigned char ossl_der_oid_prime239v2[DER_OID_SZ_prime239v2]; /* * prime239v3 OBJECT IDENTIFIER ::= { primeCurve 6 } */ #define DER_OID_V_prime239v3 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x06 #define DER_OID_SZ_prime239v3 10 -extern const unsigned char der_oid_prime239v3[DER_OID_SZ_prime239v3]; +extern const unsigned char ossl_der_oid_prime239v3[DER_OID_SZ_prime239v3]; /* * prime256v1 OBJECT IDENTIFIER ::= { primeCurve 7 } */ #define DER_OID_V_prime256v1 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 #define DER_OID_SZ_prime256v1 10 -extern const unsigned char der_oid_prime256v1[DER_OID_SZ_prime256v1]; +extern const unsigned char ossl_der_oid_prime256v1[DER_OID_SZ_prime256v1]; /* * ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { iso(1) member-body(2) @@ -220,7 +220,7 @@ extern const unsigned char der_oid_prime256v1[DER_OID_SZ_prime256v1]; */ #define DER_OID_V_ecdsa_with_SHA224 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01 #define DER_OID_SZ_ecdsa_with_SHA224 10 -extern const unsigned char der_oid_ecdsa_with_SHA224[DER_OID_SZ_ecdsa_with_SHA224]; +extern const unsigned char ossl_der_oid_ecdsa_with_SHA224[DER_OID_SZ_ecdsa_with_SHA224]; /* * ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) @@ -228,7 +228,7 @@ extern const unsigned char der_oid_ecdsa_with_SHA224[DER_OID_SZ_ecdsa_with_SHA22 */ #define DER_OID_V_ecdsa_with_SHA256 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02 #define DER_OID_SZ_ecdsa_with_SHA256 10 -extern const unsigned char der_oid_ecdsa_with_SHA256[DER_OID_SZ_ecdsa_with_SHA256]; +extern const unsigned char ossl_der_oid_ecdsa_with_SHA256[DER_OID_SZ_ecdsa_with_SHA256]; /* * ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) @@ -236,7 +236,7 @@ extern const unsigned char der_oid_ecdsa_with_SHA256[DER_OID_SZ_ecdsa_with_SHA25 */ #define DER_OID_V_ecdsa_with_SHA384 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x03 #define DER_OID_SZ_ecdsa_with_SHA384 10 -extern const unsigned char der_oid_ecdsa_with_SHA384[DER_OID_SZ_ecdsa_with_SHA384]; +extern const unsigned char ossl_der_oid_ecdsa_with_SHA384[DER_OID_SZ_ecdsa_with_SHA384]; /* * ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) @@ -244,39 +244,39 @@ extern const unsigned char der_oid_ecdsa_with_SHA384[DER_OID_SZ_ecdsa_with_SHA38 */ #define DER_OID_V_ecdsa_with_SHA512 DER_P_OBJECT, 8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x04 #define DER_OID_SZ_ecdsa_with_SHA512 10 -extern const unsigned char der_oid_ecdsa_with_SHA512[DER_OID_SZ_ecdsa_with_SHA512]; +extern const unsigned char ossl_der_oid_ecdsa_with_SHA512[DER_OID_SZ_ecdsa_with_SHA512]; /* * id-ecdsa-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 9 } */ #define DER_OID_V_id_ecdsa_with_sha3_224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x09 #define DER_OID_SZ_id_ecdsa_with_sha3_224 11 -extern const unsigned char der_oid_id_ecdsa_with_sha3_224[DER_OID_SZ_id_ecdsa_with_sha3_224]; +extern const unsigned char ossl_der_oid_id_ecdsa_with_sha3_224[DER_OID_SZ_id_ecdsa_with_sha3_224]; /* * id-ecdsa-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 10 } */ #define DER_OID_V_id_ecdsa_with_sha3_256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0A #define DER_OID_SZ_id_ecdsa_with_sha3_256 11 -extern const unsigned char der_oid_id_ecdsa_with_sha3_256[DER_OID_SZ_id_ecdsa_with_sha3_256]; +extern const unsigned char ossl_der_oid_id_ecdsa_with_sha3_256[DER_OID_SZ_id_ecdsa_with_sha3_256]; /* * id-ecdsa-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 11 } */ #define DER_OID_V_id_ecdsa_with_sha3_384 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0B #define DER_OID_SZ_id_ecdsa_with_sha3_384 11 -extern const unsigned char der_oid_id_ecdsa_with_sha3_384[DER_OID_SZ_id_ecdsa_with_sha3_384]; +extern const unsigned char ossl_der_oid_id_ecdsa_with_sha3_384[DER_OID_SZ_id_ecdsa_with_sha3_384]; /* * id-ecdsa-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 12 } */ #define DER_OID_V_id_ecdsa_with_sha3_512 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0C #define DER_OID_SZ_id_ecdsa_with_sha3_512 11 -extern const unsigned char der_oid_id_ecdsa_with_sha3_512[DER_OID_SZ_id_ecdsa_with_sha3_512]; +extern const unsigned char ossl_der_oid_id_ecdsa_with_sha3_512[DER_OID_SZ_id_ecdsa_with_sha3_512]; /* Subject Public Key Info */ -int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec); +int ossl_DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec); /* Signature */ -int DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, - EC_KEY *ec, int mdnid); +int ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid); diff --git a/providers/common/include/prov/der_ecx.h b/providers/common/include/prov/der_ecx.h new file mode 100644 index 0000000000..da5fb1d016 --- /dev/null +++ b/providers/common/include/prov/der_ecx.h @@ -0,0 +1,47 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/der.h" +#include "crypto/ecx.h" + +/* Well known OIDs precompiled */ + +/* + * id-X25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 110 } + */ +#define DER_OID_V_id_X25519 DER_P_OBJECT, 3, 0x2B, 0x65, 0x6E +#define DER_OID_SZ_id_X25519 5 +extern const unsigned char ossl_der_oid_id_X25519[DER_OID_SZ_id_X25519]; + +/* + * id-X448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 111 } + */ +#define DER_OID_V_id_X448 DER_P_OBJECT, 3, 0x2B, 0x65, 0x6F +#define DER_OID_SZ_id_X448 5 +extern const unsigned char ossl_der_oid_id_X448[DER_OID_SZ_id_X448]; + +/* + * id-Ed25519 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 112 } + */ +#define DER_OID_V_id_Ed25519 DER_P_OBJECT, 3, 0x2B, 0x65, 0x70 +#define DER_OID_SZ_id_Ed25519 5 +extern const unsigned char ossl_der_oid_id_Ed25519[DER_OID_SZ_id_Ed25519]; + +/* + * id-Ed448 OBJECT IDENTIFIER ::= { id-edwards-curve-algs 113 } + */ +#define DER_OID_V_id_Ed448 DER_P_OBJECT, 3, 0x2B, 0x65, 0x71 +#define DER_OID_SZ_id_Ed448 5 +extern const unsigned char ossl_der_oid_id_Ed448[DER_OID_SZ_id_Ed448]; + + +int ossl_DER_w_algorithmIdentifier_ED25519(WPACKET *pkt, int cont, ECX_KEY *ec); +int ossl_DER_w_algorithmIdentifier_ED448(WPACKET *pkt, int cont, ECX_KEY *ec); +int ossl_DER_w_algorithmIdentifier_X25519(WPACKET *pkt, int cont, ECX_KEY *ec); +int ossl_DER_w_algorithmIdentifier_X448(WPACKET *pkt, int cont, ECX_KEY *ec); diff --git a/providers/common/include/prov/der_rsa.h b/providers/common/include/prov/der_rsa.h index a854a3307d..6e0801790c 100644 --- a/providers/common/include/prov/der_rsa.h +++ b/providers/common/include/prov/der_rsa.h @@ -17,140 +17,140 @@ */ #define DER_OID_V_hashAlgs DER_P_OBJECT, 8, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02 #define DER_OID_SZ_hashAlgs 10 -extern const unsigned char der_oid_hashAlgs[DER_OID_SZ_hashAlgs]; +extern const unsigned char ossl_der_oid_hashAlgs[DER_OID_SZ_hashAlgs]; /* * rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ #define DER_OID_V_rsaEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 #define DER_OID_SZ_rsaEncryption 11 -extern const unsigned char der_oid_rsaEncryption[DER_OID_SZ_rsaEncryption]; +extern const unsigned char ossl_der_oid_rsaEncryption[DER_OID_SZ_rsaEncryption]; /* * id-RSAES-OAEP OBJECT IDENTIFIER ::= { pkcs-1 7 } */ #define DER_OID_V_id_RSAES_OAEP DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x07 #define DER_OID_SZ_id_RSAES_OAEP 11 -extern const unsigned char der_oid_id_RSAES_OAEP[DER_OID_SZ_id_RSAES_OAEP]; +extern const unsigned char ossl_der_oid_id_RSAES_OAEP[DER_OID_SZ_id_RSAES_OAEP]; /* * id-pSpecified OBJECT IDENTIFIER ::= { pkcs-1 9 } */ #define DER_OID_V_id_pSpecified DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x09 #define DER_OID_SZ_id_pSpecified 11 -extern const unsigned char der_oid_id_pSpecified[DER_OID_SZ_id_pSpecified]; +extern const unsigned char ossl_der_oid_id_pSpecified[DER_OID_SZ_id_pSpecified]; /* * id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 } */ #define DER_OID_V_id_RSASSA_PSS DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A #define DER_OID_SZ_id_RSASSA_PSS 11 -extern const unsigned char der_oid_id_RSASSA_PSS[DER_OID_SZ_id_RSASSA_PSS]; +extern const unsigned char ossl_der_oid_id_RSASSA_PSS[DER_OID_SZ_id_RSASSA_PSS]; /* * md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } */ #define DER_OID_V_md2WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x02 #define DER_OID_SZ_md2WithRSAEncryption 11 -extern const unsigned char der_oid_md2WithRSAEncryption[DER_OID_SZ_md2WithRSAEncryption]; +extern const unsigned char ossl_der_oid_md2WithRSAEncryption[DER_OID_SZ_md2WithRSAEncryption]; /* * md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } */ #define DER_OID_V_md5WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x04 #define DER_OID_SZ_md5WithRSAEncryption 11 -extern const unsigned char der_oid_md5WithRSAEncryption[DER_OID_SZ_md5WithRSAEncryption]; +extern const unsigned char ossl_der_oid_md5WithRSAEncryption[DER_OID_SZ_md5WithRSAEncryption]; /* * sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } */ #define DER_OID_V_sha1WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05 #define DER_OID_SZ_sha1WithRSAEncryption 11 -extern const unsigned char der_oid_sha1WithRSAEncryption[DER_OID_SZ_sha1WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha1WithRSAEncryption[DER_OID_SZ_sha1WithRSAEncryption]; /* * sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 } */ #define DER_OID_V_sha224WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0E #define DER_OID_SZ_sha224WithRSAEncryption 11 -extern const unsigned char der_oid_sha224WithRSAEncryption[DER_OID_SZ_sha224WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha224WithRSAEncryption[DER_OID_SZ_sha224WithRSAEncryption]; /* * sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } */ #define DER_OID_V_sha256WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B #define DER_OID_SZ_sha256WithRSAEncryption 11 -extern const unsigned char der_oid_sha256WithRSAEncryption[DER_OID_SZ_sha256WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha256WithRSAEncryption[DER_OID_SZ_sha256WithRSAEncryption]; /* * sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } */ #define DER_OID_V_sha384WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0C #define DER_OID_SZ_sha384WithRSAEncryption 11 -extern const unsigned char der_oid_sha384WithRSAEncryption[DER_OID_SZ_sha384WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha384WithRSAEncryption[DER_OID_SZ_sha384WithRSAEncryption]; /* * sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } */ #define DER_OID_V_sha512WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0D #define DER_OID_SZ_sha512WithRSAEncryption 11 -extern const unsigned char der_oid_sha512WithRSAEncryption[DER_OID_SZ_sha512WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha512WithRSAEncryption[DER_OID_SZ_sha512WithRSAEncryption]; /* * sha512-224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 15 } */ #define DER_OID_V_sha512_224WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0F #define DER_OID_SZ_sha512_224WithRSAEncryption 11 -extern const unsigned char der_oid_sha512_224WithRSAEncryption[DER_OID_SZ_sha512_224WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha512_224WithRSAEncryption[DER_OID_SZ_sha512_224WithRSAEncryption]; /* * sha512-256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 16 } */ #define DER_OID_V_sha512_256WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x10 #define DER_OID_SZ_sha512_256WithRSAEncryption 11 -extern const unsigned char der_oid_sha512_256WithRSAEncryption[DER_OID_SZ_sha512_256WithRSAEncryption]; +extern const unsigned char ossl_der_oid_sha512_256WithRSAEncryption[DER_OID_SZ_sha512_256WithRSAEncryption]; /* * id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 } */ #define DER_OID_V_id_mgf1 DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x08 #define DER_OID_SZ_id_mgf1 11 -extern const unsigned char der_oid_id_mgf1[DER_OID_SZ_id_mgf1]; +extern const unsigned char ossl_der_oid_id_mgf1[DER_OID_SZ_id_mgf1]; /* * id-rsassa-pkcs1-v1_5-with-sha3-224 OBJECT IDENTIFIER ::= { sigAlgs 13 } */ #define DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_224 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0D #define DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_224 11 -extern const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_224]; +extern const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_224]; /* * id-rsassa-pkcs1-v1_5-with-sha3-256 OBJECT IDENTIFIER ::= { sigAlgs 14 } */ #define DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_256 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0E #define DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_256 11 -extern const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_256]; +extern const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_256]; /* * id-rsassa-pkcs1-v1_5-with-sha3-384 OBJECT IDENTIFIER ::= { sigAlgs 15 } */ #define DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_384 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x0F #define DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_384 11 -extern const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_384]; +extern const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_384]; /* * id-rsassa-pkcs1-v1_5-with-sha3-512 OBJECT IDENTIFIER ::= { sigAlgs 16 } */ #define DER_OID_V_id_rsassa_pkcs1_v1_5_with_sha3_512 DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x10 #define DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_512 11 -extern const unsigned char der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_512]; +extern const unsigned char ossl_der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512[DER_OID_SZ_id_rsassa_pkcs1_v1_5_with_sha3_512]; /* * md4WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 3 } */ #define DER_OID_V_md4WithRSAEncryption DER_P_OBJECT, 9, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x03 #define DER_OID_SZ_md4WithRSAEncryption 11 -extern const unsigned char der_oid_md4WithRSAEncryption[DER_OID_SZ_md4WithRSAEncryption]; +extern const unsigned char ossl_der_oid_md4WithRSAEncryption[DER_OID_SZ_md4WithRSAEncryption]; /* * ripemd160WithRSAEncryption OBJECT IDENTIFIER ::= { @@ -159,14 +159,14 @@ extern const unsigned char der_oid_md4WithRSAEncryption[DER_OID_SZ_md4WithRSAEnc */ #define DER_OID_V_ripemd160WithRSAEncryption DER_P_OBJECT, 6, 0x2B, 0x24, 0x03, 0x03, 0x01, 0x02 #define DER_OID_SZ_ripemd160WithRSAEncryption 8 -extern const unsigned char der_oid_ripemd160WithRSAEncryption[DER_OID_SZ_ripemd160WithRSAEncryption]; +extern const unsigned char ossl_der_oid_ripemd160WithRSAEncryption[DER_OID_SZ_ripemd160WithRSAEncryption]; /* PSS parameters */ -int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, - const RSA_PSS_PARAMS_30 *pss); +int ossl_DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, + const RSA_PSS_PARAMS_30 *pss); /* Subject Public Key Info */ -int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa); +int ossl_DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa); /* Signature */ -int DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, - RSA *rsa, int mdnid); +int ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, + RSA *rsa, int mdnid); diff --git a/providers/common/include/prov/der_sm2.h b/providers/common/include/prov/der_sm2.h new file mode 100644 index 0000000000..216f670620 --- /dev/null +++ b/providers/common/include/prov/der_sm2.h @@ -0,0 +1,33 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/der.h" + +/* Well known OIDs precompiled */ + +/* + * sm2-with-SM3 OBJECT IDENTIFIER ::= { sm-scheme 501 } + */ +#define DER_OID_V_sm2_with_SM3 DER_P_OBJECT, 8, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x83, 0x75 +#define DER_OID_SZ_sm2_with_SM3 10 +extern const unsigned char ossl_der_oid_sm2_with_SM3[DER_OID_SZ_sm2_with_SM3]; + +/* + * curveSM2 OBJECT IDENTIFIER ::= { sm-scheme 301 } + */ +#define DER_OID_V_curveSM2 DER_P_OBJECT, 8, 0x2A, 0x81, 0x1C, 0xCF, 0x55, 0x01, 0x82, 0x2D +#define DER_OID_SZ_curveSM2 10 +extern const unsigned char ossl_der_oid_curveSM2[DER_OID_SZ_curveSM2]; + + +/* Subject Public Key Info */ +int DER_w_algorithmIdentifier_SM2(WPACKET *pkt, int cont, EC_KEY *ec); +/* Signature */ +int DER_w_algorithmIdentifier_SM2_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid); diff --git a/providers/common/include/prov/der_wrap.h b/providers/common/include/prov/der_wrap.h index e9557798c6..ace0b0cc42 100644 --- a/providers/common/include/prov/der_wrap.h +++ b/providers/common/include/prov/der_wrap.h @@ -18,26 +18,26 @@ */ #define DER_OID_V_id_alg_CMS3DESwrap DER_P_OBJECT, 11, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x10, 0x03, 0x06 #define DER_OID_SZ_id_alg_CMS3DESwrap 13 -extern const unsigned char der_oid_id_alg_CMS3DESwrap[DER_OID_SZ_id_alg_CMS3DESwrap]; +extern const unsigned char ossl_der_oid_id_alg_CMS3DESwrap[DER_OID_SZ_id_alg_CMS3DESwrap]; /* * id-aes128-wrap OBJECT IDENTIFIER ::= { aes 5 } */ #define DER_OID_V_id_aes128_wrap DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x05 #define DER_OID_SZ_id_aes128_wrap 11 -extern const unsigned char der_oid_id_aes128_wrap[DER_OID_SZ_id_aes128_wrap]; +extern const unsigned char ossl_der_oid_id_aes128_wrap[DER_OID_SZ_id_aes128_wrap]; /* * id-aes192-wrap OBJECT IDENTIFIER ::= { aes 25 } */ #define DER_OID_V_id_aes192_wrap DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x19 #define DER_OID_SZ_id_aes192_wrap 11 -extern const unsigned char der_oid_id_aes192_wrap[DER_OID_SZ_id_aes192_wrap]; +extern const unsigned char ossl_der_oid_id_aes192_wrap[DER_OID_SZ_id_aes192_wrap]; /* * id-aes256-wrap OBJECT IDENTIFIER ::= { aes 45 } */ #define DER_OID_V_id_aes256_wrap DER_P_OBJECT, 9, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2D #define DER_OID_SZ_id_aes256_wrap 11 -extern const unsigned char der_oid_id_aes256_wrap[DER_OID_SZ_id_aes256_wrap]; +extern const unsigned char ossl_der_oid_id_aes256_wrap[DER_OID_SZ_id_aes256_wrap]; diff --git a/providers/common/include/prov/provider_ctx.h b/providers/common/include/prov/provider_ctx.h index a252143e81..c8126e1761 100644 --- a/providers/common/include/prov/provider_ctx.h +++ b/providers/common/include/prov/provider_ctx.h @@ -17,7 +17,7 @@ typedef struct prov_ctx_st { const OSSL_CORE_HANDLE *handle; - OPENSSL_CTX *libctx; /* For all provider modules */ + OSSL_LIB_CTX *libctx; /* For all provider modules */ BIO_METHOD *corebiometh; } PROV_CTX; @@ -25,16 +25,16 @@ typedef struct prov_ctx_st { * To be used anywhere the library context needs to be passed, such as to * fetching functions. */ -# define PROV_LIBRARY_CONTEXT_OF(provctx) \ - PROV_CTX_get0_library_context((provctx)) +# define PROV_LIBCTX_OF(provctx) \ + ossl_prov_ctx_get0_libctx((provctx)) -PROV_CTX *PROV_CTX_new(void); -void PROV_CTX_free(PROV_CTX *ctx); -void PROV_CTX_set0_library_context(PROV_CTX *ctx, OPENSSL_CTX *libctx); -void PROV_CTX_set0_handle(PROV_CTX *ctx, const OSSL_CORE_HANDLE *handle); -void PROV_CTX_set0_core_bio_method(PROV_CTX *ctx, BIO_METHOD *corebiometh); -OPENSSL_CTX *PROV_CTX_get0_library_context(PROV_CTX *ctx); -const OSSL_CORE_HANDLE *PROV_CTX_get0_handle(PROV_CTX *ctx); -BIO_METHOD *PROV_CTX_get0_core_bio_method(PROV_CTX *ctx); +PROV_CTX *ossl_prov_ctx_new(void); +void ossl_prov_ctx_free(PROV_CTX *ctx); +void ossl_prov_ctx_set0_libctx(PROV_CTX *ctx, OSSL_LIB_CTX *libctx); +void ossl_prov_ctx_set0_handle(PROV_CTX *ctx, const OSSL_CORE_HANDLE *handle); +void ossl_prov_ctx_set0_core_bio_method(PROV_CTX *ctx, BIO_METHOD *corebiometh); +OSSL_LIB_CTX *ossl_prov_ctx_get0_libctx(PROV_CTX *ctx); +const OSSL_CORE_HANDLE *ossl_prov_ctx_get0_handle(PROV_CTX *ctx); +BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(PROV_CTX *ctx); #endif diff --git a/providers/common/include/prov/provider_util.h b/providers/common/include/prov/provider_util.h index 9b5b983299..1f6f4687ad 100644 --- a/providers/common/include/prov/provider_util.h +++ b/providers/common/include/prov/provider_util.h @@ -45,7 +45,7 @@ typedef struct { */ int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc, const OSSL_PARAM params[], - OPENSSL_CTX *ctx); + OSSL_LIB_CTX *ctx); /* Reset the PROV_CIPHER fields and free any allocated cipher reference */ void ossl_prov_cipher_reset(PROV_CIPHER *pc); @@ -58,6 +58,14 @@ const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc); ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc); /* Digest functions */ + +/* + * Fetch a digest from the specified libctx using the provided mdname and + * propquery. Store the result in the PROV_DIGEST and return the fetched md. + */ +const EVP_MD *ossl_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx, + const char *mdname, const char *propquery); + /* * Load a digest from the specified parameters with the specified context. * The params "properties", "engine" and "digest" are used to determine the @@ -66,7 +74,7 @@ ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc); */ int ossl_prov_digest_load_from_params(PROV_DIGEST *pd, const OSSL_PARAM params[], - OPENSSL_CTX *ctx); + OSSL_LIB_CTX *ctx); /* Reset the PROV_DIGEST fields and free any allocated digest reference */ void ossl_prov_digest_reset(PROV_DIGEST *pd); @@ -78,6 +86,21 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src); const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd); ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd); + +/* + * Set the various parameters on an EVP_MAC_CTX from the supplied arguments. + * If any of the supplied ciphername/mdname etc are NULL then the values + * from the supplied params (if non NULL) are used instead. + */ +int ossl_prov_set_macctx(EVP_MAC_CTX *macctx, + const OSSL_PARAM params[], + const char *ciphername, + const char *mdname, + const char *engine, + const char *properties, + const unsigned char *key, + size_t keylen); + /* MAC functions */ /* * Load an EVP_MAC_CTX* from the specified parameters with the specified @@ -100,7 +123,7 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx, const char *macname, const char *ciphername, const char *mdname, - OPENSSL_CTX *ctx); + OSSL_LIB_CTX *ctx); typedef struct ag_capable_st { OSSL_ALGORITHM alg; diff --git a/providers/common/include/prov/providercommon.h b/providers/common/include/prov/providercommon.h index f39d2e313f..622fe1977e 100644 --- a/providers/common/include/prov/providercommon.h +++ b/providers/common/include/prov/providercommon.h @@ -10,11 +10,17 @@ #include #include -const OSSL_CORE_HANDLE *FIPS_get_core_handle(OPENSSL_CTX *ctx); +const OSSL_CORE_HANDLE *FIPS_get_core_handle(OSSL_LIB_CTX *ctx); const char *ossl_prov_util_nid_to_name(int nid); -int cipher_capable_aes_cbc_hmac_sha1(void); -int cipher_capable_aes_cbc_hmac_sha256(void); +int ossl_cipher_capable_aes_cbc_hmac_sha1(void); +int ossl_cipher_capable_aes_cbc_hmac_sha256(void); OSSL_FUNC_provider_get_capabilities_fn provider_get_capabilities; + +/* Set the error state if this is a FIPS module */ +void ossl_set_error_state(const char *type); + +/* Return true if the module is in a usable condition */ +int ossl_prov_is_running(void); diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index bdc39e4121..d972a819e2 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -75,6 +75,9 @@ int ERR_load_PROV_strings(void); # define PROV_R_FAILED_TO_GET_PARAMETER 103 # define PROV_R_FAILED_TO_SET_PARAMETER 104 # define PROV_R_FAILED_TO_SIGN 175 +# define PROV_R_FIPS_MODULE_CONDITIONAL_ERROR 227 +# define PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE 224 +# define PROV_R_FIPS_MODULE_IN_ERROR_STATE 225 # define PROV_R_GENERATE_ERROR 191 # define PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 165 # define PROV_R_INAVLID_UKM_LENGTH 146 @@ -88,6 +91,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_INVALID_DATA 115 # define PROV_R_INVALID_DIGEST 122 # define PROV_R_INVALID_DIGEST_LENGTH 166 +# define PROV_R_INVALID_DIGEST_SIZE 218 # define PROV_R_INVALID_ITERATION_COUNT 123 # define PROV_R_INVALID_IVLEN 116 # define PROV_R_INVALID_IV_LENGTH 109 @@ -127,7 +131,10 @@ int ERR_load_PROV_strings(void); # define PROV_R_MISSING_TYPE 134 # define PROV_R_MISSING_XCGHASH 135 # define PROV_R_MODULE_INTEGRITY_FAILURE 214 +# define PROV_R_NOT_A_PRIVATE_KEY 221 +# define PROV_R_NOT_A_PUBLIC_KEY 220 # define PROV_R_NOT_INSTANTIATED 193 +# define PROV_R_NOT_PARAMETERS 226 # define PROV_R_NOT_SUPPORTED 136 # define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 # define PROV_R_NO_KEY_SET 114 @@ -136,12 +143,14 @@ int ERR_load_PROV_strings(void); # define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106 # define PROV_R_PARENT_LOCKING_NOT_ENABLED 182 # define PROV_R_PARENT_STRENGTH_TOO_WEAK 194 +# define PROV_R_PATH_MUST_BE_ABSOLUTE 219 # define PROV_R_PERSONALISATION_STRING_TOO_LONG 195 # define PROV_R_PSS_SALTLEN_TOO_SMALL 172 # define PROV_R_READ_KEY 159 # define PROV_R_REQUEST_TOO_LARGE_FOR_DRBG 196 # define PROV_R_REQUIRE_CTR_MODE_CIPHER 206 # define PROV_R_RESEED_ERROR 197 +# define PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 222 # define PROV_R_SELF_TEST_KAT_FAILURE 215 # define PROV_R_SELF_TEST_POST_FAILURE 216 # define PROV_R_TAG_NOTSET 119 @@ -162,6 +171,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_UNSUPPORTED_KEY_SIZE 153 # define PROV_R_UNSUPPORTED_MAC_TYPE 137 # define PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS 152 +# define PROV_R_URI_AUTHORITY_UNSUPPORTED 223 # define PROV_R_VALUE_ERROR 138 # define PROV_R_WRONG_FINAL_BLOCK_LENGTH 107 # define PROV_R_WRONG_OUTPUT_BUFFER_SIZE 139 diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h new file mode 100644 index 0000000000..8ab3370263 --- /dev/null +++ b/providers/common/include/prov/securitycheck.h @@ -0,0 +1,25 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* Functions that are common */ +int ossl_rsa_check_key(const RSA *rsa, int protect); +int ec_check_key(const EC_KEY *ec, int protect); +int dsa_check_key(const DSA *dsa, int sign); +int dh_check_key(const DH *dh); + +int digest_is_allowed(const EVP_MD *md); +int digest_get_approved_nid_with_sha1(const EVP_MD *md, int sha1_allowed); + +/* Functions that are common */ +int digest_md_to_nid(const EVP_MD *md, const OSSL_ITEM *it, size_t it_len); +int digest_get_approved_nid(const EVP_MD *md); + +/* Functions that have different implementations for the FIPS_MODULE */ +int digest_rsa_sign_get_md_nid(const EVP_MD *md, int sha1_allowed); +int securitycheck_enabled(void); diff --git a/providers/common/provider_ctx.c b/providers/common/provider_ctx.c index 04cca1f23e..9690abfd57 100644 --- a/providers/common/provider_ctx.c +++ b/providers/common/provider_ctx.c @@ -11,49 +11,49 @@ #include "prov/provider_ctx.h" #include "prov/bio.h" -PROV_CTX *PROV_CTX_new(void) +PROV_CTX *ossl_prov_ctx_new(void) { return OPENSSL_zalloc(sizeof(PROV_CTX)); } -void PROV_CTX_free(PROV_CTX *ctx) +void ossl_prov_ctx_free(PROV_CTX *ctx) { OPENSSL_free(ctx); } -void PROV_CTX_set0_library_context(PROV_CTX *ctx, OPENSSL_CTX *libctx) +void ossl_prov_ctx_set0_libctx(PROV_CTX *ctx, OSSL_LIB_CTX *libctx) { if (ctx != NULL) ctx->libctx = libctx; } -void PROV_CTX_set0_handle(PROV_CTX *ctx, const OSSL_CORE_HANDLE *handle) +void ossl_prov_ctx_set0_handle(PROV_CTX *ctx, const OSSL_CORE_HANDLE *handle) { if (ctx != NULL) ctx->handle = handle; } -void PROV_CTX_set0_core_bio_method(PROV_CTX *ctx, BIO_METHOD *corebiometh) +void ossl_prov_ctx_set0_core_bio_method(PROV_CTX *ctx, BIO_METHOD *corebiometh) { if (ctx != NULL) ctx->corebiometh = corebiometh; } -OPENSSL_CTX *PROV_CTX_get0_library_context(PROV_CTX *ctx) +OSSL_LIB_CTX *ossl_prov_ctx_get0_libctx(PROV_CTX *ctx) { if (ctx == NULL) return NULL; return ctx->libctx; } -const OSSL_CORE_HANDLE *PROV_CTX_get0_handle(PROV_CTX *ctx) +const OSSL_CORE_HANDLE *ossl_prov_ctx_get0_handle(PROV_CTX *ctx) { if (ctx == NULL) return NULL; return ctx->handle; } -BIO_METHOD *PROV_CTX_get0_core_bio_method(PROV_CTX *ctx) +BIO_METHOD *ossl_prov_ctx_get0_core_bio_method(PROV_CTX *ctx) { if (ctx == NULL) return NULL; diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index e65ce96471..606d78cc57 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -58,6 +58,12 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER), "failed to set parameter"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SIGN), "failed to sign"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR), + "fips module conditional error"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE), + "fips module entering error state"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_IN_ERROR_STATE), + "fips module in error state"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_GENERATE_ERROR), "generate error"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "illegal or unsupported padding mode"}, @@ -79,6 +85,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST), "invalid digest"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_SIZE), + "invalid digest size"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_ITERATION_COUNT), "invalid iteration count"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IVLEN), "invalid ivlen"}, @@ -131,7 +139,10 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_XCGHASH), "missing xcghash"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MODULE_INTEGRITY_FAILURE), "module integrity failure"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_PARAMETERS), "not parameters"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH), "not xof or invalid length"}, @@ -145,6 +156,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "parent locking not enabled"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_STRENGTH_TOO_WEAK), "parent strength too weak"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PATH_MUST_BE_ABSOLUTE), + "path must be absolute"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PERSONALISATION_STRING_TOO_LONG), "personalisation string too long"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PSS_SALTLEN_TOO_SMALL), @@ -155,6 +168,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUIRE_CTR_MODE_CIPHER), "require ctr mode cipher"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_RESEED_ERROR), "reseed error"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES), + "search only supported for directories"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_KAT_FAILURE), "self test kat failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_POST_FAILURE), @@ -192,6 +207,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "unsupported mac type"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS), "unsupported number of rounds"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_URI_AUTHORITY_UNSUPPORTED), + "uri authority unsupported"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_VALUE_ERROR), "value error"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c index f6155e7dce..2499d1534e 100644 --- a/providers/common/provider_util.c +++ b/providers/common/provider_util.c @@ -14,6 +14,8 @@ #include #include #include "prov/provider_util.h" +#include "prov/providercommonerr.h" +#include "internal/nelem.h" void ossl_prov_cipher_reset(PROV_CIPHER *pc) { @@ -50,7 +52,7 @@ static int load_common(const OSSL_PARAM params[], const char **propquery, /* TODO legacy stuff, to be removed */ /* Inside the FIPS module, we don't support legacy ciphers */ #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_ENGINE) - p = OSSL_PARAM_locate_const(params, "engine"); + p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; @@ -65,7 +67,7 @@ static int load_common(const OSSL_PARAM params[], const char **propquery, int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc, const OSSL_PARAM params[], - OPENSSL_CTX *ctx) + OSSL_LIB_CTX *ctx) { const OSSL_PARAM *p; const char *propquery; @@ -122,9 +124,18 @@ int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src) return 1; } +const EVP_MD *ossl_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx, + const char *mdname, const char *propquery) +{ + EVP_MD_free(pd->alloc_md); + pd->md = pd->alloc_md = EVP_MD_fetch(libctx, mdname, propquery); + + return pd->md; +} + int ossl_prov_digest_load_from_params(PROV_DIGEST *pd, const OSSL_PARAM params[], - OPENSSL_CTX *ctx) + OSSL_LIB_CTX *ctx) { const OSSL_PARAM *p; const char *propquery; @@ -139,9 +150,8 @@ int ossl_prov_digest_load_from_params(PROV_DIGEST *pd, if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; - EVP_MD_free(pd->alloc_md); ERR_set_mark(); - pd->md = pd->alloc_md = EVP_MD_fetch(ctx, p->data, propquery); + ossl_prov_digest_fetch(pd, ctx, p->data, propquery); /* TODO legacy stuff, to be removed */ #ifndef FIPS_MODULE /* Inside the FIPS module, we don't support legacy digests */ if (pd->md == NULL) @@ -164,15 +174,80 @@ ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd) return pd->engine; } +int ossl_prov_set_macctx(EVP_MAC_CTX *macctx, + const OSSL_PARAM params[], + const char *ciphername, + const char *mdname, + const char *engine, + const char *properties, + const unsigned char *key, + size_t keylen) +{ + const OSSL_PARAM *p; + OSSL_PARAM mac_params[6], *mp = mac_params; + + if (params != NULL) { + if (mdname == NULL) { + if ((p = OSSL_PARAM_locate_const(params, + OSSL_ALG_PARAM_DIGEST)) != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + mdname = p->data; + } + } + if (ciphername == NULL) { + if ((p = OSSL_PARAM_locate_const(params, + OSSL_ALG_PARAM_CIPHER)) != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + ciphername = p->data; + } + } + if (engine == NULL) { + if ((p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_ENGINE)) + != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + engine = p->data; + } + } + } + + if (mdname != NULL) + *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + (char *)mdname, 0); + if (ciphername != NULL) + *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, + (char *)ciphername, 0); + if (properties != NULL) + *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, + (char *)properties, 0); + +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (engine != NULL) + *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_ENGINE, + (char *) engine, 0); +#endif + + if (key != NULL) + *mp++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (unsigned char *)key, + keylen); + + *mp = OSSL_PARAM_construct_end(); + + return EVP_MAC_CTX_set_params(macctx, mac_params); + +} + int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx, const OSSL_PARAM params[], const char *macname, const char *ciphername, const char *mdname, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { const OSSL_PARAM *p; - OSSL_PARAM mac_params[5], *mp = mac_params; const char *properties = NULL; if (macname == NULL @@ -207,44 +282,8 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx, if (*macctx == NULL) return 1; - if (mdname == NULL) { - if ((p = OSSL_PARAM_locate_const(params, - OSSL_ALG_PARAM_DIGEST)) != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - mdname = p->data; - } - } - if (ciphername == NULL) { - if ((p = OSSL_PARAM_locate_const(params, - OSSL_ALG_PARAM_CIPHER)) != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - ciphername = p->data; - } - } - - if (mdname != NULL) - *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, - (char *)mdname, 0); - if (ciphername != NULL) - *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER, - (char *)ciphername, 0); - if (properties != NULL) - *mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_PROPERTIES, - (char *)properties, 0); - -#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) - if ((p = OSSL_PARAM_locate_const(params, "engine")) != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - *mp++ = OSSL_PARAM_construct_utf8_string("engine", - p->data, p->data_size); - } -#endif - *mp = OSSL_PARAM_construct_end(); - - if (EVP_MAC_CTX_set_params(*macctx, mac_params)) + if (ossl_prov_set_macctx(*macctx, params, ciphername, mdname, NULL, + properties, NULL, 0)) return 1; EVP_MAC_CTX_free(*macctx); diff --git a/providers/common/securitycheck.c b/providers/common/securitycheck.c new file mode 100644 index 0000000000..a95fa9dda9 --- /dev/null +++ b/providers/common/securitycheck.c @@ -0,0 +1,209 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include +#include +#include "prov/securitycheck.h" +#include "prov/providercommonerr.h" + +/* + * FIPS requires a minimum security strength of 112 bits (for encryption or + * signing), and for legacy purposes 80 bits (for decryption or verifying). + * Set protect = 1 for encryption or signing operations, or 0 otherwise. See + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf. + */ +int ossl_rsa_check_key(const RSA *rsa, int protect) +{ +#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) { + int sz = RSA_bits(rsa); + + return protect ? (sz >= 2048) : (sz >= 1024); + } +#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return 1; +} + +#ifndef OPENSSL_NO_EC +/* + * In FIPS mode: + * protect should be 1 for any operations that need 112 bits of security + * strength (such as signing, and key exchange), or 0 for operations that allow + * a lower security strength (such as verify). + * + * For ECDH key agreement refer to SP800-56A + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf + * "Appendix D" + * + * For ECDSA signatures refer to + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf + * "Table 2" + */ +int ec_check_key(const EC_KEY *ec, int protect) +{ +# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) { + int nid, strength; + const char *curve_name; + const EC_GROUP *group = EC_KEY_get0_group(ec); + + if (group == NULL) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group"); + return 0; + } + nid = EC_GROUP_get_curve_name(group); + if (nid == NID_undef) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, + "Explicit curves are not allowed in fips mode"); + return 0; + } + + curve_name = EC_curve_nid2nist(nid); + if (curve_name == NULL) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, + "Curve %s is not approved in FIPS mode", curve_name); + return 0; + } + + /* + * For EC the security strength is the (order_bits / 2) + * e.g. P-224 is 112 bits. + */ + strength = EC_GROUP_order_bits(group) / 2; + /* The min security strength allowed for legacy verification is 80 bits */ + if (strength < 80) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); + return 0; + } + + /* + * For signing or key agreement only allow curves with at least 112 bits of + * security strength + */ + if (protect && strength < 112) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, + "Curve %s cannot be used for signing", curve_name); + return 0; + } + } +# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return 1; +} +#endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_DSA +/* + * Check for valid key sizes if fips mode. Refer to + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf + * "Table 2" + */ +int dsa_check_key(const DSA *dsa, int sign) +{ +# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) { + size_t L, N; + const BIGNUM *p, *q; + + if (dsa == NULL) + return 0; + + p = DSA_get0_p(dsa); + q = DSA_get0_q(dsa); + if (p == NULL || q == NULL) + return 0; + + L = BN_num_bits(p); + N = BN_num_bits(q); + + /* + * Valid sizes or verification - Note this could be a fips186-2 type + * key - so we allow 512 also. When this is no longer suppported the + * lower bound should be increased to 1024. + */ + if (!sign) + return (L >= 512 && N >= 160); + + /* Valid sizes for both sign and verify */ + if (L == 2048 && (N == 224 || N == 256)) + return 1; + return (L == 3072 && N == 256); + } +# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return 1; +} +#endif /* OPENSSL_NO_DSA */ + +#ifndef OPENSSL_NO_DH +/* + * For DH key agreement refer to SP800-56A + * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar3.pdf + * "Section 5.5.1.1FFC Domain Parameter Selection/Generation" and + * "Appendix D" FFC Safe-prime Groups + */ +int dh_check_key(const DH *dh) +{ +# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) { + size_t L, N; + const BIGNUM *p, *q; + + if (dh == NULL) + return 0; + + p = DH_get0_p(dh); + q = DH_get0_q(dh); + if (p == NULL || q == NULL) + return 0; + + L = BN_num_bits(p); + if (L < 2048) + return 0; + + /* If it is a safe prime group then it is ok */ + if (DH_get_nid(dh)) + return 1; + + /* If not then it must be FFC, which only allows certain sizes. */ + N = BN_num_bits(q); + + return (L == 2048 && (N == 224 || N == 256)); + } +# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return 1; +} +#endif /* OPENSSL_NO_DH */ + +int digest_get_approved_nid_with_sha1(const EVP_MD *md, int sha1_allowed) +{ + int mdnid = digest_get_approved_nid(md); + +# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) { + if (mdnid == NID_sha1 && !sha1_allowed) + mdnid = NID_undef; + } +# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return mdnid; +} + +int digest_is_allowed(const EVP_MD *md) +{ +# if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) + return digest_get_approved_nid(md) != NID_undef; +# endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return 1; +} diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c new file mode 100644 index 0000000000..e88b642ae2 --- /dev/null +++ b/providers/common/securitycheck_default.c @@ -0,0 +1,42 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include "prov/securitycheck.h" +#include "internal/nelem.h" + +/* Disable the security checks in the default provider */ +int securitycheck_enabled(void) +{ + return 0; +} + +int digest_rsa_sign_get_md_nid(const EVP_MD *md, ossl_unused int sha1_allowed) +{ + int mdnid; + + static const OSSL_ITEM name_to_nid[] = { + { NID_md5, OSSL_DIGEST_NAME_MD5 }, + { NID_md5_sha1, OSSL_DIGEST_NAME_MD5_SHA1 }, + { NID_md2, OSSL_DIGEST_NAME_MD2 }, + { NID_md4, OSSL_DIGEST_NAME_MD4 }, + { NID_mdc2, OSSL_DIGEST_NAME_MDC2 }, + { NID_ripemd160, OSSL_DIGEST_NAME_RIPEMD160 }, + }; + + mdnid = digest_get_approved_nid_with_sha1(md, 1); + if (mdnid == NID_undef) + mdnid = digest_md_to_nid(md, name_to_nid, OSSL_NELEM(name_to_nid)); + return mdnid; +} diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c new file mode 100644 index 0000000000..94457d6ccf --- /dev/null +++ b/providers/common/securitycheck_fips.c @@ -0,0 +1,40 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include +#include +#include "prov/securitycheck.h" +#include "prov/providercommonerr.h" + +extern int FIPS_security_check_enabled(void); + +int securitycheck_enabled(void) +{ +#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + return FIPS_security_check_enabled(); +#else + return 0; +#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ +} + +int digest_rsa_sign_get_md_nid(const EVP_MD *md, int sha1_allowed) +{ +#if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS) + if (securitycheck_enabled()) + return digest_get_approved_nid_with_sha1(md, sha1_allowed); +#endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */ + return digest_get_approved_nid(md); +} diff --git a/providers/decoders.inc b/providers/decoders.inc new file mode 100644 index 0000000000..4f5699418b --- /dev/null +++ b/providers/decoders.inc @@ -0,0 +1,42 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef DECODER +# error Macro DECODER undefined +#endif + +#ifndef OPENSSL_NO_DH + DECODER("DH", "yes", "der", ossl_der_to_dh_decoder_functions), + DECODER("DHX", "yes", "der", ossl_der_to_dhx_decoder_functions), +#endif +#ifndef OPENSSL_NO_DSA + DECODER("DSA", "yes", "der", ossl_der_to_dsa_decoder_functions), + DECODER("DSA", "yes", "mblob", ossl_msblob_to_dsa_decoder_functions), +# ifndef OPENSSL_NO_RC4 + DECODER("DSA", "yes", "pvk", ossl_pvk_to_dsa_decoder_functions), +# endif +#endif +#ifndef OPENSSL_NO_EC + DECODER("EC", "yes", "der", ossl_der_to_ec_decoder_functions), + DECODER("ED25519", "yes", "der", ossl_der_to_ed25519_decoder_functions), + DECODER("ED448", "yes", "der", ossl_der_to_ed448_decoder_functions), + DECODER("X25519", "yes", "der", ossl_der_to_x25519_decoder_functions), + DECODER("X448", "yes", "der", ossl_der_to_x448_decoder_functions), +#endif + DECODER("RSA", "yes", "der", ossl_der_to_rsa_decoder_functions), + DECODER("RSA-PSS", "yes", "der", ossl_der_to_rsapss_decoder_functions), +#ifndef OPENSSL_NO_DSA + DECODER("RSA", "yes", "mblob", ossl_msblob_to_rsa_decoder_functions), +# ifndef OPENSSL_NO_RC4 + DECODER("RSA", "yes", "pvk", ossl_pvk_to_rsa_decoder_functions), +# endif +#endif + + DECODER("DER", "yes", "pem", ossl_pem_to_der_decoder_functions), + diff --git a/providers/defltprov.c b/providers/defltprov.c index fa2fadbc95..959c48d1db 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -41,6 +41,7 @@ static const OSSL_PARAM deflt_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END }; @@ -62,7 +63,9 @@ static int deflt_get_params(void *provctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR)) return 0; - + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); + if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) + return 0; return 1; } @@ -95,32 +98,34 @@ static int deflt_get_params(void *provctx, OSSL_PARAM params[]) */ static const OSSL_ALGORITHM deflt_digests[] = { /* Our primary name:NIST name[:our older names] */ - { "SHA1:SHA-1", "provider=default", sha1_functions }, - { "SHA2-224:SHA-224:SHA224", "provider=default", sha224_functions }, - { "SHA2-256:SHA-256:SHA256", "provider=default", sha256_functions }, - { "SHA2-384:SHA-384:SHA384", "provider=default", sha384_functions }, - { "SHA2-512:SHA-512:SHA512", "provider=default", sha512_functions }, + { "SHA1:SHA-1:SSL3-SHA1", "provider=default", ossl_sha1_functions }, + { "SHA2-224:SHA-224:SHA224", "provider=default", ossl_sha224_functions }, + { "SHA2-256:SHA-256:SHA256", "provider=default", ossl_sha256_functions }, + { "SHA2-384:SHA-384:SHA384", "provider=default", ossl_sha384_functions }, + { "SHA2-512:SHA-512:SHA512", "provider=default", ossl_sha512_functions }, { "SHA2-512/224:SHA-512/224:SHA512-224", "provider=default", - sha512_224_functions }, + ossl_sha512_224_functions }, { "SHA2-512/256:SHA-512/256:SHA512-256", "provider=default", - sha512_256_functions }, + ossl_sha512_256_functions }, /* We agree with NIST here, so one name only */ - { "SHA3-224", "provider=default", sha3_224_functions }, - { "SHA3-256", "provider=default", sha3_256_functions }, - { "SHA3-384", "provider=default", sha3_384_functions }, - { "SHA3-512", "provider=default", sha3_512_functions }, + { "SHA3-224", "provider=default", ossl_sha3_224_functions }, + { "SHA3-256", "provider=default", ossl_sha3_256_functions }, + { "SHA3-384", "provider=default", ossl_sha3_384_functions }, + { "SHA3-512", "provider=default", ossl_sha3_512_functions }, /* * KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for * the KMAC-128 and KMAC-256. */ - { "KECCAK-KMAC-128:KECCAK-KMAC128", "provider=default", keccak_kmac_128_functions }, - { "KECCAK-KMAC-256:KECCAK-KMAC256", "provider=default", keccak_kmac_256_functions }, + { "KECCAK-KMAC-128:KECCAK-KMAC128", "provider=default", + ossl_keccak_kmac_128_functions }, + { "KECCAK-KMAC-256:KECCAK-KMAC256", "provider=default", + ossl_keccak_kmac_256_functions }, /* Our primary name:NIST name */ - { "SHAKE-128:SHAKE128", "provider=default", shake_128_functions }, - { "SHAKE-256:SHAKE256", "provider=default", shake_256_functions }, + { "SHAKE-128:SHAKE128", "provider=default", ossl_shake_128_functions }, + { "SHAKE-256:SHAKE256", "provider=default", ossl_shake_256_functions }, #ifndef OPENSSL_NO_BLAKE2 /* @@ -130,159 +135,159 @@ static const OSSL_ALGORITHM deflt_digests[] = { * If we assume that "2b" and "2s" are versions, that pattern * fits with ours. We also add our historical names. */ - { "BLAKE2S-256:BLAKE2s256", "provider=default", blake2s256_functions }, - { "BLAKE2B-512:BLAKE2b512", "provider=default", blake2b512_functions }, + { "BLAKE2S-256:BLAKE2s256", "provider=default", ossl_blake2s256_functions }, + { "BLAKE2B-512:BLAKE2b512", "provider=default", ossl_blake2b512_functions }, #endif /* OPENSSL_NO_BLAKE2 */ #ifndef OPENSSL_NO_SM3 - { "SM3", "provider=default", sm3_functions }, + { "SM3", "provider=default", ossl_sm3_functions }, #endif /* OPENSSL_NO_SM3 */ #ifndef OPENSSL_NO_MD5 - { "MD5", "provider=default", md5_functions }, - { "MD5-SHA1", "provider=default", md5_sha1_functions }, + { "MD5:SSL3-MD5", "provider=default", ossl_md5_functions }, + { "MD5-SHA1", "provider=default", ossl_md5_sha1_functions }, #endif /* OPENSSL_NO_MD5 */ { NULL, NULL, NULL } }; static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = { - ALG("NULL", null_functions), - ALG("AES-256-ECB", aes256ecb_functions), - ALG("AES-192-ECB", aes192ecb_functions), - ALG("AES-128-ECB", aes128ecb_functions), - ALG("AES-256-CBC", aes256cbc_functions), - ALG("AES-192-CBC", aes192cbc_functions), - ALG("AES-128-CBC", aes128cbc_functions), - ALG("AES-128-CBC-CTS", aes128cbc_cts_functions), - ALG("AES-192-CBC-CTS", aes192cbc_cts_functions), - ALG("AES-256-CBC-CTS", aes256cbc_cts_functions), - ALG("AES-256-OFB", aes256ofb_functions), - ALG("AES-192-OFB", aes192ofb_functions), - ALG("AES-128-OFB", aes128ofb_functions), - ALG("AES-256-CFB", aes256cfb_functions), - ALG("AES-192-CFB", aes192cfb_functions), - ALG("AES-128-CFB", aes128cfb_functions), - ALG("AES-256-CFB1", aes256cfb1_functions), - ALG("AES-192-CFB1", aes192cfb1_functions), - ALG("AES-128-CFB1", aes128cfb1_functions), - ALG("AES-256-CFB8", aes256cfb8_functions), - ALG("AES-192-CFB8", aes192cfb8_functions), - ALG("AES-128-CFB8", aes128cfb8_functions), - ALG("AES-256-CTR", aes256ctr_functions), - ALG("AES-192-CTR", aes192ctr_functions), - ALG("AES-128-CTR", aes128ctr_functions), - ALG("AES-256-XTS", aes256xts_functions), - ALG("AES-128-XTS", aes128xts_functions), + ALG("NULL", ossl_null_functions), + ALG("AES-256-ECB", ossl_aes256ecb_functions), + ALG("AES-192-ECB", ossl_aes192ecb_functions), + ALG("AES-128-ECB", ossl_aes128ecb_functions), + ALG("AES-256-CBC:AES256", ossl_aes256cbc_functions), + ALG("AES-192-CBC:AES192", ossl_aes192cbc_functions), + ALG("AES-128-CBC:AES128", ossl_aes128cbc_functions), + ALG("AES-128-CBC-CTS", ossl_aes128cbc_cts_functions), + ALG("AES-192-CBC-CTS", ossl_aes192cbc_cts_functions), + ALG("AES-256-CBC-CTS", ossl_aes256cbc_cts_functions), + ALG("AES-256-OFB", ossl_aes256ofb_functions), + ALG("AES-192-OFB", ossl_aes192ofb_functions), + ALG("AES-128-OFB", ossl_aes128ofb_functions), + ALG("AES-256-CFB", ossl_aes256cfb_functions), + ALG("AES-192-CFB", ossl_aes192cfb_functions), + ALG("AES-128-CFB", ossl_aes128cfb_functions), + ALG("AES-256-CFB1", ossl_aes256cfb1_functions), + ALG("AES-192-CFB1", ossl_aes192cfb1_functions), + ALG("AES-128-CFB1", ossl_aes128cfb1_functions), + ALG("AES-256-CFB8", ossl_aes256cfb8_functions), + ALG("AES-192-CFB8", ossl_aes192cfb8_functions), + ALG("AES-128-CFB8", ossl_aes128cfb8_functions), + ALG("AES-256-CTR", ossl_aes256ctr_functions), + ALG("AES-192-CTR", ossl_aes192ctr_functions), + ALG("AES-128-CTR", ossl_aes128ctr_functions), + ALG("AES-256-XTS", ossl_aes256xts_functions), + ALG("AES-128-XTS", ossl_aes128xts_functions), #ifndef OPENSSL_NO_OCB - ALG("AES-256-OCB", aes256ocb_functions), - ALG("AES-192-OCB", aes192ocb_functions), - ALG("AES-128-OCB", aes128ocb_functions), + ALG("AES-256-OCB", ossl_aes256ocb_functions), + ALG("AES-192-OCB", ossl_aes192ocb_functions), + ALG("AES-128-OCB", ossl_aes128ocb_functions), #endif /* OPENSSL_NO_OCB */ #ifndef OPENSSL_NO_SIV - ALG("AES-128-SIV", aes128siv_functions), - ALG("AES-192-SIV", aes192siv_functions), - ALG("AES-256-SIV", aes256siv_functions), + ALG("AES-128-SIV", ossl_aes128siv_functions), + ALG("AES-192-SIV", ossl_aes192siv_functions), + ALG("AES-256-SIV", ossl_aes256siv_functions), #endif /* OPENSSL_NO_SIV */ - ALG("AES-256-GCM:id-aes256-GCM", aes256gcm_functions), - ALG("AES-192-GCM:id-aes192-GCM", aes192gcm_functions), - ALG("AES-128-GCM:id-aes128-GCM", aes128gcm_functions), - ALG("AES-256-CCM:id-aes256-CCM", aes256ccm_functions), - ALG("AES-192-CCM:id-aes192-CCM", aes192ccm_functions), - ALG("AES-128-CCM:id-aes128-CCM", aes128ccm_functions), - ALG("AES-256-WRAP:id-aes256-wrap:AES256-WRAP", aes256wrap_functions), - ALG("AES-192-WRAP:id-aes192-wrap:AES192-WRAP", aes192wrap_functions), - ALG("AES-128-WRAP:id-aes128-wrap:AES128-WRAP", aes128wrap_functions), + ALG("AES-256-GCM:id-aes256-GCM", ossl_aes256gcm_functions), + ALG("AES-192-GCM:id-aes192-GCM", ossl_aes192gcm_functions), + ALG("AES-128-GCM:id-aes128-GCM", ossl_aes128gcm_functions), + ALG("AES-256-CCM:id-aes256-CCM", ossl_aes256ccm_functions), + ALG("AES-192-CCM:id-aes192-CCM", ossl_aes192ccm_functions), + ALG("AES-128-CCM:id-aes128-CCM", ossl_aes128ccm_functions), + ALG("AES-256-WRAP:id-aes256-wrap:AES256-WRAP", ossl_aes256wrap_functions), + ALG("AES-192-WRAP:id-aes192-wrap:AES192-WRAP", ossl_aes192wrap_functions), + ALG("AES-128-WRAP:id-aes128-wrap:AES128-WRAP", ossl_aes128wrap_functions), ALG("AES-256-WRAP-PAD:id-aes256-wrap-pad:AES256-WRAP-PAD", - aes256wrappad_functions), + ossl_aes256wrappad_functions), ALG("AES-192-WRAP-PAD:id-aes192-wrap-pad:AES192-WRAP-PAD", - aes192wrappad_functions), + ossl_aes192wrappad_functions), ALG("AES-128-WRAP-PAD:id-aes128-wrap-pad:AES128-WRAP-PAD", - aes128wrappad_functions), - ALGC("AES-128-CBC-HMAC-SHA1", aes128cbc_hmac_sha1_functions, - cipher_capable_aes_cbc_hmac_sha1), - ALGC("AES-256-CBC-HMAC-SHA1", aes256cbc_hmac_sha1_functions, - cipher_capable_aes_cbc_hmac_sha1), - ALGC("AES-128-CBC-HMAC-SHA256", aes128cbc_hmac_sha256_functions, - cipher_capable_aes_cbc_hmac_sha256), - ALGC("AES-256-CBC-HMAC-SHA256", aes256cbc_hmac_sha256_functions, - cipher_capable_aes_cbc_hmac_sha256), + ossl_aes128wrappad_functions), + ALGC("AES-128-CBC-HMAC-SHA1", ossl_aes128cbc_hmac_sha1_functions, + ossl_cipher_capable_aes_cbc_hmac_sha1), + ALGC("AES-256-CBC-HMAC-SHA1", ossl_aes256cbc_hmac_sha1_functions, + ossl_cipher_capable_aes_cbc_hmac_sha1), + ALGC("AES-128-CBC-HMAC-SHA256", ossl_aes128cbc_hmac_sha256_functions, + ossl_cipher_capable_aes_cbc_hmac_sha256), + ALGC("AES-256-CBC-HMAC-SHA256", ossl_aes256cbc_hmac_sha256_functions, + ossl_cipher_capable_aes_cbc_hmac_sha256), #ifndef OPENSSL_NO_ARIA - ALG("ARIA-256-GCM", aria256gcm_functions), - ALG("ARIA-192-GCM", aria192gcm_functions), - ALG("ARIA-128-GCM", aria128gcm_functions), - ALG("ARIA-256-CCM", aria256ccm_functions), - ALG("ARIA-192-CCM", aria192ccm_functions), - ALG("ARIA-128-CCM", aria128ccm_functions), - ALG("ARIA-256-ECB", aria256ecb_functions), - ALG("ARIA-192-ECB", aria192ecb_functions), - ALG("ARIA-128-ECB", aria128ecb_functions), - ALG("ARIA-256-CBC:ARIA256", aria256cbc_functions), - ALG("ARIA-192-CBC:ARIA192", aria192cbc_functions), - ALG("ARIA-128-CBC:ARIA128", aria128cbc_functions), - ALG("ARIA-256-OFB", aria256ofb_functions), - ALG("ARIA-192-OFB", aria192ofb_functions), - ALG("ARIA-128-OFB", aria128ofb_functions), - ALG("ARIA-256-CFB", aria256cfb_functions), - ALG("ARIA-192-CFB", aria192cfb_functions), - ALG("ARIA-128-CFB", aria128cfb_functions), - ALG("ARIA-256-CFB1", aria256cfb1_functions), - ALG("ARIA-192-CFB1", aria192cfb1_functions), - ALG("ARIA-128-CFB1", aria128cfb1_functions), - ALG("ARIA-256-CFB8", aria256cfb8_functions), - ALG("ARIA-192-CFB8", aria192cfb8_functions), - ALG("ARIA-128-CFB8", aria128cfb8_functions), - ALG("ARIA-256-CTR", aria256ctr_functions), - ALG("ARIA-192-CTR", aria192ctr_functions), - ALG("ARIA-128-CTR", aria128ctr_functions), + ALG("ARIA-256-GCM", ossl_aria256gcm_functions), + ALG("ARIA-192-GCM", ossl_aria192gcm_functions), + ALG("ARIA-128-GCM", ossl_aria128gcm_functions), + ALG("ARIA-256-CCM", ossl_aria256ccm_functions), + ALG("ARIA-192-CCM", ossl_aria192ccm_functions), + ALG("ARIA-128-CCM", ossl_aria128ccm_functions), + ALG("ARIA-256-ECB", ossl_aria256ecb_functions), + ALG("ARIA-192-ECB", ossl_aria192ecb_functions), + ALG("ARIA-128-ECB", ossl_aria128ecb_functions), + ALG("ARIA-256-CBC:ARIA256", ossl_aria256cbc_functions), + ALG("ARIA-192-CBC:ARIA192", ossl_aria192cbc_functions), + ALG("ARIA-128-CBC:ARIA128", ossl_aria128cbc_functions), + ALG("ARIA-256-OFB", ossl_aria256ofb_functions), + ALG("ARIA-192-OFB", ossl_aria192ofb_functions), + ALG("ARIA-128-OFB", ossl_aria128ofb_functions), + ALG("ARIA-256-CFB", ossl_aria256cfb_functions), + ALG("ARIA-192-CFB", ossl_aria192cfb_functions), + ALG("ARIA-128-CFB", ossl_aria128cfb_functions), + ALG("ARIA-256-CFB1", ossl_aria256cfb1_functions), + ALG("ARIA-192-CFB1", ossl_aria192cfb1_functions), + ALG("ARIA-128-CFB1", ossl_aria128cfb1_functions), + ALG("ARIA-256-CFB8", ossl_aria256cfb8_functions), + ALG("ARIA-192-CFB8", ossl_aria192cfb8_functions), + ALG("ARIA-128-CFB8", ossl_aria128cfb8_functions), + ALG("ARIA-256-CTR", ossl_aria256ctr_functions), + ALG("ARIA-192-CTR", ossl_aria192ctr_functions), + ALG("ARIA-128-CTR", ossl_aria128ctr_functions), #endif /* OPENSSL_NO_ARIA */ #ifndef OPENSSL_NO_CAMELLIA - ALG("CAMELLIA-256-ECB", camellia256ecb_functions), - ALG("CAMELLIA-192-ECB", camellia192ecb_functions), - ALG("CAMELLIA-128-ECB", camellia128ecb_functions), - ALG("CAMELLIA-256-CBC:CAMELLIA256", camellia256cbc_functions), - ALG("CAMELLIA-192-CBC:CAMELLIA192", camellia192cbc_functions), - ALG("CAMELLIA-128-CBC:CAMELLIA128", camellia128cbc_functions), - ALG("CAMELLIA-256-OFB", camellia256ofb_functions), - ALG("CAMELLIA-192-OFB", camellia192ofb_functions), - ALG("CAMELLIA-128-OFB", camellia128ofb_functions), - ALG("CAMELLIA-256-CFB", camellia256cfb_functions), - ALG("CAMELLIA-192-CFB", camellia192cfb_functions), - ALG("CAMELLIA-128-CFB", camellia128cfb_functions), - ALG("CAMELLIA-256-CFB1", camellia256cfb1_functions), - ALG("CAMELLIA-192-CFB1", camellia192cfb1_functions), - ALG("CAMELLIA-128-CFB1", camellia128cfb1_functions), - ALG("CAMELLIA-256-CFB8", camellia256cfb8_functions), - ALG("CAMELLIA-192-CFB8", camellia192cfb8_functions), - ALG("CAMELLIA-128-CFB8", camellia128cfb8_functions), - ALG("CAMELLIA-256-CTR", camellia256ctr_functions), - ALG("CAMELLIA-192-CTR", camellia192ctr_functions), - ALG("CAMELLIA-128-CTR", camellia128ctr_functions), + ALG("CAMELLIA-256-ECB", ossl_camellia256ecb_functions), + ALG("CAMELLIA-192-ECB", ossl_camellia192ecb_functions), + ALG("CAMELLIA-128-ECB", ossl_camellia128ecb_functions), + ALG("CAMELLIA-256-CBC:CAMELLIA256", ossl_camellia256cbc_functions), + ALG("CAMELLIA-192-CBC:CAMELLIA192", ossl_camellia192cbc_functions), + ALG("CAMELLIA-128-CBC:CAMELLIA128", ossl_camellia128cbc_functions), + ALG("CAMELLIA-256-OFB", ossl_camellia256ofb_functions), + ALG("CAMELLIA-192-OFB", ossl_camellia192ofb_functions), + ALG("CAMELLIA-128-OFB", ossl_camellia128ofb_functions), + ALG("CAMELLIA-256-CFB", ossl_camellia256cfb_functions), + ALG("CAMELLIA-192-CFB", ossl_camellia192cfb_functions), + ALG("CAMELLIA-128-CFB", ossl_camellia128cfb_functions), + ALG("CAMELLIA-256-CFB1", ossl_camellia256cfb1_functions), + ALG("CAMELLIA-192-CFB1", ossl_camellia192cfb1_functions), + ALG("CAMELLIA-128-CFB1", ossl_camellia128cfb1_functions), + ALG("CAMELLIA-256-CFB8", ossl_camellia256cfb8_functions), + ALG("CAMELLIA-192-CFB8", ossl_camellia192cfb8_functions), + ALG("CAMELLIA-128-CFB8", ossl_camellia128cfb8_functions), + ALG("CAMELLIA-256-CTR", ossl_camellia256ctr_functions), + ALG("CAMELLIA-192-CTR", ossl_camellia192ctr_functions), + ALG("CAMELLIA-128-CTR", ossl_camellia128ctr_functions), #endif /* OPENSSL_NO_CAMELLIA */ #ifndef OPENSSL_NO_DES - ALG("DES-EDE3-ECB:DES-EDE3", tdes_ede3_ecb_functions), - ALG("DES-EDE3-CBC:DES3", tdes_ede3_cbc_functions), - ALG("DES-EDE3-OFB", tdes_ede3_ofb_functions), - ALG("DES-EDE3-CFB", tdes_ede3_cfb_functions), - ALG("DES-EDE3-CFB8", tdes_ede3_cfb8_functions), - ALG("DES-EDE3-CFB1", tdes_ede3_cfb1_functions), - ALG("DES3-WRAP:id-smime-alg-CMS3DESwrap", tdes_wrap_cbc_functions), - ALG("DES-EDE-ECB:DES-EDE", tdes_ede2_ecb_functions), - ALG("DES-EDE-CBC", tdes_ede2_cbc_functions), - ALG("DES-EDE-OFB", tdes_ede2_ofb_functions), - ALG("DES-EDE-CFB", tdes_ede2_cfb_functions), + ALG("DES-EDE3-ECB:DES-EDE3", ossl_tdes_ede3_ecb_functions), + ALG("DES-EDE3-CBC:DES3", ossl_tdes_ede3_cbc_functions), + ALG("DES-EDE3-OFB", ossl_tdes_ede3_ofb_functions), + ALG("DES-EDE3-CFB", ossl_tdes_ede3_cfb_functions), + ALG("DES-EDE3-CFB8", ossl_tdes_ede3_cfb8_functions), + ALG("DES-EDE3-CFB1", ossl_tdes_ede3_cfb1_functions), + ALG("DES3-WRAP:id-smime-alg-CMS3DESwrap", ossl_tdes_wrap_cbc_functions), + ALG("DES-EDE-ECB:DES-EDE", ossl_tdes_ede2_ecb_functions), + ALG("DES-EDE-CBC", ossl_tdes_ede2_cbc_functions), + ALG("DES-EDE-OFB", ossl_tdes_ede2_ofb_functions), + ALG("DES-EDE-CFB", ossl_tdes_ede2_cfb_functions), #endif /* OPENSSL_NO_DES */ #ifndef OPENSSL_NO_SM4 - ALG("SM4-ECB", sm4128ecb_functions), - ALG("SM4-CBC:SM4", sm4128cbc_functions), - ALG("SM4-CTR", sm4128ctr_functions), - ALG("SM4-OFB:SM4-OFB128", sm4128ofb128_functions), - ALG("SM4-CFB:SM4-CFB128", sm4128cfb128_functions), + ALG("SM4-ECB", ossl_sm4128ecb_functions), + ALG("SM4-CBC:SM4", ossl_sm4128cbc_functions), + ALG("SM4-CTR", ossl_sm4128ctr_functions), + ALG("SM4-OFB:SM4-OFB128", ossl_sm4128ofb128_functions), + ALG("SM4-CFB:SM4-CFB128", ossl_sm4128cfb128_functions), #endif /* OPENSSL_NO_SM4 */ #ifndef OPENSSL_NO_CHACHA - ALG("ChaCha20", chacha20_functions), + ALG("ChaCha20", ossl_chacha20_functions), # ifndef OPENSSL_NO_POLY1305 - ALG("ChaCha20-Poly1305", chacha20_poly1305_functions), + ALG("ChaCha20-Poly1305", ossl_chacha20_ossl_poly1305_functions), # endif /* OPENSSL_NO_POLY1305 */ #endif /* OPENSSL_NO_CHACHA */ { { NULL, NULL, NULL }, NULL } @@ -291,121 +296,172 @@ static OSSL_ALGORITHM exported_ciphers[OSSL_NELEM(deflt_ciphers)]; static const OSSL_ALGORITHM deflt_macs[] = { #ifndef OPENSSL_NO_BLAKE2 - { "BLAKE2BMAC", "provider=default", blake2bmac_functions }, - { "BLAKE2SMAC", "provider=default", blake2smac_functions }, + { "BLAKE2BMAC", "provider=default", ossl_blake2bmac_functions }, + { "BLAKE2SMAC", "provider=default", ossl_blake2smac_functions }, #endif #ifndef OPENSSL_NO_CMAC - { "CMAC", "provider=default", cmac_functions }, + { "CMAC", "provider=default", ossl_cmac_functions }, #endif - { "GMAC", "provider=default", gmac_functions }, - { "HMAC", "provider=default", hmac_functions }, - { "KMAC-128:KMAC128", "provider=default", kmac128_functions }, - { "KMAC-256:KMAC256", "provider=default", kmac256_functions }, + { "GMAC", "provider=default", ossl_gmac_functions }, + { "HMAC", "provider=default", ossl_hmac_functions }, + { "KMAC-128:KMAC128", "provider=default", ossl_kmac128_functions }, + { "KMAC-256:KMAC256", "provider=default", ossl_kmac256_functions }, #ifndef OPENSSL_NO_SIPHASH - { "SIPHASH", "provider=default", siphash_functions }, + { "SIPHASH", "provider=default", ossl_siphash_functions }, #endif #ifndef OPENSSL_NO_POLY1305 - { "POLY1305", "provider=default", poly1305_functions }, + { "POLY1305", "provider=default", ossl_poly1305_functions }, #endif { NULL, NULL, NULL } }; static const OSSL_ALGORITHM deflt_kdfs[] = { - { "HKDF", "provider=default", kdf_hkdf_functions }, - { "SSKDF", "provider=default", kdf_sskdf_functions }, - { "PBKDF2", "provider=default", kdf_pbkdf2_functions }, - { "SSHKDF", "provider=default", kdf_sshkdf_functions }, - { "X963KDF", "provider=default", kdf_x963_kdf_functions }, - { "TLS1-PRF", "provider=default", kdf_tls1_prf_functions }, - { "KBKDF", "provider=default", kdf_kbkdf_functions }, + { "HKDF", "provider=default", ossl_kdf_hkdf_functions }, + { "SSKDF", "provider=default", ossl_kdf_sskdf_functions }, + { "PBKDF2", "provider=default", ossl_kdf_pbkdf2_functions }, + { "PKCS12KDF", "provider=default", ossl_kdf_pkcs12_functions }, + { "SSHKDF", "provider=default", ossl_kdf_sshkdf_functions }, + { "X963KDF", "provider=default", ossl_kdf_x963_kdf_functions }, + { "TLS1-PRF", "provider=default", ossl_kdf_tls1_prf_functions }, + { "KBKDF", "provider=default", ossl_kdf_kbkdf_functions }, #ifndef OPENSSL_NO_CMS - { "X942KDF", "provider=default", kdf_x942_kdf_functions }, + { "X942KDF", "provider=default", ossl_kdf_x942_kdf_functions }, #endif #ifndef OPENSSL_NO_SCRYPT - { "SCRYPT:id-scrypt", "provider=default", kdf_scrypt_functions }, + { "SCRYPT:id-scrypt", "provider=default", ossl_kdf_scrypt_functions }, #endif - { "KRB5KDF", "provider=default", kdf_krb5kdf_functions }, + { "KRB5KDF", "provider=default", ossl_kdf_krb5kdf_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM deflt_keyexch[] = { #ifndef OPENSSL_NO_DH - { "DH:dhKeyAgreement", "provider=default", dh_keyexch_functions }, + { "DH:dhKeyAgreement", "provider=default", ossl_dh_keyexch_functions }, #endif #ifndef OPENSSL_NO_EC - { "ECDH", "provider=default", ecdh_keyexch_functions }, - { "X25519", "provider=default", x25519_keyexch_functions }, - { "X448", "provider=default", x448_keyexch_functions }, + { "ECDH", "provider=default", ecossl_dh_keyexch_functions }, + { "X25519", "provider=default", ossl_x25519_keyexch_functions }, + { "X448", "provider=default", ossl_x448_keyexch_functions }, #endif + { "TLS1-PRF", "provider=default", ossl_kdf_tls1_prf_keyexch_functions }, + { "HKDF", "provider=default", ossl_kdf_hkdf_keyexch_functions }, + { "SCRYPT:id-scrypt", "provider=default", + ossl_kdf_scrypt_keyexch_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM deflt_rands[] = { - { "CTR-DRBG", "provider=default", drbg_ctr_functions }, - { "HASH-DRBG", "provider=default", drbg_hash_functions }, - { "HMAC-DRBG", "provider=default", drbg_hmac_functions }, - { "TEST-RAND", "provider=default", test_rng_functions }, + { "CTR-DRBG", "provider=default", ossl_drbg_ctr_functions }, + { "HASH-DRBG", "provider=default", ossl_drbg_hash_functions }, + { "HMAC-DRBG", "provider=default", ossl_drbg_ossl_hmac_functions }, + { "TEST-RAND", "provider=default", ossl_test_rng_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM deflt_signature[] = { #ifndef OPENSSL_NO_DSA - { "DSA:dsaEncryption", "provider=default", dsa_signature_functions }, + { "DSA:dsaEncryption", "provider=default", ossl_dsa_signature_functions }, #endif - { "RSA:rsaEncryption", "provider=default", rsa_signature_functions }, + { "RSA:rsaEncryption", "provider=default", ossl_rsa_signature_functions }, #ifndef OPENSSL_NO_EC - { "ED25519:Ed25519", "provider=default", ed25519_signature_functions }, - { "ED448:Ed448", "provider=default", ed448_signature_functions }, - { "ECDSA", "provider=default", ecdsa_signature_functions }, + { "ED25519:Ed25519", "provider=default", ossl_ed25519_signature_functions }, + { "ED448:Ed448", "provider=default", ossl_ed448_signature_functions }, + { "ECDSA", "provider=default", ecossl_dsa_signature_functions }, +# ifndef OPENSSL_NO_SM2 + { "SM2", "provider=default", sm2_signature_functions }, +# endif +#endif + { "HMAC", "provider=default", ossl_mac_legacy_hmac_signature_functions }, + { "SIPHASH", "provider=default", + ossl_mac_legacy_siphash_signature_functions }, +#ifndef OPENSSL_NO_POLY1305 + { "POLY1305", "provider=default", + ossl_mac_legacy_poly1305_signature_functions }, +#endif +#ifndef OPENSSL_NO_CMAC + { "CMAC", "provider=default", ossl_mac_legacy_cmac_signature_functions }, #endif { NULL, NULL, NULL } }; static const OSSL_ALGORITHM deflt_asym_cipher[] = { - { "RSA:rsaEncryption", "provider=default", rsa_asym_cipher_functions }, + { "RSA:rsaEncryption", "provider=default", ossl_rsa_asym_cipher_functions }, +#ifndef OPENSSL_NO_SM2 + { "SM2", "provider=default", sm2_asym_cipher_functions }, +#endif + { NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM deflt_asym_kem[] = { + { "RSA", "provider=default", ossl_rsa_asym_kem_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM deflt_keymgmt[] = { #ifndef OPENSSL_NO_DH - { "DH:dhKeyAgreement", "provider=default", dh_keymgmt_functions }, + { "DH:dhKeyAgreement", "provider=default", ossl_dh_keymgmt_functions }, + { "DHX:X9.42 DH:dhpublicnumber", "provider=default", + ossl_dhx_keymgmt_functions }, #endif #ifndef OPENSSL_NO_DSA - { "DSA:dsaEncryption", "provider=default", dsa_keymgmt_functions }, + { "DSA:dsaEncryption", "provider=default", ossl_dsa_keymgmt_functions }, #endif - { "RSA:rsaEncryption", "provider=default", rsa_keymgmt_functions }, - { "RSA-PSS:RSASSA-PSS", "provider=default", rsapss_keymgmt_functions }, + { "RSA:rsaEncryption", "provider=default", ossl_rsa_keymgmt_functions }, + { "RSA-PSS:RSASSA-PSS", "provider=default", ossl_rsapss_keymgmt_functions }, #ifndef OPENSSL_NO_EC - { "EC:id-ecPublicKey", "provider=default", ec_keymgmt_functions }, - { "X25519", "provider=default", x25519_keymgmt_functions }, - { "X448", "provider=default", x448_keymgmt_functions }, - { "ED25519", "provider=default", ed25519_keymgmt_functions }, - { "ED448", "provider=default", ed448_keymgmt_functions }, + { "EC:id-ecPublicKey", "provider=default", ossl_ec_keymgmt_functions }, + { "X25519", "provider=default", ossl_x25519_keymgmt_functions }, + { "X448", "provider=default", ossl_x448_keymgmt_functions }, + { "ED25519", "provider=default", ossl_ed25519_keymgmt_functions }, + { "ED448", "provider=default", ossl_ed448_keymgmt_functions }, +#endif + { "TLS1-PRF", "provider=default", ossl_kdf_keymgmt_functions }, + { "HKDF", "provider=default", ossl_kdf_keymgmt_functions }, + { "SCRYPT:id-scrypt", "provider=default", ossl_kdf_keymgmt_functions }, + { "HMAC", "provider=default", ossl_mac_legacy_keymgmt_functions }, + { "SIPHASH", "provider=default", ossl_mac_legacy_keymgmt_functions }, +#ifndef OPENSSL_NO_POLY1305 + { "POLY1305", "provider=default", ossl_mac_legacy_keymgmt_functions }, +#endif +#ifndef OPENSSL_NO_CMAC + { "CMAC", "provider=default", ossl_cossl_mac_legacy_keymgmt_functions }, +#endif +#ifndef OPENSSL_NO_SM2 + { "SM2", "provider=default", sm2_keymgmt_functions }, #endif { NULL, NULL, NULL } }; -static const OSSL_ALGORITHM deflt_serializer[] = { -#define SER(name, fips, format, type, func_table) \ +static const OSSL_ALGORITHM deflt_encoder[] = { +#define ENCODER(name, _fips, _output, func_table) \ { name, \ - "provider=default,fips=" fips ",format=" format ",type=" type, \ + "provider=default,fips=" _fips ",output=" _output, \ (func_table) } -#include "serializers.inc" +#include "encoders.inc" { NULL, NULL, NULL } }; -#undef SER +#undef ENCODER -static const OSSL_ALGORITHM deflt_deserializer[] = { -#define DESER(name, fips, input, func_table) \ +static const OSSL_ALGORITHM deflt_decoder[] = { +#define DECODER(name, _fips, _input, func_table) \ { name, \ - "provider=default,fips=" fips ",input=" input, \ + "provider=default,fips=" _fips ",input=" _input, \ (func_table) } -#include "deserializers.inc" +#include "decoders.inc" + { NULL, NULL, NULL } +}; +#undef DECODER + +static const OSSL_ALGORITHM deflt_store[] = { +#define STORE(name, _fips, func_table) \ + { name, "provider=default,fips=" _fips, (func_table) }, + +#include "stores.inc" { NULL, NULL, NULL } +#undef STORE }; -#undef DESER static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id, int *no_cache) @@ -431,10 +487,14 @@ static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id, return deflt_signature; case OSSL_OP_ASYM_CIPHER: return deflt_asym_cipher; - case OSSL_OP_SERIALIZER: - return deflt_serializer; - case OSSL_OP_DESERIALIZER: - return deflt_deserializer; + case OSSL_OP_KEM: + return deflt_asym_kem; + case OSSL_OP_ENCODER: + return deflt_encoder; + case OSSL_OP_DECODER: + return deflt_decoder; + case OSSL_OP_STORE: + return deflt_store; } return NULL; } @@ -442,8 +502,8 @@ static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id, static void deflt_teardown(void *provctx) { - BIO_meth_free(PROV_CTX_get0_core_bio_method(provctx)); - PROV_CTX_free(provctx); + BIO_meth_free(ossl_prov_ctx_get0_core_bio_method(provctx)); + ossl_prov_ctx_free(provctx); } /* Functions we provide to the core */ @@ -463,7 +523,7 @@ int ossl_default_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH **out, void **provctx) { - OSSL_FUNC_core_get_library_context_fn *c_get_libctx = NULL; + OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; BIO_METHOD *corebiometh; if (!ossl_prov_bio_from_dispatch(in)) @@ -476,8 +536,8 @@ int ossl_default_provider_init(const OSSL_CORE_HANDLE *handle, case OSSL_FUNC_CORE_GET_PARAMS: c_get_params = OSSL_FUNC_core_get_params(in); break; - case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT: - c_get_libctx = OSSL_FUNC_core_get_library_context(in); + case OSSL_FUNC_CORE_GET_LIBCTX: + c_get_libctx = OSSL_FUNC_core_get_libctx(in); break; default: /* Just ignore anything we don't understand */ @@ -496,15 +556,16 @@ int ossl_default_provider_init(const OSSL_CORE_HANDLE *handle, * This only works for built-in providers. Most providers should * create their own library context. */ - if ((*provctx = PROV_CTX_new()) == NULL + if ((*provctx = ossl_prov_ctx_new()) == NULL || (corebiometh = bio_prov_init_bio_method()) == NULL) { - PROV_CTX_free(*provctx); + ossl_prov_ctx_free(*provctx); *provctx = NULL; return 0; } - PROV_CTX_set0_library_context(*provctx, (OPENSSL_CTX *)c_get_libctx(handle)); - PROV_CTX_set0_handle(*provctx, handle); - PROV_CTX_set0_core_bio_method(*provctx, corebiometh); + ossl_prov_ctx_set0_libctx(*provctx, + (OSSL_LIB_CTX *)c_get_libctx(handle)); + ossl_prov_ctx_set0_handle(*provctx, handle); + ossl_prov_ctx_set0_core_bio_method(*provctx, corebiometh); *out = deflt_dispatch_table; diff --git a/providers/deserializers.inc b/providers/deserializers.inc deleted file mode 100644 index ead1c67878..0000000000 --- a/providers/deserializers.inc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef DESER -# error Macro DESER undefined -#endif - -#ifndef OPENSSL_NO_DH - DESER("DH", "yes", "der", der_to_dh_deserializer_functions), -#endif -#ifndef OPENSSL_NO_DSA - DESER("DSA", "yes", "der", der_to_dsa_deserializer_functions), -#endif -#ifndef OPENSSL_NO_EC - DESER("EC", "yes", "der", der_to_ec_deserializer_functions), - DESER("ED25519", "yes", "der", der_to_ed25519_deserializer_functions), - DESER("ED448", "yes", "der", der_to_ed448_deserializer_functions), - DESER("X25519", "yes", "der", der_to_x25519_deserializer_functions), - DESER("X448", "yes", "der", der_to_x448_deserializer_functions), -#endif - DESER("RSA", "yes", "der", der_to_rsa_deserializer_functions), - DESER("RSA-PSS", "yes", "der", der_to_rsapss_deserializer_functions), - - DESER("DER", "yes", "pem", pem_to_der_deserializer_functions), diff --git a/providers/encoders.inc b/providers/encoders.inc new file mode 100644 index 0000000000..1ae0d4fb4c --- /dev/null +++ b/providers/encoders.inc @@ -0,0 +1,57 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef ENCODER +# error Macro ENCODER undefined +#endif + + ENCODER("RSA", "yes", "text", ossl_rsa_to_text_encoder_functions), + ENCODER("RSA", "yes", "der", ossl_rsa_to_der_encoder_functions), + ENCODER("RSA", "yes", "pem", ossl_rsa_to_pem_encoder_functions), + ENCODER("RSA-PSS", "yes", "text", ossl_rsapss_to_text_encoder_functions), + ENCODER("RSA-PSS", "yes", "der", ossl_rsapss_to_der_encoder_functions), + ENCODER("RSA-PSS", "yes", "pem", ossl_rsapss_to_pem_encoder_functions), + +#ifndef OPENSSL_NO_DH + ENCODER("DH", "yes", "text", ossl_dh_to_text_encoder_functions), + ENCODER("DH", "yes", "der", ossl_dh_to_der_encoder_functions), + ENCODER("DH", "yes", "pem", ossl_dh_to_pem_encoder_functions), + + ENCODER("DHX", "yes", "text", ossl_dhx_to_text_encoder_functions), + ENCODER("DHX", "yes", "der", ossl_dhx_to_der_encoder_functions), + ENCODER("DHX", "yes", "pem", ossl_dhx_to_pem_encoder_functions), +#endif + +#ifndef OPENSSL_NO_DSA + ENCODER("DSA", "yes", "text", ossl_dsa_to_text_encoder_functions), + ENCODER("DSA", "yes", "der", ossl_dsa_to_der_encoder_functions), + ENCODER("DSA", "yes", "pem", ossl_dsa_to_pem_encoder_functions), +#endif + +#ifndef OPENSSL_NO_EC + ENCODER("X25519", "yes", "text", ossl_x25519_to_text_encoder_functions), + ENCODER("X25519", "yes", "der", ossl_x25519_to_der_encoder_functions), + ENCODER("X25519", "yes", "pem", ossl_x25519_to_pem_encoder_functions), + + ENCODER("X448", "yes", "text", ossl_x448_to_text_encoder_functions), + ENCODER("X448", "yes", "der", ossl_x448_to_der_encoder_functions), + ENCODER("X448", "yes", "pem", ossl_x448_to_pem_encoder_functions), + + ENCODER("ED25519", "yes", "text", ossl_ed25519_to_text_encoder_functions), + ENCODER("ED25519", "yes", "der", ossl_ed25519_to_der_encoder_functions), + ENCODER("ED25519", "yes", "pem", ossl_ed25519_to_pem_encoder_functions), + + ENCODER("ED448", "yes", "text", ossl_ed448_to_text_encoder_functions), + ENCODER("ED448", "yes", "der", ossl_ed448_to_der_encoder_functions), + ENCODER("ED448", "yes", "pem", ossl_ed448_to_pem_encoder_functions), + + ENCODER("EC", "yes", "text", ossl_ec_to_text_encoder_functions), + ENCODER("EC", "yes", "der", ossl_ec_to_der_encoder_functions), + ENCODER("EC", "yes", "pem", ossl_ec_to_pem_encoder_functions), +#endif diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 77cd75fcdf..93b5dede67 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -12,7 +12,7 @@ #include #include /* NIDs used by ossl_prov_util_nid_to_name() */ #include -#include /* OPENSSL_CTX_get0_public_drbg() */ +#include /* RAND_get0_public() */ #include "internal/cryptlib.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" @@ -37,15 +37,18 @@ static OSSL_FUNC_provider_query_operation_fn fips_query; #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL) extern OSSL_FUNC_core_thread_start_fn *c_thread_start; +int FIPS_security_check_enabled(void); /* * TODO(3.0): Should these be stored in the provider side provctx? Could they * ever be different from one init to the next? Unfortunately we can't do this * at the moment because c_put_error/c_add_error_vdata do not provide - * us with the OPENSSL_CTX as a parameter. + * us with the OSSL_LIB_CTX as a parameter. */ static SELF_TEST_POST_PARAMS selftest_params; +static int fips_security_checks = 1; +static const char *fips_security_check_option = "1"; /* Functions provided by the core */ static OSSL_FUNC_core_gettable_params_fn *c_gettable_params; @@ -69,12 +72,14 @@ static OSSL_FUNC_CRYPTO_secure_free_fn *c_CRYPTO_secure_free; static OSSL_FUNC_CRYPTO_secure_clear_free_fn *c_CRYPTO_secure_clear_free; static OSSL_FUNC_CRYPTO_secure_allocated_fn *c_CRYPTO_secure_allocated; static OSSL_FUNC_BIO_vsnprintf_fn *c_BIO_vsnprintf; +static OSSL_FUNC_self_test_cb_fn *c_stcbfn = NULL; +static OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; typedef struct fips_global_st { const OSSL_CORE_HANDLE *handle; } FIPS_GLOBAL; -static void *fips_prov_ossl_ctx_new(OPENSSL_CTX *libctx) +static void *fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) { FIPS_GLOBAL *fgbl = OPENSSL_zalloc(sizeof(*fgbl)); @@ -86,7 +91,7 @@ static void fips_prov_ossl_ctx_free(void *fgbl) OPENSSL_free(fgbl); } -static const OPENSSL_CTX_METHOD fips_prov_ossl_ctx_method = { +static const OSSL_LIB_CTX_METHOD fips_prov_ossl_ctx_method = { fips_prov_ossl_ctx_new, fips_prov_ossl_ctx_free, }; @@ -97,6 +102,8 @@ static const OSSL_PARAM fips_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END }; @@ -105,6 +112,7 @@ static const OSSL_PARAM fips_param_types[] = { * NOTE: inside core_get_params() these will be loaded from config items * stored inside prov->parameters (except for * OSSL_PROV_PARAM_CORE_MODULE_FILENAME). + * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS is not a self test parameter. */ static OSSL_PARAM core_params[] = { @@ -123,6 +131,12 @@ static OSSL_PARAM core_params[] = OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_VERSION, selftest_params.indicator_version, sizeof(selftest_params.indicator_version)), + OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS, + selftest_params.conditional_error_check, + sizeof(selftest_params.conditional_error_check)), + OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS, + fips_security_check_option, + sizeof(fips_security_check_option)), OSSL_PARAM_END }; @@ -144,10 +158,32 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR)) return 0; - + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); + if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) + return 0; + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_SECURITY_CHECKS); + if (p != NULL && !OSSL_PARAM_set_int(p, fips_security_checks)) + return 0; return 1; } +static void set_self_test_cb(const OSSL_CORE_HANDLE *handle) +{ + if (c_stcbfn != NULL && c_get_libctx != NULL) { + c_stcbfn(c_get_libctx(handle), &selftest_params.cb, + &selftest_params.cb_arg); + } else { + selftest_params.cb = NULL; + selftest_params.cb_arg = NULL; + } +} + +static int fips_self_test(void *provctx) +{ + set_self_test_cb(FIPS_get_core_handle(selftest_params.libctx)); + return SELF_TEST_post(&selftest_params, 1) ? 1 : 0; +} + /* FIPS specific version of the function of the same name in provlib.c */ /* TODO(3.0) - Is this function needed ? */ const char *ossl_prov_util_nid_to_name(int nid) @@ -271,90 +307,94 @@ const char *ossl_prov_util_nid_to_name(int nid) */ static const OSSL_ALGORITHM fips_digests[] = { /* Our primary name:NiST name[:our older names] */ - { "SHA1:SHA-1", FIPS_DEFAULT_PROPERTIES, sha1_functions }, - { "SHA2-224:SHA-224:SHA224", FIPS_DEFAULT_PROPERTIES, sha224_functions }, - { "SHA2-256:SHA-256:SHA256", FIPS_DEFAULT_PROPERTIES, sha256_functions }, - { "SHA2-384:SHA-384:SHA384", FIPS_DEFAULT_PROPERTIES, sha384_functions }, - { "SHA2-512:SHA-512:SHA512", FIPS_DEFAULT_PROPERTIES, sha512_functions }, + { "SHA1:SHA-1:SSL3-SHA1", FIPS_DEFAULT_PROPERTIES, ossl_sha1_functions }, + { "SHA2-224:SHA-224:SHA224", FIPS_DEFAULT_PROPERTIES, + ossl_sha224_functions }, + { "SHA2-256:SHA-256:SHA256", FIPS_DEFAULT_PROPERTIES, + ossl_sha256_functions }, + { "SHA2-384:SHA-384:SHA384", FIPS_DEFAULT_PROPERTIES, + ossl_sha384_functions }, + { "SHA2-512:SHA-512:SHA512", FIPS_DEFAULT_PROPERTIES, + ossl_sha512_functions }, { "SHA2-512/224:SHA-512/224:SHA512-224", FIPS_DEFAULT_PROPERTIES, - sha512_224_functions }, + ossl_sha512_224_functions }, { "SHA2-512/256:SHA-512/256:SHA512-256", FIPS_DEFAULT_PROPERTIES, - sha512_256_functions }, + ossl_sha512_256_functions }, /* We agree with NIST here, so one name only */ - { "SHA3-224", FIPS_DEFAULT_PROPERTIES, sha3_224_functions }, - { "SHA3-256", FIPS_DEFAULT_PROPERTIES, sha3_256_functions }, - { "SHA3-384", FIPS_DEFAULT_PROPERTIES, sha3_384_functions }, - { "SHA3-512", FIPS_DEFAULT_PROPERTIES, sha3_512_functions }, + { "SHA3-224", FIPS_DEFAULT_PROPERTIES, ossl_sha3_224_functions }, + { "SHA3-256", FIPS_DEFAULT_PROPERTIES, ossl_sha3_256_functions }, + { "SHA3-384", FIPS_DEFAULT_PROPERTIES, ossl_sha3_384_functions }, + { "SHA3-512", FIPS_DEFAULT_PROPERTIES, ossl_sha3_512_functions }, - { "SHAKE-128:SHAKE128", FIPS_DEFAULT_PROPERTIES, shake_128_functions }, - { "SHAKE-256:SHAKE256", FIPS_DEFAULT_PROPERTIES, shake_256_functions }, + { "SHAKE-128:SHAKE128", FIPS_DEFAULT_PROPERTIES, ossl_shake_128_functions }, + { "SHAKE-256:SHAKE256", FIPS_DEFAULT_PROPERTIES, ossl_shake_256_functions }, /* * KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for * KMAC128 and KMAC256. */ { "KECCAK-KMAC-128:KECCAK-KMAC128", FIPS_DEFAULT_PROPERTIES, - keccak_kmac_128_functions }, + ossl_keccak_kmac_128_functions }, { "KECCAK-KMAC-256:KECCAK-KMAC256", FIPS_DEFAULT_PROPERTIES, - keccak_kmac_256_functions }, + ossl_keccak_kmac_256_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM_CAPABLE fips_ciphers[] = { /* Our primary name[:ASN.1 OID name][:our older names] */ - ALG("AES-256-ECB", aes256ecb_functions), - ALG("AES-192-ECB", aes192ecb_functions), - ALG("AES-128-ECB", aes128ecb_functions), - ALG("AES-256-CBC", aes256cbc_functions), - ALG("AES-192-CBC", aes192cbc_functions), - ALG("AES-128-CBC", aes128cbc_functions), - ALG("AES-256-CBC-CTS", aes256cbc_cts_functions), - ALG("AES-192-CBC-CTS", aes192cbc_cts_functions), - ALG("AES-128-CBC-CTS", aes128cbc_cts_functions), - ALG("AES-256-OFB", aes256ofb_functions), - ALG("AES-192-OFB", aes192ofb_functions), - ALG("AES-128-OFB", aes128ofb_functions), - ALG("AES-256-CFB", aes256cfb_functions), - ALG("AES-192-CFB", aes192cfb_functions), - ALG("AES-128-CFB", aes128cfb_functions), - ALG("AES-256-CFB1", aes256cfb1_functions), - ALG("AES-192-CFB1", aes192cfb1_functions), - ALG("AES-128-CFB1", aes128cfb1_functions), - ALG("AES-256-CFB8", aes256cfb8_functions), - ALG("AES-192-CFB8", aes192cfb8_functions), - ALG("AES-128-CFB8", aes128cfb8_functions), - ALG("AES-256-CTR", aes256ctr_functions), - ALG("AES-192-CTR", aes192ctr_functions), - ALG("AES-128-CTR", aes128ctr_functions), - ALG("AES-256-XTS", aes256xts_functions), - ALG("AES-128-XTS", aes128xts_functions), - ALG("AES-256-GCM:id-aes256-GCM", aes256gcm_functions), - ALG("AES-192-GCM:id-aes192-GCM", aes192gcm_functions), - ALG("AES-128-GCM:id-aes128-GCM", aes128gcm_functions), - ALG("AES-256-CCM:id-aes256-CCM", aes256ccm_functions), - ALG("AES-192-CCM:id-aes192-CCM", aes192ccm_functions), - ALG("AES-128-CCM:id-aes128-CCM", aes128ccm_functions), - ALG("AES-256-WRAP:id-aes256-wrap:AES256-WRAP", aes256wrap_functions), - ALG("AES-192-WRAP:id-aes192-wrap:AES192-WRAP", aes192wrap_functions), - ALG("AES-128-WRAP:id-aes128-wrap:AES128-WRAP", aes128wrap_functions), + ALG("AES-256-ECB", ossl_aes256ecb_functions), + ALG("AES-192-ECB", ossl_aes192ecb_functions), + ALG("AES-128-ECB", ossl_aes128ecb_functions), + ALG("AES-256-CBC:AES256", ossl_aes256cbc_functions), + ALG("AES-192-CBC:AES192", ossl_aes192cbc_functions), + ALG("AES-128-CBC:AES128", ossl_aes128cbc_functions), + ALG("AES-256-CBC-CTS", ossl_aes256cbc_cts_functions), + ALG("AES-192-CBC-CTS", ossl_aes192cbc_cts_functions), + ALG("AES-128-CBC-CTS", ossl_aes128cbc_cts_functions), + ALG("AES-256-OFB", ossl_aes256ofb_functions), + ALG("AES-192-OFB", ossl_aes192ofb_functions), + ALG("AES-128-OFB", ossl_aes128ofb_functions), + ALG("AES-256-CFB", ossl_aes256cfb_functions), + ALG("AES-192-CFB", ossl_aes192cfb_functions), + ALG("AES-128-CFB", ossl_aes128cfb_functions), + ALG("AES-256-CFB1", ossl_aes256cfb1_functions), + ALG("AES-192-CFB1", ossl_aes192cfb1_functions), + ALG("AES-128-CFB1", ossl_aes128cfb1_functions), + ALG("AES-256-CFB8", ossl_aes256cfb8_functions), + ALG("AES-192-CFB8", ossl_aes192cfb8_functions), + ALG("AES-128-CFB8", ossl_aes128cfb8_functions), + ALG("AES-256-CTR", ossl_aes256ctr_functions), + ALG("AES-192-CTR", ossl_aes192ctr_functions), + ALG("AES-128-CTR", ossl_aes128ctr_functions), + ALG("AES-256-XTS", ossl_aes256xts_functions), + ALG("AES-128-XTS", ossl_aes128xts_functions), + ALG("AES-256-GCM:id-aes256-GCM", ossl_aes256gcm_functions), + ALG("AES-192-GCM:id-aes192-GCM", ossl_aes192gcm_functions), + ALG("AES-128-GCM:id-aes128-GCM", ossl_aes128gcm_functions), + ALG("AES-256-CCM:id-aes256-CCM", ossl_aes256ccm_functions), + ALG("AES-192-CCM:id-aes192-CCM", ossl_aes192ccm_functions), + ALG("AES-128-CCM:id-aes128-CCM", ossl_aes128ccm_functions), + ALG("AES-256-WRAP:id-aes256-wrap:AES256-WRAP", ossl_aes256wrap_functions), + ALG("AES-192-WRAP:id-aes192-wrap:AES192-WRAP", ossl_aes192wrap_functions), + ALG("AES-128-WRAP:id-aes128-wrap:AES128-WRAP", ossl_aes128wrap_functions), ALG("AES-256-WRAP-PAD:id-aes256-wrap-pad:AES256-WRAP-PAD", - aes256wrappad_functions), + ossl_aes256wrappad_functions), ALG("AES-192-WRAP-PAD:id-aes192-wrap-pad:AES192-WRAP-PAD", - aes192wrappad_functions), + ossl_aes192wrappad_functions), ALG("AES-128-WRAP-PAD:id-aes128-wrap-pad:AES128-WRAP-PAD", - aes128wrappad_functions), - ALGC("AES-128-CBC-HMAC-SHA1", aes128cbc_hmac_sha1_functions, - cipher_capable_aes_cbc_hmac_sha1), - ALGC("AES-256-CBC-HMAC-SHA1", aes256cbc_hmac_sha1_functions, - cipher_capable_aes_cbc_hmac_sha1), - ALGC("AES-128-CBC-HMAC-SHA256", aes128cbc_hmac_sha256_functions, - cipher_capable_aes_cbc_hmac_sha256), - ALGC("AES-256-CBC-HMAC-SHA256", aes256cbc_hmac_sha256_functions, - cipher_capable_aes_cbc_hmac_sha256), + ossl_aes128wrappad_functions), + ALGC("AES-128-CBC-HMAC-SHA1", ossl_aes128cbc_hmac_sha1_functions, + ossl_cipher_capable_aes_cbc_hmac_sha1), + ALGC("AES-256-CBC-HMAC-SHA1", ossl_aes256cbc_hmac_sha1_functions, + ossl_cipher_capable_aes_cbc_hmac_sha1), + ALGC("AES-128-CBC-HMAC-SHA256", ossl_aes128cbc_hmac_sha256_functions, + ossl_cipher_capable_aes_cbc_hmac_sha256), + ALGC("AES-256-CBC-HMAC-SHA256", ossl_aes256cbc_hmac_sha256_functions, + ossl_cipher_capable_aes_cbc_hmac_sha256), #ifndef OPENSSL_NO_DES - ALG("DES-EDE3-ECB:DES-EDE3", tdes_ede3_ecb_functions), - ALG("DES-EDE3-CBC:DES3", tdes_ede3_cbc_functions), + ALG("DES-EDE3-ECB:DES-EDE3", ossl_tdes_ede3_ecb_functions), + ALG("DES-EDE3-CBC:DES3", ossl_tdes_ede3_cbc_functions), #endif /* OPENSSL_NO_DES */ { { NULL, NULL, NULL }, NULL } }; @@ -362,80 +402,107 @@ static OSSL_ALGORITHM exported_fips_ciphers[OSSL_NELEM(fips_ciphers)]; static const OSSL_ALGORITHM fips_macs[] = { #ifndef OPENSSL_NO_CMAC - { "CMAC", FIPS_DEFAULT_PROPERTIES, cmac_functions }, + { "CMAC", FIPS_DEFAULT_PROPERTIES, ossl_cmac_functions }, #endif - { "GMAC", FIPS_DEFAULT_PROPERTIES, gmac_functions }, - { "HMAC", FIPS_DEFAULT_PROPERTIES, hmac_functions }, - { "KMAC-128:KMAC128", FIPS_DEFAULT_PROPERTIES, kmac128_functions }, - { "KMAC-256:KMAC256", FIPS_DEFAULT_PROPERTIES, kmac256_functions }, + { "GMAC", FIPS_DEFAULT_PROPERTIES, ossl_gmac_functions }, + { "HMAC", FIPS_DEFAULT_PROPERTIES, ossl_hmac_functions }, + { "KMAC-128:KMAC128", FIPS_DEFAULT_PROPERTIES, ossl_kmac128_functions }, + { "KMAC-256:KMAC256", FIPS_DEFAULT_PROPERTIES, ossl_kmac256_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM fips_kdfs[] = { - { "HKDF", FIPS_DEFAULT_PROPERTIES, kdf_hkdf_functions }, - { "SSKDF", FIPS_DEFAULT_PROPERTIES, kdf_sskdf_functions }, - { "PBKDF2", FIPS_DEFAULT_PROPERTIES, kdf_pbkdf2_functions }, - { "SSHKDF", FIPS_DEFAULT_PROPERTIES, kdf_sshkdf_functions }, - { "X963KDF", FIPS_DEFAULT_PROPERTIES, kdf_x963_kdf_functions }, - { "TLS1-PRF", FIPS_DEFAULT_PROPERTIES, kdf_tls1_prf_functions }, - { "KBKDF", FIPS_DEFAULT_PROPERTIES, kdf_kbkdf_functions }, + { "HKDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_functions }, + { "SSKDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_sskdf_functions }, + { "PBKDF2", FIPS_DEFAULT_PROPERTIES, ossl_kdf_pbkdf2_functions }, + { "SSHKDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_sshkdf_functions }, + { "X963KDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_x963_kdf_functions }, + { "TLS1-PRF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_tls1_prf_functions }, + { "KBKDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_kbkdf_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM fips_rands[] = { - { "CTR-DRBG", FIPS_DEFAULT_PROPERTIES, drbg_ctr_functions }, - { "HASH-DRBG", FIPS_DEFAULT_PROPERTIES, drbg_hash_functions }, - { "HMAC-DRBG", FIPS_DEFAULT_PROPERTIES, drbg_hmac_functions }, - { "TEST-RAND", FIPS_UNAPPROVED_PROPERTIES, test_rng_functions }, + { "CTR-DRBG", FIPS_DEFAULT_PROPERTIES, ossl_drbg_ctr_functions }, + { "HASH-DRBG", FIPS_DEFAULT_PROPERTIES, ossl_drbg_hash_functions }, + { "HMAC-DRBG", FIPS_DEFAULT_PROPERTIES, ossl_drbg_ossl_hmac_functions }, + { "TEST-RAND", FIPS_UNAPPROVED_PROPERTIES, ossl_test_rng_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM fips_keyexch[] = { #ifndef OPENSSL_NO_DH - { "DH:dhKeyAgreement", FIPS_DEFAULT_PROPERTIES, dh_keyexch_functions }, + { "DH:dhKeyAgreement", FIPS_DEFAULT_PROPERTIES, ossl_dh_keyexch_functions }, #endif #ifndef OPENSSL_NO_EC - { "ECDH", FIPS_DEFAULT_PROPERTIES, ecdh_keyexch_functions }, - { "X25519", FIPS_DEFAULT_PROPERTIES, x25519_keyexch_functions }, - { "X448", FIPS_DEFAULT_PROPERTIES, x448_keyexch_functions }, + { "ECDH", FIPS_DEFAULT_PROPERTIES, ecossl_dh_keyexch_functions }, + { "X25519", FIPS_DEFAULT_PROPERTIES, ossl_x25519_keyexch_functions }, + { "X448", FIPS_DEFAULT_PROPERTIES, ossl_x448_keyexch_functions }, #endif + { "TLS1-PRF", FIPS_DEFAULT_PROPERTIES, + ossl_kdf_tls1_prf_keyexch_functions }, + { "HKDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_keyexch_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM fips_signature[] = { #ifndef OPENSSL_NO_DSA - { "DSA:dsaEncryption", FIPS_DEFAULT_PROPERTIES, dsa_signature_functions }, + { "DSA:dsaEncryption", FIPS_DEFAULT_PROPERTIES, + ossl_dsa_signature_functions }, #endif - { "RSA:rsaEncryption", FIPS_DEFAULT_PROPERTIES, rsa_signature_functions }, + { "RSA:rsaEncryption", FIPS_DEFAULT_PROPERTIES, + ossl_rsa_signature_functions }, #ifndef OPENSSL_NO_EC - { "ED25519", FIPS_DEFAULT_PROPERTIES, ed25519_signature_functions }, - { "ED448", FIPS_DEFAULT_PROPERTIES, ed448_signature_functions }, - { "ECDSA", FIPS_DEFAULT_PROPERTIES, ecdsa_signature_functions }, + { "ED25519", FIPS_DEFAULT_PROPERTIES, ossl_ed25519_signature_functions }, + { "ED448", FIPS_DEFAULT_PROPERTIES, ossl_ed448_signature_functions }, + { "ECDSA", FIPS_DEFAULT_PROPERTIES, ecossl_dsa_signature_functions }, +#endif + { "HMAC", FIPS_DEFAULT_PROPERTIES, + ossl_mac_legacy_hmac_signature_functions }, +#ifndef OPENSSL_NO_CMAC + { "CMAC", FIPS_DEFAULT_PROPERTIES, + ossl_mac_legacy_cmac_signature_functions }, #endif { NULL, NULL, NULL } }; static const OSSL_ALGORITHM fips_asym_cipher[] = { - { "RSA:rsaEncryption", FIPS_DEFAULT_PROPERTIES, rsa_asym_cipher_functions }, + { "RSA:rsaEncryption", FIPS_DEFAULT_PROPERTIES, + ossl_rsa_asym_cipher_functions }, + { NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM fips_asym_kem[] = { + { "RSA", FIPS_DEFAULT_PROPERTIES, ossl_rsa_asym_kem_functions }, { NULL, NULL, NULL } }; static const OSSL_ALGORITHM fips_keymgmt[] = { #ifndef OPENSSL_NO_DH - { "DH:dhKeyAgreement", FIPS_DEFAULT_PROPERTIES, dh_keymgmt_functions }, + { "DH:dhKeyAgreement", FIPS_DEFAULT_PROPERTIES, ossl_dh_keymgmt_functions }, + { "DHX:X9.42 DH:dhpublicnumber", FIPS_DEFAULT_PROPERTIES, + ossl_dhx_keymgmt_functions }, #endif #ifndef OPENSSL_NO_DSA - { "DSA", FIPS_DEFAULT_PROPERTIES, dsa_keymgmt_functions }, + { "DSA", FIPS_DEFAULT_PROPERTIES, ossl_dsa_keymgmt_functions }, #endif - { "RSA:rsaEncryption", FIPS_DEFAULT_PROPERTIES, rsa_keymgmt_functions }, + { "RSA:rsaEncryption", FIPS_DEFAULT_PROPERTIES, + ossl_rsa_keymgmt_functions }, { "RSA-PSS:RSASSA-PSS", FIPS_DEFAULT_PROPERTIES, - rsapss_keymgmt_functions }, + ossl_rsapss_keymgmt_functions }, #ifndef OPENSSL_NO_EC - { "EC:id-ecPublicKey", FIPS_DEFAULT_PROPERTIES, ec_keymgmt_functions }, - { "X25519", FIPS_DEFAULT_PROPERTIES, x25519_keymgmt_functions }, - { "X448", FIPS_DEFAULT_PROPERTIES, x448_keymgmt_functions }, - { "ED25519", FIPS_DEFAULT_PROPERTIES, ed25519_keymgmt_functions }, - { "ED448", FIPS_DEFAULT_PROPERTIES, ed448_keymgmt_functions }, + { "EC:id-ecPublicKey", FIPS_DEFAULT_PROPERTIES, ossl_ec_keymgmt_functions }, + { "X25519", FIPS_DEFAULT_PROPERTIES, ossl_x25519_keymgmt_functions }, + { "X448", FIPS_DEFAULT_PROPERTIES, ossl_x448_keymgmt_functions }, + { "ED25519", FIPS_DEFAULT_PROPERTIES, ossl_ed25519_keymgmt_functions }, + { "ED448", FIPS_DEFAULT_PROPERTIES, ossl_ed448_keymgmt_functions }, +#endif + { "TLS1-PRF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions }, + { "HKDF", FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions }, + { "HMAC", FIPS_DEFAULT_PROPERTIES, ossl_mac_legacy_keymgmt_functions }, +#ifndef OPENSSL_NO_CMAC + { "CMAC", FIPS_DEFAULT_PROPERTIES, + ossl_cossl_mac_legacy_keymgmt_functions }, #endif { NULL, NULL, NULL } }; @@ -444,11 +511,16 @@ static const OSSL_ALGORITHM *fips_query(void *provctx, int operation_id, int *no_cache) { *no_cache = 0; + + if (!ossl_prov_is_running()) + return NULL; + switch (operation_id) { case OSSL_OP_DIGEST: return fips_digests; case OSSL_OP_CIPHER: - ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers); + ossl_prov_cache_exported_algorithms(fips_ciphers, + exported_fips_ciphers); return exported_fips_ciphers; case OSSL_OP_MAC: return fips_macs; @@ -464,14 +536,16 @@ static const OSSL_ALGORITHM *fips_query(void *provctx, int operation_id, return fips_signature; case OSSL_OP_ASYM_CIPHER: return fips_asym_cipher; + case OSSL_OP_KEM: + return fips_asym_kem; } return NULL; } static void fips_teardown(void *provctx) { - OPENSSL_CTX_free(PROV_LIBRARY_CONTEXT_OF(provctx)); - PROV_CTX_free(provctx); + OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx)); + ossl_prov_ctx_free(provctx); } static void fips_intern_teardown(void *provctx) @@ -480,7 +554,7 @@ static void fips_intern_teardown(void *provctx) * We know that the library context is the same as for the outer provider, * so no need to destroy it here. */ - PROV_CTX_free(provctx); + ossl_prov_ctx_free(provctx); } /* Functions we provide to the core */ @@ -489,7 +563,9 @@ static const OSSL_DISPATCH fips_dispatch_table[] = { { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))fips_gettable_params }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query }, - { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))provider_get_capabilities }, + { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, + (void (*)(void))provider_get_capabilities }, + { OSSL_FUNC_PROVIDER_SELF_TEST, (void (*)(void))fips_self_test }, { 0, NULL } }; @@ -500,21 +576,18 @@ static const OSSL_DISPATCH intern_dispatch_table[] = { { 0, NULL } }; - int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, void **provctx) { FIPS_GLOBAL *fgbl; - OPENSSL_CTX *libctx = NULL; - OSSL_FUNC_self_test_cb_fn *stcbfn = NULL; - OSSL_FUNC_core_get_library_context_fn *c_get_libctx = NULL; + OSSL_LIB_CTX *libctx = NULL; for (; in->function_id != 0; in++) { switch (in->function_id) { - case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT: - c_get_libctx = OSSL_FUNC_core_get_library_context(in); + case OSSL_FUNC_CORE_GET_LIBCTX: + c_get_libctx = OSSL_FUNC_core_get_libctx(in); break; case OSSL_FUNC_CORE_GETTABLE_PARAMS: c_gettable_params = OSSL_FUNC_core_gettable_params(in); @@ -592,7 +665,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, c_BIO_vsnprintf = OSSL_FUNC_BIO_vsnprintf(in); break; case OSSL_FUNC_SELF_TEST_CB: { - stcbfn = OSSL_FUNC_self_test_cb(in); + c_stcbfn = OSSL_FUNC_self_test_cb(in); break; } default: @@ -601,36 +674,38 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, } } - if (stcbfn != NULL && c_get_libctx != NULL) { - stcbfn(c_get_libctx(handle), &selftest_params.cb, - &selftest_params.cb_arg); - } - else { - selftest_params.cb = NULL; - selftest_params.cb_arg = NULL; - } + set_self_test_cb(handle); if (!c_get_params(handle, core_params)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } + /* Disable the conditional error check if is disabled in the fips config file*/ + if (selftest_params.conditional_error_check != NULL + && strcmp(selftest_params.conditional_error_check, "0") == 0) + SELF_TEST_disable_conditional_error_state(); + + /* Disable the security check if is disabled in the fips config file*/ + if (fips_security_check_option != NULL + && strcmp(fips_security_check_option, "0") == 0) + fips_security_checks = 0; /* Create a context. */ - if ((*provctx = PROV_CTX_new()) == NULL - || (libctx = OPENSSL_CTX_new()) == NULL) { + if ((*provctx = ossl_prov_ctx_new()) == NULL + || (libctx = OSSL_LIB_CTX_new()) == NULL) { /* * We free libctx separately here and only here because it hasn't * been attached to *provctx. All other error paths below rely * solely on fips_teardown. */ - OPENSSL_CTX_free(libctx); + OSSL_LIB_CTX_free(libctx); goto err; } - PROV_CTX_set0_library_context(*provctx, libctx); - PROV_CTX_set0_handle(*provctx, handle); + ossl_prov_ctx_set0_libctx(*provctx, libctx); + ossl_prov_ctx_set0_handle(*provctx, handle); - if ((fgbl = openssl_ctx_get_data(libctx, OPENSSL_CTX_FIPS_PROV_INDEX, - &fips_prov_ossl_ctx_method)) == NULL) + if ((fgbl = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_FIPS_PROV_INDEX, + &fips_prov_ossl_ctx_method)) == NULL) goto err; fgbl->handle = handle; @@ -642,7 +717,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, } /* TODO(3.0): Tests will hang if this is removed */ - (void)OPENSSL_CTX_get0_public_drbg(libctx); + (void)RAND_get0_public(libctx); *out = fips_dispatch_table; return 1; @@ -665,30 +740,32 @@ int fips_intern_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH **out, void **provctx) { - OSSL_FUNC_core_get_library_context_fn *c_get_libctx = NULL; + OSSL_FUNC_core_get_libctx_fn *c_internal_get_libctx = NULL; for (; in->function_id != 0; in++) { switch (in->function_id) { - case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT: - c_get_libctx = OSSL_FUNC_core_get_library_context(in); + case OSSL_FUNC_CORE_GET_LIBCTX: + c_internal_get_libctx = OSSL_FUNC_core_get_libctx(in); break; default: break; } } - if (c_get_libctx == NULL) + if (c_internal_get_libctx == NULL) return 0; - if ((*provctx = PROV_CTX_new()) == NULL) + if ((*provctx = ossl_prov_ctx_new()) == NULL) return 0; + /* * Using the parent library context only works because we are a built-in * internal provider. This is not something that most providers would be * able to do. */ - PROV_CTX_set0_library_context(*provctx, (OPENSSL_CTX *)c_get_libctx(handle)); - PROV_CTX_set0_handle(*provctx, handle); + ossl_prov_ctx_set0_libctx(*provctx, + (OSSL_LIB_CTX *)c_internal_get_libctx(handle)); + ossl_prov_ctx_set0_handle(*provctx, handle); *out = intern_dispatch_table; return 1; @@ -736,15 +813,15 @@ int ERR_pop_to_mark(void) /* * This must take a library context, since it's called from the depths * of crypto/initthread.c code, where it's (correctly) assumed that the - * passed caller argument is an OPENSSL_CTX pointer (since the same routine + * passed caller argument is an OSSL_LIB_CTX pointer (since the same routine * is also called from other parts of libcrypto, which all pass around a - * OPENSSL_CTX pointer) + * OSSL_LIB_CTX pointer) */ -const OSSL_CORE_HANDLE *FIPS_get_core_handle(OPENSSL_CTX *libctx) +const OSSL_CORE_HANDLE *FIPS_get_core_handle(OSSL_LIB_CTX *libctx) { - FIPS_GLOBAL *fgbl = openssl_ctx_get_data(libctx, - OPENSSL_CTX_FIPS_PROV_INDEX, - &fips_prov_ossl_ctx_method); + FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx, + OSSL_LIB_CTX_FIPS_PROV_INDEX, + &fips_prov_ossl_ctx_method); if (fgbl == NULL) return NULL; @@ -818,3 +895,25 @@ int BIO_snprintf(char *buf, size_t n, const char *format, ...) va_end(args); return ret; } + +int FIPS_security_check_enabled(void) +{ + return fips_security_checks; +} + +void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, + void **cbarg) +{ + if (libctx == NULL) + libctx = selftest_params.libctx; + + if (c_stcbfn != NULL && c_get_libctx != NULL) { + /* Get the parent libctx */ + c_stcbfn(c_get_libctx(FIPS_get_core_handle(libctx)), cb, cbarg); + } else { + if (cb != NULL) + *cb = NULL; + if (cbarg != NULL) + *cbarg = NULL; + } +} diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c index 8902510b44..4d8e640c38 100644 --- a/providers/fips/self_test.c +++ b/providers/fips/self_test.c @@ -15,11 +15,13 @@ #include #include "e_os.h" #include "prov/providercommonerr.h" +#include "prov/providercommon.h" + /* * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS * module because all such initialisation should be associated with an - * individual OPENSSL_CTX. That doesn't work with the self test though because - * it should be run once regardless of the number of OPENSSL_CTXs we have. + * individual OSSL_LIB_CTX. That doesn't work with the self test though because + * it should be run once regardless of the number of OSSL_LIB_CTXs we have. */ #define ALLOW_RUN_ONCE_IN_FIPS #include @@ -30,12 +32,19 @@ #define FIPS_STATE_RUNNING 2 #define FIPS_STATE_ERROR 3 +/* + * The number of times the module will report it is in the error state + * before going quiet. + */ +#define FIPS_ERROR_REPORTING_RATE_LIMIT 10 + /* The size of a temp buffer used to read in data */ #define INTEGRITY_BUF_SIZE (4096) #define MAX_MD_SIZE 64 #define MAC_NAME "HMAC" #define DIGEST_NAME "SHA256" +static int FIPS_conditional_error_check = 1; static int FIPS_state = FIPS_STATE_INIT; static CRYPTO_RWLOCK *self_test_lock = NULL; static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS }; @@ -114,6 +123,22 @@ DEP_DECLARE() #elif defined(__GNUC__) # define DEP_INIT_ATTRIBUTE static __attribute__((constructor)) # define DEP_FINI_ATTRIBUTE static __attribute__((destructor)) + +#elif defined(__TANDEM) +DEP_DECLARE() /* must be declared before calling init() or cleanup() */ +# define DEP_INIT_ATTRIBUTE +# define DEP_FINI_ATTRIBUTE + +/* Method automatically called by the NonStop OS when the DLL loads */ +void __INIT__init(void) { + init(); +} + +/* Method automatically called by the NonStop OS prior to unloading the DLL */ +void __TERM__cleanup(void) { + cleanup(); +} + #endif #if defined(DEP_INIT_ATTRIBUTE) && defined(DEP_FINI_ATTRIBUTE) @@ -135,7 +160,7 @@ DEP_FINI_ATTRIBUTE void cleanup(void) */ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb, unsigned char *expected, size_t expected_len, - OPENSSL_CTX *libctx, OSSL_SELF_TEST *ev, + OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev, const char *event_type) { int ret = 0, status; @@ -149,8 +174,10 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC); mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL); + if (mac == NULL) + goto err; ctx = EVP_MAC_CTX_new(mac); - if (mac == NULL || ctx == NULL) + if (ctx == NULL) goto err; *p++ = OSSL_PARAM_construct_utf8_string("digest", DIGEST_NAME, @@ -300,8 +327,43 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) (*st->bio_free_cb)(bio_indicator); (*st->bio_free_cb)(bio_module); } - FIPS_state = ok ? FIPS_STATE_RUNNING : FIPS_STATE_ERROR; + if (ok) + FIPS_state = FIPS_STATE_RUNNING; + else + ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE); CRYPTO_THREAD_unlock(self_test_lock); return ok; } + +void SELF_TEST_disable_conditional_error_state(void) +{ + FIPS_conditional_error_check = 0; +} + +void ossl_set_error_state(const char *type) +{ + int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0); + + if (!cond_test || (FIPS_conditional_error_check == 1)) { + FIPS_state = FIPS_STATE_ERROR; + ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE); + } else { + ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR); + } +} + +int ossl_prov_is_running(void) +{ + const int res = FIPS_state == FIPS_STATE_RUNNING + || FIPS_state == FIPS_STATE_SELFTEST; + static unsigned int rate_limit = 0; + + if (res) { + rate_limit = 0; + } else if (FIPS_state == FIPS_STATE_ERROR) { + if (rate_limit++ < FIPS_ERROR_REPORTING_RATE_LIMIT) + ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE); + } + return res; +} diff --git a/providers/fips/self_test.h b/providers/fips/self_test.h index 20f8a12472..ff5928eeb4 100644 --- a/providers/fips/self_test.h +++ b/providers/fips/self_test.h @@ -21,6 +21,9 @@ typedef struct self_test_post_params_st { const char *indicator_data; /* data to perform MAC on */ const char *indicator_checksum_data; /* Expected MAC integrity value */ + /* Used for continuous tests */ + const char *conditional_error_check; + /* BIO callbacks supplied to the FIPS provider */ OSSL_FUNC_BIO_new_file_fn *bio_new_file_cb; OSSL_FUNC_BIO_new_membuf_fn *bio_new_buffer_cb; @@ -28,9 +31,11 @@ typedef struct self_test_post_params_st { OSSL_FUNC_BIO_free_fn *bio_free_cb; OSSL_CALLBACK *cb; void *cb_arg; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; } SELF_TEST_POST_PARAMS; int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test); -int SELF_TEST_kats(OSSL_SELF_TEST *event, OPENSSL_CTX *libctx); +int SELF_TEST_kats(OSSL_SELF_TEST *event, OSSL_LIB_CTX *libctx); + +void SELF_TEST_disable_conditional_error_state(void); diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc index 17bfc950db..8a4b6fcee0 100644 --- a/providers/fips/self_test_data.inc +++ b/providers/fips/self_test_data.inc @@ -101,6 +101,18 @@ typedef struct st_kat_sign_st { size_t sig_expected_len; } ST_KAT_SIGN; +typedef struct st_kat_asym_cipher_st { + const char *desc; + const char *algorithm; + int encrypt; + const ST_KAT_PARAM *key; + const ST_KAT_PARAM *postinit; + const unsigned char *in; + size_t in_len; + const unsigned char *expected; + size_t expected_len; +} ST_KAT_ASYM_CIPHER; + /*- DIGEST TEST DATA */ static const unsigned char sha1_pt[] = "abc"; static const unsigned char sha1_digest[] = { @@ -943,7 +955,7 @@ static const unsigned char rsa_qInv[] = { 0xF8, 0xF3, 0x95, 0xFE, 0x31, 0x25, 0x50, 0x12 }; -static const ST_KAT_PARAM rsa_key[] = { +static const ST_KAT_PARAM rsa_crt_key[] = { ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e), ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_D, rsa_d), @@ -955,6 +967,25 @@ static const ST_KAT_PARAM rsa_key[] = { ST_KAT_PARAM_END() }; +static const ST_KAT_PARAM rsa_pub_key[] = { + ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n), + ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e), + ST_KAT_PARAM_END() +}; + +static const ST_KAT_PARAM rsa_priv_key[] = { + ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_N, rsa_n), + ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_E, rsa_e), + ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_RSA_D, rsa_d), + ST_KAT_PARAM_END() +}; + +static const ST_KAT_PARAM rsa_enc_params[] = { + ST_KAT_PARAM_UTF8STRING(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, + OSSL_PKEY_RSA_PAD_MODE_NONE), + ST_KAT_PARAM_END() +}; + static const unsigned char rsa_expected_sig[256] = { 0xad, 0xbe, 0x2a, 0xaf, 0x16, 0x85, 0xc5, 0x00, 0x91, 0x3e, 0xd0, 0x49, 0xfb, 0x3a, 0x81, 0xb9, @@ -990,6 +1021,45 @@ static const unsigned char rsa_expected_sig[256] = { 0x2c, 0x68, 0xf0, 0x37, 0xa9, 0xd2, 0x56, 0xd6 }; +static const unsigned char rsa_asym_plaintext_encrypt[256] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, +}; +static const unsigned char rsa_asym_expected_encrypt[256] = { + 0x54, 0xac, 0x23, 0x96, 0x1d, 0x82, 0x5d, 0x8b, + 0x8f, 0x36, 0x33, 0xd0, 0xf4, 0x02, 0xa2, 0x61, + 0xb1, 0x13, 0xd4, 0x4a, 0x46, 0x06, 0x37, 0x3c, + 0xbf, 0x40, 0x05, 0x3c, 0xc6, 0x3b, 0x64, 0xdc, + 0x22, 0x22, 0xaf, 0x36, 0x79, 0x62, 0x45, 0xf0, + 0x97, 0x82, 0x22, 0x44, 0x86, 0x4a, 0x7c, 0xfa, + 0xac, 0x03, 0x21, 0x84, 0x3f, 0x31, 0xad, 0x2a, + 0xa4, 0x6e, 0x7a, 0xc5, 0x93, 0xf3, 0x0f, 0xfc, + 0xf1, 0x62, 0xce, 0x82, 0x12, 0x45, 0xc9, 0x35, + 0xb0, 0x7a, 0xcd, 0x99, 0x8c, 0x91, 0x6b, 0x5a, + 0xd3, 0x46, 0xdb, 0xf9, 0x9e, 0x52, 0x49, 0xbd, + 0x1e, 0xe8, 0xda, 0xac, 0x61, 0x47, 0xc2, 0xda, + 0xfc, 0x1e, 0xfb, 0x74, 0xd7, 0xd6, 0xc1, 0x18, + 0x86, 0x3e, 0x20, 0x9c, 0x7a, 0xe1, 0x04, 0xb7, + 0x38, 0x43, 0xb1, 0x4e, 0xa0, 0xd8, 0xc1, 0x39, + 0x4d, 0xe1, 0xd3, 0xb0, 0xb3, 0xf1, 0x82, 0x87, + 0x1f, 0x74, 0xb5, 0x69, 0xfd, 0x33, 0xd6, 0x21, + 0x7c, 0x61, 0x60, 0x28, 0xca, 0x70, 0xdb, 0xa0, + 0xbb, 0xc8, 0x73, 0xa9, 0x82, 0xf8, 0x6b, 0xd8, + 0xf0, 0xc9, 0x7b, 0x20, 0xdf, 0x9d, 0xfb, 0x8c, + 0xd4, 0xa2, 0x89, 0xe1, 0x9b, 0x04, 0xad, 0xaa, + 0x11, 0x6c, 0x8f, 0xce, 0x83, 0x29, 0x56, 0x69, + 0xbb, 0x00, 0x3b, 0xef, 0xca, 0x2d, 0xcd, 0x52, + 0xc8, 0xf1, 0xb3, 0x9b, 0xb4, 0x4f, 0x6d, 0x9c, + 0x3d, 0x69, 0xcc, 0x6d, 0x1f, 0x38, 0x4d, 0xe6, + 0xbb, 0x0c, 0x87, 0xdc, 0x5f, 0xa9, 0x24, 0x93, + 0x03, 0x46, 0xa2, 0x33, 0x6c, 0xf4, 0xd8, 0x5d, + 0x68, 0xf3, 0xd3, 0xe0, 0xf2, 0x30, 0xdb, 0xf5, + 0x4f, 0x0f, 0xad, 0xc7, 0xd0, 0xaa, 0x47, 0xd9, + 0x9f, 0x85, 0x1b, 0x2e, 0x6c, 0x3c, 0x57, 0x04, + 0x29, 0xf4, 0xf5, 0x66, 0x7d, 0x93, 0x4a, 0xaa, + 0x05, 0x52, 0x55, 0xc1, 0xc6, 0x06, 0x90, 0xab, +}; + #endif /* OPENSSL_NO_RSA */ #ifndef OPENSSL_NO_EC @@ -1153,7 +1223,7 @@ static const ST_KAT_SIGN st_kat_sign_tests[] = { OSSL_SELF_TEST_DESC_SIGN_RSA, "RSA", "SHA-256", - rsa_key, + rsa_crt_key, ITM(rsa_expected_sig) }, #endif /* OPENSSL_NO_RSA */ @@ -1182,3 +1252,35 @@ static const ST_KAT_SIGN st_kat_sign_tests[] = { }, #endif /* OPENSSL_NO_DSA */ }; + +static const ST_KAT_ASYM_CIPHER st_kat_asym_cipher_tests[] = { +#ifndef OPENSSL_NO_RSA + { + OSSL_SELF_TEST_DESC_ASYM_RSA_ENC, + "RSA", + 1, + rsa_pub_key, + rsa_enc_params, + ITM(rsa_asym_plaintext_encrypt), + ITM(rsa_asym_expected_encrypt), + }, + { + OSSL_SELF_TEST_DESC_ASYM_RSA_DEC, + "RSA", + 0, + rsa_priv_key, + rsa_enc_params, + ITM(rsa_asym_expected_encrypt), + ITM(rsa_asym_plaintext_encrypt), + }, + { + OSSL_SELF_TEST_DESC_ASYM_RSA_DEC, + "RSA", + 0, + rsa_crt_key, + rsa_enc_params, + ITM(rsa_asym_expected_encrypt), + ITM(rsa_asym_plaintext_encrypt), + }, +#endif /* OPENSSL_NO_RSA */ +}; diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c index 8c88f8be5d..c61646aafe 100644 --- a/providers/fips/self_test_kats.c +++ b/providers/fips/self_test_kats.c @@ -18,7 +18,7 @@ #include "self_test_data.inc" static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { int ok = 0; unsigned char out[EVP_MAX_MD_SIZE]; @@ -83,7 +83,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, /* Test a single KAT for encrypt/decrypt */ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { int ret = 0, encrypt = 1, len, ct_len = 0, pt_len = 0; EVP_CIPHER_CTX *ctx = NULL; @@ -179,7 +179,7 @@ static int add_params(OSSL_PARAM_BLD *bld, const ST_KAT_PARAM *params, } static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { int ret = 0; unsigned char out[64]; @@ -236,7 +236,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, } static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { int ret = 0; unsigned char out[256]; @@ -315,7 +315,10 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, if (!EVP_RAND_set_ctx_params(test, drbg_params)) goto err; - /* This calls RAND_DRBG_reseed() internally when prediction_resistance = 1 */ + /* + * This calls ossl_prov_drbg_reseed() internally when + * prediction_resistance = 1 + */ if (!EVP_RAND_generate(drbg, out, t->expectedlen, strength, prediction_resistance, t->entropyaddin2, t->entropyaddin2len)) @@ -329,7 +332,8 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, if (!EVP_RAND_uninstantiate(drbg)) goto err; /* - * Check that the DRBG data has been zeroized after RAND_DRBG_uninstantiate. + * Check that the DRBG data has been zeroized after + * ossl_prov_drbg_uninstantiate. */ if (!EVP_RAND_verify_zeroization(drbg)) goto err; @@ -342,10 +346,8 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st, return ret; } - - static int self_test_ka(const ST_KAT_KAS *t, - OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) + OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int ret = 0; EVP_PKEY_CTX *kactx = NULL, *dctx = NULL; @@ -421,7 +423,7 @@ static int self_test_ka(const ST_KAT_KAS *t, } static int self_test_sign(const ST_KAT_SIGN *t, - OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) + OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int ret = 0; OSSL_PARAM *params = NULL, *params_sig = NULL; @@ -504,12 +506,99 @@ static int self_test_sign(const ST_KAT_SIGN *t, return ret; } +/* + * Test an encrypt or decrypt KAT.. + * + * FIPS 140-2 IG D.9 states that separate KAT tests are needed for encrypt + * and decrypt.. + */ +static int self_test_asym_cipher(const ST_KAT_ASYM_CIPHER *t, OSSL_SELF_TEST *st, + OSSL_LIB_CTX *libctx) +{ + int ret = 0; + OSSL_PARAM *keyparams = NULL, *initparams = NULL; + OSSL_PARAM_BLD *keybld = NULL, *initbld = NULL; + EVP_PKEY_CTX *encctx = NULL, *keyctx = NULL; + EVP_PKEY *key = NULL; + BN_CTX *bnctx = NULL; + unsigned char out[256]; + size_t outlen = sizeof(out); + + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_ASYM_CIPHER, t->desc); + + bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) + goto err; + + /* Load a public or private key from data */ + keybld = OSSL_PARAM_BLD_new(); + if (keybld == NULL + || !add_params(keybld, t->key, bnctx)) + goto err; + keyparams = OSSL_PARAM_BLD_to_param(keybld); + keyctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, NULL); + if (keyctx == NULL || keyparams == NULL) + goto err; + if (EVP_PKEY_key_fromdata_init(keyctx) <= 0 + || EVP_PKEY_fromdata(keyctx, &key, keyparams) <= 0) + goto err; + + /* Create a EVP_PKEY_CTX to use for the encrypt or decrypt operation */ + encctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL); + if (encctx == NULL + || (t->encrypt && EVP_PKEY_encrypt_init(encctx) <= 0) + || (!t->encrypt && EVP_PKEY_decrypt_init(encctx) <= 0)) + goto err; + + /* Add any additional parameters such as padding */ + if (t->postinit != NULL) { + initbld = OSSL_PARAM_BLD_new(); + if (initbld == NULL) + goto err; + if (!add_params(initbld, t->postinit, bnctx)) + goto err; + initparams = OSSL_PARAM_BLD_to_param(initbld); + if (initparams == NULL) + goto err; + if (EVP_PKEY_CTX_set_params(encctx, initparams) <= 0) + goto err; + } + + if (t->encrypt) { + if (EVP_PKEY_encrypt(encctx, out, &outlen, + t->in, t->in_len) <= 0) + goto err; + } else { + if (EVP_PKEY_decrypt(encctx, out, &outlen, + t->in, t->in_len) <= 0) + goto err; + } + /* Check the KAT */ + OSSL_SELF_TEST_oncorrupt_byte(st, out); + if (outlen != t->expected_len + || memcmp(out, t->expected, t->expected_len) != 0) + goto err; + + ret = 1; +err: + BN_CTX_free(bnctx); + EVP_PKEY_free(key); + EVP_PKEY_CTX_free(encctx); + EVP_PKEY_CTX_free(keyctx); + OSSL_PARAM_BLD_free_params(keyparams); + OSSL_PARAM_BLD_free(keybld); + OSSL_PARAM_BLD_free_params(initparams); + OSSL_PARAM_BLD_free(initbld); + OSSL_SELF_TEST_onend(st, ret); + return ret; +} + /* * Test a data driven list of KAT's for digest algorithms. * All tests are run regardless of if they fail or not. * Return 0 if any test fails. */ -static int self_test_digests(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +static int self_test_digests(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int i, ret = 1; @@ -520,7 +609,7 @@ static int self_test_digests(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) return ret; } -static int self_test_ciphers(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +static int self_test_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int i, ret = 1; @@ -531,7 +620,18 @@ static int self_test_ciphers(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) return ret; } -static int self_test_kdfs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +static int self_test_asym_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) +{ + int i, ret = 1; + + for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_cipher_tests); ++i) { + if (!self_test_asym_cipher(&st_kat_asym_cipher_tests[i], st, libctx)) + ret = 0; + } + return ret; +} + +static int self_test_kdfs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int i, ret = 1; @@ -542,7 +642,7 @@ static int self_test_kdfs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) return ret; } -static int self_test_drbgs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +static int self_test_drbgs(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int i, ret = 1; @@ -553,7 +653,7 @@ static int self_test_drbgs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) return ret; } -static int self_test_kas(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +static int self_test_kas(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int i, ret = 1; @@ -564,7 +664,7 @@ static int self_test_kas(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) return ret; } -static int self_test_signatures(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int i, ret = 1; @@ -580,7 +680,7 @@ static int self_test_signatures(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) * Return 1 is successful, otherwise return 0. * This runs all the tests regardless of if any fail. */ -int SELF_TEST_kats(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) +int SELF_TEST_kats(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx) { int ret = 1; @@ -596,6 +696,8 @@ int SELF_TEST_kats(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx) ret = 0; if (!self_test_kas(st, libctx)) ret = 0; + if (!self_test_asym_ciphers(st, libctx)) + ret = 0; return ret; } diff --git a/providers/implementations/asymciphers/build.info b/providers/implementations/asymciphers/build.info index b4033d8a7d..4b629d04ee 100644 --- a/providers/implementations/asymciphers/build.info +++ b/providers/implementations/asymciphers/build.info @@ -2,5 +2,10 @@ # switch each to the Legacy provider when needed. $RSA_GOAL=../../libimplementations.a +$SM2_GOAL=../../libimplementations.a SOURCE[$RSA_GOAL]=rsa_enc.c + +IF[{- !$disabled{"sm2"} -}] + SOURCE[$SM2_GOAL]=sm2_enc.c +ENDIF diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index 8a5cd5cdc3..1287cc303a 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -28,13 +28,15 @@ #include "prov/providercommonerr.h" #include "prov/provider_ctx.h" #include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/securitycheck.h" #include static OSSL_FUNC_asym_cipher_newctx_fn rsa_newctx; -static OSSL_FUNC_asym_cipher_encrypt_init_fn rsa_init; +static OSSL_FUNC_asym_cipher_encrypt_init_fn rsa_encrypt_init; static OSSL_FUNC_asym_cipher_encrypt_fn rsa_encrypt; -static OSSL_FUNC_asym_cipher_decrypt_init_fn rsa_init; +static OSSL_FUNC_asym_cipher_decrypt_init_fn rsa_decrypt_init; static OSSL_FUNC_asym_cipher_decrypt_fn rsa_decrypt; static OSSL_FUNC_asym_cipher_freectx_fn rsa_freectx; static OSSL_FUNC_asym_cipher_dupctx_fn rsa_dupctx; @@ -60,9 +62,10 @@ static OSSL_ITEM padding_item[] = { */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; RSA *rsa; int pad_mode; + int operation; /* OAEP message digest */ EVP_MD *oaep_md; /* message digest for MGF1 */ @@ -77,23 +80,30 @@ typedef struct { static void *rsa_newctx(void *provctx) { - PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); + PROV_RSA_CTX *prsactx; + if (!ossl_prov_is_running()) + return NULL; + prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); if (prsactx == NULL) return NULL; - prsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + prsactx->libctx = PROV_LIBCTX_OF(provctx); return prsactx; } -static int rsa_init(void *vprsactx, void *vrsa) +static int rsa_init(void *vprsactx, void *vrsa, int operation) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - if (prsactx == NULL || vrsa == NULL || !RSA_up_ref(vrsa)) + if (!ossl_prov_is_running() + || prsactx == NULL + || vrsa == NULL + || !RSA_up_ref(vrsa)) return 0; RSA_free(prsactx->rsa); prsactx->rsa = vrsa; + prsactx->operation = operation; switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: @@ -103,16 +113,32 @@ static int rsa_init(void *vprsactx, void *vrsa) ERR_raise(ERR_LIB_PROV, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return 0; } - + if (!ossl_rsa_check_key(vrsa, operation == EVP_PKEY_OP_ENCRYPT)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } return 1; } +static int rsa_encrypt_init(void *vprsactx, void *vrsa) +{ + return rsa_init(vprsactx, vrsa, EVP_PKEY_OP_ENCRYPT); +} + +static int rsa_decrypt_init(void *vprsactx, void *vrsa) +{ + return rsa_init(vprsactx, vrsa, EVP_PKEY_OP_DECRYPT); +} + static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, size_t outsize, const unsigned char *in, size_t inlen) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; int ret; + if (!ossl_prov_is_running()) + return 0; + if (out == NULL) { size_t len = RSA_size(prsactx->rsa); @@ -139,12 +165,12 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, return 0; } ret = - rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(prsactx->libctx, tbuf, - rsasize, in, inlen, - prsactx->oaep_label, - prsactx->oaep_labellen, - prsactx->oaep_md, - prsactx->mgf1_md); + ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(prsactx->libctx, tbuf, + rsasize, in, inlen, + prsactx->oaep_label, + prsactx->oaep_labellen, + prsactx->oaep_md, + prsactx->mgf1_md); if (!ret) { OPENSSL_free(tbuf); @@ -171,6 +197,9 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, int ret; size_t len = RSA_size(prsactx->rsa); + if (!ossl_prov_is_running()) + return 0; + if (prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { if (out == NULL) { *outlen = SSL_MAX_MASTER_KEY_LENGTH; @@ -235,11 +264,9 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, ERR_raise(ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION); return 0; } - ret = rsa_padding_check_PKCS1_type_2_TLS(prsactx->libctx, out, - outsize, - tbuf, len, - prsactx->client_version, - prsactx->alt_version); + ret = ossl_rsa_padding_check_PKCS1_type_2_TLS( + prsactx->libctx, out, outsize, tbuf, len, + prsactx->client_version, prsactx->alt_version); } OPENSSL_free(tbuf); } else { @@ -269,6 +296,9 @@ static void *rsa_dupctx(void *vprsactx) PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; PROV_RSA_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; @@ -382,7 +412,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_gettable_ctx_params(void) +static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -526,16 +556,16 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_settable_ctx_params(void) +static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } -const OSSL_DISPATCH rsa_asym_cipher_functions[] = { +const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[] = { { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))rsa_newctx }, - { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_init }, + { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_encrypt_init }, { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))rsa_encrypt }, - { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_init }, + { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_decrypt_init }, { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))rsa_decrypt }, { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))rsa_freectx }, { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))rsa_dupctx }, diff --git a/providers/implementations/asymciphers/sm2_enc.c b/providers/implementations/asymciphers/sm2_enc.c new file mode 100644 index 0000000000..a67e2c26e4 --- /dev/null +++ b/providers/implementations/asymciphers/sm2_enc.c @@ -0,0 +1,225 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "prov/providercommonerr.h" +#include "prov/provider_ctx.h" +#include "prov/implementations.h" +#include "prov/provider_util.h" + +static OSSL_FUNC_asym_cipher_newctx_fn sm2_newctx; +static OSSL_FUNC_asym_cipher_encrypt_init_fn sm2_init; +static OSSL_FUNC_asym_cipher_encrypt_fn sm2_asym_encrypt; +static OSSL_FUNC_asym_cipher_decrypt_init_fn sm2_init; +static OSSL_FUNC_asym_cipher_decrypt_fn sm2_asym_decrypt; +static OSSL_FUNC_asym_cipher_freectx_fn sm2_freectx; +static OSSL_FUNC_asym_cipher_dupctx_fn sm2_dupctx; +static OSSL_FUNC_asym_cipher_get_ctx_params_fn sm2_get_ctx_params; +static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn sm2_gettable_ctx_params; +static OSSL_FUNC_asym_cipher_set_ctx_params_fn sm2_set_ctx_params; +static OSSL_FUNC_asym_cipher_settable_ctx_params_fn sm2_settable_ctx_params; + +/* + * What's passed as an actual key is defined by the KEYMGMT interface. + * We happen to know that our KEYMGMT simply passes EC_KEY structures, so + * we use that here too. + */ + +typedef struct { + OSSL_LIB_CTX *libctx; + EC_KEY *key; + PROV_DIGEST md; +} PROV_SM2_CTX; + +static void *sm2_newctx(void *provctx) +{ + PROV_SM2_CTX *psm2ctx = OPENSSL_zalloc(sizeof(PROV_SM2_CTX)); + + if (psm2ctx == NULL) + return NULL; + psm2ctx->libctx = PROV_LIBCTX_OF(provctx); + + return psm2ctx; +} + +static int sm2_init(void *vpsm2ctx, void *vkey) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx == NULL || vkey == NULL || !EC_KEY_up_ref(vkey)) + return 0; + EC_KEY_free(psm2ctx->key); + psm2ctx->key = vkey; + + return 1; +} + +static const EVP_MD *sm2_get_md(PROV_SM2_CTX *psm2ctx) +{ + const EVP_MD *md = ossl_prov_digest_md(&psm2ctx->md); + + if (md == NULL) + md = ossl_prov_digest_fetch(&psm2ctx->md, psm2ctx->libctx, "SM3", NULL); + + return md; +} + +static int sm2_asym_encrypt(void *vpsm2ctx, unsigned char *out, size_t *outlen, + size_t outsize, const unsigned char *in, + size_t inlen) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + const EVP_MD *md = sm2_get_md(psm2ctx); + + if (md == NULL) + return 0; + + if (out == NULL) { + if (!sm2_ciphertext_size(psm2ctx->key, md, inlen, outlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + return 1; + } + + return sm2_encrypt(psm2ctx->key, md, in, inlen, out, outlen); +} + +static int sm2_asym_decrypt(void *vpsm2ctx, unsigned char *out, size_t *outlen, + size_t outsize, const unsigned char *in, + size_t inlen) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + const EVP_MD *md = sm2_get_md(psm2ctx); + + if (md == NULL) + return 0; + + if (out == NULL) { + if (!sm2_plaintext_size(psm2ctx->key, md, inlen, outlen)) + return 0; + return 1; + } + + return sm2_decrypt(psm2ctx->key, md, in, inlen, out, outlen); +} + +static void sm2_freectx(void *vpsm2ctx) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + EC_KEY_free(psm2ctx->key); + ossl_prov_digest_reset(&psm2ctx->md); + + OPENSSL_free(psm2ctx); +} + +static void *sm2_dupctx(void *vpsm2ctx) +{ + PROV_SM2_CTX *srcctx = (PROV_SM2_CTX *)vpsm2ctx; + PROV_SM2_CTX *dstctx; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + if (dstctx->key != NULL && !EC_KEY_up_ref(dstctx->key)) { + OPENSSL_free(dstctx); + return NULL; + } + + if (!ossl_prov_digest_copy(&dstctx->md, &srcctx->md)) { + sm2_freectx(dstctx); + return NULL; + } + + return dstctx; +} + +static int sm2_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + OSSL_PARAM *p; + + if (vpsm2ctx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_DIGEST); + if (p != NULL) { + const EVP_MD *md = ossl_prov_digest_md(&psm2ctx->md); + + if (!OSSL_PARAM_set_utf8_string(p, md == NULL ? "" + : EVP_MD_name(md))) + return 0; + } + + return 1; +} + +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *sm2_gettable_ctx_params(ossl_unused void *provctx) +{ + return known_gettable_ctx_params; +} + +static int sm2_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[]) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx == NULL || params == NULL) + return 0; + + if (!ossl_prov_digest_load_from_params(&psm2ctx->md, params, + psm2ctx->libctx)) + return 0; + + return 1; +} + +static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_ENGINE, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *sm2_settable_ctx_params(ossl_unused void *provctx) +{ + return known_settable_ctx_params; +} + +const OSSL_DISPATCH sm2_asym_cipher_functions[] = { + { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))sm2_newctx }, + { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))sm2_init }, + { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))sm2_asym_encrypt }, + { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))sm2_init }, + { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))sm2_asym_decrypt }, + { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))sm2_freectx }, + { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))sm2_dupctx }, + { OSSL_FUNC_ASYM_CIPHER_GET_CTX_PARAMS, + (void (*)(void))sm2_get_ctx_params }, + { OSSL_FUNC_ASYM_CIPHER_GETTABLE_CTX_PARAMS, + (void (*)(void))sm2_gettable_ctx_params }, + { OSSL_FUNC_ASYM_CIPHER_SET_CTX_PARAMS, + (void (*)(void))sm2_set_ctx_params }, + { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, + (void (*)(void))sm2_settable_ctx_params }, + { 0, NULL } +}; diff --git a/providers/implementations/build.info b/providers/implementations/build.info index 839478ef36..a2f60653e2 100644 --- a/providers/implementations/build.info +++ b/providers/implementations/build.info @@ -1,2 +1,2 @@ SUBDIRS=digests ciphers rands macs kdfs exchange keymgmt signature asymciphers \ - serializers + encode_decode storemgmt kem diff --git a/providers/implementations/ciphers/cipher_aes.c b/providers/implementations/ciphers/cipher_aes.c index b0c716e3b7..2f469c131a 100644 --- a/providers/implementations/ciphers/cipher_aes.c +++ b/providers/implementations/ciphers/cipher_aes.c @@ -18,6 +18,7 @@ #include "cipher_aes.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn aes_freectx; static OSSL_FUNC_cipher_dupctx_fn aes_dupctx; @@ -26,15 +27,19 @@ static void aes_freectx(void *vctx) { PROV_AES_CTX *ctx = (PROV_AES_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *aes_dupctx(void *ctx) { PROV_AES_CTX *in = (PROV_AES_CTX *)ctx; - PROV_AES_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_AES_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -44,47 +49,47 @@ static void *aes_dupctx(void *ctx) return ret; } -/* aes256ecb_functions */ +/* ossl_aes256ecb_functions */ IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 256, 128, 0, block) -/* aes192ecb_functions */ +/* ossl_aes192ecb_functions */ IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 192, 128, 0, block) -/* aes128ecb_functions */ +/* ossl_aes128ecb_functions */ IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 128, 128, 0, block) -/* aes256cbc_functions */ +/* ossl_aes256cbc_functions */ IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 256, 128, 128, block) -/* aes192cbc_functions */ +/* ossl_aes192cbc_functions */ IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 192, 128, 128, block) -/* aes128cbc_functions */ +/* ossl_aes128cbc_functions */ IMPLEMENT_generic_cipher(aes, AES, cbc, CBC, 0, 128, 128, 128, block) -/* aes256ofb_functions */ +/* ossl_aes256ofb_functions */ IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 256, 8, 128, stream) -/* aes192ofb_functions */ +/* ossl_aes192ofb_functions */ IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 192, 8, 128, stream) -/* aes128ofb_functions */ +/* ossl_aes128ofb_functions */ IMPLEMENT_generic_cipher(aes, AES, ofb, OFB, 0, 128, 8, 128, stream) -/* aes256cfb_functions */ +/* ossl_aes256cfb_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 256, 8, 128, stream) -/* aes192cfb_functions */ +/* ossl_aes192cfb_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 192, 8, 128, stream) -/* aes128cfb_functions */ +/* ossl_aes128cfb_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb, CFB, 0, 128, 8, 128, stream) -/* aes256cfb1_functions */ +/* ossl_aes256cfb1_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 256, 8, 128, stream) -/* aes192cfb1_functions */ +/* ossl_aes192cfb1_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 192, 8, 128, stream) -/* aes128cfb1_functions */ +/* ossl_aes128cfb1_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb1, CFB, 0, 128, 8, 128, stream) -/* aes256cfb8_functions */ +/* ossl_aes256cfb8_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 256, 8, 128, stream) -/* aes192cfb8_functions */ +/* ossl_aes192cfb8_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 192, 8, 128, stream) -/* aes128cfb8_functions */ +/* ossl_aes128cfb8_functions */ IMPLEMENT_generic_cipher(aes, AES, cfb8, CFB, 0, 128, 8, 128, stream) -/* aes256ctr_functions */ +/* ossl_aes256ctr_functions */ IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 256, 8, 128, stream) -/* aes192ctr_functions */ +/* ossl_aes192ctr_functions */ IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 192, 8, 128, stream) -/* aes128ctr_functions */ +/* ossl_aes128ctr_functions */ IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 128, 8, 128, stream) #include "cipher_aes_cts.inc" diff --git a/providers/implementations/ciphers/cipher_aes.h b/providers/implementations/ciphers/cipher_aes.h index f2ee746295..7eaf76c8c4 100644 --- a/providers/implementations/ciphers/cipher_aes.h +++ b/providers/implementations/ciphers/cipher_aes.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -51,12 +51,12 @@ typedef struct prov_aes_ctx_st { } PROV_AES_CTX; -#define PROV_CIPHER_HW_aes_ofb PROV_CIPHER_HW_aes_ofb128 -#define PROV_CIPHER_HW_aes_cfb PROV_CIPHER_HW_aes_cfb128 -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ofb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cfb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cfb1(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_cfb8(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ctr(size_t keybits); +#define ossl_prov_cipher_hw_aes_ofb ossl_prov_cipher_hw_aes_ofb128 +#define ossl_prov_cipher_hw_aes_cfb ossl_prov_cipher_hw_aes_cfb128 +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ofb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb1(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_cfb8(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ctr(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c index 046a66c56d..1ff2a29590 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c @@ -16,12 +16,15 @@ /* Dispatch functions for AES_CBC_HMAC_SHA ciphers */ +/* Only for SSL3_VERSION and TLS1_VERSION */ +#include #include "cipher_aes_cbc_hmac_sha.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #ifndef AES_CBC_HMAC_SHA_CAPABLE # define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags) \ -const OSSL_DISPATCH nm##kbits##sub##_functions[] = { \ +const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = { \ { 0, NULL } \ }; #else @@ -39,12 +42,12 @@ static OSSL_FUNC_cipher_get_ctx_params_fn aes_get_ctx_params; static OSSL_FUNC_cipher_gettable_ctx_params_fn aes_gettable_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn aes_set_ctx_params; static OSSL_FUNC_cipher_settable_ctx_params_fn aes_settable_ctx_params; -# define aes_gettable_params cipher_generic_gettable_params -# define aes_einit cipher_generic_einit -# define aes_dinit cipher_generic_dinit -# define aes_update cipher_generic_stream_update -# define aes_final cipher_generic_stream_final -# define aes_cipher cipher_generic_cipher +# define aes_gettable_params ossl_cipher_generic_gettable_params +# define aes_einit ossl_cipher_generic_einit +# define aes_dinit ossl_cipher_generic_dinit +# define aes_update ossl_cipher_generic_stream_update +# define aes_final ossl_cipher_generic_stream_final +# define aes_cipher ossl_cipher_generic_cipher static const OSSL_PARAM cipher_aes_known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_MAC_KEY, NULL, 0), @@ -59,7 +62,7 @@ static const OSSL_PARAM cipher_aes_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *aes_settable_ctx_params(void) +const OSSL_PARAM *aes_settable_ctx_params(ossl_unused void *provctx) { return cipher_aes_known_settable_ctx_params; } @@ -172,6 +175,26 @@ static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; } } + + p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_TLS_VERSION); + if (p != NULL) { + if (!OSSL_PARAM_get_uint(p, &ctx->base.tlsversion)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (ctx->base.tlsversion == SSL3_VERSION + || ctx->base.tlsversion == TLS1_VERSION) { + if (!ossl_assert(ctx->base.removetlspad >= AES_BLOCK_SIZE)) { + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); + return 0; + } + /* + * There is no explicit IV with these TLS versions, so don't attempt + * to remove it. + */ + ctx->base.removetlspad -= AES_BLOCK_SIZE; + } + } return ret; } @@ -234,6 +257,12 @@ static int aes_get_ctx_params(void *vctx, OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV_STATE); + if (p != NULL + && !OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } return 1; } @@ -248,9 +277,10 @@ static const OSSL_PARAM cipher_aes_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV_STATE, NULL, 0), OSSL_PARAM_END }; -const OSSL_PARAM *aes_gettable_ctx_params(void) +const OSSL_PARAM *aes_gettable_ctx_params(ossl_unused void *provctx) { return cipher_aes_known_gettable_ctx_params; } @@ -260,9 +290,9 @@ static void base_init(void *provctx, PROV_AES_HMAC_SHA_CTX *ctx, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags) { - cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, - EVP_CIPH_CBC_MODE, flags, - &meths->base, provctx); + ossl_cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, + EVP_CIPH_CBC_MODE, flags, + &meths->base, provctx); ctx->hw = (PROV_CIPHER_HW_AES_HMAC_SHA *)ctx->base.hw; } @@ -270,11 +300,15 @@ static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags) { - PROV_AES_HMAC_SHA1_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_AES_HMAC_SHA1_CTX *ctx; + + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) base_init(provctx, &ctx->base_ctx, - PROV_CIPHER_HW_aes_cbc_hmac_sha1(), kbits, blkbits, + ossl_prov_cipher_hw_aes_cbc_hmac_sha1(), kbits, blkbits, ivbits, flags); return ctx; } @@ -284,7 +318,7 @@ static void aes_cbc_hmac_sha1_freectx(void *vctx) PROV_AES_HMAC_SHA1_CTX *ctx = (PROV_AES_HMAC_SHA1_CTX *)vctx; if (ctx != NULL) { - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } @@ -293,11 +327,15 @@ static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags) { - PROV_AES_HMAC_SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_AES_HMAC_SHA256_CTX *ctx; + + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) base_init(provctx, &ctx->base_ctx, - PROV_CIPHER_HW_aes_cbc_hmac_sha256(), kbits, blkbits, + ossl_prov_cipher_hw_aes_cbc_hmac_sha256(), kbits, blkbits, ivbits, flags); return ctx; } @@ -307,7 +345,7 @@ static void aes_cbc_hmac_sha256_freectx(void *vctx) PROV_AES_HMAC_SHA256_CTX *ctx = (PROV_AES_HMAC_SHA256_CTX *)vctx; if (ctx != NULL) { - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } @@ -321,10 +359,10 @@ static void *nm##_##kbits##_##sub##_newctx(void *provctx) \ static OSSL_FUNC_cipher_get_params_fn nm##_##kbits##_##sub##_get_params; \ static int nm##_##kbits##_##sub##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_CBC_MODE, \ - flags, kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_CBC_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ -const OSSL_DISPATCH nm##kbits##sub##_functions[] = { \ +const OSSL_DISPATCH ossl_##nm##kbits##sub##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))nm##_##kbits##_##sub##_newctx },\ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))nm##_##sub##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))nm##_einit }, \ @@ -349,11 +387,11 @@ const OSSL_DISPATCH nm##kbits##sub##_functions[] = { \ #endif /* AES_CBC_HMAC_SHA_CAPABLE */ -/* aes128cbc_hmac_sha1_functions */ +/* ossl_aes128cbc_hmac_sha1_functions */ IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS) -/* aes256cbc_hmac_sha1_functions */ +/* ossl_aes256cbc_hmac_sha1_functions */ IMPLEMENT_CIPHER(aes, cbc_hmac_sha1, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS) -/* aes128cbc_hmac_sha256_functions */ +/* ossl_aes128cbc_hmac_sha256_functions */ IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 128, 128, 128, AES_CBC_HMAC_SHA_FLAGS) -/* aes256cbc_hmac_sha256_functions */ +/* ossl_aes256cbc_hmac_sha256_functions */ IMPLEMENT_CIPHER(aes, cbc_hmac_sha256, 256, 128, 128, AES_CBC_HMAC_SHA_FLAGS) diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h index 73d39bbc42..6aaf3f06fb 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h @@ -10,8 +10,8 @@ #include "prov/ciphercommon.h" #include "crypto/aes_platform.h" -int cipher_capable_aes_cbc_hmac_sha1(void); -int cipher_capable_aes_cbc_hmac_sha256(void); +int ossl_cipher_capable_aes_cbc_hmac_sha1(void); +int ossl_cipher_capable_aes_cbc_hmac_sha256(void); typedef struct prov_cipher_hw_aes_hmac_sha_ctx_st { PROV_CIPHER_HW base; /* must be first */ @@ -26,8 +26,8 @@ typedef struct prov_cipher_hw_aes_hmac_sha_ctx_st { # endif /* OPENSSL_NO_MULTIBLOCK) */ } PROV_CIPHER_HW_AES_HMAC_SHA; -const PROV_CIPHER_HW_AES_HMAC_SHA *PROV_CIPHER_HW_aes_cbc_hmac_sha1(void); -const PROV_CIPHER_HW_AES_HMAC_SHA *PROV_CIPHER_HW_aes_cbc_hmac_sha256(void); +const PROV_CIPHER_HW_AES_HMAC_SHA *ossl_prov_cipher_hw_aes_cbc_hmac_sha1(void); +const PROV_CIPHER_HW_AES_HMAC_SHA *ossl_prov_cipher_hw_aes_cbc_hmac_sha256(void); #ifdef AES_CBC_HMAC_SHA_CAPABLE # include diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c index 12644e780f..f8db563d18 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c @@ -17,12 +17,12 @@ #include "cipher_aes_cbc_hmac_sha.h" #if !defined(AES_CBC_HMAC_SHA_CAPABLE) || !defined(AESNI_CAPABLE) -int cipher_capable_aes_cbc_hmac_sha1(void) +int ossl_cipher_capable_aes_cbc_hmac_sha1(void) { return 0; } -const PROV_CIPHER_HW_AES_HMAC_SHA *PROV_CIPHER_HW_aes_cbc_hmac_sha1(void) +const PROV_CIPHER_HW_AES_HMAC_SHA *ossl_prov_cipher_hw_aes_cbc_hmac_sha1(void) { return NULL; } @@ -37,7 +37,7 @@ void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks, const AES_KEY *key, unsigned char iv[16], SHA_CTX *ctx, const void *in0); -int cipher_capable_aes_cbc_hmac_sha1(void) +int ossl_cipher_capable_aes_cbc_hmac_sha1(void) { return AESNI_CBC_HMAC_SHA_CAPABLE; } @@ -788,7 +788,7 @@ static const PROV_CIPHER_HW_AES_HMAC_SHA cipher_hw_aes_hmac_sha1 = { # endif }; -const PROV_CIPHER_HW_AES_HMAC_SHA *PROV_CIPHER_HW_aes_cbc_hmac_sha1(void) +const PROV_CIPHER_HW_AES_HMAC_SHA *ossl_prov_cipher_hw_aes_cbc_hmac_sha1(void) { return &cipher_hw_aes_hmac_sha1; } diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c index 35106e0171..8587c414cd 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c @@ -17,12 +17,12 @@ #include "cipher_aes_cbc_hmac_sha.h" #if !defined(AES_CBC_HMAC_SHA_CAPABLE) || !defined(AESNI_CAPABLE) -int cipher_capable_aes_cbc_hmac_sha256(void) +int ossl_cipher_capable_aes_cbc_hmac_sha256(void) { return 0; } -const PROV_CIPHER_HW_AES_HMAC_SHA *PROV_CIPHER_HW_aes_cbc_hmac_sha256(void) +const PROV_CIPHER_HW_AES_HMAC_SHA *ossl_prov_cipher_hw_aes_cbc_hmac_sha256(void) { return NULL; } @@ -37,7 +37,7 @@ int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks, const AES_KEY *key, unsigned char iv[16], SHA256_CTX *ctx, const void *in0); -int cipher_capable_aes_cbc_hmac_sha256(void) +int ossl_cipher_capable_aes_cbc_hmac_sha256(void) { return AESNI_CBC_HMAC_SHA_CAPABLE && aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL); @@ -837,7 +837,7 @@ static const PROV_CIPHER_HW_AES_HMAC_SHA cipher_hw_aes_hmac_sha256 = { # endif }; -const PROV_CIPHER_HW_AES_HMAC_SHA *PROV_CIPHER_HW_aes_cbc_hmac_sha256(void) +const PROV_CIPHER_HW_AES_HMAC_SHA *ossl_prov_cipher_hw_aes_cbc_hmac_sha256(void) { return &cipher_hw_aes_hmac_sha256; } diff --git a/providers/implementations/ciphers/cipher_aes_ccm.c b/providers/implementations/ciphers/cipher_aes_ccm.c index ae32e34d25..5913b2ce0c 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm.c +++ b/providers/implementations/ciphers/cipher_aes_ccm.c @@ -18,13 +18,18 @@ #include "cipher_aes_ccm.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static void *aes_ccm_newctx(void *provctx, size_t keybits) { - PROV_AES_CCM_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_AES_CCM_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) - ccm_initctx(&ctx->base, keybits, PROV_AES_HW_ccm(keybits)); + ccm_initctx(&ctx->base, keybits, ossl_prov_aes_hw_ccm(keybits)); return ctx; } @@ -36,9 +41,9 @@ static void aes_ccm_freectx(void *vctx) OPENSSL_clear_free(ctx, sizeof(*ctx)); } -/* aes128ccm_functions */ +/* ossl_aes128ccm_functions */ IMPLEMENT_aead_cipher(aes, ccm, CCM, AEAD_FLAGS, 128, 8, 96); -/* aes192ccm_functions */ +/* ossl_aes192ccm_functions */ IMPLEMENT_aead_cipher(aes, ccm, CCM, AEAD_FLAGS, 192, 8, 96); -/* aes256ccm_functions */ +/* ossl_aes256ccm_functions */ IMPLEMENT_aead_cipher(aes, ccm, CCM, AEAD_FLAGS, 256, 8, 96); diff --git a/providers/implementations/ciphers/cipher_aes_ccm.h b/providers/implementations/ciphers/cipher_aes_ccm.h index ee0257c5f6..fd35080db3 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm.h +++ b/providers/implementations/ciphers/cipher_aes_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -45,4 +45,4 @@ typedef struct prov_aes_ccm_ctx_st { } ccm; } PROV_AES_CCM_CTX; -const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keylen); +const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keylen); diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw.c b/providers/implementations/ciphers/cipher_aes_ccm_hw.c index db2e3f2742..db50187ea9 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw.c @@ -62,7 +62,7 @@ static const PROV_CCM_HW aes_ccm = { #elif defined(SPARC_AES_CAPABLE) # include "cipher_aes_ccm_hw_t4.inc" #else -const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits) +const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { return &aes_ccm; } diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc index 7e83565809..1860f3f701 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,7 +32,7 @@ static const PROV_CCM_HW aesni_ccm = { ccm_generic_gettag }; -const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits) +const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { return AESNI_CAPABLE ? &aesni_ccm : &aes_ccm; } diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_s390x.inc index cec7c96902..7253f03a7e 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw_s390x.inc +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw_s390x.inc @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -258,7 +258,7 @@ static const PROV_CCM_HW s390x_aes_ccm = { s390x_aes_ccm_gettag }; -const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits) +const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { if ((keybits == 128 && S390X_aes_128_ccm_CAPABLE) || (keybits == 192 && S390X_aes_192_ccm_CAPABLE) diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw_t4.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_t4.inc index c4b6d15ed9..f659ab9b2d 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw_t4.inc +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw_t4.inc @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -30,7 +30,7 @@ static const PROV_CCM_HW t4_aes_ccm = { ccm_generic_gettag }; -const PROV_CCM_HW *PROV_AES_HW_ccm(size_t keybits) +const PROV_CCM_HW *ossl_prov_aes_hw_ccm(size_t keybits) { return SPARC_AES_CAPABLE ? &t4_aes_ccm : &aes_ccm; } diff --git a/providers/implementations/ciphers/cipher_aes_cts.h b/providers/implementations/ciphers/cipher_aes_cts.h index 6b0dfdd2c1..37dd3df329 100644 --- a/providers/implementations/ciphers/cipher_aes_cts.h +++ b/providers/implementations/ciphers/cipher_aes_cts.h @@ -9,8 +9,8 @@ #include "crypto/evp.h" -OSSL_FUNC_cipher_update_fn aes_cbc_cts_block_update; -OSSL_FUNC_cipher_final_fn aes_cbc_cts_block_final; +OSSL_FUNC_cipher_update_fn ossl_aes_cbc_cts_block_update; +OSSL_FUNC_cipher_final_fn ossl_aes_cbc_cts_block_final; -const char *aes_cbc_cts_mode_id2name(unsigned int id); -int aes_cbc_cts_mode_name2id(const char *name); +const char *ossl_aes_cbc_cts_mode_id2name(unsigned int id); +int ossl_aes_cbc_cts_mode_name2id(const char *name); diff --git a/providers/implementations/ciphers/cipher_aes_cts.inc b/providers/implementations/ciphers/cipher_aes_cts.inc index 5b33e972c5..6eb85a083f 100644 --- a/providers/implementations/ciphers/cipher_aes_cts.inc +++ b/providers/implementations/ciphers/cipher_aes_cts.inc @@ -28,14 +28,14 @@ static int aes_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS_MODE); if (p != NULL) { - const char *name = aes_cbc_cts_mode_id2name(ctx->cts_mode); + const char *name = ossl_aes_cbc_cts_mode_id2name(ctx->cts_mode); if (name == NULL || !OSSL_PARAM_set_utf8_string(p, name)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } } - return cipher_generic_get_ctx_params(vctx, params); + return ossl_cipher_generic_get_ctx_params(vctx, params); } CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(aes_cbc_cts) @@ -52,13 +52,13 @@ static int aes_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) goto err; - id = aes_cbc_cts_mode_name2id(p->data); + id = ossl_aes_cbc_cts_mode_name2id(p->data); if (id < 0) goto err; ctx->cts_mode = (unsigned int)id; } - return cipher_generic_set_ctx_params(vctx, params); + return ossl_cipher_generic_set_ctx_params(vctx, params); err: ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; @@ -70,25 +70,25 @@ err: static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ static int alg##_cts_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ + kbits, blkbits, ivbits); \ } \ -const OSSL_DISPATCH alg##kbits##lcmode##_cts_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_cts_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, \ - (void (*)(void)) alg##_##lcmode##_cts_block_update }, \ + (void (*)(void)) ossl_##alg##_##lcmode##_cts_block_update }, \ { OSSL_FUNC_CIPHER_FINAL, \ - (void (*)(void)) alg##_##lcmode##_cts_block_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + (void (*)(void)) ossl_##alg##_##lcmode##_cts_block_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_cts_##kbits##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void))aes_cbc_cts_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ @@ -100,9 +100,9 @@ const OSSL_DISPATCH alg##kbits##lcmode##_cts_functions[] = { \ { 0, NULL } \ }; -/* aes256cbc_cts_functions */ +/* ossl_aes256cbc_cts_functions */ IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, EVP_CIPH_FLAG_CTS, 256, 128, 128, block) -/* aes192cbc_cts_functions */ +/* ossl_aes192cbc_cts_functions */ IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, EVP_CIPH_FLAG_CTS, 192, 128, 128, block) -/* aes128cbc_cts_functions */ +/* ossl_aes128cbc_cts_functions */ IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, EVP_CIPH_FLAG_CTS, 128, 128, 128, block) diff --git a/providers/implementations/ciphers/cipher_aes_cts_fips.c b/providers/implementations/ciphers/cipher_aes_cts_fips.c index 81e81ad5f2..48d3ea8b09 100644 --- a/providers/implementations/ciphers/cipher_aes_cts_fips.c +++ b/providers/implementations/ciphers/cipher_aes_cts_fips.c @@ -72,7 +72,7 @@ static CTS_MODE_NAME2ID cts_modes[] = #endif }; -const char *aes_cbc_cts_mode_id2name(unsigned int id) +const char *ossl_aes_cbc_cts_mode_id2name(unsigned int id) { size_t i; @@ -83,7 +83,7 @@ const char *aes_cbc_cts_mode_id2name(unsigned int id) return NULL; } -int aes_cbc_cts_mode_name2id(const char *name) +int ossl_aes_cbc_cts_mode_name2id(const char *name) { size_t i; @@ -307,7 +307,7 @@ static size_t cts128_cs2_decrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, } #endif -int aes_cbc_cts_block_update(void *vctx, unsigned char *out, size_t *outl, +int ossl_aes_cbc_cts_block_update(void *vctx, unsigned char *out, size_t *outl, size_t outsize, const unsigned char *in, size_t inl) { @@ -360,7 +360,7 @@ int aes_cbc_cts_block_update(void *vctx, unsigned char *out, size_t *outl, return 1; } -int aes_cbc_cts_block_final(void *vctx, unsigned char *out, size_t *outl, +int ossl_aes_cbc_cts_block_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { *outl = 0; diff --git a/providers/implementations/ciphers/cipher_aes_gcm.c b/providers/implementations/ciphers/cipher_aes_gcm.c index 92a0ad1795..6e97b1f9d9 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm.c +++ b/providers/implementations/ciphers/cipher_aes_gcm.c @@ -18,13 +18,22 @@ #include "cipher_aes_gcm.h" #include "prov/implementations.h" +#include "prov/providercommon.h" + +#define AES_GCM_IV_MIN_SIZE (64 / 8) /* size in bytes */ +/* Note: GCM_IV_MAX_SIZE is listed in ciphercommon_gcm.h */ static void *aes_gcm_newctx(void *provctx, size_t keybits) { - PROV_AES_GCM_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_AES_GCM_CTX *ctx; + + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) - gcm_initctx(provctx, &ctx->base, keybits, PROV_AES_HW_gcm(keybits), 8); + gcm_initctx(provctx, &ctx->base, keybits, ossl_prov_aes_hw_gcm(keybits), + AES_GCM_IV_MIN_SIZE); return ctx; } @@ -36,9 +45,9 @@ static void aes_gcm_freectx(void *vctx) OPENSSL_clear_free(ctx, sizeof(*ctx)); } -/* aes128gcm_functions */ +/* ossl_aes128gcm_functions */ IMPLEMENT_aead_cipher(aes, gcm, GCM, AEAD_FLAGS, 128, 8, 96); -/* aes192gcm_functions */ +/* ossl_aes192gcm_functions */ IMPLEMENT_aead_cipher(aes, gcm, GCM, AEAD_FLAGS, 192, 8, 96); -/* aes256gcm_functions */ +/* ossl_aes256gcm_functions */ IMPLEMENT_aead_cipher(aes, gcm, GCM, AEAD_FLAGS, 256, 8, 96); diff --git a/providers/implementations/ciphers/cipher_aes_gcm.h b/providers/implementations/ciphers/cipher_aes_gcm.h index d7006408de..bcffa15871 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm.h +++ b/providers/implementations/ciphers/cipher_aes_gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,4 +41,4 @@ typedef struct prov_aes_gcm_ctx_st { } plat; } PROV_AES_GCM_CTX; -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits); +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c index c662887272..f29a280643 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c @@ -142,7 +142,7 @@ static const PROV_GCM_HW aes_gcm = { #elif defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM) # include "cipher_aes_gcm_hw_armv8.inc" #else -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { return &aes_gcm; } diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc index 9e2504a343..c25bd617c2 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc @@ -31,7 +31,7 @@ static const PROV_GCM_HW aesni_gcm = { gcm_one_shot }; -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { return AESNI_CAPABLE ? &aesni_gcm : &aes_gcm; } diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc index f44ada0faf..5c84bf31fd 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc @@ -77,7 +77,7 @@ static const PROV_GCM_HW armv8_aes_gcm = { gcm_one_shot }; -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { return AES_PMULL_CAPABLE ? &armv8_aes_gcm : &aes_gcm; } diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.inc index e13771a449..f797093928 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.inc @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -290,7 +290,7 @@ static const PROV_GCM_HW s390x_aes_gcm = { s390x_aes_gcm_one_shot }; -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { if ((keybits == 128 && S390X_aes_128_gcm_CAPABLE) || (keybits == 192 && S390X_aes_192_gcm_CAPABLE) diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc index 0a477128d3..1ad3ea465d 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc @@ -46,7 +46,7 @@ static const PROV_GCM_HW t4_aes_gcm = { gcm_cipher_final, gcm_one_shot }; -const PROV_GCM_HW *PROV_AES_HW_gcm(size_t keybits) +const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits) { return SPARC_AES_CAPABLE ? &t4_aes_gcm : &aes_gcm; } diff --git a/providers/implementations/ciphers/cipher_aes_hw.c b/providers/implementations/ciphers/cipher_aes_hw.c index e0bd4db6d3..0b6f06f915 100644 --- a/providers/implementations/ciphers/cipher_aes_hw.c +++ b/providers/implementations/ciphers/cipher_aes_hw.c @@ -126,11 +126,11 @@ IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_aes_copyctx, PROV_AES_CTX) #define PROV_CIPHER_HW_aes_mode(mode) \ static const PROV_CIPHER_HW aes_##mode = { \ cipher_hw_aes_initkey, \ - cipher_hw_generic_##mode, \ + ossl_cipher_hw_generic_##mode, \ cipher_hw_aes_copyctx \ }; \ PROV_CIPHER_HW_declare(mode) \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ { \ PROV_CIPHER_HW_select(mode) \ return &aes_##mode; \ diff --git a/providers/implementations/ciphers/cipher_aes_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_hw_aesni.inc index 8d3aef69b7..13b52d5987 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_aesni.inc +++ b/providers/implementations/ciphers/cipher_aes_hw_aesni.inc @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,11 +12,11 @@ * This file is included by cipher_aes_hw.c */ -#define cipher_hw_aesni_ofb128 cipher_hw_generic_ofb128 -#define cipher_hw_aesni_cfb128 cipher_hw_generic_cfb128 -#define cipher_hw_aesni_cfb8 cipher_hw_generic_cfb8 -#define cipher_hw_aesni_cfb1 cipher_hw_generic_cfb1 -#define cipher_hw_aesni_ctr cipher_hw_generic_ctr +#define cipher_hw_aesni_ofb128 ossl_cipher_hw_generic_ofb128 +#define cipher_hw_aesni_cfb128 ossl_cipher_hw_generic_cfb128 +#define cipher_hw_aesni_cfb8 ossl_cipher_hw_generic_cfb8 +#define cipher_hw_aesni_cfb1 ossl_cipher_hw_generic_cfb1 +#define cipher_hw_aesni_ctr ossl_cipher_hw_generic_ctr static int cipher_hw_aesni_initkey(PROV_CIPHER_CTX *dat, const unsigned char *key, size_t keylen) diff --git a/providers/implementations/ciphers/cipher_aes_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_hw_s390x.inc index 56e2dc9e38..ff88673f14 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_s390x.inc +++ b/providers/implementations/ciphers/cipher_aes_hw_s390x.inc @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,9 +17,9 @@ #define s390x_aes_cbc_initkey cipher_hw_aes_initkey #define s390x_aes_cfb1_initkey cipher_hw_aes_initkey #define s390x_aes_ctr_initkey cipher_hw_aes_initkey -#define s390x_aes_cbc_cipher_hw cipher_hw_generic_cbc -#define s390x_aes_cfb1_cipher_hw cipher_hw_generic_cfb1 -#define s390x_aes_ctr_cipher_hw cipher_hw_generic_ctr +#define s390x_aes_cbc_cipher_hw ossl_cipher_hw_generic_cbc +#define s390x_aes_cfb1_cipher_hw ossl_cipher_hw_generic_cfb1 +#define s390x_aes_ctr_cipher_hw ossl_cipher_hw_generic_ctr #define S390X_aes_128_ofb128_CAPABLE S390X_aes_128_ofb_CAPABLE #define S390X_aes_192_ofb128_CAPABLE S390X_aes_192_ofb_CAPABLE @@ -99,6 +99,7 @@ static int s390x_aes_ofb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, } } + memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); adat->plat.s390x.res = n; return 1; } @@ -161,6 +162,7 @@ static int s390x_aes_cfb128_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, } } + memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); adat->plat.s390x.res = n; return 1; } @@ -187,6 +189,7 @@ static int s390x_aes_cfb8_cipher_hw(PROV_CIPHER_CTX *dat, unsigned char *out, s390x_kmf(in, len, out, adat->plat.s390x.fc, &adat->plat.s390x.param.kmo_kmf); + memcpy(dat->iv, adat->plat.s390x.param.kmo_kmf.cv, dat->ivlen); return 1; } diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c index 230b353c50..7cb3f6a764 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.c +++ b/providers/implementations/ciphers/cipher_aes_ocb.c @@ -15,6 +15,7 @@ #include "internal/deprecated.h" #include "cipher_aes_ocb.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/ciphercommon_aead.h" #include "prov/implementations.h" @@ -39,6 +40,8 @@ static OSSL_FUNC_cipher_freectx_fn aes_ocb_freectx; static OSSL_FUNC_cipher_dupctx_fn aes_ocb_dupctx; static OSSL_FUNC_cipher_get_ctx_params_fn aes_ocb_get_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn aes_ocb_set_ctx_params; +static OSSL_FUNC_cipher_gettable_ctx_params_fn cipher_ocb_gettable_ctx_params; +static OSSL_FUNC_cipher_settable_ctx_params_fn cipher_ocb_settable_ctx_params; /* * The following methods could be moved into PROV_AES_OCB_HW if @@ -101,33 +104,36 @@ static ossl_inline int aes_generic_ocb_copy_ctx(PROV_AES_OCB_CTX *dst, static int aes_ocb_init(void *vctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, int enc) { - PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx; - - ctx->aad_buf_len = 0; - ctx->data_buf_len = 0; - ctx->base.enc = enc; - - if (iv != NULL) { - if (ivlen != ctx->base.ivlen) { - /* IV len must be 1 to 15 */ - if (ivlen < OCB_MIN_IV_LEN || ivlen > OCB_MAX_IV_LEN) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); - return 0; - } - ctx->base.ivlen = ivlen; - } - if (!cipher_generic_initiv(&ctx->base, iv, ivlen)) - return 0; - ctx->iv_state = IV_STATE_BUFFERED; - } - if (key != NULL) { - if (keylen != ctx->base.keylen) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); - return 0; - } - return ctx->base.hw->init(&ctx->base, key, keylen); - } - return 1; + PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx; + + if (!ossl_prov_is_running()) + return 0; + + ctx->aad_buf_len = 0; + ctx->data_buf_len = 0; + ctx->base.enc = enc; + + if (iv != NULL) { + if (ivlen != ctx->base.ivlen) { + /* IV len must be 1 to 15 */ + if (ivlen < OCB_MIN_IV_LEN || ivlen > OCB_MAX_IV_LEN) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + ctx->base.ivlen = ivlen; + } + if (!ossl_cipher_generic_initiv(&ctx->base, iv, ivlen)) + return 0; + ctx->iv_state = IV_STATE_BUFFERED; + } + if (key != NULL) { + if (keylen != ctx->base.keylen) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + return ctx->base.hw->init(&ctx->base, key, keylen); + } + return 1; } static int aes_ocb_einit(void *vctx, const unsigned char *key, size_t keylen, @@ -252,6 +258,9 @@ static int aes_ocb_block_final(void *vctx, unsigned char *out, size_t *outl, { PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + /* If no block_update has run then the iv still needs to be set */ if (!ctx->key_set || !update_iv(ctx)) return 0; @@ -291,11 +300,15 @@ static int aes_ocb_block_final(void *vctx, unsigned char *out, size_t *outl, static void *aes_ocb_newctx(void *provctx, size_t kbits, size_t blkbits, size_t ivbits, unsigned int mode, uint64_t flags) { - PROV_AES_OCB_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_AES_OCB_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, - PROV_CIPHER_HW_aes_ocb(kbits), NULL); + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, + ossl_prov_cipher_hw_aes_ocb(kbits), NULL); ctx->taglen = OCB_DEFAULT_TAG_LEN; } return ctx; @@ -307,7 +320,7 @@ static void aes_ocb_freectx(void *vctx) if (ctx != NULL) { aes_generic_ocb_cleanup(ctx); - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } @@ -315,8 +328,12 @@ static void aes_ocb_freectx(void *vctx) static void *aes_ocb_dupctx(void *vctx) { PROV_AES_OCB_CTX *in = (PROV_AES_OCB_CTX *)vctx; - PROV_AES_OCB_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_AES_OCB_CTX *ret; + + if (!ossl_prov_is_running()) + return NULL; + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -414,6 +431,18 @@ static int aes_ocb_get_ctx_params(void *vctx, OSSL_PARAM params[]) return 0; } } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV_STATE); + if (p != NULL) { + if (ctx->base.ivlen > p->data_size) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->base.iv, ctx->base.ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->base.iv, ctx->base.ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); if (p != NULL) { if (p->data_type != OSSL_PARAM_OCTET_STRING) { @@ -434,10 +463,11 @@ static const OSSL_PARAM cipher_ocb_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV_STATE, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *cipher_ocb_gettable_ctx_params(void) +static const OSSL_PARAM *cipher_ocb_gettable_ctx_params(ossl_unused void *p_ctx) { return cipher_ocb_known_gettable_ctx_params; } @@ -448,7 +478,7 @@ static const OSSL_PARAM cipher_ocb_known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *cipher_ocb_settable_ctx_params(void) +static const OSSL_PARAM *cipher_ocb_settable_ctx_params(ossl_unused void *p_ctx) { return cipher_ocb_known_settable_ctx_params; } @@ -458,6 +488,9 @@ static int aes_ocb_cipher(void *vctx, unsigned char *out, size_t *outl, { PROV_AES_OCB_CTX *ctx = (PROV_AES_OCB_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -476,8 +509,8 @@ static int aes_ocb_cipher(void *vctx, unsigned char *out, size_t *outl, static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##mode##_get_params; \ static int aes_##kbits##_##mode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ - flags, kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn aes_##kbits##_##mode##_newctx; \ static void *aes_##kbits##_##mode##_newctx(void *provctx) \ @@ -485,7 +518,7 @@ static void *aes_##kbits##_##mode##_newctx(void *provctx) \ return aes_##mode##_newctx(provctx, kbits, blkbits, ivbits, \ EVP_CIPH_##UCMODE##_MODE, flags); \ } \ -const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \ +const OSSL_DISPATCH ossl_##aes##kbits##mode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void))aes_##kbits##_##mode##_newctx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_##mode##_einit }, \ @@ -502,7 +535,7 @@ const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void))aes_##mode##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))cipher_ocb_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ @@ -513,4 +546,3 @@ const OSSL_DISPATCH aes##kbits##mode##_functions[] = { \ IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 256, 128, OCB_DEFAULT_IV_LEN * 8); IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 192, 128, OCB_DEFAULT_IV_LEN * 8); IMPLEMENT_cipher(ocb, OCB, AES_OCB_FLAGS, 128, 128, OCB_DEFAULT_IV_LEN * 8); - diff --git a/providers/implementations/ciphers/cipher_aes_ocb.h b/providers/implementations/ciphers/cipher_aes_ocb.h index 94d8183167..370717b436 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.h +++ b/providers/implementations/ciphers/cipher_aes_ocb.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -36,4 +36,4 @@ typedef struct prov_aes_ocb_ctx_st { unsigned char aad_buf[OCB_MAX_AAD_LEN]; /* Store partial AAD blocks */ } PROV_AES_OCB_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ocb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ocb(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_ocb_hw.c b/providers/implementations/ciphers/cipher_aes_ocb_hw.c index 5caca0b1df..7aa97dc77e 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb_hw.c +++ b/providers/implementations/ciphers/cipher_aes_ocb_hw.c @@ -113,7 +113,7 @@ static const PROV_CIPHER_HW aes_generic_ocb = { NULL }; PROV_CIPHER_HW_declare() -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_ocb(size_t keybits) +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_ocb(size_t keybits) { PROV_CIPHER_HW_select() return &aes_generic_ocb; diff --git a/providers/implementations/ciphers/cipher_aes_siv.c b/providers/implementations/ciphers/cipher_aes_siv.c index 84c078da82..7a83506c24 100644 --- a/providers/implementations/ciphers/cipher_aes_siv.c +++ b/providers/implementations/ciphers/cipher_aes_siv.c @@ -17,6 +17,7 @@ #include "cipher_aes_siv.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/ciphercommon_aead.h" #include "prov/provider_ctx.h" @@ -27,15 +28,19 @@ static void *aes_siv_newctx(void *provctx, size_t keybits, unsigned int mode, uint64_t flags) { - PROV_AES_SIV_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_AES_SIV_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { ctx->taglen = SIV_LEN; ctx->mode = mode; ctx->flags = flags; ctx->keylen = keybits / 8; - ctx->hw = PROV_CIPHER_HW_aes_siv(keybits); - ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + ctx->hw = ossl_prov_cipher_hw_aes_siv(keybits); + ctx->libctx = PROV_LIBCTX_OF(provctx); } return ctx; } @@ -53,8 +58,12 @@ static void aes_siv_freectx(void *vctx) static void *siv_dupctx(void *vctx) { PROV_AES_SIV_CTX *in = (PROV_AES_SIV_CTX *)vctx; - PROV_AES_SIV_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_AES_SIV_CTX *ret; + + if (!ossl_prov_is_running()) + return NULL; + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -71,6 +80,9 @@ static int siv_init(void *vctx, const unsigned char *key, size_t keylen, { PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->enc = enc; if (key != NULL) { @@ -100,6 +112,9 @@ static int siv_cipher(void *vctx, unsigned char *out, size_t *outl, { PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (inl == 0) { *outl = 0; return 1; @@ -123,6 +138,9 @@ static int siv_stream_final(void *vctx, unsigned char *out, size_t *outl, { PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (!ctx->hw->cipher(vctx, out, NULL, 0)) return 0; @@ -166,7 +184,7 @@ static const OSSL_PARAM aes_siv_known_gettable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *aes_siv_gettable_ctx_params(void) +static const OSSL_PARAM *aes_siv_gettable_ctx_params(ossl_unused void *provctx) { return aes_siv_known_gettable_ctx_params; } @@ -216,25 +234,39 @@ static const OSSL_PARAM aes_siv_known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *aes_siv_settable_ctx_params(void) +static const OSSL_PARAM *aes_siv_settable_ctx_params(ossl_unused void *provctx) { return aes_siv_known_settable_ctx_params; } #define IMPLEMENT_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits) \ +static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ +static OSSL_FUNC_cipher_freectx_fn alg##_##lc##_freectx; \ +static OSSL_FUNC_cipher_dupctx_fn lc##_dupctx; \ +static OSSL_FUNC_cipher_encrypt_init_fn lc##_einit; \ +static OSSL_FUNC_cipher_decrypt_init_fn lc##_dinit; \ +static OSSL_FUNC_cipher_update_fn lc##_stream_update; \ +static OSSL_FUNC_cipher_final_fn lc##_stream_final; \ +static OSSL_FUNC_cipher_cipher_fn lc##_cipher; \ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ +static OSSL_FUNC_cipher_gettable_params_fn alg##_##lc##_gettable_ctx_params; \ +static OSSL_FUNC_cipher_get_ctx_params_fn alg##_##lc##_get_ctx_params; \ +static OSSL_FUNC_cipher_gettable_ctx_params_fn \ + alg##_##lc##_gettable_ctx_params; \ +static OSSL_FUNC_cipher_set_ctx_params_fn alg##_##lc##_set_ctx_params; \ +static OSSL_FUNC_cipher_settable_ctx_params_fn \ + alg##_##lc##_settable_ctx_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, 2*kbits, blkbits, ivbits); \ } \ -static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, 2*kbits, EVP_CIPH_##UCMODE##_MODE, \ flags); \ } \ -const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) lc##_dupctx }, \ @@ -246,7 +278,7 @@ const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lc##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void)) alg##_##lc##_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ diff --git a/providers/implementations/ciphers/cipher_aes_siv.h b/providers/implementations/ciphers/cipher_aes_siv.h index 3179943f0e..6d2649f049 100644 --- a/providers/implementations/ciphers/cipher_aes_siv.h +++ b/providers/implementations/ciphers/cipher_aes_siv.h @@ -31,7 +31,7 @@ typedef struct prov_siv_ctx_st { EVP_CIPHER *ctr; /* These are fetched - so we need to free them */ EVP_CIPHER *cbc; const PROV_CIPHER_HW_AES_SIV *hw; - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; } PROV_AES_SIV_CTX; -const PROV_CIPHER_HW_AES_SIV *PROV_CIPHER_HW_aes_siv(size_t keybits); +const PROV_CIPHER_HW_AES_SIV *ossl_prov_cipher_hw_aes_siv(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_siv_hw.c b/providers/implementations/ciphers/cipher_aes_siv_hw.c index 547eb1a4c4..f4ad6639cf 100644 --- a/providers/implementations/ciphers/cipher_aes_siv_hw.c +++ b/providers/implementations/ciphers/cipher_aes_siv_hw.c @@ -22,7 +22,7 @@ static int aes_siv_initkey(void *vctx, const unsigned char *key, size_t keylen) PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx; SIV128_CONTEXT *sctx = &ctx->siv; size_t klen = keylen / 2; - OPENSSL_CTX *libctx = ctx->libctx; + OSSL_LIB_CTX *libctx = ctx->libctx; const char *propq = NULL; EVP_CIPHER_free(ctx->cbc); @@ -130,7 +130,7 @@ static const PROV_CIPHER_HW_AES_SIV aes_siv_hw = aes_siv_dupctx, }; -const PROV_CIPHER_HW_AES_SIV *PROV_CIPHER_HW_aes_siv(size_t keybits) +const PROV_CIPHER_HW_AES_SIV *ossl_prov_cipher_hw_aes_siv(size_t keybits) { return &aes_siv_hw; } diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c index 5c2ab1c507..3918161b46 100644 --- a/providers/implementations/ciphers/cipher_aes_wrp.c +++ b/providers/implementations/ciphers/cipher_aes_wrp.c @@ -14,6 +14,7 @@ #include "internal/deprecated.h" #include "cipher_aes.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" @@ -49,12 +50,17 @@ typedef struct prov_aes_wrap_ctx_st { static void *aes_wrap_newctx(size_t kbits, size_t blkbits, size_t ivbits, unsigned int mode, uint64_t flags) { - PROV_AES_WRAP_CTX *wctx = OPENSSL_zalloc(sizeof(*wctx)); - PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)wctx; + PROV_AES_WRAP_CTX *wctx; + PROV_CIPHER_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + wctx = OPENSSL_zalloc(sizeof(*wctx)); + ctx = (PROV_CIPHER_CTX *)wctx; if (ctx != NULL) { - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, - NULL, NULL); + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, + NULL, NULL); ctx->pad = (ctx->ivlen == AES_WRAP_PAD_IVLEN); } return wctx; @@ -64,7 +70,7 @@ static void aes_wrap_freectx(void *vctx) { PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(wctx, sizeof(*wctx)); } @@ -75,6 +81,9 @@ static int aes_wrap_init(void *vctx, const unsigned char *key, PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; PROV_AES_WRAP_CTX *wctx = (PROV_AES_WRAP_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->enc = enc; ctx->block = enc ? (block128_f)AES_encrypt : (block128_f)AES_decrypt; if (ctx->pad) @@ -83,7 +92,7 @@ static int aes_wrap_init(void *vctx, const unsigned char *key, wctx->wrapfn = enc ? CRYPTO_128_wrap : CRYPTO_128_unwrap; if (iv != NULL) { - if (!cipher_generic_initiv(ctx, iv, ivlen)) + if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } if (key != NULL) { @@ -160,6 +169,9 @@ static int aes_wrap_cipher_internal(void *vctx, unsigned char *out, static int aes_wrap_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { + if (!ossl_prov_is_running()) + return 0; + *outl = 0; return 1; } @@ -171,6 +183,9 @@ static int aes_wrap_cipher(void *vctx, PROV_AES_WRAP_CTX *ctx = (PROV_AES_WRAP_CTX *)vctx; size_t len; + if (!ossl_prov_is_running()) + return 0; + if (inl == 0) { *outl = 0; return 1; @@ -213,8 +228,8 @@ static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[]) static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##fname##_get_params; \ static int aes_##kbits##_##fname##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ - flags, kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,\ + flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn aes_##kbits##fname##_newctx; \ static void *aes_##kbits##fname##_newctx(void *provctx) \ @@ -222,7 +237,7 @@ static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return aes_##mode##_newctx(kbits, blkbits, ivbits, \ EVP_CIPH_##UCMODE##_MODE, flags); \ } \ - const OSSL_DISPATCH aes##kbits##fname##_functions[] = { \ + const OSSL_DISPATCH ossl_##aes##kbits##fname##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void))aes_##kbits##fname##_newctx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_##mode##_einit }, \ @@ -233,15 +248,15 @@ static int aes_wrap_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))aes_##kbits##_##fname##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_get_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void))aes_wrap_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ { 0, NULL } \ } diff --git a/providers/implementations/ciphers/cipher_aes_xts.c b/providers/implementations/ciphers/cipher_aes_xts.c index f564075abe..7ccad56198 100644 --- a/providers/implementations/ciphers/cipher_aes_xts.c +++ b/providers/implementations/ciphers/cipher_aes_xts.c @@ -1,3 +1,4 @@ + /* * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * @@ -16,6 +17,7 @@ #include "cipher_aes_xts.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" /* TODO (3.0) Figure out what flags need to be set */ @@ -74,10 +76,13 @@ static int aes_xts_init(void *vctx, const unsigned char *key, size_t keylen, PROV_AES_XTS_CTX *xctx = (PROV_AES_XTS_CTX *)vctx; PROV_CIPHER_CTX *ctx = &xctx->base; + if (!ossl_prov_is_running()) + return 0; + ctx->enc = enc; if (iv != NULL) { - if (!cipher_generic_initiv(vctx, iv, ivlen)) + if (!ossl_cipher_generic_initiv(vctx, iv, ivlen)) return 0; } if (key != NULL) { @@ -110,8 +115,9 @@ static void *aes_xts_newctx(void *provctx, unsigned int mode, uint64_t flags, PROV_AES_XTS_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { - cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, flags, - PROV_CIPHER_HW_aes_xts(kbits), NULL); + ossl_cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, + flags, ossl_prov_cipher_hw_aes_xts(kbits), + NULL); } return ctx; } @@ -120,7 +126,7 @@ static void aes_xts_freectx(void *vctx) { PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } @@ -129,6 +135,9 @@ static void *aes_xts_dupctx(void *vctx) PROV_AES_XTS_CTX *in = (PROV_AES_XTS_CTX *)vctx; PROV_AES_XTS_CTX *ret = NULL; + if (!ossl_prov_is_running()) + return NULL; + if (in->xts.key1 != NULL) { if (in->xts.key1 != &in->ks1) return NULL; @@ -151,7 +160,8 @@ static int aes_xts_cipher(void *vctx, unsigned char *out, size_t *outl, { PROV_AES_XTS_CTX *ctx = (PROV_AES_XTS_CTX *)vctx; - if (ctx->xts.key1 == NULL + if (!ossl_prov_is_running() + || ctx->xts.key1 == NULL || ctx->xts.key2 == NULL || !ctx->base.iv_set || out == NULL @@ -202,6 +212,8 @@ static int aes_xts_stream_update(void *vctx, unsigned char *out, size_t *outl, static int aes_xts_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { + if (!ossl_prov_is_running()) + return 0; *outl = 0; return 1; } @@ -211,7 +223,7 @@ static const OSSL_PARAM aes_xts_known_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *aes_xts_settable_ctx_params(void) +static const OSSL_PARAM *aes_xts_settable_ctx_params(ossl_unused void *provctx) { return aes_xts_known_settable_ctx_params; } @@ -245,7 +257,7 @@ static int aes_xts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) static OSSL_FUNC_cipher_get_params_fn aes_##kbits##_##lcmode##_get_params; \ static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, 2 * kbits, AES_XTS_BLOCK_BITS, \ AES_XTS_IV_BITS); \ } \ @@ -255,7 +267,7 @@ static void *aes_##kbits##_xts_newctx(void *provctx) \ return aes_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, flags, 2 * kbits, \ AES_XTS_BLOCK_BITS, AES_XTS_IV_BITS); \ } \ -const OSSL_DISPATCH aes##kbits##xts_functions[] = { \ +const OSSL_DISPATCH ossl_aes##kbits##xts_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))aes_##kbits##_xts_newctx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))aes_xts_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))aes_xts_dinit }, \ @@ -267,11 +279,11 @@ const OSSL_DISPATCH aes##kbits##xts_functions[] = { \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))aes_##kbits##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_get_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void))aes_xts_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ diff --git a/providers/implementations/ciphers/cipher_aes_xts.h b/providers/implementations/ciphers/cipher_aes_xts.h index 23ae696197..95b5c9074c 100644 --- a/providers/implementations/ciphers/cipher_aes_xts.h +++ b/providers/implementations/ciphers/cipher_aes_xts.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -32,4 +32,4 @@ typedef struct prov_aes_xts_ctx_st { OSSL_xts_stream_fn stream; } PROV_AES_XTS_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_xts(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aes_xts_hw.c b/providers/implementations/ciphers/cipher_aes_xts_hw.c index e1c8182556..15c136bafd 100644 --- a/providers/implementations/ciphers/cipher_aes_xts_hw.c +++ b/providers/implementations/ciphers/cipher_aes_xts_hw.c @@ -66,15 +66,18 @@ static int cipher_hw_aes_xts_generic_initkey(PROV_CIPHER_CTX *ctx, if (BSAES_CAPABLE) { stream_enc = bsaes_xts_encrypt; stream_dec = bsaes_xts_decrypt; - } + } else #endif /* BSAES_CAPABLE */ - #ifdef VPAES_CAPABLE if (VPAES_CAPABLE) { XTS_SET_KEY_FN(vpaes_set_encrypt_key, vpaes_set_decrypt_key, vpaes_encrypt, vpaes_decrypt, stream_enc, stream_dec); + return 1; } else #endif /* VPAES_CAPABLE */ + { + (void)0; + } { XTS_SET_KEY_FN(AES_set_encrypt_key, AES_set_decrypt_key, AES_encrypt, AES_decrypt, stream_enc, stream_dec); @@ -166,7 +169,7 @@ static const PROV_CIPHER_HW aes_generic_xts = { cipher_hw_aes_xts_copyctx }; PROV_CIPHER_HW_declare_xts() -const PROV_CIPHER_HW *PROV_CIPHER_HW_aes_xts(size_t keybits) +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_xts(size_t keybits) { PROV_CIPHER_HW_select_xts() return &aes_generic_xts; diff --git a/providers/implementations/ciphers/cipher_aria.c b/providers/implementations/ciphers/cipher_aria.c index a079617928..be69c39bab 100644 --- a/providers/implementations/ciphers/cipher_aria.c +++ b/providers/implementations/ciphers/cipher_aria.c @@ -11,6 +11,7 @@ #include "cipher_aria.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn aria_freectx; static OSSL_FUNC_cipher_dupctx_fn aria_dupctx; @@ -19,15 +20,19 @@ static void aria_freectx(void *vctx) { PROV_ARIA_CTX *ctx = (PROV_ARIA_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *aria_dupctx(void *ctx) { PROV_ARIA_CTX *in = (PROV_ARIA_CTX *)ctx; - PROV_ARIA_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_ARIA_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -37,45 +42,45 @@ static void *aria_dupctx(void *ctx) return ret; } -/* aria256ecb_functions */ +/* ossl_aria256ecb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ecb, ECB, 0, 256, 128, 0, block) -/* aria192ecb_functions */ +/* ossl_aria192ecb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ecb, ECB, 0, 192, 128, 0, block) -/* aria128ecb_functions */ +/* ossl_aria128ecb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ecb, ECB, 0, 128, 128, 0, block) -/* aria256cbc_functions */ +/* ossl_aria256cbc_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cbc, CBC, 0, 256, 128, 128, block) -/* aria192cbc_functions */ +/* ossl_aria192cbc_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cbc, CBC, 0, 192, 128, 128, block) -/* aria128cbc_functions */ +/* ossl_aria128cbc_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cbc, CBC, 0, 128, 128, 128, block) -/* aria256ofb_functions */ +/* ossl_aria256ofb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ofb, OFB, 0, 256, 8, 128, stream) -/* aria192ofb_functions */ +/* ossl_aria192ofb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ofb, OFB, 0, 192, 8, 128, stream) -/* aria128ofb_functions */ +/* ossl_aria128ofb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ofb, OFB, 0, 128, 8, 128, stream) -/* aria256cfb_functions */ +/* ossl_aria256cfb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb, CFB, 0, 256, 8, 128, stream) -/* aria192cfb_functions */ +/* ossl_aria192cfb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb, CFB, 0, 192, 8, 128, stream) -/* aria128cfb_functions */ +/* ossl_aria128cfb_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb, CFB, 0, 128, 8, 128, stream) -/* aria256cfb1_functions */ +/* ossl_aria256cfb1_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb1, CFB, 0, 256, 8, 128, stream) -/* aria192cfb1_functions */ +/* ossl_aria192cfb1_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb1, CFB, 0, 192, 8, 128, stream) -/* aria128cfb1_functions */ +/* ossl_aria128cfb1_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb1, CFB, 0, 128, 8, 128, stream) -/* aria256cfb8_functions */ +/* ossl_aria256cfb8_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb8, CFB, 0, 256, 8, 128, stream) -/* aria192cfb8_functions */ +/* ossl_aria192cfb8_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb8, CFB, 0, 192, 8, 128, stream) -/* aria128cfb8_functions */ +/* ossl_aria128cfb8_functions */ IMPLEMENT_generic_cipher(aria, ARIA, cfb8, CFB, 0, 128, 8, 128, stream) -/* aria256ctr_functions */ +/* ossl_aria256ctr_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ctr, CTR, 0, 256, 8, 128, stream) -/* aria192ctr_functions */ +/* ossl_aria192ctr_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ctr, CTR, 0, 192, 8, 128, stream) -/* aria128ctr_functions */ +/* ossl_aria128ctr_functions */ IMPLEMENT_generic_cipher(aria, ARIA, ctr, CTR, 0, 128, 8, 128, stream) diff --git a/providers/implementations/ciphers/cipher_aria.h b/providers/implementations/ciphers/cipher_aria.h index 282408c58e..39f84d3b43 100644 --- a/providers/implementations/ciphers/cipher_aria.h +++ b/providers/implementations/ciphers/cipher_aria.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,12 +19,12 @@ typedef struct prov_aria_ctx_st { } PROV_ARIA_CTX; -# define PROV_CIPHER_HW_aria_ofb PROV_CIPHER_HW_aria_ofb128 -# define PROV_CIPHER_HW_aria_cfb PROV_CIPHER_HW_aria_cfb128 -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ofb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb1(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_cfb8(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_ctr(size_t keybits); +#define ossl_prov_cipher_hw_aria_ofb ossl_prov_cipher_hw_aria_ofb128 +#define ossl_prov_cipher_hw_aria_cfb ossl_prov_cipher_hw_aria_cfb128 +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_ofb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_cfb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_cfb1(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_cfb8(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_ctr(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aria_ccm.c b/providers/implementations/ciphers/cipher_aria_ccm.c index ffc8166d68..a19ad65b62 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm.c +++ b/providers/implementations/ciphers/cipher_aria_ccm.c @@ -11,15 +11,20 @@ #include "cipher_aria_ccm.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn aria_ccm_freectx; static void *aria_ccm_newctx(void *provctx, size_t keybits) { - PROV_ARIA_CCM_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_ARIA_CCM_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) - ccm_initctx(&ctx->base, keybits, PROV_ARIA_HW_ccm(keybits)); + ccm_initctx(&ctx->base, keybits, ossl_prov_aria_hw_ccm(keybits)); return ctx; } diff --git a/providers/implementations/ciphers/cipher_aria_ccm.h b/providers/implementations/ciphers/cipher_aria_ccm.h index a85cf899ef..558da4973f 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm.h +++ b/providers/implementations/ciphers/cipher_aria_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,4 +19,4 @@ typedef struct prov_aria_ccm_ctx_st { } ks; /* ARIA key schedule to use */ } PROV_ARIA_CCM_CTX; -const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keylen); +const PROV_CCM_HW *ossl_prov_aria_hw_ccm(size_t keylen); diff --git a/providers/implementations/ciphers/cipher_aria_ccm_hw.c b/providers/implementations/ciphers/cipher_aria_ccm_hw.c index db3a9c8ea8..ec39f5702f 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm_hw.c +++ b/providers/implementations/ciphers/cipher_aria_ccm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,7 +34,7 @@ static const PROV_CCM_HW ccm_aria = { ccm_generic_auth_decrypt, ccm_generic_gettag }; -const PROV_CCM_HW *PROV_ARIA_HW_ccm(size_t keybits) +const PROV_CCM_HW *ossl_prov_aria_hw_ccm(size_t keybits) { return &ccm_aria; } diff --git a/providers/implementations/ciphers/cipher_aria_gcm.c b/providers/implementations/ciphers/cipher_aria_gcm.c index 7205522d7d..ad667ae27a 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm.c +++ b/providers/implementations/ciphers/cipher_aria_gcm.c @@ -11,13 +11,21 @@ #include "cipher_aria_gcm.h" #include "prov/implementations.h" +#include "prov/providercommon.h" + +#define ARIA_GCM_IV_MIN_SIZE (32 / 8) /* size in bytes */ static void *aria_gcm_newctx(void *provctx, size_t keybits) { - PROV_ARIA_GCM_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_ARIA_GCM_CTX *ctx; + + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) - gcm_initctx(provctx, &ctx->base, keybits, PROV_ARIA_HW_gcm(keybits), 4); + gcm_initctx(provctx, &ctx->base, keybits, + ossl_prov_aria_hw_gcm(keybits), ARIA_GCM_IV_MIN_SIZE); return ctx; } @@ -29,10 +37,10 @@ static void aria_gcm_freectx(void *vctx) OPENSSL_clear_free(ctx, sizeof(*ctx)); } -/* aria128gcm_functions */ +/* ossl_aria128gcm_functions */ IMPLEMENT_aead_cipher(aria, gcm, GCM, AEAD_FLAGS, 128, 8, 96); -/* aria192gcm_functions */ +/* ossl_aria192gcm_functions */ IMPLEMENT_aead_cipher(aria, gcm, GCM, AEAD_FLAGS, 192, 8, 96); -/* aria256gcm_functions */ +/* ossl_aria256gcm_functions */ IMPLEMENT_aead_cipher(aria, gcm, GCM, AEAD_FLAGS, 256, 8, 96); diff --git a/providers/implementations/ciphers/cipher_aria_gcm.h b/providers/implementations/ciphers/cipher_aria_gcm.h index 2d08a59029..6251e8322f 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm.h +++ b/providers/implementations/ciphers/cipher_aria_gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,4 +19,4 @@ typedef struct prov_aria_gcm_ctx_st { } ks; } PROV_ARIA_GCM_CTX; -const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits); +const PROV_GCM_HW *ossl_prov_aria_hw_gcm(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_aria_gcm_hw.c b/providers/implementations/ciphers/cipher_aria_gcm_hw.c index 1d8e470b20..54c635e4bf 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aria_gcm_hw.c @@ -31,7 +31,7 @@ static const PROV_GCM_HW aria_gcm = { gcm_cipher_final, gcm_one_shot }; -const PROV_GCM_HW *PROV_ARIA_HW_gcm(size_t keybits) +const PROV_GCM_HW *ossl_prov_aria_hw_gcm(size_t keybits) { return &aria_gcm; } diff --git a/providers/implementations/ciphers/cipher_aria_hw.c b/providers/implementations/ciphers/cipher_aria_hw.c index b0c5675f1b..f457aaf750 100644 --- a/providers/implementations/ciphers/cipher_aria_hw.c +++ b/providers/implementations/ciphers/cipher_aria_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,10 +34,10 @@ IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_aria_copyctx, PROV_ARIA_CTX) # define PROV_CIPHER_HW_aria_mode(mode) \ static const PROV_CIPHER_HW aria_##mode = { \ cipher_hw_aria_initkey, \ - cipher_hw_chunked_##mode, \ + ossl_cipher_hw_chunked_##mode, \ cipher_hw_aria_copyctx \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_aria_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_aria_##mode(size_t keybits) \ { \ return &aria_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_blowfish.c b/providers/implementations/ciphers/cipher_blowfish.c index 3eb4ebead2..6320f560a0 100644 --- a/providers/implementations/ciphers/cipher_blowfish.c +++ b/providers/implementations/ciphers/cipher_blowfish.c @@ -17,6 +17,7 @@ #include "cipher_blowfish.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #define BF_FLAGS (EVP_CIPH_VARIABLE_LENGTH) @@ -27,15 +28,19 @@ static void blowfish_freectx(void *vctx) { PROV_BLOWFISH_CTX *ctx = (PROV_BLOWFISH_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *blowfish_dupctx(void *ctx) { PROV_BLOWFISH_CTX *in = (PROV_BLOWFISH_CTX *)ctx; - PROV_BLOWFISH_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_BLOWFISH_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; diff --git a/providers/implementations/ciphers/cipher_blowfish.h b/providers/implementations/ciphers/cipher_blowfish.h index 2d66d1bc0e..bbdc9da378 100644 --- a/providers/implementations/ciphers/cipher_blowfish.h +++ b/providers/implementations/ciphers/cipher_blowfish.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ typedef struct prov_blowfish_ctx_st { } ks; } PROV_BLOWFISH_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_ofb64(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_cfb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_blowfish_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_blowfish_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_blowfish_ofb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_blowfish_cfb64(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_blowfish_hw.c b/providers/implementations/ciphers/cipher_blowfish_hw.c index 3ff43e4c27..4855a71f68 100644 --- a/providers/implementations/ciphers/cipher_blowfish_hw.c +++ b/providers/implementations/ciphers/cipher_blowfish_hw.c @@ -31,7 +31,7 @@ static const PROV_CIPHER_HW bf_##mode = { \ cipher_hw_blowfish_initkey, \ cipher_hw_blowfish_##mode##_cipher \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_blowfish_##mode(size_t keybits) \ { \ return &bf_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_camellia.c b/providers/implementations/ciphers/cipher_camellia.c index ffb23b475a..02bef547fd 100644 --- a/providers/implementations/ciphers/cipher_camellia.c +++ b/providers/implementations/ciphers/cipher_camellia.c @@ -17,6 +17,7 @@ #include "cipher_camellia.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn camellia_freectx; static OSSL_FUNC_cipher_dupctx_fn camellia_dupctx; @@ -25,15 +26,19 @@ static void camellia_freectx(void *vctx) { PROV_CAMELLIA_CTX *ctx = (PROV_CAMELLIA_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *camellia_dupctx(void *ctx) { PROV_CAMELLIA_CTX *in = (PROV_CAMELLIA_CTX *)ctx; - PROV_CAMELLIA_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_CAMELLIA_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -43,46 +48,46 @@ static void *camellia_dupctx(void *ctx) return ret; } -/* camellia256ecb_functions */ +/* ossl_camellia256ecb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ecb, ECB, 0, 256, 128, 0, block) -/* camellia192ecb_functions */ +/* ossl_camellia192ecb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ecb, ECB, 0, 192, 128, 0, block) -/* camellia128ecb_functions */ +/* ossl_camellia128ecb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ecb, ECB, 0, 128, 128, 0, block) -/* camellia256cbc_functions */ +/* ossl_camellia256cbc_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cbc, CBC, 0, 256, 128, 128, block) -/* camellia192cbc_functions */ +/* ossl_camellia192cbc_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cbc, CBC, 0, 192, 128, 128, block) -/* camellia128cbc_functions */ +/* ossl_camellia128cbc_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cbc, CBC, 0, 128, 128, 128, block) -/* camellia256ofb_functions */ +/* ossl_camellia256ofb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ofb, OFB, 0, 256, 8, 128, stream) -/* camellia192ofb_functions */ +/* ossl_camellia192ofb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ofb, OFB, 0, 192, 8, 128, stream) -/* camellia128ofb_functions */ +/* ossl_camellia128ofb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ofb, OFB, 0, 128, 8, 128, stream) -/* camellia256cfb_functions */ +/* ossl_camellia256cfb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb, CFB, 0, 256, 8, 128, stream) -/* camellia192cfb_functions */ +/* ossl_camellia192cfb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb, CFB, 0, 192, 8, 128, stream) -/* camellia128cfb_functions */ +/* ossl_camellia128cfb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb, CFB, 0, 128, 8, 128, stream) -/* camellia256cfb1_functions */ +/* ossl_camellia256cfb1_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb1, CFB, 0, 256, 8, 128, stream) -/* camellia192cfb1_functions */ +/* ossl_camellia192cfb1_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb1, CFB, 0, 192, 8, 128, stream) -/* camellia128cfb1_functions */ +/* ossl_camellia128cfb1_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb1, CFB, 0, 128, 8, 128, stream) -/* camellia256cfb8_functions */ +/* ossl_camellia256cfb8_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb8, CFB, 0, 256, 8, 128, stream) -/* camellia192cfb8_functions */ +/* ossl_camellia192cfb8_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb8, CFB, 0, 192, 8, 128, stream) -/* camellia128cfb8_functions */ +/* ossl_camellia128cfb8_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, cfb8, CFB, 0, 128, 8, 128, stream) -/* camellia256ctr_functions */ +/* ossl_camellia256ctr_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 256, 8, 128, stream) -/* camellia192ctr_functions */ +/* ossl_camellia192ctr_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 192, 8, 128, stream) -/* camellia128ctr_functions */ +/* ossl_camellia128ctr_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 128, 8, 128, stream) diff --git a/providers/implementations/ciphers/cipher_camellia.h b/providers/implementations/ciphers/cipher_camellia.h index 07f67dbad8..bd4debcd39 100644 --- a/providers/implementations/ciphers/cipher_camellia.h +++ b/providers/implementations/ciphers/cipher_camellia.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,12 +19,12 @@ typedef struct prov_camellia_ctx_st { } ks; } PROV_CAMELLIA_CTX; -#define PROV_CIPHER_HW_camellia_ofb PROV_CIPHER_HW_camellia_ofb128 -#define PROV_CIPHER_HW_camellia_cfb PROV_CIPHER_HW_camellia_cfb128 -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ofb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb1(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_cfb8(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_ctr(size_t keybits); +#define ossl_prov_cipher_hw_camellia_ofb ossl_prov_cipher_hw_camellia_ofb128 +#define ossl_prov_cipher_hw_camellia_cfb ossl_prov_cipher_hw_camellia_cfb128 +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_ofb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_cfb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_cfb1(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_cfb8(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_ctr(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_camellia_hw.c b/providers/implementations/ciphers/cipher_camellia_hw.c index 3a8fa282c3..e8ada99a7e 100644 --- a/providers/implementations/ciphers/cipher_camellia_hw.c +++ b/providers/implementations/ciphers/cipher_camellia_hw.c @@ -54,11 +54,11 @@ IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_camellia_copyctx, PROV_CAMELLIA_CTX) #define PROV_CIPHER_HW_camellia_mode(mode) \ static const PROV_CIPHER_HW camellia_##mode = { \ cipher_hw_camellia_initkey, \ - cipher_hw_generic_##mode, \ + ossl_cipher_hw_generic_##mode, \ cipher_hw_camellia_copyctx \ }; \ PROV_CIPHER_HW_declare(mode) \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_camellia_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_camellia_##mode(size_t keybits) \ { \ PROV_CIPHER_HW_select(mode) \ return &camellia_##mode; \ diff --git a/providers/implementations/ciphers/cipher_cast.h b/providers/implementations/ciphers/cipher_cast.h index 218f5c4fb5..84b58621c1 100644 --- a/providers/implementations/ciphers/cipher_cast.h +++ b/providers/implementations/ciphers/cipher_cast.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ typedef struct prov_cast_ctx_st { } ks; } PROV_CAST_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_cast5_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_cast5_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_cast5_ofb64(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_cast5_cfb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_cast5_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_cast5_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_cast5_ofb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_cast5_cfb64(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_cast5.c b/providers/implementations/ciphers/cipher_cast5.c index 938b8d2013..7c686013d8 100644 --- a/providers/implementations/ciphers/cipher_cast5.c +++ b/providers/implementations/ciphers/cipher_cast5.c @@ -17,6 +17,7 @@ #include "cipher_cast.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #define CAST5_FLAGS (EVP_CIPH_VARIABLE_LENGTH) @@ -28,15 +29,19 @@ static void cast5_freectx(void *vctx) { PROV_CAST_CTX *ctx = (PROV_CAST_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *cast5_dupctx(void *ctx) { PROV_CAST_CTX *in = (PROV_CAST_CTX *)ctx; - PROV_CAST_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_CAST_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -46,11 +51,11 @@ static void *cast5_dupctx(void *ctx) return ret; } -/* cast5128ecb_functions */ +/* ossl_cast5128ecb_functions */ IMPLEMENT_var_keylen_cipher(cast5, CAST, ecb, ECB, CAST5_FLAGS, 128, 64, 0, block) -/* cast5128cbc_functions */ +/* ossl_cast5128cbc_functions */ IMPLEMENT_var_keylen_cipher(cast5, CAST, cbc, CBC, CAST5_FLAGS, 128, 64, 64, block) -/* cast5128ofb64_functions */ +/* ossl_cast5128ofb64_functions */ IMPLEMENT_var_keylen_cipher(cast5, CAST, ofb64, OFB, CAST5_FLAGS, 128, 8, 64, stream) -/* cast5128cfb64_functions */ +/* ossl_cast5128cfb64_functions */ IMPLEMENT_var_keylen_cipher(cast5, CAST, cfb64, CFB, CAST5_FLAGS, 128, 8, 64, stream) diff --git a/providers/implementations/ciphers/cipher_cast5_hw.c b/providers/implementations/ciphers/cipher_cast5_hw.c index 2257b405f0..73f0628e57 100644 --- a/providers/implementations/ciphers/cipher_cast5_hw.c +++ b/providers/implementations/ciphers/cipher_cast5_hw.c @@ -31,7 +31,7 @@ static const PROV_CIPHER_HW cast5_##mode = { \ cipher_hw_cast5_initkey, \ cipher_hw_cast5_##mode##_cipher \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_cast5_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_cast5_##mode(size_t keybits) \ { \ return &cast5_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_chacha20.c b/providers/implementations/ciphers/cipher_chacha20.c index 6759b0e0f9..8e0727ae47 100644 --- a/providers/implementations/ciphers/cipher_chacha20.c +++ b/providers/implementations/ciphers/cipher_chacha20.c @@ -11,6 +11,7 @@ #include "cipher_chacha20.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #define CHACHA20_KEYLEN (CHACHA_KEY_SIZE) @@ -26,28 +27,32 @@ static OSSL_FUNC_cipher_get_ctx_params_fn chacha20_get_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn chacha20_set_ctx_params; static OSSL_FUNC_cipher_gettable_ctx_params_fn chacha20_gettable_ctx_params; static OSSL_FUNC_cipher_settable_ctx_params_fn chacha20_settable_ctx_params; -#define chacha20_cipher cipher_generic_cipher -#define chacha20_update cipher_generic_stream_update -#define chacha20_final cipher_generic_stream_final -#define chacha20_gettable_params cipher_generic_gettable_params +#define chacha20_cipher ossl_cipher_generic_cipher +#define chacha20_update ossl_cipher_generic_stream_update +#define chacha20_final ossl_cipher_generic_stream_final +#define chacha20_gettable_params ossl_cipher_generic_gettable_params void chacha20_initctx(PROV_CHACHA20_CTX *ctx) { - cipher_generic_initkey(ctx, CHACHA20_KEYLEN * 8, - CHACHA20_BLKLEN * 8, - CHACHA20_IVLEN * 8, - 0, CHACHA20_FLAGS, - PROV_CIPHER_HW_chacha20(CHACHA20_KEYLEN * 8), - NULL); + ossl_cipher_generic_initkey(ctx, CHACHA20_KEYLEN * 8, + CHACHA20_BLKLEN * 8, + CHACHA20_IVLEN * 8, + 0, CHACHA20_FLAGS, + ossl_prov_cipher_hw_chacha20(CHACHA20_KEYLEN * 8), + NULL); } static void *chacha20_newctx(void *provctx) { - PROV_CHACHA20_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_CHACHA20_CTX *ctx; - if (ctx != NULL) - chacha20_initctx(ctx); - return ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx != NULL) + chacha20_initctx(ctx); + return ctx; } static void chacha20_freectx(void *vctx) @@ -55,17 +60,17 @@ static void chacha20_freectx(void *vctx) PROV_CHACHA20_CTX *ctx = (PROV_CHACHA20_CTX *)vctx; if (ctx != NULL) { - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } static int chacha20_get_params(OSSL_PARAM params[]) { - return cipher_generic_get_params(params, 0, CHACHA20_FLAGS, - CHACHA20_KEYLEN * 8, - CHACHA20_BLKLEN * 8, - CHACHA20_IVLEN * 8); + return ossl_cipher_generic_get_params(params, 0, CHACHA20_FLAGS, + CHACHA20_KEYLEN * 8, + CHACHA20_BLKLEN * 8, + CHACHA20_IVLEN * 8); } static int chacha20_get_ctx_params(void *vctx, OSSL_PARAM params[]) @@ -91,7 +96,7 @@ static const OSSL_PARAM chacha20_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *chacha20_gettable_ctx_params(void) +const OSSL_PARAM *chacha20_gettable_ctx_params(ossl_unused void *provctx) { return chacha20_known_gettable_ctx_params; } @@ -131,7 +136,7 @@ static const OSSL_PARAM chacha20_known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *chacha20_settable_ctx_params(void) +const OSSL_PARAM *chacha20_settable_ctx_params(ossl_unused void *provctx) { return chacha20_known_settable_ctx_params; } @@ -141,7 +146,8 @@ int chacha20_einit(void *vctx, const unsigned char *key, size_t keylen, { int ret; - ret= cipher_generic_einit(vctx, key, keylen, iv, ivlen); + /* The generic function checks for ossl_prov_is_running() */ + ret= ossl_cipher_generic_einit(vctx, key, keylen, iv, ivlen); if (ret && iv != NULL) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; PROV_CIPHER_HW_CHACHA20 *hw = (PROV_CIPHER_HW_CHACHA20 *)ctx->hw; @@ -156,7 +162,8 @@ int chacha20_dinit(void *vctx, const unsigned char *key, size_t keylen, { int ret; - ret= cipher_generic_dinit(vctx, key, keylen, iv, ivlen); + /* The generic function checks for ossl_prov_is_running() */ + ret= ossl_cipher_generic_dinit(vctx, key, keylen, iv, ivlen); if (ret && iv != NULL) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; PROV_CIPHER_HW_CHACHA20 *hw = (PROV_CIPHER_HW_CHACHA20 *)ctx->hw; @@ -166,8 +173,8 @@ int chacha20_dinit(void *vctx, const unsigned char *key, size_t keylen, return ret; } -/* chacha20_functions */ -const OSSL_DISPATCH chacha20_functions[] = { +/* ossl_chacha20_functions */ +const OSSL_DISPATCH ossl_chacha20_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))chacha20_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))chacha20_freectx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))chacha20_einit }, diff --git a/providers/implementations/ciphers/cipher_chacha20.h b/providers/implementations/ciphers/cipher_chacha20.h index 808570f6dc..c494de7d85 100644 --- a/providers/implementations/ciphers/cipher_chacha20.h +++ b/providers/implementations/ciphers/cipher_chacha20.h @@ -27,7 +27,7 @@ typedef struct prov_cipher_hw_chacha20_st { } PROV_CIPHER_HW_CHACHA20; -const PROV_CIPHER_HW *PROV_CIPHER_HW_chacha20(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_chacha20(size_t keybits); OSSL_FUNC_cipher_encrypt_init_fn chacha20_einit; OSSL_FUNC_cipher_decrypt_init_fn chacha20_dinit; diff --git a/providers/implementations/ciphers/cipher_chacha20_hw.c b/providers/implementations/ciphers/cipher_chacha20_hw.c index dce0a6c11c..06cb6b12d3 100644 --- a/providers/implementations/ciphers/cipher_chacha20_hw.c +++ b/providers/implementations/ciphers/cipher_chacha20_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -114,7 +114,7 @@ static const PROV_CIPHER_HW_CHACHA20 chacha20_hw = { chacha20_initiv }; -const PROV_CIPHER_HW *PROV_CIPHER_HW_chacha20(size_t keybits) +const PROV_CIPHER_HW *ossl_prov_cipher_hw_chacha20(size_t keybits) { return (PROV_CIPHER_HW *)&chacha20_hw; } diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index a93f722551..7a9cc5c20f 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -11,6 +11,7 @@ #include "cipher_chacha20_poly1305.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" @@ -37,23 +38,27 @@ static OSSL_FUNC_cipher_set_ctx_params_fn chacha20_poly1305_set_ctx_params; static OSSL_FUNC_cipher_cipher_fn chacha20_poly1305_cipher; static OSSL_FUNC_cipher_final_fn chacha20_poly1305_final; static OSSL_FUNC_cipher_gettable_ctx_params_fn chacha20_poly1305_gettable_ctx_params; -#define chacha20_poly1305_settable_ctx_params cipher_aead_settable_ctx_params -#define chacha20_poly1305_gettable_params cipher_generic_gettable_params +#define chacha20_poly1305_settable_ctx_params ossl_cipher_aead_settable_ctx_params +#define chacha20_poly1305_gettable_params ossl_cipher_generic_gettable_params #define chacha20_poly1305_update chacha20_poly1305_cipher static void *chacha20_poly1305_newctx(void *provctx) { - PROV_CHACHA20_POLY1305_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_CHACHA20_POLY1305_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { - cipher_generic_initkey(&ctx->base, CHACHA20_POLY1305_KEYLEN * 8, - CHACHA20_POLY1305_BLKLEN * 8, - CHACHA20_POLY1305_IVLEN * 8, - CHACHA20_POLY1305_MODE, - CHACHA20_POLY1305_FLAGS, - PROV_CIPHER_HW_chacha20_poly1305( - CHACHA20_POLY1305_KEYLEN * 8), - NULL); + ossl_cipher_generic_initkey(&ctx->base, CHACHA20_POLY1305_KEYLEN * 8, + CHACHA20_POLY1305_BLKLEN * 8, + CHACHA20_POLY1305_IVLEN * 8, + CHACHA20_POLY1305_MODE, + CHACHA20_POLY1305_FLAGS, + ossl_prov_cipher_hw_chacha20_poly1305( + CHACHA20_POLY1305_KEYLEN * 8), + NULL); ctx->nonce_len = CHACHA20_POLY1305_IVLEN; ctx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; chacha20_initctx(&ctx->chacha); @@ -66,17 +71,17 @@ static void chacha20_poly1305_freectx(void *vctx) PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)vctx; if (ctx != NULL) { - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } } static int chacha20_poly1305_get_params(OSSL_PARAM params[]) { - return cipher_generic_get_params(params, 0, CHACHA20_POLY1305_FLAGS, - CHACHA20_POLY1305_KEYLEN * 8, - CHACHA20_POLY1305_BLKLEN * 8, - CHACHA20_POLY1305_IVLEN * 8); + return ossl_cipher_generic_get_params(params, 0, CHACHA20_POLY1305_FLAGS, + CHACHA20_POLY1305_KEYLEN * 8, + CHACHA20_POLY1305_BLKLEN * 8, + CHACHA20_POLY1305_IVLEN * 8); } static int chacha20_poly1305_get_ctx_params(void *vctx, OSSL_PARAM params[]) @@ -135,7 +140,8 @@ static const OSSL_PARAM chacha20_poly1305_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *chacha20_poly1305_gettable_ctx_params(void) +static const OSSL_PARAM *chacha20_poly1305_gettable_ctx_params + (ossl_unused void *provctx) { return chacha20_poly1305_known_gettable_ctx_params; } @@ -228,7 +234,8 @@ static int chacha20_poly1305_einit(void *vctx, const unsigned char *key, { int ret; - ret = cipher_generic_einit(vctx, key, keylen, iv, ivlen); + /* The generic function checks for ossl_prov_is_running() */ + ret = ossl_cipher_generic_einit(vctx, key, keylen, iv, ivlen); if (ret && iv != NULL) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; PROV_CIPHER_HW_CHACHA20_POLY1305 *hw = @@ -245,7 +252,8 @@ static int chacha20_poly1305_dinit(void *vctx, const unsigned char *key, { int ret; - ret = cipher_generic_dinit(vctx, key, keylen, iv, ivlen); + /* The generic function checks for ossl_prov_is_running() */ + ret = ossl_cipher_generic_dinit(vctx, key, keylen, iv, ivlen); if (ret && iv != NULL) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; PROV_CIPHER_HW_CHACHA20_POLY1305 *hw = @@ -264,6 +272,9 @@ static int chacha20_poly1305_cipher(void *vctx, unsigned char *out, PROV_CIPHER_HW_CHACHA20_POLY1305 *hw = (PROV_CIPHER_HW_CHACHA20_POLY1305 *)ctx->hw; + if (!ossl_prov_is_running()) + return 0; + if (inl == 0) { *outl = 0; return 1; @@ -287,6 +298,9 @@ static int chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl, PROV_CIPHER_HW_CHACHA20_POLY1305 *hw = (PROV_CIPHER_HW_CHACHA20_POLY1305 *)ctx->hw; + if (!ossl_prov_is_running()) + return 0; + if (hw->aead_cipher(ctx, out, outl, NULL, 0) <= 0) return 0; @@ -294,8 +308,8 @@ static int chacha20_poly1305_final(void *vctx, unsigned char *out, size_t *outl, return 1; } -/* chacha20_poly1305_functions */ -const OSSL_DISPATCH chacha20_poly1305_functions[] = { +/* ossl_chacha20_ossl_poly1305_functions */ +const OSSL_DISPATCH ossl_chacha20_ossl_poly1305_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))chacha20_poly1305_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))chacha20_poly1305_freectx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))chacha20_poly1305_einit }, diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.h b/providers/implementations/ciphers/cipher_chacha20_poly1305.h index 00b173d1ed..1f6f0066dc 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.h +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,4 +40,4 @@ typedef struct prov_cipher_hw_chacha_aead_st { size_t flen); } PROV_CIPHER_HW_CHACHA20_POLY1305; -const PROV_CIPHER_HW *PROV_CIPHER_HW_chacha20_poly1305(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_chacha20_poly1305(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c b/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c index d9f314c9b6..8bbae6529a 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c @@ -399,7 +399,7 @@ static const PROV_CIPHER_HW_CHACHA20_POLY1305 chacha20poly1305_hw = chacha_poly1305_tls_iv_set_fixed }; -const PROV_CIPHER_HW *PROV_CIPHER_HW_chacha20_poly1305(size_t keybits) +const PROV_CIPHER_HW *ossl_prov_cipher_hw_chacha20_poly1305(size_t keybits) { return (PROV_CIPHER_HW *)&chacha20poly1305_hw; } diff --git a/providers/implementations/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c index 4974234efd..345adfab60 100644 --- a/providers/implementations/ciphers/cipher_des.c +++ b/providers/implementations/ciphers/cipher_des.c @@ -17,6 +17,7 @@ #include "cipher_des.h" #include #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" /* TODO(3.0) Figure out what flags need to be here */ @@ -32,19 +33,27 @@ static void *des_newctx(void *provctx, size_t kbits, size_t blkbits, size_t ivbits, unsigned int mode, uint64_t flags, const PROV_CIPHER_HW *hw) { - PROV_DES_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_DES_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, hw, - provctx); + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, mode, flags, + hw, provctx); return ctx; } static void *des_dupctx(void *ctx) { PROV_DES_CTX *in = (PROV_DES_CTX *)ctx; - PROV_DES_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_DES_CTX *ret; + + if (!ossl_prov_is_running()) + return NULL; + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -58,7 +67,7 @@ static void des_freectx(void *vctx) { PROV_DES_CTX *ctx = (PROV_DES_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } @@ -67,12 +76,15 @@ static int des_init(void *vctx, const unsigned char *key, size_t keylen, { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->num = 0; ctx->bufsz = 0; ctx->enc = enc; if (iv != NULL) { - if (!cipher_generic_initiv(ctx, iv, ivlen)) + if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } @@ -119,7 +131,7 @@ static int des_get_ctx_params(void *vctx, OSSL_PARAM params[]) PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; OSSL_PARAM *p; - if (!cipher_generic_get_ctx_params(vctx, params)) + if (!ossl_cipher_generic_get_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); @@ -142,16 +154,16 @@ static void *des_##lcmode##_newctx(void *provctx) \ static OSSL_FUNC_cipher_get_params_fn des_##lcmode##_get_params; \ static int des_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ -const OSSL_DISPATCH des_##lcmode##_functions[] = { \ +const OSSL_DISPATCH ossl_##des_##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))des_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))des_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, \ - (void (*)(void))cipher_generic_##block##_update }, \ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##block##_final },\ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + (void (*)(void))ossl_cipher_generic_##block##_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##block##_final },\ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void))des_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))des_dupctx }, \ @@ -159,26 +171,26 @@ const OSSL_DISPATCH des_##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))des_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))des_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))des_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_set_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ { 0, NULL } \ } -/* des_ecb_functions */ +/* ossl_des_ecb_functions */ IMPLEMENT_des_cipher(des, ecb, ECB, DES_FLAGS, 64, 64, 0, block); -/* des_cbc_functions */ +/* ossl_des_cbc_functions */ IMPLEMENT_des_cipher(des, cbc, CBC, DES_FLAGS, 64, 64, 64, block); -/* des_ofb64_functions */ +/* ossl_des_ofb64_functions */ IMPLEMENT_des_cipher(des, ofb64, OFB, DES_FLAGS, 64, 8, 64, stream); -/* des_cfb64_functions */ +/* ossl_des_cfb64_functions */ IMPLEMENT_des_cipher(des, cfb64, CFB, DES_FLAGS, 64, 8, 64, stream); -/* des_cfb1_functions */ +/* ossl_des_cfb1_functions */ IMPLEMENT_des_cipher(des, cfb1, CFB, DES_FLAGS, 64, 8, 64, stream); -/* des_cfb8_functions */ +/* ossl_des_cfb8_functions */ IMPLEMENT_des_cipher(des, cfb8, CFB, DES_FLAGS, 64, 8, 64, stream); diff --git a/providers/implementations/ciphers/cipher_desx_hw.c b/providers/implementations/ciphers/cipher_desx_hw.c index dac6c396b1..7dc4c50ef5 100644 --- a/providers/implementations/ciphers/cipher_desx_hw.c +++ b/providers/implementations/ciphers/cipher_desx_hw.c @@ -73,7 +73,8 @@ static const PROV_CIPHER_HW desx_cbc = cipher_hw_desx_cbc, cipher_hw_desx_copyctx }; -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void) + +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_desx_cbc(void) { return &desx_cbc; } diff --git a/providers/implementations/ciphers/cipher_idea.c b/providers/implementations/ciphers/cipher_idea.c index 7fc5d8403d..bc716290a4 100644 --- a/providers/implementations/ciphers/cipher_idea.c +++ b/providers/implementations/ciphers/cipher_idea.c @@ -18,6 +18,7 @@ #include "cipher_idea.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn idea_freectx; static OSSL_FUNC_cipher_dupctx_fn idea_dupctx; @@ -26,15 +27,19 @@ static void idea_freectx(void *vctx) { PROV_IDEA_CTX *ctx = (PROV_IDEA_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *idea_dupctx(void *ctx) { PROV_IDEA_CTX *in = (PROV_IDEA_CTX *)ctx; - PROV_IDEA_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_IDEA_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -44,11 +49,11 @@ static void *idea_dupctx(void *ctx) return ret; } -/* idea128ecb_functions */ +/* ossl_idea128ecb_functions */ IMPLEMENT_generic_cipher(idea, IDEA, ecb, ECB, 0, 128, 64, 0, block) -/* idea128cbc_functions */ +/* ossl_idea128cbc_functions */ IMPLEMENT_generic_cipher(idea, IDEA, cbc, CBC, 0, 128, 64, 64, block) -/* idea128ofb64_functions */ +/* ossl_idea128ofb64_functions */ IMPLEMENT_generic_cipher(idea, IDEA, ofb64, OFB, 0, 128, 8, 64, stream) -/* idea128cfb64_functions */ +/* ossl_idea128cfb64_functions */ IMPLEMENT_generic_cipher(idea, IDEA, cfb64, CFB, 0, 128, 8, 64, stream) diff --git a/providers/implementations/ciphers/cipher_idea.h b/providers/implementations/ciphers/cipher_idea.h index ebe590b93c..212efa8af5 100644 --- a/providers/implementations/ciphers/cipher_idea.h +++ b/providers/implementations/ciphers/cipher_idea.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ typedef struct prov_idea_ctx_st { } ks; } PROV_IDEA_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_idea_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_idea_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_idea_ofb64(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_idea_cfb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_idea_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_idea_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_idea_ofb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_idea_cfb64(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_idea_hw.c b/providers/implementations/ciphers/cipher_idea_hw.c index 009ef358d0..1c451b77ed 100644 --- a/providers/implementations/ciphers/cipher_idea_hw.c +++ b/providers/implementations/ciphers/cipher_idea_hw.c @@ -43,7 +43,7 @@ static const PROV_CIPHER_HW idea_##mode = { \ cipher_hw_idea_initkey, \ cipher_hw_idea_##mode##_cipher \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_idea_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_idea_##mode(size_t keybits) \ { \ return &idea_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_null.c b/providers/implementations/ciphers/cipher_null.c index 713d29e3e8..c3ebb25c28 100644 --- a/providers/implementations/ciphers/cipher_null.c +++ b/providers/implementations/ciphers/cipher_null.c @@ -12,6 +12,7 @@ #include #include "prov/implementations.h" #include "prov/ciphercommon.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" typedef struct prov_cipher_null_ctx_st { @@ -23,6 +24,9 @@ typedef struct prov_cipher_null_ctx_st { static OSSL_FUNC_cipher_newctx_fn null_newctx; static void *null_newctx(void *provctx) { + if (!ossl_prov_is_running()) + return NULL; + return OPENSSL_zalloc(sizeof(PROV_CIPHER_NULL_CTX)); } @@ -38,6 +42,9 @@ static int null_einit(void *vctx, const unsigned char *key, size_t keylen, { PROV_CIPHER_NULL_CTX *ctx = (PROV_CIPHER_NULL_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->enc = 1; return 1; } @@ -46,6 +53,9 @@ static OSSL_FUNC_cipher_decrypt_init_fn null_dinit; static int null_dinit(void *vctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen) { + if (!ossl_prov_is_running()) + return 0; + return 1; } @@ -55,6 +65,9 @@ static int null_cipher(void *vctx, unsigned char *out, size_t *outl, { PROV_CIPHER_NULL_CTX *ctx = (PROV_CIPHER_NULL_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (!ctx->enc && ctx->tlsmacsize > 0) { /* * TLS NULL cipher as per: @@ -77,6 +90,9 @@ static OSSL_FUNC_cipher_final_fn null_final; static int null_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { + if (!ossl_prov_is_running()) + return 0; + *outl = 0; return 1; } @@ -84,7 +100,7 @@ static int null_final(void *vctx, unsigned char *out, size_t *outl, static OSSL_FUNC_cipher_get_params_fn null_get_params; static int null_get_params(OSSL_PARAM params[]) { - return cipher_generic_get_params(params, 0, 0, 0, 8, 0); + return ossl_cipher_generic_get_params(params, 0, 0, 0, 8, 0); } static const OSSL_PARAM null_known_gettable_ctx_params[] = { @@ -95,7 +111,7 @@ static const OSSL_PARAM null_known_gettable_ctx_params[] = { }; static OSSL_FUNC_cipher_gettable_ctx_params_fn null_gettable_ctx_params; -static const OSSL_PARAM *null_gettable_ctx_params(void) +static const OSSL_PARAM *null_gettable_ctx_params(ossl_unused void *provctx) { return null_known_gettable_ctx_params; } @@ -131,7 +147,7 @@ static const OSSL_PARAM null_known_settable_ctx_params[] = { }; static OSSL_FUNC_cipher_settable_ctx_params_fn null_settable_ctx_params; -static const OSSL_PARAM *null_settable_ctx_params(void) +static const OSSL_PARAM *null_settable_ctx_params(ossl_unused void *provctx) { return null_known_settable_ctx_params; } @@ -154,7 +170,7 @@ static int null_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -const OSSL_DISPATCH null_functions[] = { +const OSSL_DISPATCH ossl_null_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void)) null_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) null_freectx }, @@ -166,7 +182,7 @@ const OSSL_DISPATCH null_functions[] = { { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))null_cipher }, { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void)) null_get_params }, { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, - (void (*)(void))cipher_generic_gettable_params }, + (void (*)(void))ossl_cipher_generic_gettable_params }, { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))null_get_ctx_params }, { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))null_gettable_ctx_params }, diff --git a/providers/implementations/ciphers/cipher_rc2.c b/providers/implementations/ciphers/cipher_rc2.c index d1558be002..b7c244f245 100644 --- a/providers/implementations/ciphers/cipher_rc2.c +++ b/providers/implementations/ciphers/cipher_rc2.c @@ -17,6 +17,7 @@ #include "cipher_rc2.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #define RC2_40_MAGIC 0xa0 @@ -32,15 +33,19 @@ static void rc2_freectx(void *vctx) { PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *rc2_dupctx(void *ctx) { PROV_RC2_CTX *in = (PROV_RC2_CTX *)ctx; - PROV_RC2_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_RC2_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -83,7 +88,7 @@ static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[]) PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; OSSL_PARAM *p; - if (!cipher_generic_get_ctx_params(vctx, params)) + if (!ossl_cipher_generic_get_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RC2_KEYBITS); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_bits)) { @@ -137,7 +142,7 @@ static int rc2_set_ctx_params(void *vctx, OSSL_PARAM params[]) PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; const OSSL_PARAM *p; - if (!cipher_var_keylen_set_ctx_params(vctx, params)) + if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_RC2_KEYBITS); if (p != NULL) { @@ -160,7 +165,7 @@ static int rc2_set_ctx_params(void *vctx, OSSL_PARAM params[]) || ((size_t)ASN1_TYPE_get_int_octetstring(type, &num, iv, ctx->base.ivlen) != ctx->base.ivlen) - || !cipher_generic_initiv(&ctx->base, iv, ctx->base.ivlen) + || !ossl_cipher_generic_initiv(&ctx->base, iv, ctx->base.ivlen) || (ctx->key_bits = rc2_magic_to_keybits(num)) == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); ret = 0; @@ -192,35 +197,39 @@ CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc2) static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ { \ - PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + PROV_##UCALG##_CTX *ctx; \ + if (!ossl_prov_is_running()) \ + return NULL; \ + ctx = OPENSSL_zalloc(sizeof(*ctx)); \ if (ctx != NULL) { \ - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ EVP_CIPH_##UCMODE##_MODE, flags, \ - PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \ + ossl_prov_cipher_hw_##alg##_##lcmode(kbits), \ + NULL); \ ctx->key_bits = kbits; \ } \ return ctx; \ } \ -const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void))rc2_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ @@ -232,16 +241,16 @@ const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ { 0, NULL } \ }; -/* rc2128ecb_functions */ +/* ossl_rc2128ecb_functions */ IMPLEMENT_cipher(rc2, RC2, ecb, ECB, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 0, block) -/* rc2128cbc_functions */ +/* ossl_rc2128cbc_functions */ IMPLEMENT_cipher(rc2, RC2, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 64, block) -/* rc240cbc_functions */ +/* ossl_rc240cbc_functions */ IMPLEMENT_cipher(rc2, RC2, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 40, 64, 64, block) -/* rc264cbc_functions */ +/* ossl_rc264cbc_functions */ IMPLEMENT_cipher(rc2, RC2, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 64, 64, 64, block) -/* rc2128ofb128_functions */ +/* ossl_rc2128ofb128_functions */ IMPLEMENT_cipher(rc2, RC2, ofb128, OFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream) -/* rc2128cfb128_functions */ +/* ossl_rc2128cfb128_functions */ IMPLEMENT_cipher(rc2, RC2, cfb128, CFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream) diff --git a/providers/implementations/ciphers/cipher_rc2.h b/providers/implementations/ciphers/cipher_rc2.h index 82f0f6ca74..7a4bea5ac4 100644 --- a/providers/implementations/ciphers/cipher_rc2.h +++ b/providers/implementations/ciphers/cipher_rc2.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,10 +19,10 @@ typedef struct prov_rc2_ctx_st { size_t key_bits; } PROV_RC2_CTX; -#define PROV_CIPHER_HW_rc2_ofb128 PROV_CIPHER_HW_rc2_ofb64 -#define PROV_CIPHER_HW_rc2_cfb128 PROV_CIPHER_HW_rc2_cfb64 +#define ossl_prov_cipher_hw_rc2_ofb128 ossl_prov_cipher_hw_rc2_ofb64 +#define ossl_prov_cipher_hw_rc2_cfb128 ossl_prov_cipher_hw_rc2_cfb64 -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc2_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc2_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc2_ofb64(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc2_cfb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc2_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc2_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc2_ofb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc2_cfb64(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_rc2_hw.c b/providers/implementations/ciphers/cipher_rc2_hw.c index 2583172bd8..da9ff729cd 100644 --- a/providers/implementations/ciphers/cipher_rc2_hw.c +++ b/providers/implementations/ciphers/cipher_rc2_hw.c @@ -32,7 +32,7 @@ static const PROV_CIPHER_HW rc2_##mode = { \ cipher_hw_rc2_initkey, \ cipher_hw_rc2_##mode##_cipher \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc2_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc2_##mode(size_t keybits) \ { \ return &rc2_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_rc4.c b/providers/implementations/ciphers/cipher_rc4.c index 4660185d45..91644fca59 100644 --- a/providers/implementations/ciphers/cipher_rc4.c +++ b/providers/implementations/ciphers/cipher_rc4.c @@ -17,6 +17,7 @@ #include "cipher_rc4.h" #include "prov/implementations.h" +#include "prov/providercommon.h" /* TODO (3.0) Figure out what flags are required */ #define RC4_FLAGS EVP_CIPH_FLAG_DEFAULT_ASN1 @@ -28,15 +29,19 @@ static void rc4_freectx(void *vctx) { PROV_RC4_CTX *ctx = (PROV_RC4_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *rc4_dupctx(void *ctx) { PROV_RC4_CTX *in = (PROV_RC4_CTX *)ctx; - PROV_RC4_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_RC4_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -50,45 +55,48 @@ static void *rc4_dupctx(void *ctx) static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_get_params; \ static int alg##_##kbits##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, 0, flags, \ + return ossl_cipher_generic_get_params(params, 0, flags, \ kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_newctx; \ static void * alg##_##kbits##_newctx(void *provctx) \ { \ - PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + PROV_##UCALG##_CTX *ctx; \ + if (!ossl_prov_is_running()) \ + return NULL; \ + ctx = OPENSSL_zalloc(sizeof(*ctx)); \ if (ctx != NULL) { \ - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, 0, flags, \ - PROV_CIPHER_HW_##alg(kbits), NULL); \ + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, 0, flags, \ + ossl_prov_cipher_hw_##alg(kbits), NULL); \ } \ return ctx; \ } \ -const OSSL_DISPATCH alg##kbits##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void)) alg##_##kbits##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_get_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_var_keylen_set_ctx_params }, \ + (void (*)(void))ossl_cipher_var_keylen_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_var_keylen_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_var_keylen_settable_ctx_params }, \ { 0, NULL } \ }; -/* rc440_functions */ +/* ossl_rc440_functions */ IMPLEMENT_cipher(rc4, RC4, EVP_CIPH_VARIABLE_LENGTH, 40, 8, 0, stream) -/* rc4128_functions */ +/* ossl_rc4128_functions */ IMPLEMENT_cipher(rc4, RC4, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 0, stream) diff --git a/providers/implementations/ciphers/cipher_rc4.h b/providers/implementations/ciphers/cipher_rc4.h index a2d0a50f21..40d822ceb2 100644 --- a/providers/implementations/ciphers/cipher_rc4.h +++ b/providers/implementations/ciphers/cipher_rc4.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,4 +18,4 @@ typedef struct prov_rc4_ctx_st { } ks; } PROV_RC4_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc4(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc4(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c index d9535e23ce..69d47b03fe 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c @@ -17,6 +17,7 @@ #include "cipher_rc4_hmac_md5.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" /* TODO(3.0) Figure out what flags are required */ @@ -37,24 +38,29 @@ static OSSL_FUNC_cipher_gettable_ctx_params_fn rc4_hmac_md5_gettable_ctx_params; static OSSL_FUNC_cipher_set_ctx_params_fn rc4_hmac_md5_set_ctx_params; static OSSL_FUNC_cipher_settable_ctx_params_fn rc4_hmac_md5_settable_ctx_params; static OSSL_FUNC_cipher_get_params_fn rc4_hmac_md5_get_params; -#define rc4_hmac_md5_gettable_params cipher_generic_gettable_params -#define rc4_hmac_md5_einit cipher_generic_einit -#define rc4_hmac_md5_dinit cipher_generic_dinit -#define rc4_hmac_md5_update cipher_generic_stream_update -#define rc4_hmac_md5_final cipher_generic_stream_final -#define rc4_hmac_md5_cipher cipher_generic_cipher +#define rc4_hmac_md5_gettable_params ossl_cipher_generic_gettable_params +#define rc4_hmac_md5_einit ossl_cipher_generic_einit +#define rc4_hmac_md5_dinit ossl_cipher_generic_dinit +#define rc4_hmac_md5_update ossl_cipher_generic_stream_update +#define rc4_hmac_md5_final ossl_cipher_generic_stream_final +#define rc4_hmac_md5_cipher ossl_cipher_generic_cipher static void *rc4_hmac_md5_newctx(void *provctx) { - PROV_RC4_HMAC_MD5_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + PROV_RC4_HMAC_MD5_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) - cipher_generic_initkey(ctx, RC4_HMAC_MD5_KEY_BITS, - RC4_HMAC_MD5_BLOCK_BITS, - RC4_HMAC_MD5_IV_BITS, - RC4_HMAC_MD5_MODE, RC4_HMAC_MD5_FLAGS, - PROV_CIPHER_HW_rc4_hmac_md5(RC4_HMAC_MD5_KEY_BITS), - NULL); + ossl_cipher_generic_initkey(ctx, RC4_HMAC_MD5_KEY_BITS, + RC4_HMAC_MD5_BLOCK_BITS, + RC4_HMAC_MD5_IV_BITS, + RC4_HMAC_MD5_MODE, RC4_HMAC_MD5_FLAGS, + ossl_prov_cipher_hw_rc4_hmac_md5( + RC4_HMAC_MD5_KEY_BITS + ), NULL); return ctx; } @@ -62,7 +68,7 @@ static void rc4_hmac_md5_freectx(void *vctx) { PROV_RC4_HMAC_MD5_CTX *ctx = (PROV_RC4_HMAC_MD5_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } @@ -72,7 +78,7 @@ static const OSSL_PARAM rc4_hmac_md5_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *rc4_hmac_md5_gettable_ctx_params(void) +const OSSL_PARAM *rc4_hmac_md5_gettable_ctx_params(ossl_unused void *provctx) { return rc4_hmac_md5_known_gettable_ctx_params; } @@ -107,7 +113,7 @@ static const OSSL_PARAM rc4_hmac_md5_known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD, NULL, 0), OSSL_PARAM_END }; -const OSSL_PARAM *rc4_hmac_md5_settable_ctx_params(void) +const OSSL_PARAM *rc4_hmac_md5_settable_ctx_params(ossl_unused void *provctx) { return rc4_hmac_md5_known_settable_ctx_params; } @@ -168,14 +174,14 @@ static int rc4_hmac_md5_set_ctx_params(void *vctx, const OSSL_PARAM params[]) static int rc4_hmac_md5_get_params(OSSL_PARAM params[]) { - return cipher_generic_get_params(params, RC4_HMAC_MD5_MODE, + return ossl_cipher_generic_get_params(params, RC4_HMAC_MD5_MODE, RC4_HMAC_MD5_FLAGS, RC4_HMAC_MD5_KEY_BITS, RC4_HMAC_MD5_BLOCK_BITS, RC4_HMAC_MD5_IV_BITS); } -const OSSL_DISPATCH rc4_hmac_md5_functions[] = { +const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[] = { { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))rc4_hmac_md5_newctx }, { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))rc4_hmac_md5_freectx }, { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc4_hmac_md5_einit }, diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5.h b/providers/implementations/ciphers/cipher_rc4_hmac_md5.h index ff7ed7ef86..1697aabbf3 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5.h +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -30,4 +30,4 @@ typedef struct prov_cipher_hw_rc4_hmac_md5_st { } PROV_CIPHER_HW_RC4_HMAC_MD5; -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc4_hmac_md5(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc4_hmac_md5(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5_hw.c b/providers/implementations/ciphers/cipher_rc4_hmac_md5_hw.c index 54b8f08628..73233a2de7 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5_hw.c +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5_hw.c @@ -225,7 +225,8 @@ static const PROV_CIPHER_HW_RC4_HMAC_MD5 rc4_hmac_md5_hw = { cipher_hw_rc4_hmac_md5_tls_init, cipher_hw_rc4_hmac_md5_init_mackey }; -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc4_hmac_md5(size_t keybits) + +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc4_hmac_md5(size_t keybits) { return (PROV_CIPHER_HW *)&rc4_hmac_md5_hw; } diff --git a/providers/implementations/ciphers/cipher_rc4_hw.c b/providers/implementations/ciphers/cipher_rc4_hw.c index 8d88aca73c..09192b5d5e 100644 --- a/providers/implementations/ciphers/cipher_rc4_hw.c +++ b/providers/implementations/ciphers/cipher_rc4_hw.c @@ -37,7 +37,7 @@ static const PROV_CIPHER_HW rc4_hw = { cipher_hw_rc4_initkey, cipher_hw_rc4_cipher }; -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc4(size_t keybits) +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc4(size_t keybits) { return &rc4_hw; } diff --git a/providers/implementations/ciphers/cipher_rc5.c b/providers/implementations/ciphers/cipher_rc5.c index 68ce6fdd91..80de5f4bdd 100644 --- a/providers/implementations/ciphers/cipher_rc5.c +++ b/providers/implementations/ciphers/cipher_rc5.c @@ -17,6 +17,7 @@ #include "cipher_rc5.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" static OSSL_FUNC_cipher_freectx_fn rc5_freectx; @@ -28,15 +29,19 @@ static void rc5_freectx(void *vctx) { PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *rc5_dupctx(void *ctx) { PROV_RC5_CTX *in = (PROV_RC5_CTX *)ctx; - PROV_RC5_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_RC5_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -51,7 +56,7 @@ static int rc5_set_ctx_params(void *vctx, const OSSL_PARAM params[]) PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx; const OSSL_PARAM *p; - if (!cipher_var_keylen_set_ctx_params(vctx, params)) + if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ROUNDS); @@ -88,7 +93,7 @@ static int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[]) PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx; OSSL_PARAM *p; - if (!cipher_generic_get_ctx_params(vctx, params)) + if (!ossl_cipher_generic_get_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ROUNDS); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->rounds)) { @@ -103,35 +108,39 @@ static int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[]) static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ { \ - PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + PROV_##UCALG##_CTX *ctx; \ + if (!ossl_prov_is_running()) \ + return NULL; \ + ctx = OPENSSL_zalloc(sizeof(*ctx)); \ if (ctx != NULL) { \ - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ - EVP_CIPH_##UCMODE##_MODE, flags, \ - PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \ + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ + EVP_CIPH_##UCMODE##_MODE, flags, \ + ossl_prov_cipher_hw_##alg##_##lcmode(kbits),\ + NULL); \ ctx->rounds = RC5_12_ROUNDS; \ } \ return ctx; \ } \ -const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit },\ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit },\ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void))rc5_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ @@ -143,11 +152,11 @@ const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ { 0, NULL } \ }; -/* rc5128ecb_functions */ +/* ossl_rc5128ecb_functions */ IMPLEMENT_cipher(rc5, RC5, ecb, ECB, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 0, block) -/* rc5128cbc_functions */ +/* ossl_rc5128cbc_functions */ IMPLEMENT_cipher(rc5, RC5, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 64, block) -/* rc5128ofb64_functions */ +/* ossl_rc5128ofb64_functions */ IMPLEMENT_cipher(rc5, RC5, ofb64, OFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream) -/* rc5128cfb64_functions */ +/* ossl_rc5128cfb64_functions */ IMPLEMENT_cipher(rc5, RC5, cfb64, CFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream) diff --git a/providers/implementations/ciphers/cipher_rc5.h b/providers/implementations/ciphers/cipher_rc5.h index fe0d09f710..c630e7c87b 100644 --- a/providers/implementations/ciphers/cipher_rc5.h +++ b/providers/implementations/ciphers/cipher_rc5.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,7 +19,7 @@ typedef struct prov_blowfish_ctx_st { unsigned int rounds; /* number of rounds */ } PROV_RC5_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_ofb64(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_cfb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc5_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc5_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc5_ofb64(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc5_cfb64(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_rc5_hw.c b/providers/implementations/ciphers/cipher_rc5_hw.c index 0d3d513148..898bd383f9 100644 --- a/providers/implementations/ciphers/cipher_rc5_hw.c +++ b/providers/implementations/ciphers/cipher_rc5_hw.c @@ -30,7 +30,7 @@ static const PROV_CIPHER_HW rc5_##mode = { \ cipher_hw_rc5_initkey, \ cipher_hw_rc5_##mode##_cipher \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_rc5_##mode(size_t keybits) \ { \ return &rc5_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_seed.c b/providers/implementations/ciphers/cipher_seed.c index 53520b3c4d..bae6a8e530 100644 --- a/providers/implementations/ciphers/cipher_seed.c +++ b/providers/implementations/ciphers/cipher_seed.c @@ -17,6 +17,7 @@ #include "cipher_seed.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn seed_freectx; static OSSL_FUNC_cipher_dupctx_fn seed_dupctx; @@ -25,15 +26,19 @@ static void seed_freectx(void *vctx) { PROV_SEED_CTX *ctx = (PROV_SEED_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *seed_dupctx(void *ctx) { PROV_SEED_CTX *in = (PROV_SEED_CTX *)ctx; - PROV_SEED_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_SEED_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -43,11 +48,11 @@ static void *seed_dupctx(void *ctx) return ret; } -/* seed128ecb_functions */ +/* ossl_seed128ecb_functions */ IMPLEMENT_generic_cipher(seed, SEED, ecb, ECB, 0, 128, 128, 0, block) -/* seed128cbc_functions */ +/* ossl_seed128cbc_functions */ IMPLEMENT_generic_cipher(seed, SEED, cbc, CBC, 0, 128, 128, 128, block) -/* seed128ofb128_functions */ +/* ossl_seed128ofb128_functions */ IMPLEMENT_generic_cipher(seed, SEED, ofb128, OFB, 0, 128, 8, 128, stream) -/* seed128cfb128_functions */ +/* ossl_seed128cfb128_functions */ IMPLEMENT_generic_cipher(seed, SEED, cfb128, CFB, 0, 128, 8, 128, stream) diff --git a/providers/implementations/ciphers/cipher_seed.h b/providers/implementations/ciphers/cipher_seed.h index 976af35005..9006a9183b 100644 --- a/providers/implementations/ciphers/cipher_seed.h +++ b/providers/implementations/ciphers/cipher_seed.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ typedef struct prov_seed_ctx_st { } ks; } PROV_SEED_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_seed_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_seed_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_seed_ofb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_seed_cfb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_seed_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_seed_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_seed_ofb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_seed_cfb128(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_seed_hw.c b/providers/implementations/ciphers/cipher_seed_hw.c index 016b3bc221..2d1dba92bc 100644 --- a/providers/implementations/ciphers/cipher_seed_hw.c +++ b/providers/implementations/ciphers/cipher_seed_hw.c @@ -31,7 +31,7 @@ static const PROV_CIPHER_HW seed_##mode = { \ cipher_hw_seed_initkey, \ cipher_hw_seed_##mode##_cipher \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_seed_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_seed_##mode(size_t keybits) \ { \ return &seed_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_sm4.c b/providers/implementations/ciphers/cipher_sm4.c index a5920562fc..6cf2731c6d 100644 --- a/providers/implementations/ciphers/cipher_sm4.c +++ b/providers/implementations/ciphers/cipher_sm4.c @@ -11,6 +11,7 @@ #include "cipher_sm4.h" #include "prov/implementations.h" +#include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn sm4_freectx; static OSSL_FUNC_cipher_dupctx_fn sm4_dupctx; @@ -19,15 +20,19 @@ static void sm4_freectx(void *vctx) { PROV_SM4_CTX *ctx = (PROV_SM4_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *sm4_dupctx(void *ctx) { PROV_SM4_CTX *in = (PROV_SM4_CTX *)ctx; - PROV_SM4_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_SM4_CTX *ret; + if (!ossl_prov_is_running()) + return NULL; + + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -37,13 +42,13 @@ static void *sm4_dupctx(void *ctx) return ret; } -/* sm4128ecb_functions */ +/* ossl_sm4128ecb_functions */ IMPLEMENT_generic_cipher(sm4, SM4, ecb, ECB, 0, 128, 128, 0, block) -/* sm4128cbc_functions */ +/* ossl_sm4128cbc_functions */ IMPLEMENT_generic_cipher(sm4, SM4, cbc, CBC, 0, 128, 128, 128, block) -/* sm4128ctr_functions */ +/* ossl_sm4128ctr_functions */ IMPLEMENT_generic_cipher(sm4, SM4, ctr, CTR, 0, 128, 8, 128, stream) -/* sm4128ofb128_functions */ +/* ossl_sm4128ofb128_functions */ IMPLEMENT_generic_cipher(sm4, SM4, ofb128, OFB, 0, 128, 8, 128, stream) -/* sm4128cfb128_functions */ +/* ossl_sm4128cfb128_functions */ IMPLEMENT_generic_cipher(sm4, SM4, cfb128, CFB, 0, 128, 8, 128, stream) diff --git a/providers/implementations/ciphers/cipher_sm4.h b/providers/implementations/ciphers/cipher_sm4.h index d5c9633552..f7f833fcb4 100644 --- a/providers/implementations/ciphers/cipher_sm4.h +++ b/providers/implementations/ciphers/cipher_sm4.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,8 +18,8 @@ typedef struct prov_cast_ctx_st { } ks; } PROV_SM4_CTX; -const PROV_CIPHER_HW *PROV_CIPHER_HW_sm4_cbc(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_sm4_ecb(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_sm4_ctr(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_sm4_ofb128(size_t keybits); -const PROV_CIPHER_HW *PROV_CIPHER_HW_sm4_cfb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_cbc(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_ecb(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_ctr(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_ofb128(size_t keybits); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_cfb128(size_t keybits); diff --git a/providers/implementations/ciphers/cipher_sm4_hw.c b/providers/implementations/ciphers/cipher_sm4_hw.c index 73e88280c2..5cfa81d46f 100644 --- a/providers/implementations/ciphers/cipher_sm4_hw.c +++ b/providers/implementations/ciphers/cipher_sm4_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,10 +31,10 @@ IMPLEMENT_CIPHER_HW_COPYCTX(cipher_hw_sm4_copyctx, PROV_SM4_CTX) # define PROV_CIPHER_HW_sm4_mode(mode) \ static const PROV_CIPHER_HW sm4_##mode = { \ cipher_hw_sm4_initkey, \ - cipher_hw_chunked_##mode, \ + ossl_cipher_hw_chunked_##mode, \ cipher_hw_sm4_copyctx \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_sm4_##mode(size_t keybits) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_sm4_##mode(size_t keybits) \ { \ return &sm4_##mode; \ } diff --git a/providers/implementations/ciphers/cipher_tdes.c b/providers/implementations/ciphers/cipher_tdes.c index 82af8bdc16..c9fb1ceda7 100644 --- a/providers/implementations/ciphers/cipher_tdes.c +++ b/providers/implementations/ciphers/cipher_tdes.c @@ -23,7 +23,7 @@ * TODO(3.0) - ECB mode does not use an IV - but existing test code is setting * an IV. Fixing this could potentially make applications break. */ -/* tdes_ede3_ecb_functions */ +/* ossl_tdes_ede3_ecb_functions */ IMPLEMENT_tdes_cipher(ede3, EDE3, ecb, ECB, TDES_FLAGS, 64*3, 64, 64, block); -/* tdes_ede3_cbc_functions */ +/* ossl_tdes_ede3_cbc_functions */ IMPLEMENT_tdes_cipher(ede3, EDE3, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block); diff --git a/providers/implementations/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h index 7bb689d583..081a00fffa 100644 --- a/providers/implementations/ciphers/cipher_tdes.h +++ b/providers/implementations/ciphers/cipher_tdes.h @@ -30,27 +30,28 @@ typedef struct prov_tdes_ctx_st { } PROV_TDES_CTX; -#define IMPLEMENT_tdes_cipher(type, UCTYPE, lcmode, UCMODE, flags, \ +#define IMPLEMENT_tdes_cipher(type, UCTYPE, lcmode, UCMODE, flags, \ kbits, blkbits, ivbits, block) \ -static OSSL_FUNC_cipher_newctx_fn tdes_##type##_##lcmode##_newctx; \ +static OSSL_FUNC_cipher_newctx_fn tdes_##type##_##lcmode##_newctx; \ static void *tdes_##type##_##lcmode##_newctx(void *provctx) \ { \ return tdes_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, kbits, blkbits, \ - ivbits, flags, PROV_CIPHER_HW_tdes_##type##_##lcmode());\ + ivbits, flags, \ + ossl_prov_cipher_hw_tdes_##type##_##lcmode()); \ } \ -static OSSL_FUNC_cipher_get_params_fn tdes_##type##_##lcmode##_get_params; \ +static OSSL_FUNC_cipher_get_params_fn tdes_##type##_##lcmode##_get_params; \ static int tdes_##type##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ -const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = { \ +const OSSL_DISPATCH ossl_tdes_##type##_##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))tdes_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))tdes_dinit }, \ { OSSL_FUNC_CIPHER_UPDATE, \ - (void (*)(void))cipher_generic_##block##_update }, \ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##block##_final },\ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + (void (*)(void))ossl_cipher_generic_##block##_update }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##block##_final },\ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void))tdes_##type##_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))tdes_dupctx }, \ @@ -58,14 +59,14 @@ const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))tdes_##type##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))tdes_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))tdes_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_set_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ { 0, NULL } \ } @@ -78,24 +79,25 @@ OSSL_FUNC_cipher_decrypt_init_fn tdes_dinit; OSSL_FUNC_cipher_get_ctx_params_fn tdes_get_ctx_params; OSSL_FUNC_cipher_gettable_ctx_params_fn tdes_gettable_ctx_params; -#define PROV_CIPHER_HW_tdes_mode(type, mode) \ +#define PROV_CIPHER_HW_tdes_mode(type, mode) \ static const PROV_CIPHER_HW type##_##mode = { \ - cipher_hw_tdes_##type##_initkey, \ - cipher_hw_tdes_##mode, \ - cipher_hw_tdes_copyctx \ + ossl_cipher_hw_tdes_##type##_initkey, \ + ossl_cipher_hw_tdes_##mode, \ + ossl_cipher_hw_tdes_copyctx \ }; \ -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_##type##_##mode(void) \ +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_##type##_##mode(void) \ { \ return &type##_##mode; \ } -int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, - size_t keylen); -void cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src); -int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); +int ossl_cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, size_t keylen); +void ossl_cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, + const PROV_CIPHER_CTX *src); +int ossl_cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +int ossl_cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cbc(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ecb(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede3_cbc(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede3_ecb(void); diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c index a226e2aac4..17b8ce40b0 100644 --- a/providers/implementations/ciphers/cipher_tdes_common.c +++ b/providers/implementations/ciphers/cipher_tdes_common.c @@ -17,24 +17,33 @@ #include "cipher_tdes.h" #include #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw) { - PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx)); + PROV_TDES_CTX *tctx; + if (!ossl_prov_is_running()) + return NULL; + + tctx = OPENSSL_zalloc(sizeof(*tctx)); if (tctx != NULL) - cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, hw, - provctx); + ossl_cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, + hw, provctx); return tctx; } void *tdes_dupctx(void *ctx) { PROV_TDES_CTX *in = (PROV_TDES_CTX *)ctx; - PROV_TDES_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + PROV_TDES_CTX *ret; + + if (!ossl_prov_is_running()) + return NULL; + ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -48,7 +57,7 @@ void tdes_freectx(void *vctx) { PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx; - cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); + ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); OPENSSL_clear_free(ctx, sizeof(*ctx)); } @@ -57,12 +66,15 @@ static int tdes_init(void *vctx, const unsigned char *key, size_t keylen, { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->num = 0; ctx->bufsz = 0; ctx->enc = enc; if (iv != NULL) { - if (!cipher_generic_initiv(ctx, iv, ivlen)) + if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } @@ -115,7 +127,7 @@ int tdes_get_ctx_params(void *vctx, OSSL_PARAM params[]) PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; OSSL_PARAM *p; - if (!cipher_generic_get_ctx_params(vctx, params)) + if (!ossl_cipher_generic_get_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); diff --git a/providers/implementations/ciphers/cipher_tdes_default.c b/providers/implementations/ciphers/cipher_tdes_default.c index 87b0369faa..0e75d0ff11 100644 --- a/providers/implementations/ciphers/cipher_tdes_default.c +++ b/providers/implementations/ciphers/cipher_tdes_default.c @@ -16,20 +16,20 @@ #include "cipher_tdes_default.h" #include "prov/implementations.h" -/* tdes_ede3_ofb_functions */ +/* ossl_tdes_ede3_ofb_functions */ IMPLEMENT_tdes_cipher(ede3, EDE3, ofb, OFB, TDES_FLAGS, 64*3, 8, 64, stream); -/* tdes_ede3_cfb_functions */ +/* ossl_tdes_ede3_cfb_functions */ IMPLEMENT_tdes_cipher(ede3, EDE3, cfb, CFB, TDES_FLAGS, 64*3, 8, 64, stream); -/* tdes_ede3_cfb1_functions */ +/* ossl_tdes_ede3_cfb1_functions */ IMPLEMENT_tdes_cipher(ede3, EDE3, cfb1, CFB, TDES_FLAGS, 64*3, 8, 64, stream); -/* tdes_ede3_cfb8_functions */ +/* ossl_tdes_ede3_cfb8_functions */ IMPLEMENT_tdes_cipher(ede3, EDE3, cfb8, CFB, TDES_FLAGS, 64*3, 8, 64, stream); -/* tdes_ede2_ecb_functions */ +/* ossl_tdes_ede2_ecb_functions */ IMPLEMENT_tdes_cipher(ede2, EDE2, ecb, ECB, TDES_FLAGS, 64*2, 64, 64, block); -/* tdes_ede2_cbc_functions */ +/* ossl_tdes_ede2_cbc_functions */ IMPLEMENT_tdes_cipher(ede2, EDE2, cbc, CBC, TDES_FLAGS, 64*2, 64, 64, block); -/* tdes_ede2_ofb_functions */ +/* ossl_tdes_ede2_ofb_functions */ IMPLEMENT_tdes_cipher(ede2, EDE2, ofb, OFB, TDES_FLAGS, 64*2, 8, 64, stream); -/* tdes_ede2_cfb_functions */ +/* ossl_tdes_ede2_cfb_functions */ IMPLEMENT_tdes_cipher(ede2, EDE2, cfb, CFB, TDES_FLAGS, 64*2, 8, 64, stream); diff --git a/providers/implementations/ciphers/cipher_tdes_default.h b/providers/implementations/ciphers/cipher_tdes_default.h index 0bc499fc86..dc8458b5da 100644 --- a/providers/implementations/ciphers/cipher_tdes_default.h +++ b/providers/implementations/ciphers/cipher_tdes_default.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,16 +10,16 @@ #include "prov/ciphercommon.h" #include "cipher_tdes.h" -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ofb(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb1(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb8(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede3_ofb(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede3_cfb(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede3_cfb1(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede3_cfb8(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_cbc(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_ecb(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_ofb(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede2_cfb(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede2_cbc(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede2_ecb(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede2_ofb(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_ede2_cfb(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_desx_cbc(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_desx_cbc(void); -const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_wrap_cbc(void); +const PROV_CIPHER_HW *ossl_prov_cipher_hw_tdes_wrap_cbc(void); diff --git a/providers/implementations/ciphers/cipher_tdes_default_hw.c b/providers/implementations/ciphers/cipher_tdes_default_hw.c index 4bb99bd327..b7c7ea11f7 100644 --- a/providers/implementations/ciphers/cipher_tdes_default_hw.c +++ b/providers/implementations/ciphers/cipher_tdes_default_hw.c @@ -19,8 +19,9 @@ #define ks2 tks.ks[1] #define ks3 tks.ks[2] -static int cipher_hw_tdes_ede2_initkey(PROV_CIPHER_CTX *ctx, - const unsigned char *key, size_t keylen) +static int ossl_cipher_hw_tdes_ede2_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, + size_t keylen) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; DES_cblock *deskey = (DES_cblock *)key; @@ -44,8 +45,8 @@ static int cipher_hw_tdes_ede2_initkey(PROV_CIPHER_CTX *ctx, return 1; } -static int cipher_hw_tdes_ofb(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) +static int ossl_cipher_hw_tdes_ofb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; int num = ctx->num; @@ -65,8 +66,8 @@ static int cipher_hw_tdes_ofb(PROV_CIPHER_CTX *ctx, unsigned char *out, return 1; } -static int cipher_hw_tdes_cfb(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) +static int ossl_cipher_hw_tdes_cfb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; int num = ctx->num; @@ -93,8 +94,8 @@ static int cipher_hw_tdes_cfb(PROV_CIPHER_CTX *ctx, unsigned char *out, * Although we have a CFB-r implementation for 3-DES, it doesn't pack the * right way, so wrap it here */ -static int cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) +static int ossl_cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; size_t n; @@ -114,8 +115,8 @@ static int cipher_hw_tdes_cfb1(PROV_CIPHER_CTX *ctx, unsigned char *out, return 1; } -static int cipher_hw_tdes_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) +static int ossl_cipher_hw_tdes_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; diff --git a/providers/implementations/ciphers/cipher_tdes_hw.c b/providers/implementations/ciphers/cipher_tdes_hw.c index 82f232a602..4382969f44 100644 --- a/providers/implementations/ciphers/cipher_tdes_hw.c +++ b/providers/implementations/ciphers/cipher_tdes_hw.c @@ -20,8 +20,8 @@ #define ks2 tks.ks[1] #define ks3 tks.ks[2] -int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, - size_t keylen) +int ossl_cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, + const unsigned char *key, size_t keylen) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; DES_cblock *deskey = (DES_cblock *)key; @@ -45,7 +45,8 @@ int cipher_hw_tdes_ede3_initkey(PROV_CIPHER_CTX *ctx, const unsigned char *key, return 1; } -void cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) +void ossl_cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, + const PROV_CIPHER_CTX *src) { PROV_TDES_CTX *sctx = (PROV_TDES_CTX *)src; PROV_TDES_CTX *dctx = (PROV_TDES_CTX *)dst; @@ -54,8 +55,8 @@ void cipher_hw_tdes_copyctx(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src) dst->ks = &dctx->tks.ks; } -int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) +int ossl_cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) { PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; @@ -77,8 +78,8 @@ int cipher_hw_tdes_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, return 1; } -int cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) +int ossl_cipher_hw_tdes_ecb(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) { size_t i; PROV_TDES_CTX *tctx = (PROV_TDES_CTX *)ctx; diff --git a/providers/implementations/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c index 73d00a58d5..6d908a3ed5 100644 --- a/providers/implementations/ciphers/cipher_tdes_wrap.c +++ b/providers/implementations/ciphers/cipher_tdes_wrap.c @@ -18,6 +18,7 @@ #include "cipher_tdes_default.h" #include "crypto/evp.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" /* TODO (3.0) Figure out what flags are required */ @@ -133,6 +134,9 @@ static int tdes_wrap_cipher(void *vctx, int ret; *outl = 0; + if (!ossl_prov_is_running()) + return 0; + if (outsize < inl) { PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -171,15 +175,15 @@ static OSSL_FUNC_cipher_newctx_fn tdes_wrap_newctx; \ static void *tdes_wrap_newctx(void *provctx) \ { \ return tdes_newctx(provctx, EVP_CIPH_WRAP_MODE, kbits, blkbits, ivbits, \ - flags, PROV_CIPHER_HW_tdes_wrap_cbc()); \ + flags, ossl_prov_cipher_hw_tdes_wrap_cbc()); \ } \ static OSSL_FUNC_cipher_get_params_fn tdes_wrap_get_params; \ static int tdes_wrap_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_WRAP_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_WRAP_MODE, flags, \ + kbits, blkbits, ivbits); \ } \ -const OSSL_DISPATCH tdes_wrap_cbc_functions[] = \ +const OSSL_DISPATCH ossl_tdes_wrap_cbc_functions[] = \ { \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) tdes_einit }, \ { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) tdes_dinit }, \ @@ -187,19 +191,19 @@ const OSSL_DISPATCH tdes_wrap_cbc_functions[] = \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))tdes_wrap_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))tdes_freectx }, \ { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))tdes_wrap_update }, \ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_stream_final }, \ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_stream_final },\ { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))tdes_wrap_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))tdes_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ (void (*)(void))tdes_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_set_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ { 0, NULL } \ } -/* tdes_wrap_cbc_functions */ +/* ossl_tdes_wrap_cbc_functions */ IMPLEMENT_WRAP_CIPHER(TDES_WRAP_FLAGS, 64*3, 64, 0); diff --git a/providers/implementations/ciphers/cipher_tdes_wrap_hw.c b/providers/implementations/ciphers/cipher_tdes_wrap_hw.c index 477089ff86..3c8c833320 100644 --- a/providers/implementations/ciphers/cipher_tdes_wrap_hw.c +++ b/providers/implementations/ciphers/cipher_tdes_wrap_hw.c @@ -15,6 +15,6 @@ #include "cipher_tdes_default.h" -#define cipher_hw_tdes_wrap_initkey cipher_hw_tdes_ede3_initkey +#define ossl_cipher_hw_tdes_wrap_initkey ossl_cipher_hw_tdes_ede3_initkey PROV_CIPHER_HW_tdes_mode(wrap, cbc) diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c index 2d119a7b39..8d45d7a7d7 100644 --- a/providers/implementations/ciphers/ciphercommon.c +++ b/providers/implementations/ciphers/ciphercommon.c @@ -15,6 +15,7 @@ #include #include "ciphercommon_local.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" /*- @@ -29,14 +30,14 @@ static const OSSL_PARAM cipher_known_gettable_params[] = { { OSSL_CIPHER_PARAM_TLS_MAC, OSSL_PARAM_OCTET_PTR, NULL, 0, OSSL_PARAM_UNMODIFIED }, OSSL_PARAM_END }; -const OSSL_PARAM *cipher_generic_gettable_params(void) +const OSSL_PARAM *ossl_cipher_generic_gettable_params(void *provctx) { return cipher_known_gettable_params; } -int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, - unsigned long flags, - size_t kbits, size_t blkbits, size_t ivbits) +int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, + unsigned long flags, + size_t kbits, size_t blkbits, size_t ivbits) { OSSL_PARAM *p; @@ -68,24 +69,24 @@ int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, return 1; } -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic) -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic) +CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_cipher_generic) +CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_cipher_generic) -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic) +CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_generic) OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS_VERSION, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, NULL), -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic) +CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_generic) /* * Variable key length cipher functions for OSSL_PARAM settables */ -int cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +int ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; const OSSL_PARAM *p; - if (!cipher_generic_set_ctx_params(vctx, params)) + if (!ossl_cipher_generic_set_ctx_params(vctx, params)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL) { @@ -100,9 +101,9 @@ int cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_var_keylen) +CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_cipher_var_keylen) OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_var_keylen) +CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_cipher_var_keylen) /*- * AEAD cipher functions for OSSL_PARAM gettables and settables @@ -112,12 +113,15 @@ static const OSSL_PARAM cipher_aead_known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV_STATE, NULL, 0), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0), OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD, NULL), OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_GET_IV_GEN, NULL, 0), OSSL_PARAM_END }; -const OSSL_PARAM *cipher_aead_gettable_ctx_params(void) +const OSSL_PARAM *ossl_cipher_aead_gettable_ctx_params( + ossl_unused void *provctx + ) { return cipher_aead_known_gettable_ctx_params; } @@ -130,12 +134,14 @@ static const OSSL_PARAM cipher_aead_known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_SET_IV_INV, NULL, 0), OSSL_PARAM_END }; -const OSSL_PARAM *cipher_aead_settable_ctx_params(void) +const OSSL_PARAM *ossl_cipher_aead_settable_ctx_params( + ossl_unused void *provctx + ) { return cipher_aead_known_settable_ctx_params; } -void cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx) +void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx) { if (ctx != NULL && ctx->alloced) { OPENSSL_free(ctx->tlsmac); @@ -154,8 +160,11 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx, ctx->updated = 0; ctx->enc = enc ? 1 : 0; + if (!ossl_prov_is_running()) + return 0; + if (iv != NULL && ctx->mode != EVP_CIPH_ECB_MODE) { - if (!cipher_generic_initiv(ctx, iv, ivlen)) + if (!ossl_cipher_generic_initiv(ctx, iv, ivlen)) return 0; } if (key != NULL) { @@ -172,15 +181,17 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx, return 1; } -int cipher_generic_einit(void *vctx, const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen) +int ossl_cipher_generic_einit(void *vctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen) { return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen, iv, ivlen, 1); } -int cipher_generic_dinit(void *vctx, const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen) +int ossl_cipher_generic_dinit(void *vctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen) { return cipher_generic_init_internal((PROV_CIPHER_CTX *)vctx, key, keylen, iv, ivlen, 0); @@ -189,9 +200,9 @@ int cipher_generic_dinit(void *vctx, const unsigned char *key, size_t keylen, /* Max padding including padding length byte */ #define MAX_PADDING 256 -int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, - size_t outsize, const unsigned char *in, - size_t inl) +int ossl_cipher_generic_block_update(void *vctx, unsigned char *out, + size_t *outl, size_t outsize, + const unsigned char *in, size_t inl) { size_t outlint = 0; PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; @@ -327,12 +338,15 @@ int cipher_generic_block_update(void *vctx, unsigned char *out, size_t *outl, return inl == 0; } -int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl, - size_t outsize) +int ossl_cipher_generic_block_final(void *vctx, unsigned char *out, + size_t *outl, size_t outsize) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; size_t blksz = ctx->blocksize; + if (!ossl_prov_is_running()) + return 0; + if (ctx->tlsversion > 0) { /* We never finalize TLS, so this is an error */ ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); @@ -393,9 +407,9 @@ int cipher_generic_block_final(void *vctx, unsigned char *out, size_t *outl, return 1; } -int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl, - size_t outsize, const unsigned char *in, - size_t inl) +int ossl_cipher_generic_stream_update(void *vctx, unsigned char *out, + size_t *outl, size_t outsize, + const unsigned char *in, size_t inl) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; @@ -429,19 +443,25 @@ int cipher_generic_stream_update(void *vctx, unsigned char *out, size_t *outl, return 1; } -int cipher_generic_stream_final(void *vctx, unsigned char *out, size_t *outl, - size_t outsize) +int ossl_cipher_generic_stream_final(void *vctx, unsigned char *out, + size_t *outl, size_t outsize) { + if (!ossl_prov_is_running()) + return 0; + *outl = 0; return 1; } -int cipher_generic_cipher(void *vctx, - unsigned char *out, size_t *outl, size_t outsize, - const unsigned char *in, size_t inl) +int ossl_cipher_generic_cipher(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, + size_t inl) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -456,7 +476,7 @@ int cipher_generic_cipher(void *vctx, return 1; } -int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[]) +int ossl_cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; OSSL_PARAM *p; @@ -478,6 +498,13 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[]) ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV_STATE); + if (p != NULL + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_string(p, &ctx->iv, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_NUM); if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->num)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); @@ -497,7 +524,7 @@ int cipher_generic_get_ctx_params(void *vctx, OSSL_PARAM params[]) return 1; } -int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +int ossl_cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; const OSSL_PARAM *p; @@ -539,8 +566,8 @@ int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, - size_t ivlen) +int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, + size_t ivlen) { if (ivlen != ctx->ivlen || ivlen > sizeof(ctx->iv)) { @@ -553,9 +580,10 @@ int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, return 1; } -void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, - size_t ivbits, unsigned int mode, uint64_t flags, - const PROV_CIPHER_HW *hw, void *provctx) +void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, + size_t ivbits, unsigned int mode, + uint64_t flags, const PROV_CIPHER_HW *hw, + void *provctx) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; @@ -567,5 +595,5 @@ void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, ctx->mode = mode; ctx->blocksize = blkbits / 8; if (provctx != NULL) - ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); /* used for rand */ + ctx->libctx = PROV_LIBCTX_OF(provctx); /* used for rand */ } diff --git a/providers/implementations/ciphers/ciphercommon_block.c b/providers/implementations/ciphers/ciphercommon_block.c index ba6f68eeff..68d5495b77 100644 --- a/providers/implementations/ciphers/ciphercommon_block.c +++ b/providers/implementations/ciphers/ciphercommon_block.c @@ -22,7 +22,7 @@ int ssl3_cbc_remove_padding_and_mac(size_t *reclen, unsigned char **mac, int *alloced, size_t block_size, size_t mac_size, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); int tls1_cbc_remove_padding_and_mac(size_t *reclen, size_t origreclen, @@ -31,7 +31,7 @@ int tls1_cbc_remove_padding_and_mac(size_t *reclen, int *alloced, size_t block_size, size_t mac_size, int aead, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); /* * Fills a single block of buffered data from the input, and returns the amount @@ -154,7 +154,7 @@ int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize) * 1: (in constant time) Record is publicly valid. If padding is invalid then * the mac is random */ -int tlsunpadblock(OPENSSL_CTX *libctx, unsigned int tlsversion, +int tlsunpadblock(OSSL_LIB_CTX *libctx, unsigned int tlsversion, unsigned char *buf, size_t *buflen, size_t blocksize, unsigned char **mac, int *alloced, size_t macsize, int aead) { diff --git a/providers/implementations/ciphers/ciphercommon_ccm.c b/providers/implementations/ciphers/ciphercommon_ccm.c index 2b9a0687e3..b7f21b3df6 100644 --- a/providers/implementations/ciphers/ciphercommon_ccm.c +++ b/providers/implementations/ciphers/ciphercommon_ccm.c @@ -11,6 +11,7 @@ #include "prov/ciphercommon.h" #include "prov/ciphercommon_ccm.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out, @@ -21,7 +22,7 @@ static int ccm_tls_init(PROV_CCM_CTX *ctx, unsigned char *aad, size_t alen) { size_t len; - if (alen != EVP_AEAD_TLS1_AAD_LEN) + if (!ossl_prov_is_running() || alen != EVP_AEAD_TLS1_AAD_LEN) return 0; /* Save the aad for later use. */ @@ -171,6 +172,19 @@ int ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]) } } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV_STATE); + if (p != NULL) { + if (ccm_get_ivlen(ctx) > p->data_size) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IVLEN); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); @@ -207,6 +221,9 @@ static int ccm_init(void *vctx, const unsigned char *key, size_t keylen, { PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->enc = enc; if (iv != NULL) { @@ -263,6 +280,9 @@ int ccm_stream_final(void *vctx, unsigned char *out, size_t *outl, PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; int i; + if (!ossl_prov_is_running()) + return 0; + i = ccm_cipher_internal(ctx, out, outl, NULL, 0); if (i <= 0) return 0; @@ -277,6 +297,9 @@ int ccm_cipher(void *vctx, { PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -307,6 +330,9 @@ static int ccm_tls_cipher(PROV_CCM_CTX *ctx, int rv = 0; size_t olen = 0; + if (!ossl_prov_is_running()) + goto err; + /* Encrypt/decrypt must be performed in place */ if (in == NULL || out != in || len < EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m) goto err; diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c index 080fcc9bc2..e70fc474a3 100644 --- a/providers/implementations/ciphers/ciphercommon_gcm.c +++ b/providers/implementations/ciphers/ciphercommon_gcm.c @@ -11,6 +11,7 @@ #include "prov/ciphercommon.h" #include "prov/ciphercommon_gcm.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include #include "prov/provider_ctx.h" @@ -35,7 +36,7 @@ void gcm_initctx(void *provctx, PROV_GCM_CTX *ctx, size_t keybits, ctx->ivlen = (EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN); ctx->keylen = keybits / 8; ctx->hw = hw; - ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + ctx->libctx = PROV_LIBCTX_OF(provctx); } static int gcm_init(void *vctx, const unsigned char *key, size_t keylen, @@ -43,6 +44,9 @@ static int gcm_init(void *vctx, const unsigned char *key, size_t keylen, { PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + ctx->enc = enc; if (iv != NULL) { @@ -154,7 +158,22 @@ int gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); if (p != NULL) { - if (ctx->iv_gen != 1 && ctx->iv_gen_rand != 1) + if (ctx->iv_state == IV_STATE_UNINITIALISED) + return 0; + if (ctx->ivlen > p->data_size) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p, ctx->iv, ctx->ivlen) + && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, ctx->ivlen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV_STATE); + if (p != NULL) { + if (ctx->iv_state == IV_STATE_UNINITIALISED) return 0; if (ctx->ivlen > p->data_size) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); @@ -296,6 +315,9 @@ int gcm_stream_final(void *vctx, unsigned char *out, size_t *outl, PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx; int i; + if (!ossl_prov_is_running()) + return 0; + i = gcm_cipher_internal(ctx, out, outl, NULL, 0); if (i <= 0) return 0; @@ -310,6 +332,9 @@ int gcm_cipher(void *vctx, { PROV_GCM_CTX *ctx = (PROV_GCM_CTX *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -409,7 +434,7 @@ static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len) unsigned char *buf; size_t len; - if (aad_len != EVP_AEAD_TLS1_AAD_LEN) + if (!ossl_prov_is_running() || aad_len != EVP_AEAD_TLS1_AAD_LEN) return 0; /* Save the aad for later use. */ @@ -474,7 +499,7 @@ static int gcm_tls_cipher(PROV_GCM_CTX *ctx, unsigned char *out, size_t *padlen, size_t plen = 0; unsigned char *tag = NULL; - if (!ctx->key_set) + if (!ossl_prov_is_running() || !ctx->key_set) goto err; /* Encrypt/decrypt must be performed in place */ diff --git a/providers/implementations/ciphers/ciphercommon_hw.c b/providers/implementations/ciphers/ciphercommon_hw.c index 31062f1bc6..7063593011 100644 --- a/providers/implementations/ciphers/ciphercommon_hw.c +++ b/providers/implementations/ciphers/ciphercommon_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,7 +13,7 @@ * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr. * Used if there is no special hardware implementations. */ -int cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out, +int ossl_cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { if (dat->stream.cbc) @@ -26,7 +26,7 @@ int cipher_hw_generic_cbc(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -int cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out, +int ossl_cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { size_t i, bl = dat->blocksize; @@ -45,7 +45,7 @@ int cipher_hw_generic_ecb(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -int cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out, +int ossl_cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; @@ -56,8 +56,8 @@ int cipher_hw_generic_ofb128(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -int cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out, - const unsigned char *in, size_t len) +int ossl_cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out, + const unsigned char *in, size_t len) { int num = dat->num; @@ -68,7 +68,7 @@ int cipher_hw_generic_cfb128(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -int cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out, +int ossl_cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; @@ -80,7 +80,7 @@ int cipher_hw_generic_cfb8(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -int cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out, +int ossl_cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { int num = dat->num; @@ -108,7 +108,7 @@ int cipher_hw_generic_cfb1(PROV_CIPHER_CTX *dat, unsigned char *out, return 1; } -int cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out, +int ossl_cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out, const unsigned char *in, size_t len) { unsigned int num = dat->num; @@ -129,21 +129,21 @@ int cipher_hw_generic_ctr(PROV_CIPHER_CTX *dat, unsigned char *out, * Used if there is no special hardware implementations. */ -int cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, +int ossl_cipher_hw_chunked_cbc(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= MAXCHUNK) { - cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK); + ossl_cipher_hw_generic_cbc(ctx, out, in, MAXCHUNK); inl -= MAXCHUNK; in += MAXCHUNK; out += MAXCHUNK; } if (inl > 0) - cipher_hw_generic_cbc(ctx, out, in, inl); + ossl_cipher_hw_generic_cbc(ctx, out, in, inl); return 1; } -int cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, +int ossl_cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t chunk = MAXCHUNK; @@ -151,7 +151,7 @@ int cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, if (inl < chunk) chunk = inl; while (inl > 0 && inl >= chunk) { - cipher_hw_generic_cfb8(ctx, out, in, inl); + ossl_cipher_hw_generic_cfb8(ctx, out, in, inl); inl -= chunk; in += chunk; out += chunk; @@ -161,7 +161,7 @@ int cipher_hw_chunked_cfb8(PROV_CIPHER_CTX *ctx, unsigned char *out, return 1; } -int cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out, +int ossl_cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t chunk = MAXCHUNK; @@ -169,7 +169,7 @@ int cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out, if (inl < chunk) chunk = inl; while (inl > 0 && inl >= chunk) { - cipher_hw_generic_cfb128(ctx, out, in, inl); + ossl_cipher_hw_generic_cfb128(ctx, out, in, inl); inl -= chunk; in += chunk; out += chunk; @@ -179,16 +179,16 @@ int cipher_hw_chunked_cfb128(PROV_CIPHER_CTX *ctx, unsigned char *out, return 1; } -int cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out, +int ossl_cipher_hw_chunked_ofb128(PROV_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while (inl >= MAXCHUNK) { - cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK); + ossl_cipher_hw_generic_ofb128(ctx, out, in, MAXCHUNK); inl -= MAXCHUNK; in += MAXCHUNK; out += MAXCHUNK; } if (inl > 0) - cipher_hw_generic_ofb128(ctx, out, in, inl); + ossl_cipher_hw_generic_ofb128(ctx, out, in, inl); return 1; } diff --git a/providers/implementations/ciphers/ciphercommon_local.h b/providers/implementations/ciphers/ciphercommon_local.h index 9427c0c537..b84785b731 100644 --- a/providers/implementations/ciphers/ciphercommon_local.h +++ b/providers/implementations/ciphers/ciphercommon_local.h @@ -11,6 +11,6 @@ void padblock(unsigned char *buf, size_t *buflen, size_t blocksize); int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize); -int tlsunpadblock(OPENSSL_CTX *libctx, unsigned int tlsversion, +int tlsunpadblock(OSSL_LIB_CTX *libctx, unsigned int tlsversion, unsigned char *buf, size_t *buflen, size_t blocksize, unsigned char **mac, int *alloced, size_t macsize, int aead); diff --git a/providers/implementations/digests/blake2_prov.c b/providers/implementations/digests/blake2_prov.c index cd13fd2adf..8bb1050f43 100644 --- a/providers/implementations/digests/blake2_prov.c +++ b/providers/implementations/digests/blake2_prov.c @@ -31,12 +31,12 @@ int blake2b512_init(void *ctx) return blake2b_init((BLAKE2B_CTX *)ctx, &P); } -/* blake2s256_functions */ +/* ossl_blake2s256_functions */ IMPLEMENT_digest_functions(blake2s256, BLAKE2S_CTX, BLAKE2S_BLOCKBYTES, BLAKE2S_DIGEST_LENGTH, 0, blake2s256_init, blake2s_update, blake2s_final) -/* blake2b512_functions */ +/* ossl_blake2b512_functions */ IMPLEMENT_digest_functions(blake2b512, BLAKE2B_CTX, BLAKE2B_BLOCKBYTES, BLAKE2B_DIGEST_LENGTH, 0, blake2b512_init, blake2b_update, blake2b_final) diff --git a/providers/implementations/digests/digestcommon.c b/providers/implementations/digests/digestcommon.c index 9d30b2be2c..6d926713c8 100644 --- a/providers/implementations/digests/digestcommon.c +++ b/providers/implementations/digests/digestcommon.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,7 +40,7 @@ static const OSSL_PARAM digest_default_known_gettable_params[] = { OSSL_PARAM_ulong(OSSL_DIGEST_PARAM_FLAGS, NULL), OSSL_PARAM_END }; -const OSSL_PARAM *digest_default_gettable_params(void) +const OSSL_PARAM *digest_default_gettable_params(void *provctx) { return digest_default_known_gettable_params; } diff --git a/providers/implementations/digests/md2_prov.c b/providers/implementations/digests/md2_prov.c index 481dcf6f48..a41a02c198 100644 --- a/providers/implementations/digests/md2_prov.c +++ b/providers/implementations/digests/md2_prov.c @@ -18,7 +18,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -/* md2_functions */ +/* ossl_md2_functions */ IMPLEMENT_digest_functions(md2, MD2_CTX, MD2_BLOCK, MD2_DIGEST_LENGTH, 0, MD2_Init, MD2_Update, MD2_Final) diff --git a/providers/implementations/digests/md4_prov.c b/providers/implementations/digests/md4_prov.c index 9668c68a71..97f73018c2 100644 --- a/providers/implementations/digests/md4_prov.c +++ b/providers/implementations/digests/md4_prov.c @@ -18,7 +18,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -/* md4_functions */ +/* ossl_md4_functions */ IMPLEMENT_digest_functions(md4, MD4_CTX, MD4_CBLOCK, MD4_DIGEST_LENGTH, 0, MD4_Init, MD4_Update, MD4_Final) diff --git a/providers/implementations/digests/md5_prov.c b/providers/implementations/digests/md5_prov.c index 0090c4f967..a330e057f5 100644 --- a/providers/implementations/digests/md5_prov.c +++ b/providers/implementations/digests/md5_prov.c @@ -18,7 +18,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -/* md5_functions */ +/* ossl_md5_functions */ IMPLEMENT_digest_functions(md5, MD5_CTX, MD5_CBLOCK, MD5_DIGEST_LENGTH, 0, MD5_Init, MD5_Update, MD5_Final) diff --git a/providers/implementations/digests/md5_sha1_prov.c b/providers/implementations/digests/md5_sha1_prov.c index c5dc4a36ce..7c127d74a6 100644 --- a/providers/implementations/digests/md5_sha1_prov.c +++ b/providers/implementations/digests/md5_sha1_prov.c @@ -30,7 +30,7 @@ static const OSSL_PARAM known_md5_sha1_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *md5_sha1_settable_ctx_params(void) +static const OSSL_PARAM *md5_sha1_settable_ctx_params(ossl_unused void *provctx) { return known_md5_sha1_settable_ctx_params; } @@ -50,7 +50,7 @@ static int md5_sha1_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; } -/* md5_sha1_functions */ +/* ossl_md5_sha1_functions */ IMPLEMENT_digest_functions_with_settable_ctx( md5_sha1, MD5_SHA1_CTX, MD5_SHA1_CBLOCK, MD5_SHA1_DIGEST_LENGTH, 0, md5_sha1_init, md5_sha1_update, md5_sha1_final, diff --git a/providers/implementations/digests/mdc2_prov.c b/providers/implementations/digests/mdc2_prov.c index 51958f7cf7..b184c8393c 100644 --- a/providers/implementations/digests/mdc2_prov.c +++ b/providers/implementations/digests/mdc2_prov.c @@ -30,7 +30,7 @@ static const OSSL_PARAM known_mdc2_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *mdc2_settable_ctx_params(void) +static const OSSL_PARAM *mdc2_settable_ctx_params(ossl_unused void *provctx) { return known_mdc2_settable_ctx_params; } @@ -51,7 +51,7 @@ static int mdc2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; /* Null Parameter */ } -/* mdc2_functions */ +/* ossl_mdc2_functions */ IMPLEMENT_digest_functions_with_settable_ctx( mdc2, MDC2_CTX, MDC2_BLOCK, MDC2_DIGEST_LENGTH, 0, MDC2_Init, MDC2_Update, MDC2_Final, diff --git a/providers/implementations/digests/ripemd_prov.c b/providers/implementations/digests/ripemd_prov.c index 70be9a9efc..526706c06d 100644 --- a/providers/implementations/digests/ripemd_prov.c +++ b/providers/implementations/digests/ripemd_prov.c @@ -18,7 +18,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -/* ripemd160_functions */ +/* ossl_ripemd160_functions */ IMPLEMENT_digest_functions(ripemd160, RIPEMD160_CTX, RIPEMD160_CBLOCK, RIPEMD160_DIGEST_LENGTH, 0, RIPEMD160_Init, RIPEMD160_Update, RIPEMD160_Final) diff --git a/providers/implementations/digests/sha2_prov.c b/providers/implementations/digests/sha2_prov.c index 5a73940b87..dec9c316e7 100644 --- a/providers/implementations/digests/sha2_prov.c +++ b/providers/implementations/digests/sha2_prov.c @@ -31,7 +31,7 @@ static const OSSL_PARAM known_sha1_settable_ctx_params[] = { {OSSL_DIGEST_PARAM_SSL3_MS, OSSL_PARAM_OCTET_STRING, NULL, 0, 0}, OSSL_PARAM_END }; -static const OSSL_PARAM *sha1_settable_ctx_params(void) +static const OSSL_PARAM *sha1_settable_ctx_params(ossl_unused void *provctx) { return known_sha1_settable_ctx_params; } @@ -51,43 +51,43 @@ static int sha1_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; } -/* sha1_functions */ +/* ossl_sha1_functions */ IMPLEMENT_digest_functions_with_settable_ctx( sha1, SHA_CTX, SHA_CBLOCK, SHA_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, SHA1_Init, SHA1_Update, SHA1_Final, sha1_settable_ctx_params, sha1_set_ctx_params) -/* sha224_functions */ +/* ossl_sha224_functions */ IMPLEMENT_digest_functions(sha224, SHA256_CTX, SHA256_CBLOCK, SHA224_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, SHA224_Init, SHA224_Update, SHA224_Final) -/* sha256_functions */ +/* ossl_sha256_functions */ IMPLEMENT_digest_functions(sha256, SHA256_CTX, SHA256_CBLOCK, SHA256_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, SHA256_Init, SHA256_Update, SHA256_Final) -/* sha384_functions */ +/* ossl_sha384_functions */ IMPLEMENT_digest_functions(sha384, SHA512_CTX, SHA512_CBLOCK, SHA384_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, SHA384_Init, SHA384_Update, SHA384_Final) -/* sha512_functions */ +/* ossl_sha512_functions */ IMPLEMENT_digest_functions(sha512, SHA512_CTX, SHA512_CBLOCK, SHA512_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, SHA512_Init, SHA512_Update, SHA512_Final) -/* sha512_224_functions */ +/* ossl_sha512_224_functions */ IMPLEMENT_digest_functions(sha512_224, SHA512_CTX, SHA512_CBLOCK, SHA224_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, sha512_224_init, SHA512_Update, SHA512_Final) -/* sha512_256_functions */ +/* ossl_sha512_256_functions */ IMPLEMENT_digest_functions(sha512_256, SHA512_CTX, SHA512_CBLOCK, SHA256_DIGEST_LENGTH, EVP_MD_FLAG_DIGALGID_ABSENT, diff --git a/providers/implementations/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c index d7c7e8e44b..38e2beb1e7 100644 --- a/providers/implementations/digests/sha3_prov.c +++ b/providers/implementations/digests/sha3_prov.c @@ -47,6 +47,8 @@ static sha3_final_fn generic_sha3_final; static int keccak_init(void *vctx) { + if (!ossl_prov_is_running()) + return 0; /* The newctx() handles most of the ctx fixed setup. */ sha3_reset((KECCAK1600_CTX *)vctx); return 1; @@ -95,6 +97,8 @@ static int keccak_final(void *vctx, unsigned char *out, size_t *outl, int ret = 1; KECCAK1600_CTX *ctx = vctx; + if (!ossl_prov_is_running()) + return 0; if (outsz > 0) ret = ctx->meth.final(out, ctx); @@ -145,6 +149,8 @@ static int s390x_sha3_final(unsigned char *md, void *vctx) { KECCAK1600_CTX *ctx = vctx; + if (!ossl_prov_is_running()) + return 0; s390x_klmd(ctx->buf, ctx->bufsz, NULL, 0, ctx->pad, ctx->A); memcpy(md, ctx->A, ctx->md_size); return 1; @@ -154,6 +160,8 @@ static int s390x_shake_final(unsigned char *md, void *vctx) { KECCAK1600_CTX *ctx = vctx; + if (!ossl_prov_is_running()) + return 0; s390x_klmd(ctx->buf, ctx->bufsz, md, ctx->md_size, ctx->pad, ctx->A); return 1; } @@ -185,7 +193,8 @@ static PROV_SHA3_METHOD shake_s390x_md = static OSSL_FUNC_digest_newctx_fn name##_newctx; \ static void *name##_newctx(void *provctx) \ { \ - KECCAK1600_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ + : NULL; \ \ if (ctx == NULL) \ return NULL; \ @@ -198,7 +207,8 @@ static void *name##_newctx(void *provctx) \ static OSSL_FUNC_digest_newctx_fn uname##_newctx; \ static void *uname##_newctx(void *provctx) \ { \ - KECCAK1600_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + KECCAK1600_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) \ + : NULL; \ \ if (ctx == NULL) \ return NULL; \ @@ -209,7 +219,7 @@ static void *uname##_newctx(void *provctx) \ #define PROV_FUNC_SHA3_DIGEST_COMMON(name, bitlen, blksize, dgstsize, flags) \ PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ -const OSSL_DISPATCH name##_functions[] = { \ +const OSSL_DISPATCH ossl_##name##_functions[] = { \ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \ { OSSL_FUNC_DIGEST_INIT, (void (*)(void))keccak_init }, \ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))keccak_update }, \ @@ -239,7 +249,8 @@ static void keccak_freectx(void *vctx) static void *keccak_dupctx(void *ctx) { KECCAK1600_CTX *in = (KECCAK1600_CTX *)ctx; - KECCAK1600_CTX *ret = OPENSSL_malloc(sizeof(*ret)); + KECCAK1600_CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) + : NULL; if (ret != NULL) *ret = *in; @@ -250,7 +261,7 @@ static const OSSL_PARAM known_shake_settable_ctx_params[] = { {OSSL_DIGEST_PARAM_XOFLEN, OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0}, OSSL_PARAM_END }; -static const OSSL_PARAM *shake_settable_ctx_params(void) +static const OSSL_PARAM *shake_settable_ctx_params(ossl_unused void *provctx) { return known_shake_settable_ctx_params; } @@ -288,19 +299,19 @@ static int shake_set_ctx_params(void *vctx, const OSSL_PARAM params[]) SHA3_BLOCKSIZE(bitlen), KMAC_MDSIZE(bitlen), \ EVP_MD_FLAG_XOF) -/* sha3_224_functions */ +/* ossl_sha3_224_functions */ IMPLEMENT_SHA3_functions(224) -/* sha3_256_functions */ +/* ossl_sha3_256_functions */ IMPLEMENT_SHA3_functions(256) -/* sha3_384_functions */ +/* ossl_sha3_384_functions */ IMPLEMENT_SHA3_functions(384) -/* sha3_512_functions */ +/* ossl_sha3_512_functions */ IMPLEMENT_SHA3_functions(512) -/* shake_128_functions */ +/* ossl_shake_128_functions */ IMPLEMENT_SHAKE_functions(128) -/* shake_256_functions */ +/* ossl_shake_256_functions */ IMPLEMENT_SHAKE_functions(256) -/* keccak_kmac_128_functions */ +/* ossl_keccak_kmac_128_functions */ IMPLEMENT_KMAC_functions(128) -/* keccak_kmac_256_functions */ +/* ossl_keccak_kmac_256_functions */ IMPLEMENT_KMAC_functions(256) diff --git a/providers/implementations/digests/sm3_prov.c b/providers/implementations/digests/sm3_prov.c index 88e65d1537..fec3dcbef3 100644 --- a/providers/implementations/digests/sm3_prov.c +++ b/providers/implementations/digests/sm3_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,7 +12,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -/* sm3_functions */ +/* ossl_sm3_functions */ IMPLEMENT_digest_functions(sm3, SM3_CTX, SM3_CBLOCK, SM3_DIGEST_LENGTH, 0, sm3_init, sm3_update, sm3_final) diff --git a/providers/implementations/digests/wp_prov.c b/providers/implementations/digests/wp_prov.c index d0e2d20b1d..2af70b3372 100644 --- a/providers/implementations/digests/wp_prov.c +++ b/providers/implementations/digests/wp_prov.c @@ -18,7 +18,7 @@ #include "prov/digestcommon.h" #include "prov/implementations.h" -/* wp_functions */ +/* ossl_wp_functions */ IMPLEMENT_digest_functions(wp, WHIRLPOOL_CTX, WHIRLPOOL_BBLOCK / 8, WHIRLPOOL_DIGEST_LENGTH, 0, WHIRLPOOL_Init, WHIRLPOOL_Update, WHIRLPOOL_Final) diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info new file mode 100644 index 0000000000..97e2264418 --- /dev/null +++ b/providers/implementations/encode_decode/build.info @@ -0,0 +1,21 @@ +# We make separate GOAL variables for each algorithm, to make it easy to +# switch each to the Legacy provider when needed. + +$ENCODER_GOAL=../../libimplementations.a +$DECODER_GOAL=../../libimplementations.a +$RSA_GOAL=../../libimplementations.a +$FFC_GOAL=../../libimplementations.a +$DH_GOAL=../../libimplementations.a +$DSA_GOAL=../../libimplementations.a +$ECX_GOAL=../../libimplementations.a +$EC_GOAL=../../libimplementations.a + +SOURCE[$ENCODER_GOAL]=endecoder_common.c + +SOURCE[$DECODER_GOAL]=decode_der2key.c decode_pem2der.c +IF[{- !$disabled{dsa} -}] + SOURCE[$DECODER_GOAL]=decode_ms2key.c +ENDIF + +SOURCE[$DECODER_GOAL]=encode_key2any.c encode_key2text.c +DEPEND[encode_key2any.o]=../../common/include/prov/der_rsa.h diff --git a/providers/implementations/serializers/deserialize_der2key.c b/providers/implementations/encode_decode/decode_der2key.c similarity index 50% rename from providers/implementations/serializers/deserialize_der2key.c rename to providers/implementations/encode_decode/decode_der2key.c index 87ac7b5e12..fed4ae0720 100644 --- a/providers/implementations/serializers/deserialize_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -15,20 +15,98 @@ #include #include +#include #include +#include #include +#include /* PEM_BUFSIZE and public PEM functions */ +#include #include +#include "internal/cryptlib.h" /* ossl_assert() */ +#include "internal/asn1.h" +#include "crypto/ecx.h" #include "prov/bio.h" #include "prov/implementations.h" -#include "serializer_local.h" +#include "prov/providercommonerr.h" +#include "endecoder_local.h" + +#define SET_ERR_MARK() ERR_set_mark() +#define CLEAR_ERR_MARK() \ + do { \ + int err = ERR_peek_last_error(); \ + \ + if (ERR_GET_LIB(err) == ERR_LIB_ASN1 \ + && (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG \ + || ERR_GET_REASON(err) == ASN1_R_UNSUPPORTED_TYPE \ + || ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR)) \ + ERR_pop_to_mark(); \ + else \ + ERR_clear_last_mark(); \ + } while(0) +#define RESET_ERR_MARK() \ + do { \ + CLEAR_ERR_MARK(); \ + SET_ERR_MARK(); \ + } while(0) + +static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, + unsigned char **data, long *len) +{ + BUF_MEM *mem = NULL; + BIO *in = bio_new_from_core_bio(provctx, cin); + int ok = (asn1_d2i_read_bio(in, &mem) >= 0); + + if (ok) { + *data = (unsigned char *)mem->data; + *len = (long)mem->length; + OPENSSL_free(mem); + } + BIO_free(in); + return ok; +} -static OSSL_FUNC_deserializer_newctx_fn der2rsa_newctx; +static int der_from_p8(unsigned char **new_der, long *new_der_len, + unsigned char *input_der, long input_der_len, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + const unsigned char *derp; + X509_SIG *p8 = NULL; + int ok = 0; -static OSSL_FUNC_deserializer_freectx_fn der2key_freectx; -static OSSL_FUNC_deserializer_gettable_params_fn der2key_gettable_params; -static OSSL_FUNC_deserializer_get_params_fn der2key_get_params; -static OSSL_FUNC_deserializer_deserialize_fn der2key_deserialize; -static OSSL_FUNC_deserializer_export_object_fn der2key_export_object; + if (!ossl_assert(new_der != NULL && *new_der == NULL) + || !ossl_assert(new_der_len != NULL)) + return 0; + + derp = input_der; + if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) { + char pbuf[PEM_BUFSIZE]; + size_t plen = 0; + + if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) { + ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); + } else { + const X509_ALGOR *alg = NULL; + const ASN1_OCTET_STRING *oct = NULL; + int len = 0; + + X509_SIG_get0(p8, &alg, &oct); + if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length, + new_der, &len, 0) != NULL) + ok = 1; + *new_der_len = len; + } + } + X509_SIG_free(p8); + return ok; +} + +/* ---------------------------------------------------------------------- */ + +static OSSL_FUNC_decoder_freectx_fn der2key_freectx; +static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params; +static OSSL_FUNC_decoder_get_params_fn der2key_get_params; +static OSSL_FUNC_decoder_decode_fn der2key_decode; +static OSSL_FUNC_decoder_export_object_fn der2key_export_object; typedef void *(extract_key_fn)(EVP_PKEY *); typedef void (free_key_fn)(void *); @@ -46,7 +124,7 @@ struct keytype_desc_st { }; /* - * Context used for DER to key deserialization. + * Context used for DER to key decoding. */ struct der2key_ctx_st { PROV_CTX *provctx; @@ -72,10 +150,10 @@ static void der2key_freectx(void *vctx) OPENSSL_free(ctx); } -static const OSSL_PARAM *der2key_gettable_params(void) +static const OSSL_PARAM *der2key_gettable_params(void *provctx) { static const OSSL_PARAM gettables[] = { - { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, OSSL_PARAM_END, }; @@ -86,19 +164,19 @@ static int der2key_get_params(OSSL_PARAM params[]) { OSSL_PARAM *p; - p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE); + p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER")) return 0; return 1; } -static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin, - OSSL_CALLBACK *data_cb, void *data_cbarg, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { struct der2key_ctx_st *ctx = vctx; - void *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + void *libctx = PROV_LIBCTX_OF(ctx->provctx); unsigned char *der = NULL; const unsigned char *derp; long der_len = 0; @@ -108,32 +186,41 @@ static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin, void *key = NULL; int ok = 0; - if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len)) - return 0; + SET_ERR_MARK(); + if (!read_der(ctx->provctx, cin, &der, &der_len)) + goto err; /* * Opportunistic attempt to decrypt. If it doesn't work, we try to * decode our input unencrypted. */ - if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len, - pw_cb, pw_cbarg)) { + if (der_from_p8(&new_der, &new_der_len, der, der_len, pw_cb, pw_cbarg)) { OPENSSL_free(der); der = new_der; der_len = new_der_len; } + RESET_ERR_MARK(); derp = der; pkey = d2i_PrivateKey_ex(ctx->desc->type, NULL, &derp, der_len, libctx, NULL); if (pkey == NULL) { + RESET_ERR_MARK(); derp = der; - pkey = d2i_PUBKEY(NULL, &derp, der_len); + pkey = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, NULL); } if (pkey == NULL) { + RESET_ERR_MARK(); derp = der; pkey = d2i_KeyParams(ctx->desc->type, NULL, &derp, der_len); } + err: + /* + * Prune low-level ASN.1 parse errors from error queue, assuming that + * this is called by decoder_process() in a loop trying several formats. + */ + CLEAR_ERR_MARK(); if (pkey != NULL) { /* @@ -142,7 +229,7 @@ static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin, * * TODO(3.0): The check should be done with EVP_PKEY_is_a(), but * as long as we still have #legacy internal keys, it's safer to - * use the type numbers in side the provider. + * use the type numbers inside the provider. */ if (EVP_PKEY_id(pkey) == ctx->desc->type) key = ctx->desc->extract_key(pkey); @@ -157,16 +244,19 @@ static int der2key_deserialize(void *vctx, OSSL_CORE_BIO *cin, OPENSSL_free(der); if (key != NULL) { - OSSL_PARAM params[3]; + OSSL_PARAM params[4]; + int object_type = OSSL_OBJECT_PKEY; params[0] = - OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE, + OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); + params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, (char *)ctx->desc->name, 0); /* The address of the key becomes the octet string */ - params[1] = - OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_REFERENCE, + params[2] = + OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, &key, sizeof(key)); - params[2] = OSSL_PARAM_construct_end(); + params[3] = OSSL_PARAM_construct_end(); ok = data_cb(params, data_cbarg); } @@ -196,31 +286,34 @@ static int der2key_export_object(void *vctx, #define IMPLEMENT_NEWCTX(KEYTYPEstr, KEYTYPE, keytype, extract, free) \ static const struct keytype_desc_st keytype##_desc = \ - { EVP_PKEY_##KEYTYPE, KEYTYPEstr, keytype##_keymgmt_functions, \ + { EVP_PKEY_##KEYTYPE, KEYTYPEstr, \ + ossl_##keytype##_keymgmt_functions, \ (extract_key_fn *)extract, \ (free_key_fn *)free }; \ + static OSSL_FUNC_decoder_newctx_fn der2##keytype##_newctx; \ static void *der2##keytype##_newctx(void *provctx) \ { \ return der2key_newctx(provctx, &keytype##_desc); \ } \ - const OSSL_DISPATCH der_to_##keytype##_deserializer_functions[] = { \ - { OSSL_FUNC_DESERIALIZER_NEWCTX, \ + const OSSL_DISPATCH ossl_der_to_##keytype##_decoder_functions[] = { \ + { OSSL_FUNC_DECODER_NEWCTX, \ (void (*)(void))der2##keytype##_newctx }, \ - { OSSL_FUNC_DESERIALIZER_FREECTX, \ + { OSSL_FUNC_DECODER_FREECTX, \ (void (*)(void))der2key_freectx }, \ - { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS, \ + { OSSL_FUNC_DECODER_GETTABLE_PARAMS, \ (void (*)(void))der2key_gettable_params }, \ - { OSSL_FUNC_DESERIALIZER_GET_PARAMS, \ + { OSSL_FUNC_DECODER_GET_PARAMS, \ (void (*)(void))der2key_get_params }, \ - { OSSL_FUNC_DESERIALIZER_DESERIALIZE, \ - (void (*)(void))der2key_deserialize }, \ - { OSSL_FUNC_DESERIALIZER_EXPORT_OBJECT, \ + { OSSL_FUNC_DECODER_DECODE, \ + (void (*)(void))der2key_decode }, \ + { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))der2key_export_object }, \ { 0, NULL } \ } #ifndef OPENSSL_NO_DH IMPLEMENT_NEWCTX("DH", DH, dh, EVP_PKEY_get1_DH, DH_free); +IMPLEMENT_NEWCTX("DHX", DHX, dhx, EVP_PKEY_get1_DH, DH_free); #endif #ifndef OPENSSL_NO_DSA IMPLEMENT_NEWCTX("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free); @@ -228,12 +321,12 @@ IMPLEMENT_NEWCTX("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free); #ifndef OPENSSL_NO_EC IMPLEMENT_NEWCTX("EC", EC, ec, EVP_PKEY_get1_EC_KEY, EC_KEY_free); IMPLEMENT_NEWCTX("X25519", X25519, x25519, - EVP_PKEY_get1_X25519, ecx_key_free); + evp_pkey_get1_X25519, ecx_key_free); IMPLEMENT_NEWCTX("X448", X448, x448, - EVP_PKEY_get1_X448, ecx_key_free); + evp_pkey_get1_X448, ecx_key_free); IMPLEMENT_NEWCTX("ED25519", ED25519, ed25519, - EVP_PKEY_get1_ED25519, ecx_key_free); -IMPLEMENT_NEWCTX("ED448", ED448, ed448, EVP_PKEY_get1_ED448, ecx_key_free); + evp_pkey_get1_ED25519, ecx_key_free); +IMPLEMENT_NEWCTX("ED448", ED448, ed448, evp_pkey_get1_ED448, ecx_key_free); #endif IMPLEMENT_NEWCTX("RSA", RSA, rsa, EVP_PKEY_get1_RSA, RSA_free); IMPLEMENT_NEWCTX("RSA-PSS", RSA_PSS, rsapss, EVP_PKEY_get1_RSA, RSA_free); diff --git a/providers/implementations/encode_decode/decode_ms2key.c b/providers/implementations/encode_decode/decode_ms2key.c new file mode 100644 index 0000000000..1bc55e5493 --- /dev/null +++ b/providers/implementations/encode_decode/decode_ms2key.c @@ -0,0 +1,279 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include + +#include +#include +#include +#include +#include +#include /* For public PVK functions */ +#include +#include "internal/pem.h" /* For internal PVK and "blob" headers */ +#include "internal/passphrase.h" +#include "prov/bio.h" +#include "prov/implementations.h" +#include "endecoder_local.h" + +#ifndef OPENSSL_NO_DSA +static EVP_PKEY *read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin, int *ispub) +{ + BIO *in = bio_new_from_core_bio(provctx, cin); + EVP_PKEY *pkey = ossl_b2i_bio(in, ispub); + + BIO_free(in); + return pkey; +} + +# ifndef OPENSSL_NO_RC4 +static EVP_PKEY *read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + BIO *in = NULL; + EVP_PKEY *pkey = NULL; + struct ossl_passphrase_data_st pwdata; + + memset(&pwdata, 0, sizeof(pwdata)); + if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg)) + return NULL; + + in = bio_new_from_core_bio(provctx, cin); + pkey = b2i_PVK_bio(in, ossl_pw_pem_password, &pwdata); + BIO_free(in); + + return pkey; +} +# endif +#endif + +static OSSL_FUNC_decoder_freectx_fn ms2key_freectx; +static OSSL_FUNC_decoder_gettable_params_fn ms2key_gettable_params; +static OSSL_FUNC_decoder_get_params_fn msblob2key_get_params; +#ifndef OPENSSL_NO_RC4 +static OSSL_FUNC_decoder_get_params_fn pvk2key_get_params; +#endif +static OSSL_FUNC_decoder_decode_fn msblob2key_decode; +#ifndef OPENSSL_NO_RC4 +static OSSL_FUNC_decoder_decode_fn pvk2key_decode; +#endif +static OSSL_FUNC_decoder_export_object_fn ms2key_export_object; + +typedef void *(extract_key_fn)(EVP_PKEY *); +typedef void (free_key_fn)(void *); +struct keytype_desc_st { + int type; /* EVP key type */ + const char *name; /* Keytype */ + const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ + + /* + * These must be the correct EVP_PKEY_get1_{TYPE}() and {TYPE}_free() + * function for the key. + */ + extract_key_fn *extract_key; + free_key_fn *free_key; +}; + +/* + * Context used for DER to key decoding. + */ +struct ms2key_ctx_st { + PROV_CTX *provctx; + const struct keytype_desc_st *desc; +}; + +static struct ms2key_ctx_st * +ms2key_newctx(void *provctx, const struct keytype_desc_st *desc) +{ + struct ms2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) { + ctx->provctx = provctx; + ctx->desc = desc; + } + return ctx; +} + +static void ms2key_freectx(void *vctx) +{ + struct ms2key_ctx_st *ctx = vctx; + + OPENSSL_free(ctx); +} + +static const OSSL_PARAM *ms2key_gettable_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM gettables[] = { + { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + OSSL_PARAM_END, + }; + + return gettables; +} + +static int msblob2key_get_params(OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "MSBLOB")) + return 0; + + return 1; +} + +#ifndef OPENSSL_NO_RC4 +static int pvk2key_get_params(OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "PVK")) + return 0; + + return 1; +} +#endif + +static int ms2key_post(struct ms2key_ctx_st *ctx, EVP_PKEY *pkey, + OSSL_CALLBACK *data_cb, void *data_cbarg) +{ + void *key = NULL; + int ok = 0; + + if (pkey != NULL) { + /* + * Tear out the low-level key pointer from the pkey, + * but only if it matches the expected key type. + * + * TODO(3.0): The check should be done with EVP_PKEY_is_a(), but + * as long as we still have #legacy internal keys, it's safer to + * use the type numbers in side the provider. + */ + if (EVP_PKEY_id(pkey) == ctx->desc->type) + key = ctx->desc->extract_key(pkey); + } + + if (key != NULL) { + OSSL_PARAM params[4]; + int object_type = OSSL_OBJECT_PKEY; + + params[0] = + OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); + params[1] = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + (char *)ctx->desc->name, 0); + /* The address of the key becomes the octet string */ + params[2] = + OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, + &key, sizeof(key)); + params[3] = OSSL_PARAM_construct_end(); + + ok = data_cb(params, data_cbarg); + } + ctx->desc->free_key(key); + + return ok; +} + +static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct ms2key_ctx_st *ctx = vctx; + int ispub = -1; + EVP_PKEY *pkey = read_msblob(ctx->provctx, cin, &ispub); + int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg); + + EVP_PKEY_free(pkey); + return ok; +} + +#ifndef OPENSSL_NO_RC4 +static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct ms2key_ctx_st *ctx = vctx; + EVP_PKEY *pkey = read_pvk(ctx->provctx, cin, pw_cb, pw_cbarg); + int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg); + + EVP_PKEY_free(pkey); + return ok; +} +#endif + +static int ms2key_export_object(void *vctx, + const void *reference, size_t reference_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + struct ms2key_ctx_st *ctx = vctx; + OSSL_FUNC_keymgmt_export_fn *export = + ossl_prov_get_keymgmt_export(ctx->desc->fns); + void *keydata; + + if (reference_sz == sizeof(keydata) && export != NULL) { + /* The contents of the reference is the address to our object */ + keydata = *(void **)reference; + + return export(keydata, OSSL_KEYMGMT_SELECT_ALL, + export_cb, export_cbarg); + } + return 0; +} + +#define IMPLEMENT_TYPE(KEYTYPEstr, KEYTYPE, keytype, extract, free) \ + static const struct keytype_desc_st keytype##_desc; \ + static OSSL_FUNC_decoder_newctx_fn ms2##keytype##_newctx; \ + static void *ms2##keytype##_newctx(void *provctx) \ + { \ + return ms2key_newctx(provctx, &keytype##_desc); \ + } \ + static const struct keytype_desc_st keytype##_desc = \ + { EVP_PKEY_##KEYTYPE, KEYTYPEstr, \ + ossl_##keytype##_keymgmt_functions, \ + (extract_key_fn *)extract, \ + (free_key_fn *)free } + +#define IMPLEMENT_MS(mstype, keytype) \ + const OSSL_DISPATCH \ + ossl_##mstype##_to_##keytype##_decoder_functions[] = { \ + { OSSL_FUNC_DECODER_NEWCTX, \ + (void (*)(void))ms2##keytype##_newctx }, \ + { OSSL_FUNC_DECODER_FREECTX, \ + (void (*)(void))ms2key_freectx }, \ + { OSSL_FUNC_DECODER_GETTABLE_PARAMS, \ + (void (*)(void))ms2key_gettable_params }, \ + { OSSL_FUNC_DECODER_GET_PARAMS, \ + (void (*)(void))mstype##2key_get_params }, \ + { OSSL_FUNC_DECODER_DECODE, \ + (void (*)(void))mstype##2key_decode }, \ + { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ + (void (*)(void))ms2key_export_object }, \ + { 0, NULL } \ + } + +#ifndef OPENSSL_NO_DSA +IMPLEMENT_TYPE("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free); +IMPLEMENT_MS(msblob, dsa); +# ifndef OPENSSL_NO_RC4 +IMPLEMENT_MS(pvk, dsa); +# endif +#endif +IMPLEMENT_TYPE("RSA", RSA, rsa, EVP_PKEY_get1_RSA, RSA_free); +IMPLEMENT_MS(msblob, rsa); +#ifndef OPENSSL_NO_RC4 +IMPLEMENT_MS(pvk, rsa); +#endif diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c new file mode 100644 index 0000000000..9ddc0ae3bb --- /dev/null +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -0,0 +1,220 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "internal/nelem.h" +#include "prov/bio.h" +#include "prov/implementations.h" +#include "prov/providercommonerr.h" +#include "endecoder_local.h" + +static int read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin, + char **pem_name, char **pem_header, + unsigned char **data, long *len) +{ + BIO *in = bio_new_from_core_bio(provctx, cin); + int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0); + + BIO_free(in); + return ok; +} + +static OSSL_FUNC_decoder_newctx_fn pem2der_newctx; +static OSSL_FUNC_decoder_freectx_fn pem2der_freectx; +static OSSL_FUNC_decoder_gettable_params_fn pem2der_gettable_params; +static OSSL_FUNC_decoder_get_params_fn pem2der_get_params; +static OSSL_FUNC_decoder_decode_fn pem2der_decode; + +/* + * Context used for PEM to DER decoding. + */ +struct pem2der_ctx_st { + PROV_CTX *provctx; +}; + +static void *pem2der_newctx(void *provctx) +{ + struct pem2der_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) + ctx->provctx = provctx; + return ctx; +} + +static void pem2der_freectx(void *vctx) +{ + struct pem2der_ctx_st *ctx = vctx; + + OPENSSL_free(ctx); +} + +static const OSSL_PARAM *pem2der_gettable_params(void *provctx) +{ + static const OSSL_PARAM gettables[] = { + { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + OSSL_PARAM_END, + }; + + return gettables; +} + +static int pem2der_get_params(OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "PEM")) + return 0; + + return 1; +} + +/* pem_password_cb compatible function */ +struct pem2der_pass_data_st { + OSSL_PASSPHRASE_CALLBACK *cb; + void *cbarg; +}; + +static int pem2der_pass_helper(char *buf, int num, int w, void *data) +{ + struct pem2der_pass_data_st *pass_data = data; + size_t plen; + + if (pass_data == NULL + || pass_data->cb == NULL + || !pass_data->cb(buf, num, &plen, NULL, pass_data->cbarg)) + return -1; + return (int)plen; +} + +static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + /* Strings to peal off the pem name */ + static const char *pealable_pem_name_endings[] = { + /* + * These entries should be in longest to shortest order to avoid + * mixups. + */ + "ENCRYPTED PRIVATE KEY", + "PRIVATE KEY", + "PUBLIC KEY", + "PARAMETERS" + + /* + * Libcrypto currently only supports decoding keys with provider side + * decoders, so we don't try to peal any other PEM name. That's an + * exercise for when libcrypto starts to treat other types of objects + * via providers. + */ + }; + struct pem2der_ctx_st *ctx = vctx; + char *pem_name = NULL, *pem_header = NULL; + size_t pem_name_len, i; + unsigned char *der = NULL; + long der_len = 0; + int ok = 0; + + if (read_pem(ctx->provctx, cin, &pem_name, &pem_header, + &der, &der_len) <= 0) + return 0; + + /* + * 10 is the number of characters in "Proc-Type:", which + * PEM_get_EVP_CIPHER_INFO() requires to be present. + * If the PEM header has less characters than that, it's + * not worth spending cycles on it. + */ + if (strlen(pem_header) > 10) { + EVP_CIPHER_INFO cipher; + struct pem2der_pass_data_st pass_data; + + pass_data.cb = pw_cb; + pass_data.cbarg = pw_cbarg; + if (!PEM_get_EVP_CIPHER_INFO(pem_header, &cipher) + || !PEM_do_header(&cipher, der, &der_len, + pem2der_pass_helper, &pass_data)) + goto end; + } + + /* + * Peal off certain strings from the end of |pem_name|, as they serve + * no further purpose. + */ + for (i = 0, pem_name_len = strlen(pem_name); + i < OSSL_NELEM(pealable_pem_name_endings); + i++) { + size_t peal_len = strlen(pealable_pem_name_endings[i]); + size_t pem_name_offset; + + if (peal_len <= pem_name_len) { + pem_name_offset = pem_name_len - peal_len; + if (strcmp(pem_name + pem_name_offset, + pealable_pem_name_endings[i]) == 0) { + + do { + pem_name[pem_name_offset] = '\0'; + } while (pem_name_offset > 0 + && pem_name[--pem_name_offset] == ' '); + + if (pem_name[0] == '\0') { + OPENSSL_free(pem_name); + pem_name = NULL; + } + break; + } + } + } + + { + OSSL_PARAM params[3], *p = params; + + if (pem_name != NULL) + *p++ = + OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + pem_name, 0); + *p++ = + OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, + der, der_len); + *p = OSSL_PARAM_construct_end(); + + ok = data_cb(params, data_cbarg); + } + + end: + OPENSSL_free(pem_name); + OPENSSL_free(pem_header); + OPENSSL_free(der); + return ok; +} + +const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[] = { + { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))pem2der_newctx }, + { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))pem2der_freectx }, + { OSSL_FUNC_DECODER_GETTABLE_PARAMS, + (void (*)(void))pem2der_gettable_params }, + { OSSL_FUNC_DECODER_GET_PARAMS, + (void (*)(void))pem2der_get_params }, + { OSSL_FUNC_DECODER_DECODE, (void (*)(void))pem2der_decode }, + { 0, NULL } +}; diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c new file mode 100644 index 0000000000..ca8f24fed2 --- /dev/null +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -0,0 +1,976 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Low level APIs are deprecated for public use, but still ok for internal use. + */ +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* PKCS8_encrypt() */ +#include +#include +#include +#include "internal/passphrase.h" +#include "internal/cryptlib.h" +#include "crypto/ecx.h" +#include "crypto/rsa.h" +#include "prov/implementations.h" +#include "prov/providercommonerr.h" +#include "prov/bio.h" +#include "prov/provider_ctx.h" +#include "prov/der_rsa.h" +#include "endecoder_local.h" + +struct key2any_ctx_st { + PROV_CTX *provctx; + + /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */ + int cipher_intent; + + EVP_CIPHER *cipher; + + struct ossl_passphrase_data_st pwdata; +}; + +typedef int check_key_type_fn(const void *key, int nid); +typedef int key_to_paramstring_fn(const void *key, int nid, + void **str, int *strtype); +typedef int key_to_der_fn(BIO *out, const void *key, int key_nid, + key_to_paramstring_fn *p2s, i2d_of_void *k2d, + struct key2any_ctx_st *ctx); +typedef int write_bio_of_void_fn(BIO *bp, const void *x); + +static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, + void *params, int params_type, + i2d_of_void *k2d) +{ + /* der, derlen store the key DER output and its length */ + unsigned char *der = NULL; + int derlen; + /* The final PKCS#8 info */ + PKCS8_PRIV_KEY_INFO *p8info = NULL; + + + if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL + || (derlen = k2d(key, &der)) <= 0 + || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0, + params_type, params, der, derlen)) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + PKCS8_PRIV_KEY_INFO_free(p8info); + OPENSSL_free(der); + p8info = NULL; + } + + return p8info; +} + +static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, + struct key2any_ctx_st *ctx) +{ + X509_SIG *p8 = NULL; + char kstr[PEM_BUFSIZE]; + size_t klen = 0; + + if (ctx->cipher == NULL) + return NULL; + + if (!ossl_pw_get_passphrase(kstr, sizeof(kstr), &klen, NULL, 1, + &ctx->pwdata)) { + ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); + return NULL; + } + /* First argument == -1 means "standard" */ + p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info); + OPENSSL_cleanse(kstr, klen); + return p8; +} + +static X509_SIG *key_to_encp8(const void *key, int key_nid, + void *params, int params_type, + i2d_of_void *k2d, struct key2any_ctx_st *ctx) +{ + PKCS8_PRIV_KEY_INFO *p8info = + key_to_p8info(key, key_nid, params, params_type, k2d); + X509_SIG *p8 = p8info_to_encp8(p8info, ctx); + + PKCS8_PRIV_KEY_INFO_free(p8info); + return p8; +} + +static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, + void *params, int params_type, + i2d_of_void k2d) +{ + /* der, derlen store the key DER output and its length */ + unsigned char *der = NULL; + int derlen; + /* The final X509_PUBKEY */ + X509_PUBKEY *xpk = NULL; + + + if ((xpk = X509_PUBKEY_new()) == NULL + || (derlen = k2d(key, &der)) <= 0 + || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid), + params_type, params, der, derlen)) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + X509_PUBKEY_free(xpk); + OPENSSL_free(der); + xpk = NULL; + } + + return xpk; +} + +static int key_to_der_pkcs8_bio(BIO *out, const void *key, int key_nid, + key_to_paramstring_fn *p2s, i2d_of_void *k2d, + struct key2any_ctx_st *ctx) +{ + int ret = 0; + void *str = NULL; + int strtype = V_ASN1_UNDEF; + + if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + return 0; + + if (ctx->cipher_intent) { + X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx); + + if (p8 != NULL) + ret = i2d_PKCS8_bio(out, p8); + + X509_SIG_free(p8); + } else { + PKCS8_PRIV_KEY_INFO *p8info = + key_to_p8info(key, key_nid, str, strtype, k2d); + + if (p8info != NULL) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); + + PKCS8_PRIV_KEY_INFO_free(p8info); + } + + return ret; +} + +static int key_to_pem_pkcs8_bio(BIO *out, const void *key, int key_nid, + key_to_paramstring_fn *p2s, i2d_of_void *k2d, + struct key2any_ctx_st *ctx) +{ + int ret = 0; + void *str = NULL; + int strtype = V_ASN1_UNDEF; + + if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + return 0; + + if (ctx->cipher_intent) { + X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx); + + if (p8 != NULL) + ret = PEM_write_bio_PKCS8(out, p8); + + X509_SIG_free(p8); + } else { + PKCS8_PRIV_KEY_INFO *p8info = + key_to_p8info(key, key_nid, str, strtype, k2d); + + if (p8info != NULL) + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); + + PKCS8_PRIV_KEY_INFO_free(p8info); + } + + return ret; +} + +static int key_to_der_pubkey_bio(BIO *out, const void *key, int key_nid, + key_to_paramstring_fn *p2s, i2d_of_void *k2d, + struct key2any_ctx_st *ctx) +{ + int ret = 0; + void *str = NULL; + int strtype = V_ASN1_UNDEF; + X509_PUBKEY *xpk = NULL; + + if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + return 0; + + xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); + + if (xpk != NULL) + ret = i2d_X509_PUBKEY_bio(out, xpk); + + /* Also frees |str| */ + X509_PUBKEY_free(xpk); + return ret; +} + +static int key_to_pem_pubkey_bio(BIO *out, const void *key, int key_nid, + key_to_paramstring_fn *p2s, i2d_of_void *k2d, + struct key2any_ctx_st *ctx) +{ + int ret = 0; + void *str = NULL; + int strtype = V_ASN1_UNDEF; + X509_PUBKEY *xpk = NULL; + + if (p2s != NULL && !p2s(key, key_nid, &str, &strtype)) + return 0; + + xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); + + if (xpk != NULL) + ret = PEM_write_bio_X509_PUBKEY(out, xpk); + + /* Also frees |str| */ + X509_PUBKEY_free(xpk); + return ret; +} + +#define der_output_type "DER" +#define pem_output_type "PEM" + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_DH +static int prepare_dh_params(const void *dh, int nid, + void **pstr, int *pstrtype) +{ + ASN1_STRING *params = ASN1_STRING_new(); + + if (params == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (nid == EVP_PKEY_DHX) + params->length = i2d_DHxparams(dh, ¶ms->data); + else + params->length = i2d_DHparams(dh, ¶ms->data); + + if (params->length <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + return 0; + } + params->type = V_ASN1_SEQUENCE; + + *pstr = params; + *pstrtype = V_ASN1_SEQUENCE; + return 1; +} + +static int dh_pub_to_der(const void *dh, unsigned char **pder) +{ + const BIGNUM *bn = NULL; + ASN1_INTEGER *pub_key = NULL; + int ret; + + if ((bn = DH_get0_pub_key(dh)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); + return 0; + } + + ret = i2d_ASN1_INTEGER(pub_key, pder); + + ASN1_STRING_clear_free(pub_key); + return ret; +} + +static int dh_priv_to_der(const void *dh, unsigned char **pder) +{ + const BIGNUM *bn = NULL; + ASN1_INTEGER *priv_key = NULL; + int ret; + + if ((bn = DH_get0_priv_key(dh)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); + return 0; + } + + ret = i2d_ASN1_INTEGER(priv_key, pder); + + ASN1_STRING_clear_free(priv_key); + return ret; +} + +static int dh_params_to_der_bio(BIO *out, const void *key) +{ + int type = + DH_test_flags(key, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH; + + if (type == EVP_PKEY_DH) + return i2d_DHparams_bio(out, key); + return i2d_DHxparams_bio(out, key); +} + +static int dh_params_to_pem_bio(BIO *out, const void *key) +{ + int type = + DH_test_flags(key, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH; + + if (type == EVP_PKEY_DH) + return PEM_write_bio_DHparams(out, key); + + return PEM_write_bio_DHxparams(out, key); +} + +static int dh_check_key_type(const void *key, int expected_type) +{ + int type = + DH_test_flags(key, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH; + + return type == expected_type; +} + +# define dh_evp_type EVP_PKEY_DH +# define dhx_evp_type EVP_PKEY_DHX +# define dh_input_type "DH" +# define dhx_input_type "DHX" +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_DSA +static int prepare_some_dsa_params(const void *dsa, int nid, + void **pstr, int *pstrtype) +{ + ASN1_STRING *params = ASN1_STRING_new(); + + if (params == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + + params->length = i2d_DSAparams(dsa, ¶ms->data); + + if (params->length <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + return 0; + } + + *pstrtype = V_ASN1_SEQUENCE; + *pstr = params; + return 1; +} + +static int prepare_all_dsa_params(const void *dsa, int nid, + void **pstr, int *pstrtype) +{ + const BIGNUM *p = DSA_get0_p(dsa); + const BIGNUM *q = DSA_get0_q(dsa); + const BIGNUM *g = DSA_get0_g(dsa); + + if (p != NULL && q != NULL && g != NULL) + return prepare_some_dsa_params(dsa, nid, pstr, pstrtype); + + *pstr = NULL; + *pstrtype = V_ASN1_UNDEF; + return 1; +} + +static int prepare_dsa_params(const void *dsa, int nid, + void **pstr, int *pstrtype) +{ + /* + * TODO(v3.0) implement setting save_parameters, see dsa_pub_encode() + * in crypto/dsa/dsa_ameth.c + */ + int save_parameters = 1; + + return save_parameters + ? prepare_all_dsa_params(dsa, nid, pstr, pstrtype) + : prepare_some_dsa_params(dsa, nid, pstr, pstrtype); +} + +static int dsa_pub_to_der(const void *dsa, unsigned char **pder) +{ + const BIGNUM *bn = NULL; + ASN1_INTEGER *pub_key = NULL; + int ret; + + if ((bn = DSA_get0_pub_key(dsa)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); + return 0; + } + + ret = i2d_ASN1_INTEGER(pub_key, pder); + + ASN1_STRING_clear_free(pub_key); + return ret; +} + +static int dsa_priv_to_der(const void *dsa, unsigned char **pder) +{ + const BIGNUM *bn = NULL; + ASN1_INTEGER *priv_key = NULL; + int ret; + + if ((bn = DSA_get0_priv_key(dsa)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); + return 0; + } + + ret = i2d_ASN1_INTEGER(priv_key, pder); + + ASN1_STRING_clear_free(priv_key); + return ret; +} + +static int dsa_params_to_der_bio(BIO *out, const void *key) +{ + return i2d_DSAparams_bio(out, key); +} + +static int dsa_params_to_pem_bio(BIO *out, const void *key) +{ + return PEM_write_bio_DSAparams(out, key); +} + +# define dsa_check_key_type NULL +# define dsa_evp_type EVP_PKEY_DSA +# define dsa_input_type "DSA" +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_EC +static int prepare_ec_explicit_params(const void *eckey, + void **pstr, int *pstrtype) +{ + ASN1_STRING *params = ASN1_STRING_new(); + + if (params == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + + params->length = i2d_ECParameters(eckey, ¶ms->data); + if (params->length <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + return 0; + } + + *pstrtype = V_ASN1_SEQUENCE; + *pstr = params; + return 1; +} + +static int prepare_ec_params(const void *eckey, int nid, + void **pstr, int *pstrtype) +{ + int curve_nid; + const EC_GROUP *group = EC_KEY_get0_group(eckey); + ASN1_OBJECT *params = NULL; + + if (group == NULL) + return 0; + curve_nid = EC_GROUP_get_curve_name(group); + if (curve_nid != NID_undef) { + params = OBJ_nid2obj(curve_nid); + if (params == NULL) + return 0; + } + + if (curve_nid != NID_undef + && (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) { + if (OBJ_length(params) == 0) { + /* Some curves might not have an associated OID */ + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID); + ASN1_OBJECT_free(params); + return 0; + } + *pstr = params; + *pstrtype = V_ASN1_OBJECT; + return 1; + } else { + return prepare_ec_explicit_params(eckey, pstr, pstrtype); + } +} + +static int ec_params_to_der_bio(BIO *out, const void *eckey) +{ + return i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey)); +} + +static int ec_params_to_pem_bio(BIO *out, const void *eckey) +{ + return PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey)); +} + +static int ec_pub_to_der(const void *eckey, unsigned char **pder) +{ + return i2o_ECPublicKey(eckey, pder); +} + +static int ec_priv_to_der(const void *veckey, unsigned char **pder) +{ + EC_KEY *eckey = (EC_KEY *)veckey; + unsigned int old_flags; + int ret = 0; + + /* + * For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object + * as the pkeyalg->parameter field. (For a named curve this is an OID) + * The pkey field is an octet string that holds the encoded + * ECPrivateKey SEQUENCE with the optional parameters field omitted. + * We omit this by setting the EC_PKEY_NO_PARAMETERS flag. + */ + old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */ + EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS); + ret = i2d_ECPrivateKey(eckey, pder); + EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */ + return ret; /* return the length of the der encoded data */ +} + +# define ec_check_key_type NULL +# define ec_evp_type EVP_PKEY_EC +# define ec_input_type "EC" +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_EC +# define prepare_ecx_params NULL + +static int ecx_pub_to_der(const void *vecxkey, unsigned char **pder) +{ + const ECX_KEY *ecxkey = vecxkey; + unsigned char *keyblob; + + if (ecxkey == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen); + if (keyblob == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + + *pder = keyblob; + return ecxkey->keylen; +} + +static int ecx_priv_to_der(const void *vecxkey, unsigned char **pder) +{ + const ECX_KEY *ecxkey = vecxkey; + ASN1_OCTET_STRING oct; + int keybloblen; + + if (ecxkey == NULL || ecxkey->privkey == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + oct.data = ecxkey->privkey; + oct.length = ecxkey->keylen; + oct.flags = 0; + + keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); + if (keybloblen < 0) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + + return keybloblen; +} + +# define ecx_params_to_der_bio NULL +# define ecx_params_to_pem_bio NULL +# define ecx_check_key_type NULL + +# define ed25519_evp_type EVP_PKEY_ED25519 +# define ed448_evp_type EVP_PKEY_ED448 +# define x25519_evp_type EVP_PKEY_X25519 +# define x448_evp_type EVP_PKEY_X448 +# define ed25519_input_type "ED25519" +# define ed448_input_type "ED448" +# define x25519_input_type "X25519" +# define x448_input_type "X448" +#endif + +/* ---------------------------------------------------------------------- */ + +/* + * Helper functions to prepare RSA-PSS params for encoding. We would + * have simply written the whole AlgorithmIdentifier, but existing libcrypto + * functionality doesn't allow that. + */ + +static int prepare_rsa_params(const void *rsa, int nid, + void **pstr, int *pstrtype) +{ + const RSA_PSS_PARAMS_30 *pss = ossl_rsa_get0_pss_params_30((RSA *)rsa); + + *pstr = NULL; + + switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { + case RSA_FLAG_TYPE_RSA: + /* If plain RSA, the parameters shall be NULL */ + *pstrtype = V_ASN1_NULL; + return 1; + case RSA_FLAG_TYPE_RSASSAPSS: + if (ossl_rsa_pss_params_30_is_unrestricted(pss)) { + *pstrtype = V_ASN1_UNDEF; + return 1; + } else { + ASN1_STRING *astr = NULL; + WPACKET pkt; + unsigned char *str = NULL; + size_t str_sz = 0; + int i; + + for (i = 0; i < 2; i++) { + switch (i) { + case 0: + if (!WPACKET_init_null_der(&pkt)) + goto err; + break; + case 1: + if ((str = OPENSSL_malloc(str_sz)) == NULL + || !WPACKET_init_der(&pkt, str, str_sz)) { + goto err; + } + break; + } + if (!ossl_DER_w_RSASSA_PSS_params(&pkt, -1, pss) + || !WPACKET_finish(&pkt) + || !WPACKET_get_total_written(&pkt, &str_sz)) + goto err; + WPACKET_cleanup(&pkt); + + /* + * If no PSS parameters are going to be written, there's no + * point going for another iteration. + * This saves us from getting |str| allocated just to have it + * immediately de-allocated. + */ + if (str_sz == 0) + break; + } + + if ((astr = ASN1_STRING_new()) == NULL) + goto err; + *pstrtype = V_ASN1_SEQUENCE; + ASN1_STRING_set0(astr, str, (int)str_sz); + *pstr = astr; + + return 1; + err: + OPENSSL_free(str); + return 0; + } + } + + /* Currently unsupported RSA key type */ + return 0; +} + +#define rsa_params_to_der_bio NULL +#define rsa_params_to_pem_bio NULL +#define rsa_priv_to_der (i2d_of_void *)i2d_RSAPrivateKey +#define rsa_pub_to_der (i2d_of_void *)i2d_RSAPublicKey + +static int rsa_check_key_type(const void *rsa, int expected_type) +{ + switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { + case RSA_FLAG_TYPE_RSA: + return expected_type == EVP_PKEY_RSA; + case RSA_FLAG_TYPE_RSASSAPSS: + return expected_type == EVP_PKEY_RSA_PSS; + } + + /* Currently unsupported RSA key type */ + return EVP_PKEY_NONE; +} + +#define rsa_evp_type EVP_PKEY_RSA +#define rsapss_evp_type EVP_PKEY_RSA_PSS +#define rsa_input_type "RSA" +#define rsapss_input_type "RSA-PSS" + +/* ---------------------------------------------------------------------- */ + +static OSSL_FUNC_decoder_newctx_fn key2any_newctx; +static OSSL_FUNC_decoder_freectx_fn key2any_freectx; +static OSSL_FUNC_decoder_gettable_params_fn key2any_gettable_params; + +static void *key2any_newctx(void *provctx) +{ + struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) + ctx->provctx = provctx; + + return ctx; +} + +static void key2any_freectx(void *vctx) +{ + struct key2any_ctx_st *ctx = vctx; + + ossl_pw_clear_passphrase_data(&ctx->pwdata); + EVP_CIPHER_free(ctx->cipher); + OPENSSL_free(ctx); +} + +static const OSSL_PARAM *key2any_gettable_params(void *provctx) +{ + static const OSSL_PARAM gettables[] = { + { OSSL_ENCODER_PARAM_OUTPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + OSSL_PARAM_END, + }; + + return gettables; +} + +static int key2any_get_params(OSSL_PARAM params[], const char *input_type, + const char *output_type) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_ENCODER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, input_type)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_ENCODER_PARAM_OUTPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, output_type)) + return 0; + + return 1; +} + +static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END, + }; + + return settables; +} + +static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct key2any_ctx_st *ctx = vctx; + OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); + const OSSL_PARAM *cipherp = + OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER); + const OSSL_PARAM *propsp = + OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES); + + if (cipherp != NULL) { + const char *ciphername = NULL; + const char *props = NULL; + + if (!OSSL_PARAM_get_utf8_string_ptr(cipherp, &ciphername)) + return 0; + if (propsp != NULL && !OSSL_PARAM_get_utf8_string_ptr(propsp, &props)) + return 0; + + EVP_CIPHER_free(ctx->cipher); + ctx->cipher_intent = ciphername != NULL; + if (ciphername != NULL + && ((ctx->cipher = + EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL)) + return 0; + } + return 1; +} + +static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, + const void *key, int type, + check_key_type_fn *checker, + key_to_der_fn *writer, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg, + key_to_paramstring_fn *key2paramstring, + i2d_of_void *key2der) +{ + int ret = 0; + + if (key == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + } else if (checker == NULL || checker(key, type)) { + BIO *out = bio_new_from_core_bio(ctx->provctx, cout); + + if (out != NULL + && writer != NULL + && ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg)) + ret = writer(out, key, type, key2paramstring, key2der, ctx); + + BIO_free(out); + } else { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + } + return ret; +} + +static int key2any_encode_params(struct key2any_ctx_st *ctx, + OSSL_CORE_BIO *cout, + const void *key, int type, + check_key_type_fn *checker, + write_bio_of_void_fn *writer) +{ + int ret = 0; + + if (key == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + } else if (checker == NULL || checker(key, type)) { + BIO *out = bio_new_from_core_bio(ctx->provctx, cout); + + if (out != NULL && writer != NULL) + ret = writer(out, key); + + BIO_free(out); + } else { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + } + + return ret; +} + +#define MAKE_ENCODER(impl, type, evp_type, output) \ + static OSSL_FUNC_encoder_get_params_fn \ + impl##2##output##_get_params; \ + static OSSL_FUNC_encoder_import_object_fn \ + impl##2##output##_import_object; \ + static OSSL_FUNC_encoder_free_object_fn \ + impl##2##output##_free_object; \ + static OSSL_FUNC_encoder_encode_fn impl##2##output##_encode; \ + \ + static int impl##2##output##_get_params(OSSL_PARAM params[]) \ + { \ + return key2any_get_params(params, impl##_input_type, \ + output##_output_type); \ + } \ + static void * \ + impl##2##output##_import_object(void *vctx, int selection, \ + const OSSL_PARAM params[]) \ + { \ + struct key2any_ctx_st *ctx = vctx; \ + return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ + ctx->provctx, selection, params); \ + } \ + static void impl##2##output##_free_object(void *key) \ + { \ + ossl_prov_free_key(ossl_##impl##_keymgmt_functions, key); \ + } \ + static int \ + impl##2##output##_encode(void *ctx, OSSL_CORE_BIO *cout, \ + const void *key, \ + const OSSL_PARAM key_abstract[], \ + int selection, \ + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) \ + { \ + /* We don't deal with abstract objects */ \ + if (key_abstract != NULL) { \ + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ + return 0; \ + } \ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) \ + return key2any_encode(ctx, cout, key, impl##_evp_type, \ + type##_check_key_type, \ + key_to_##output##_pkcs8_bio, \ + cb, cbarg, \ + prepare_##type##_params, \ + type##_priv_to_der); \ + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) \ + return key2any_encode(ctx, cout, key, impl##_evp_type, \ + type##_check_key_type, \ + key_to_##output##_pubkey_bio, \ + cb, cbarg, \ + prepare_##type##_params, \ + type##_pub_to_der); \ + if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) \ + return key2any_encode_params(ctx, cout, key, \ + impl##_evp_type, \ + type##_check_key_type, \ + type##_params_to_##output##_bio); \ + \ + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ + return 0; \ + } \ + const OSSL_DISPATCH ossl_##impl##_to_##output##_encoder_functions[] = { \ + { OSSL_FUNC_ENCODER_NEWCTX, \ + (void (*)(void))key2any_newctx }, \ + { OSSL_FUNC_ENCODER_FREECTX, \ + (void (*)(void))key2any_freectx }, \ + { OSSL_FUNC_ENCODER_GETTABLE_PARAMS, \ + (void (*)(void))key2any_gettable_params }, \ + { OSSL_FUNC_ENCODER_GET_PARAMS, \ + (void (*)(void))impl##2##output##_get_params }, \ + { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))key2any_settable_ctx_params }, \ + { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, \ + (void (*)(void))key2any_set_ctx_params }, \ + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ + (void (*)(void))impl##2##output##_import_object }, \ + { OSSL_FUNC_ENCODER_FREE_OBJECT, \ + (void (*)(void))impl##2##output##_free_object }, \ + { OSSL_FUNC_ENCODER_ENCODE, \ + (void (*)(void))impl##2##output##_encode }, \ + { 0, NULL } \ + } + +#ifndef OPENSSL_NO_DH +MAKE_ENCODER(dh, dh, EVP_PKEY_DH, der); +MAKE_ENCODER(dh, dh, EVP_PKEY_DH, pem); +MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, der); +MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, pem); +#endif +#ifndef OPENSSL_NO_DSA +MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, der); +MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, pem); +#endif +#ifndef OPENSSL_NO_EC +MAKE_ENCODER(ec, ec, EVP_PKEY_EC, der); +MAKE_ENCODER(ec, ec, EVP_PKEY_EC, pem); +MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, der); +MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, pem); +MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, der); +MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, pem); +MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, der); +MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, pem); +MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, der); +MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, pem); +#endif +MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, der); +MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, pem); +MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA, der); +MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA, pem); diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c new file mode 100644 index 0000000000..92efb0436e --- /dev/null +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -0,0 +1,906 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Low level APIs are deprecated for public use, but still ok for internal use. + */ +#include "internal/deprecated.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "internal/ffc.h" +#include "crypto/bn.h" /* bn_get_words() */ +#include "crypto/dh.h" /* dh_get0_params() */ +#include "crypto/dsa.h" /* dsa_get0_params() */ +#include "crypto/ec.h" /* ec_key_get_libctx */ +#include "crypto/ecx.h" /* ECX_KEY, etc... */ +#include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */ +#include "prov/bio.h" +#include "prov/implementations.h" +#include "prov/providercommonerr.h" +#include "endecoder_local.h" + +DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) + +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_FMTu "%lu" +# define BN_FMTx "%lx" +# endif + +# ifdef SIXTY_FOUR_BIT +# define BN_FMTu "%llu" +# define BN_FMTx "%llx" +# endif + +# ifdef THIRTY_TWO_BIT +# define BN_FMTu "%u" +# define BN_FMTx "%x" +# endif + +static int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) +{ + int ret = 0, use_sep = 0; + char *hex_str = NULL, *p; + const char spaces[] = " "; + const char *post_label_spc = " "; + + const char *neg = ""; + int bytes; + + if (bn == NULL) + return 0; + if (label == NULL) { + label = ""; + post_label_spc = ""; + } + + if (BN_is_zero(bn)) + return BIO_printf(out, "%s%s0\n", label, post_label_spc); + + if (BN_num_bytes(bn) <= BN_BYTES) { + BN_ULONG *words = bn_get_words(bn); + + if (BN_is_negative(bn)) + neg = "-"; + + return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", + label, post_label_spc, neg, words[0], neg, words[0]); + } + + hex_str = BN_bn2hex(bn); + p = hex_str; + if (*p == '-') { + ++p; + neg = " (Negative)"; + } + if (BIO_printf(out, "%s%s\n", label, neg) <= 0) + goto err; + + /* Keep track of how many bytes we have printed out so far */ + bytes = 0; + + if (BIO_printf(out, "%s", spaces) <= 0) + goto err; + + /* Add a leading 00 if the top bit is set */ + if (*p >= '8') { + if (BIO_printf(out, "%02x", 0) <= 0) + goto err; + ++bytes; + use_sep = 1; + } + while (*p != '\0') { + /* Do a newline after every 15 hex bytes + add the space indent */ + if ((bytes % 15) == 0 && bytes > 0) { + if (BIO_printf(out, ":\n%s", spaces) <= 0) + goto err; + use_sep = 0; /* The first byte on the next line doesnt have a : */ + } + if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", + tolower(p[0]), tolower(p[1])) <= 0) + goto err; + ++bytes; + p += 2; + use_sep = 1; + } + if (BIO_printf(out, "\n") <= 0) + goto err; + ret = 1; +err: + OPENSSL_free(hex_str); + return ret; +} + +/* Number of octets per line */ +#define LABELED_BUF_PRINT_WIDTH 15 + +static int print_labeled_buf(BIO *out, const char *label, + const unsigned char *buf, size_t buflen) +{ + size_t i; + + if (BIO_printf(out, "%s\n", label) <= 0) + return 0; + + for (i = 0; i < buflen; i++) { + if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { + if (i > 0 && BIO_printf(out, "\n") <= 0) + return 0; + if (BIO_printf(out, " ") <= 0) + return 0; + } + + if (BIO_printf(out, "%02x%s", buf[i], + (i == buflen - 1) ? "" : ":") <= 0) + return 0; + } + if (BIO_printf(out, "\n") <= 0) + return 0; + + return 1; +} + +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) +static int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc) +{ + if (ffc->nid != NID_undef) { +#ifndef OPENSSL_NO_DH + const char *name = ossl_ffc_named_group_from_uid(ffc->nid); + + if (name == NULL) + goto err; + if (BIO_printf(out, "GROUP: %s\n", name) <= 0) + goto err; + return 1; +#else + /* How could this be? We should not have a nid in a no-dh build. */ + goto err; +#endif + } + + if (!print_labeled_bignum(out, "P: ", ffc->p)) + goto err; + if (ffc->q != NULL) { + if (!print_labeled_bignum(out, "Q: ", ffc->q)) + goto err; + } + if (!print_labeled_bignum(out, "G: ", ffc->g)) + goto err; + if (ffc->j != NULL) { + if (!print_labeled_bignum(out, "J: ", ffc->j)) + goto err; + } + if (ffc->seed != NULL) { + if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) + goto err; + } + if (ffc->gindex != -1) { + if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) + goto err; + } + if (ffc->pcounter != -1) { + if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) + goto err; + } + if (ffc->h != 0) { + if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) + goto err; + } + return 1; +err: + return 0; +} +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_DH +static int dh_to_text(BIO *out, const void *key, int selection) +{ + const DH *dh = key; + const char *type_label = NULL; + const BIGNUM *priv_key = NULL, *pub_key = NULL; + const FFC_PARAMS *params = NULL; + const BIGNUM *p = NULL; + + if (out == NULL || dh == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + type_label = "DH Private-Key"; + else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + type_label = "DH Public-Key"; + else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) + type_label = "DH Parameters"; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + priv_key = DH_get0_priv_key(dh); + if (priv_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + } + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + pub_key = DH_get0_pub_key(dh); + if (pub_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + } + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + params = dh_get0_params((DH *)dh); + if (params == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); + return 0; + } + } + + p = DH_get0_p(dh); + if (p == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + + if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) + return 0; + if (priv_key != NULL + && !print_labeled_bignum(out, "private-key:", priv_key)) + return 0; + if (pub_key != NULL + && !print_labeled_bignum(out, "public-key:", pub_key)) + return 0; + if (params != NULL + && !ffc_params_to_text(out, params)) + return 0; + + return 1; +} + +# define dh_input_type "DH" +# define dhx_input_type "DHX" +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_DSA +static int dsa_to_text(BIO *out, const void *key, int selection) +{ + const DSA *dsa = key; + const char *type_label = NULL; + const BIGNUM *priv_key = NULL, *pub_key = NULL; + const FFC_PARAMS *params = NULL; + const BIGNUM *p = NULL; + + if (out == NULL || dsa == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + type_label = "Private-Key"; + else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + type_label = "Public-Key"; + else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) + type_label = "DSA-Parameters"; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + priv_key = DSA_get0_priv_key(dsa); + if (priv_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + } + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + pub_key = DSA_get0_pub_key(dsa); + if (pub_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + } + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + params = dsa_get0_params((DSA *)dsa); + if (params == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); + return 0; + } + } + + p = DSA_get0_p(dsa); + if (p == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + + if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) + return 0; + if (priv_key != NULL + && !print_labeled_bignum(out, "priv:", priv_key)) + return 0; + if (pub_key != NULL + && !print_labeled_bignum(out, "pub: ", pub_key)) + return 0; + if (params != NULL + && !ffc_params_to_text(out, params)) + return 0; + + return 1; +} + +# define dsa_input_type "DSA" +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_EC +static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group, + BN_CTX *ctx) +{ + const char *plabel = "Prime:"; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + + p = BN_CTX_get(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (b == NULL + || !EC_GROUP_get_curve(group, p, a, b, ctx)) + return 0; + + if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) { + int basis_type = EC_GROUP_get_basis_type(group); + + /* print the 'short name' of the base type OID */ + if (basis_type == NID_undef + || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0) + return 0; + plabel = "Polynomial:"; + } + return print_labeled_bignum(out, plabel, p) + && print_labeled_bignum(out, "A: ", a) + && print_labeled_bignum(out, "B: ", b); +} + +static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, + BN_CTX *ctx) +{ + const EC_POINT *point = NULL; + BIGNUM *gen = NULL; + const char *glabel = NULL; + point_conversion_form_t form; + + form = EC_GROUP_get_point_conversion_form(group); + point = EC_GROUP_get0_generator(group); + gen = BN_CTX_get(ctx); + + if (gen == NULL + || point == NULL + || EC_POINT_point2bn(group, point, form, gen, ctx) == NULL) + return 0; + + switch (form) { + case POINT_CONVERSION_COMPRESSED: + glabel = "Generator (compressed):"; + break; + case POINT_CONVERSION_UNCOMPRESSED: + glabel = "Generator (uncompressed):"; + break; + case POINT_CONVERSION_HYBRID: + glabel = "Generator (hybrid):"; + break; + default: + return 0; + } + return print_labeled_bignum(out, glabel, gen); +} + +/* Print explicit parameters */ +static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group, + OSSL_LIB_CTX *libctx) +{ + int ret = 0, tmp_nid; + BN_CTX *ctx = NULL; + const BIGNUM *order = NULL, *cofactor = NULL; + const unsigned char *seed; + size_t seed_len = 0; + + ctx = BN_CTX_new_ex(libctx); + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); + + tmp_nid = EC_GROUP_get_field_type(group); + order = EC_GROUP_get0_order(group); + if (order == NULL) + goto err; + + seed = EC_GROUP_get0_seed(group); + if (seed != NULL) + seed_len = EC_GROUP_get_seed_len(group); + cofactor = EC_GROUP_get0_cofactor(group); + + /* print the 'short name' of the field type */ + if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0 + || !ec_param_explicit_curve_to_text(out, group, ctx) + || !ec_param_explicit_gen_to_text(out, group, ctx) + || !print_labeled_bignum(out, "Order: ", order) + || (cofactor != NULL + && !print_labeled_bignum(out, "Cofactor: ", cofactor)) + || (seed != NULL + && !print_labeled_buf(out, "Seed:", seed, seed_len))) + goto err; + ret = 1; +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + +static int ec_param_to_text(BIO *out, const EC_GROUP *group, + OSSL_LIB_CTX *libctx) +{ + if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) { + const char *curve_name; + int curve_nid = EC_GROUP_get_curve_name(group); + + /* Explicit parameters */ + if (curve_nid == NID_undef) + return 0; + + if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0) + return 0; + + curve_name = EC_curve_nid2nist(curve_nid); + return (curve_name == NULL + || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0); + } else { + return ec_param_explicit_to_text(out, group, libctx); + } +} + +static int ec_to_text(BIO *out, const void *key, int selection) +{ + const EC_KEY *ec = key; + const char *type_label = NULL; + unsigned char *priv = NULL, *pub = NULL; + size_t priv_len = 0, pub_len = 0; + const EC_GROUP *group; + int ret = 0; + + if (out == NULL || ec == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((group = EC_KEY_get0_group(ec)) == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + type_label = "Private-Key"; + else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + type_label = "Public-Key"; + else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) + type_label = "EC-Parameters"; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); + + if (priv_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + goto err; + } + priv_len = EC_KEY_priv2buf(ec, &priv); + if (priv_len == 0) + goto err; + } + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec); + + if (pub_pt == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + goto err; + } + + pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL); + if (pub_len == 0) + goto err; + } + + if (BIO_printf(out, "%s: (%d bit)\n", type_label, + EC_GROUP_order_bits(group)) <= 0) + goto err; + if (priv != NULL + && !print_labeled_buf(out, "priv:", priv, priv_len)) + goto err; + if (pub != NULL + && !print_labeled_buf(out, "pub:", pub, pub_len)) + goto err; + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) + ret = ec_param_to_text(out, group, ec_key_get_libctx(ec)); +err: + OPENSSL_clear_free(priv, priv_len); + OPENSSL_free(pub); + return ret; +} + +# define ec_input_type "EC" +#endif + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_EC +static int ecx_to_text(BIO *out, const void *key, int selection) +{ + const ECX_KEY *ecx = key; + const char *type_label = NULL; + + if (out == NULL || ecx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if (ecx->privkey == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + + switch (ecx->type) { + case ECX_KEY_TYPE_X25519: + type_label = "X25519 Private-Key"; + break; + case ECX_KEY_TYPE_X448: + type_label = "X448 Private-Key"; + break; + case ECX_KEY_TYPE_ED25519: + type_label = "ED25519 Private-Key"; + break; + case ECX_KEY_TYPE_ED448: + type_label = "ED448 Private-Key"; + break; + } + } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + /* ecx->pubkey is an array, not a pointer... */ + if (!ecx->haspubkey) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + + switch (ecx->type) { + case ECX_KEY_TYPE_X25519: + type_label = "X25519 Public-Key"; + break; + case ECX_KEY_TYPE_X448: + type_label = "X448 Public-Key"; + break; + case ECX_KEY_TYPE_ED25519: + type_label = "ED25519 Public-Key"; + break; + case ECX_KEY_TYPE_ED448: + type_label = "ED448 Public-Key"; + break; + } + } + + if (BIO_printf(out, "%s:\n", type_label) <= 0) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && !print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 + && !print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) + return 0; + + return 1; +} + +# define ed25519_input_type "ED25519" +# define ed448_input_type "ED448" +# define x25519_input_type "X25519" +# define x448_input_type "X448" +#endif + +/* ---------------------------------------------------------------------- */ + +static int rsa_to_text(BIO *out, const void *key, int selection) +{ + const RSA *rsa = key; + const char *type_label = "RSA key"; + const char *modulus_label; + const char *exponent_label; + const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; + STACK_OF(BIGNUM_const) *factors = NULL; + STACK_OF(BIGNUM_const) *exps = NULL; + STACK_OF(BIGNUM_const) *coeffs = NULL; + int primes; + const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30((RSA *)rsa); + int ret = 0; + + if (out == NULL || rsa == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + factors = sk_BIGNUM_const_new_null(); + exps = sk_BIGNUM_const_new_null(); + coeffs = sk_BIGNUM_const_new_null(); + + if (factors == NULL || exps == NULL || coeffs == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + type_label = "Private-Key"; + modulus_label = "modulus:"; + exponent_label = "publicExponent:"; + } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + type_label = "Public-Key"; + modulus_label = "Modulus:"; + exponent_label = "Exponent:"; + } + + RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); + ossl_rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs); + primes = sk_BIGNUM_const_num(factors); + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if (BIO_printf(out, "%s: (%d bit, %d primes)\n", + type_label, BN_num_bits(rsa_n), primes) <= 0) + goto err; + } else { + if (BIO_printf(out, "%s: (%d bit)\n", + type_label, BN_num_bits(rsa_n)) <= 0) + goto err; + } + + if (!print_labeled_bignum(out, modulus_label, rsa_n)) + goto err; + if (!print_labeled_bignum(out, exponent_label, rsa_e)) + goto err; + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + int i; + + if (!print_labeled_bignum(out, "privateExponent:", rsa_d)) + goto err; + if (!print_labeled_bignum(out, "prime1:", + sk_BIGNUM_const_value(factors, 0))) + goto err; + if (!print_labeled_bignum(out, "prime2:", + sk_BIGNUM_const_value(factors, 1))) + goto err; + if (!print_labeled_bignum(out, "exponent1:", + sk_BIGNUM_const_value(exps, 0))) + goto err; + if (!print_labeled_bignum(out, "exponent2:", + sk_BIGNUM_const_value(exps, 1))) + goto err; + if (!print_labeled_bignum(out, "coefficient:", + sk_BIGNUM_const_value(coeffs, 0))) + goto err; + for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { + if (BIO_printf(out, "prime%d:", i + 1) <= 0) + goto err; + if (!print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(factors, i))) + goto err; + if (BIO_printf(out, "exponent%d:", i + 1) <= 0) + goto err; + if (!print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(exps, i))) + goto err; + if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) + goto err; + if (!print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(coeffs, i - 1))) + goto err; + } + } + + if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) { + switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { + case RSA_FLAG_TYPE_RSA: + if (!ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { + if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0) + goto err; + } + break; + case RSA_FLAG_TYPE_RSASSAPSS: + if (ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { + if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0) + goto err; + } else { + int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss_params); + int maskgenalg_nid = + ossl_rsa_pss_params_30_maskgenalg(pss_params); + int maskgenhashalg_nid = + ossl_rsa_pss_params_30_maskgenhashalg(pss_params); + int saltlen = ossl_rsa_pss_params_30_saltlen(pss_params); + int trailerfield = + ossl_rsa_pss_params_30_trailerfield(pss_params); + + if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0) + goto err; + if (BIO_printf(out, " Hash Algorithm: %s%s\n", + ossl_rsa_oaeppss_nid2name(hashalg_nid), + (hashalg_nid == NID_sha1 + ? " (default)" : "")) <= 0) + goto err; + if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n", + ossl_rsa_mgf_nid2name(maskgenalg_nid), + ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid), + (maskgenalg_nid == NID_mgf1 + && maskgenhashalg_nid == NID_sha1 + ? " (default)" : "")) <= 0) + goto err; + if (BIO_printf(out, " Minimum Salt Length: %d%s\n", + saltlen, + (saltlen == 20 ? " (default)" : "")) <= 0) + goto err; + /* + * TODO(3.0) Should we show the ASN.1 trailerField value, or + * the actual trailerfield byte (i.e. 0xBC for 1)? + * crypto/rsa/rsa_ameth.c isn't very clear on that, as it + * does display 0xBC when the default applies, but the ASN.1 + * trailerField value otherwise... + */ + if (BIO_printf(out, " Trailer Field: 0x%x%s\n", + trailerfield, + (trailerfield == 1 ? " (default)" : "")) <= 0) + goto err; + } + break; + } + } + + ret = 1; + err: + sk_BIGNUM_const_free(factors); + sk_BIGNUM_const_free(exps); + sk_BIGNUM_const_free(coeffs); + return ret; +} + +#define rsa_input_type "RSA" +#define rsapss_input_type "RSA-PSS" + +/* ---------------------------------------------------------------------- */ + +static void *key2text_newctx(void *provctx) +{ + return provctx; +} + +static void key2text_freectx(ossl_unused void *vctx) +{ +} + +static const OSSL_PARAM *key2text_gettable_params(void *provctx) +{ + static const OSSL_PARAM gettables[] = { + { OSSL_ENCODER_PARAM_OUTPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + OSSL_PARAM_END, + }; + + return gettables; +} + +static int key2text_get_params(OSSL_PARAM params[], const char *input_type) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_ENCODER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, input_type)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_ENCODER_PARAM_OUTPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "TEXT")) + return 0; + + return 1; +} + +static int key2text_encode(void *vctx, const void *key, int selection, + OSSL_CORE_BIO *cout, + int (*key2text)(BIO *out, const void *key, + int selection), + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) +{ + BIO *out = bio_new_from_core_bio(vctx, cout); + int ret; + + if (out == NULL) + return 0; + + ret = key2text(out, key, selection); + BIO_free(out); + + return ret; +} + +#define MAKE_TEXT_ENCODER(impl, type) \ + static OSSL_FUNC_encoder_get_params_fn \ + impl##2text_get_params; \ + static OSSL_FUNC_encoder_import_object_fn \ + impl##2text_import_object; \ + static OSSL_FUNC_encoder_free_object_fn \ + impl##2text_free_object; \ + static OSSL_FUNC_encoder_encode_fn impl##2text_encode; \ + \ + static int impl##2text_get_params(OSSL_PARAM params[]) \ + { \ + return key2text_get_params(params, impl##_input_type); \ + } \ + static void *impl##2text_import_object(void *ctx, int selection, \ + const OSSL_PARAM params[]) \ + { \ + return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ + ctx, selection, params); \ + } \ + static void impl##2text_free_object(void *key) \ + { \ + ossl_prov_free_key(ossl_##impl##_keymgmt_functions, key); \ + } \ + static int impl##2text_encode(void *vctx, OSSL_CORE_BIO *cout, \ + const void *key, \ + const OSSL_PARAM key_abstract[], \ + int selection, \ + OSSL_PASSPHRASE_CALLBACK *cb, \ + void *cbarg) \ + { \ + /* We don't deal with abstract objects */ \ + if (key_abstract != NULL) { \ + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ + return 0; \ + } \ + return key2text_encode(vctx, key, selection, cout, \ + type##_to_text, cb, cbarg); \ + } \ + const OSSL_DISPATCH ossl_##impl##_to_text_encoder_functions[] = { \ + { OSSL_FUNC_ENCODER_NEWCTX, \ + (void (*)(void))key2text_newctx }, \ + { OSSL_FUNC_ENCODER_FREECTX, \ + (void (*)(void))key2text_freectx }, \ + { OSSL_FUNC_ENCODER_GETTABLE_PARAMS, \ + (void (*)(void))key2text_gettable_params }, \ + { OSSL_FUNC_ENCODER_GET_PARAMS, \ + (void (*)(void))impl##2text_get_params }, \ + { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ + (void (*)(void))impl##2text_import_object }, \ + { OSSL_FUNC_ENCODER_FREE_OBJECT, \ + (void (*)(void))impl##2text_free_object }, \ + { OSSL_FUNC_ENCODER_ENCODE, \ + (void (*)(void))impl##2text_encode }, \ + { 0, NULL } \ + } + +#ifndef OPENSSL_NO_DH +MAKE_TEXT_ENCODER(dh, dh); +MAKE_TEXT_ENCODER(dhx, dh); +#endif +#ifndef OPENSSL_NO_DSA +MAKE_TEXT_ENCODER(dsa, dsa); +#endif +#ifndef OPENSSL_NO_EC +MAKE_TEXT_ENCODER(ec, ec); +MAKE_TEXT_ENCODER(ed25519, ecx); +MAKE_TEXT_ENCODER(ed448, ecx); +MAKE_TEXT_ENCODER(x25519, ecx); +MAKE_TEXT_ENCODER(x448, ecx); +#endif +MAKE_TEXT_ENCODER(rsa, rsa); +MAKE_TEXT_ENCODER(rsapss, rsa); diff --git a/providers/implementations/encode_decode/endecoder_common.c b/providers/implementations/encode_decode/endecoder_common.c new file mode 100644 index 0000000000..c85fe915ac --- /dev/null +++ b/providers/implementations/encode_decode/endecoder_common.c @@ -0,0 +1,84 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "endecoder_local.h" + +OSSL_FUNC_keymgmt_new_fn * +ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns) +{ + /* Pilfer the keymgmt dispatch table */ + for (; fns->function_id != 0; fns++) + if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW) + return OSSL_FUNC_keymgmt_new(fns); + + return NULL; +} + +OSSL_FUNC_keymgmt_free_fn * +ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns) +{ + /* Pilfer the keymgmt dispatch table */ + for (; fns->function_id != 0; fns++) + if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE) + return OSSL_FUNC_keymgmt_free(fns); + + return NULL; +} + +OSSL_FUNC_keymgmt_import_fn * +ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns) +{ + /* Pilfer the keymgmt dispatch table */ + for (; fns->function_id != 0; fns++) + if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT) + return OSSL_FUNC_keymgmt_import(fns); + + return NULL; +} + +OSSL_FUNC_keymgmt_export_fn * +ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns) +{ + /* Pilfer the keymgmt dispatch table */ + for (; fns->function_id != 0; fns++) + if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT) + return OSSL_FUNC_keymgmt_export(fns); + + return NULL; +} + +void *ossl_prov_import_key(const OSSL_DISPATCH *fns, void *provctx, + int selection, const OSSL_PARAM params[]) +{ + OSSL_FUNC_keymgmt_new_fn *kmgmt_new = ossl_prov_get_keymgmt_new(fns); + OSSL_FUNC_keymgmt_free_fn *kmgmt_free = ossl_prov_get_keymgmt_free(fns); + OSSL_FUNC_keymgmt_import_fn *kmgmt_import = + ossl_prov_get_keymgmt_import(fns); + void *key = NULL; + + if (kmgmt_new != NULL && kmgmt_import != NULL && kmgmt_free != NULL) { + if ((key = kmgmt_new(provctx)) == NULL + || !kmgmt_import(key, selection, params)) { + kmgmt_free(key); + key = NULL; + } + } + return key; +} + +void ossl_prov_free_key(const OSSL_DISPATCH *fns, void *key) +{ + OSSL_FUNC_keymgmt_free_fn *kmgmt_free = ossl_prov_get_keymgmt_free(fns); + + if (kmgmt_free != NULL) + kmgmt_free(key); +} + diff --git a/providers/implementations/encode_decode/endecoder_local.h b/providers/implementations/encode_decode/endecoder_local.h new file mode 100644 index 0000000000..ab431b8086 --- /dev/null +++ b/providers/implementations/encode_decode/endecoder_local.h @@ -0,0 +1,26 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "prov/provider_ctx.h" + +OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns); +OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns); +OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns); +OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns); + +int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len, + unsigned char *input_der, long input_der_len, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg); + +void *ossl_prov_import_key(const OSSL_DISPATCH *fns, void *provctx, + int selection, const OSSL_PARAM params[]); +void ossl_prov_free_key(const OSSL_DISPATCH *fns, void *key); diff --git a/providers/implementations/exchange/build.info b/providers/implementations/exchange/build.info index 3127f9a3e7..4659dc9b0e 100644 --- a/providers/implementations/exchange/build.info +++ b/providers/implementations/exchange/build.info @@ -2,8 +2,10 @@ # switch each to the Legacy provider when needed. $DH_GOAL=../../libimplementations.a +$ECDH_GOAL=../../libimplementations.a $ECX_GOAL=../../libimplementations.a $ECDH_GOAL=../../libimplementations.a +$KDF_GOAL=../../libimplementations.a IF[{- !$disabled{dh} -}] SOURCE[$DH_GOAL]=dh_exch.c @@ -22,6 +24,7 @@ ENDIF IF[{- !$disabled{ec} -}] SOURCE[$ECX_GOAL]=ecx_exch.c DEFINE[$ECX_GOAL]=$ECDEF - SOURCE[../../libfips.a]=ecdh_exch.c - SOURCE[../../libnonfips.a]=ecdh_exch.c + SOURCE[$ECDH_GOAL]=ecdh_exch.c ENDIF + +SOURCE[$KDF_GOAL]=kdf_exch.c diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c index 765ab2e89a..3eeac98497 100644 --- a/providers/implementations/exchange/dh_exch.c +++ b/providers/implementations/exchange/dh_exch.c @@ -13,13 +13,17 @@ */ #include "internal/deprecated.h" +#include #include #include #include #include +#include #include +#include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" +#include "prov/securitycheck.h" #include "crypto/dh.h" static OSSL_FUNC_keyexch_newctx_fn dh_newctx; @@ -30,6 +34,23 @@ static OSSL_FUNC_keyexch_freectx_fn dh_freectx; static OSSL_FUNC_keyexch_dupctx_fn dh_dupctx; static OSSL_FUNC_keyexch_set_ctx_params_fn dh_set_ctx_params; static OSSL_FUNC_keyexch_settable_ctx_params_fn dh_settable_ctx_params; +static OSSL_FUNC_keyexch_get_ctx_params_fn dh_get_ctx_params; +static OSSL_FUNC_keyexch_gettable_ctx_params_fn dh_gettable_ctx_params; + +/* + * This type is only really used to handle some legacy related functionality. + * If you need to use other KDF's (such as SSKDF) just use PROV_DH_KDF_NONE + * here and then create and run a KDF after the key is derived. + * Note that X942 has 2 variants of key derivation: + * (1) DH_KDF_X9_42_ASN1 - which contains an ANS1 encoded object that has + * the counter embedded in it. + * (2) DH_KDF_X941_CONCAT - which is the same as ECDH_X963_KDF (which can be + * done by creating a "X963KDF". + */ +enum kdf_type { + PROV_DH_KDF_NONE = 0, + PROV_DH_KDF_X9_42_ASN1 +}; /* * What's passed as an actual key is defined by the KEYMGMT interface. @@ -38,19 +59,36 @@ static OSSL_FUNC_keyexch_settable_ctx_params_fn dh_settable_ctx_params; */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; DH *dh; DH *dhpeer; unsigned int pad : 1; + + /* DH KDF */ + /* KDF (if any) to use for DH */ + enum kdf_type kdf_type; + /* Message digest to use for key derivation */ + EVP_MD *kdf_md; + /* User key material */ + unsigned char *kdf_ukm; + size_t kdf_ukmlen; + /* KDF output length */ + size_t kdf_outlen; + char *kdf_cekalg; } PROV_DH_CTX; static void *dh_newctx(void *provctx) { - PROV_DH_CTX *pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_CTX)); + PROV_DH_CTX *pdhctx; + + if (!ossl_prov_is_running()) + return NULL; + pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_CTX)); if (pdhctx == NULL) return NULL; - pdhctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + pdhctx->libctx = PROV_LIBCTX_OF(provctx); + pdhctx->kdf_type = PROV_DH_KDF_NONE; return pdhctx; } @@ -58,26 +96,34 @@ static int dh_init(void *vpdhctx, void *vdh) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; - if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh)) + if (!ossl_prov_is_running() + || pdhctx == NULL + || vdh == NULL + || !DH_up_ref(vdh)) return 0; DH_free(pdhctx->dh); pdhctx->dh = vdh; - return 1; + pdhctx->kdf_type = PROV_DH_KDF_NONE; + return dh_check_key(vdh); } static int dh_set_peer(void *vpdhctx, void *vdh) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; - if (pdhctx == NULL || vdh == NULL || !DH_up_ref(vdh)) + if (!ossl_prov_is_running() + || pdhctx == NULL + || vdh == NULL + || !DH_up_ref(vdh)) return 0; DH_free(pdhctx->dhpeer); pdhctx->dhpeer = vdh; return 1; } -static int dh_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen, - size_t outlen) +static int dh_plain_derive(void *vpdhctx, + unsigned char *secret, size_t *secretlen, + size_t outlen) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; int ret; @@ -108,12 +154,77 @@ static int dh_derive(void *vpdhctx, unsigned char *secret, size_t *secretlen, return 1; } +static int dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret, + size_t *secretlen, size_t outlen) +{ + PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; + unsigned char *stmp = NULL; + size_t stmplen; + int ret = 0; + + if (secret == NULL) { + *secretlen = pdhctx->kdf_outlen; + return 1; + } + + if (pdhctx->kdf_outlen > outlen) + return 0; + if (!dh_plain_derive(pdhctx, NULL, &stmplen, 0)) + return 0; + if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!dh_plain_derive(pdhctx, stmp, &stmplen, stmplen)) + goto err; + + /* Do KDF stuff */ + if (pdhctx->kdf_type == PROV_DH_KDF_X9_42_ASN1) { + if (!dh_KDF_X9_42_asn1(secret, pdhctx->kdf_outlen, + stmp, stmplen, + pdhctx->kdf_cekalg, + pdhctx->kdf_ukm, + pdhctx->kdf_ukmlen, + pdhctx->kdf_md, + pdhctx->libctx, NULL)) + goto err; + } + *secretlen = pdhctx->kdf_outlen; + ret = 1; +err: + OPENSSL_secure_clear_free(stmp, stmplen); + return ret; +} + +static int dh_derive(void *vpdhctx, unsigned char *secret, + size_t *psecretlen, size_t outlen) +{ + PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; + + if (!ossl_prov_is_running()) + return 0; + + switch (pdhctx->kdf_type) { + case PROV_DH_KDF_NONE: + return dh_plain_derive(pdhctx, secret, psecretlen, outlen); + case PROV_DH_KDF_X9_42_ASN1: + return dh_X9_42_kdf_derive(pdhctx, secret, psecretlen, outlen); + default: + break; + } + return 0; +} + + static void dh_freectx(void *vpdhctx) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; + OPENSSL_free(pdhctx->kdf_cekalg); DH_free(pdhctx->dh); DH_free(pdhctx->dhpeer); + EVP_MD_free(pdhctx->kdf_md); + OPENSSL_clear_free(pdhctx->kdf_ukm, pdhctx->kdf_ukmlen); OPENSSL_free(pdhctx); } @@ -123,23 +234,48 @@ static void *dh_dupctx(void *vpdhctx) PROV_DH_CTX *srcctx = (PROV_DH_CTX *)vpdhctx; PROV_DH_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; *dstctx = *srcctx; - if (dstctx->dh != NULL && !DH_up_ref(dstctx->dh)) { - OPENSSL_free(dstctx); - return NULL; - } + dstctx->dh = NULL; + dstctx->dhpeer = NULL; + dstctx->kdf_md = NULL; + dstctx->kdf_ukm = NULL; + dstctx->kdf_cekalg = NULL; - if (dstctx->dhpeer != NULL && !DH_up_ref(dstctx->dhpeer)) { - DH_free(dstctx->dh); - OPENSSL_free(dstctx); - return NULL; + if (dstctx->dh != NULL && !DH_up_ref(srcctx->dh)) + goto err; + else + dstctx->dh = srcctx->dh; + + if (dstctx->dhpeer != NULL && !DH_up_ref(srcctx->dhpeer)) + goto err; + else + dstctx->dhpeer = srcctx->dhpeer; + + if (srcctx->kdf_md != NULL && !EVP_MD_up_ref(srcctx->kdf_md)) + goto err; + else + dstctx->kdf_md = srcctx->kdf_md; + + /* Duplicate UKM data if present */ + if (srcctx->kdf_ukm != NULL && srcctx->kdf_ukmlen > 0) { + dstctx->kdf_ukm = OPENSSL_memdup(srcctx->kdf_ukm, + srcctx->kdf_ukmlen); + if (dstctx->kdf_ukm == NULL) + goto err; } + dstctx->kdf_cekalg = OPENSSL_strdup(srcctx->kdf_cekalg); return dstctx; +err: + dh_freectx(dstctx); + return NULL; } static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[]) @@ -147,28 +283,184 @@ static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[]) PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; const OSSL_PARAM *p; unsigned int pad; + char name[80] = { '\0' }; /* should be big enough */ + char *str = NULL; if (pdhctx == NULL || params == NULL) return 0; + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); + if (p != NULL) { + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return 0; + + if (name[0] == '\0') + pdhctx->kdf_type = PROV_DH_KDF_NONE; + else if (strcmp(name, OSSL_KDF_NAME_X942KDF) == 0) + pdhctx->kdf_type = PROV_DH_KDF_X9_42_ASN1; + else + return 0; + } + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); + if (p != NULL) { + char mdprops[80] = { '\0' }; /* should be big enough */ + + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return 0; + + str = mdprops; + p = OSSL_PARAM_locate_const(params, + OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS); + + if (p != NULL) { + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) + return 0; + } + + EVP_MD_free(pdhctx->kdf_md); + pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); + if (!digest_is_allowed(pdhctx->kdf_md)) { + EVP_MD_free(pdhctx->kdf_md); + pdhctx->kdf_md = NULL; + } + if (pdhctx->kdf_md == NULL) + return 0; + } + + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); + if (p != NULL) { + size_t outlen; + + if (!OSSL_PARAM_get_size_t(p, &outlen)) + return 0; + pdhctx->kdf_outlen = outlen; + } + + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_UKM); + if (p != NULL) { + void *tmp_ukm = NULL; + size_t tmp_ukmlen; + + OPENSSL_free(pdhctx->kdf_ukm); + pdhctx->kdf_ukm = NULL; + pdhctx->kdf_ukmlen = 0; + /* ukm is an optional field so it can be NULL */ + if (p->data != NULL && p->data_size != 0) { + if (!OSSL_PARAM_get_octet_string(p, &tmp_ukm, 0, &tmp_ukmlen)) + return 0; + pdhctx->kdf_ukm = tmp_ukm; + pdhctx->kdf_ukmlen = tmp_ukmlen; + } + } + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); - if (p == NULL || !OSSL_PARAM_get_uint(p, &pad)) - return 0; - pdhctx->pad = pad ? 1 : 0; + if (p != NULL) { + if (!OSSL_PARAM_get_uint(p, &pad)) + return 0; + pdhctx->pad = pad ? 1 : 0; + } + + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG); + if (p != NULL) { + str = name; + if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(name))) + return 0; + pdhctx->kdf_cekalg = OPENSSL_strdup(name); + } return 1; } static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_PAD, NULL), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST_PROPS, NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), + OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *dh_settable_ctx_params(void) +static const OSSL_PARAM *dh_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } -const OSSL_DISPATCH dh_keyexch_functions[] = { +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE, NULL), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), + OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, + NULL, 0), + OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN, NULL), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *dh_gettable_ctx_params(ossl_unused void *provctx) +{ + return known_gettable_ctx_params; +} + +static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) +{ + PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; + OSSL_PARAM *p; + + if (pdhctx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); + if (p != NULL) { + const char *kdf_type = NULL; + + switch (pdhctx->kdf_type) { + case PROV_DH_KDF_NONE: + kdf_type = ""; + break; + case PROV_DH_KDF_X9_42_ASN1: + kdf_type = OSSL_KDF_NAME_X942KDF; + break; + default: + return 0; + } + + if (!OSSL_PARAM_set_utf8_string(p, kdf_type)) + return 0; + } + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_DIGEST); + if (p != NULL + && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL + ? "" + : EVP_MD_name(pdhctx->kdf_md))){ + return 0; + } + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_outlen)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM); + if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, pdhctx->kdf_ukm, 0)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_KDF_UKM_LEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, pdhctx->kdf_ukmlen)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_CEK_ALG); + if (p != NULL + && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL + ? "" : pdhctx->kdf_cekalg)) + return 0; + + return 1; +} + +const OSSL_DISPATCH ossl_dh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive }, @@ -178,5 +470,8 @@ const OSSL_DISPATCH dh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))dh_set_ctx_params }, { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, (void (*)(void))dh_settable_ctx_params }, + { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))dh_get_ctx_params }, + { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, + (void (*)(void))dh_gettable_ctx_params }, { 0, NULL } }; diff --git a/providers/implementations/exchange/ecdh_exch.c b/providers/implementations/exchange/ecdh_exch.c index ba28d5102e..0ea54ecc5f 100644 --- a/providers/implementations/exchange/ecdh_exch.c +++ b/providers/implementations/exchange/ecdh_exch.c @@ -22,7 +22,9 @@ #include #include #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/implementations.h" +#include "prov/securitycheck.h" #include "crypto/ec.h" /* ecdh_KDF_X9_63() */ static OSSL_FUNC_keyexch_newctx_fn ecdh_newctx; @@ -48,7 +50,7 @@ enum kdf_type { */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; EC_KEY *k; EC_KEY *peerk; @@ -79,12 +81,16 @@ typedef struct { static void *ecdh_newctx(void *provctx) { - PROV_ECDH_CTX *pectx = OPENSSL_zalloc(sizeof(*pectx)); + PROV_ECDH_CTX *pectx; + if (!ossl_prov_is_running()) + return NULL; + + pectx = OPENSSL_zalloc(sizeof(*pectx)); if (pectx == NULL) return NULL; - pectx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + pectx->libctx = PROV_LIBCTX_OF(provctx); pectx->cofactor_mode = -1; pectx->kdf_type = PROV_ECDH_KDF_NONE; @@ -96,13 +102,16 @@ int ecdh_init(void *vpecdhctx, void *vecdh) { PROV_ECDH_CTX *pecdhctx = (PROV_ECDH_CTX *)vpecdhctx; - if (pecdhctx == NULL || vecdh == NULL || !EC_KEY_up_ref(vecdh)) + if (!ossl_prov_is_running() + || pecdhctx == NULL + || vecdh == NULL + || !EC_KEY_up_ref(vecdh)) return 0; EC_KEY_free(pecdhctx->k); pecdhctx->k = vecdh; pecdhctx->cofactor_mode = -1; pecdhctx->kdf_type = PROV_ECDH_KDF_NONE; - return 1; + return ec_check_key(vecdh, 1); } static @@ -110,11 +119,14 @@ int ecdh_set_peer(void *vpecdhctx, void *vecdh) { PROV_ECDH_CTX *pecdhctx = (PROV_ECDH_CTX *)vpecdhctx; - if (pecdhctx == NULL || vecdh == NULL || !EC_KEY_up_ref(vecdh)) + if (!ossl_prov_is_running() + || pecdhctx == NULL + || vecdh == NULL + || !EC_KEY_up_ref(vecdh)) return 0; EC_KEY_free(pecdhctx->peerk); pecdhctx->peerk = vecdh; - return 1; + return ec_check_key(vecdh, 1); } static @@ -137,6 +149,9 @@ void *ecdh_dupctx(void *vpecdhctx) PROV_ECDH_CTX *srcctx = (PROV_ECDH_CTX *)vpecdhctx; PROV_ECDH_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; @@ -239,7 +254,10 @@ int ecdh_set_ctx_params(void *vpecdhctx, const OSSL_PARAM params[]) EVP_MD_free(pectx->kdf_md); pectx->kdf_md = EVP_MD_fetch(pectx->libctx, name, mdprops); - + if (!digest_is_allowed(pectx->kdf_md)) { + EVP_MD_free(pectx->kdf_md); + pectx->kdf_md = NULL; + } if (pectx->kdf_md == NULL) return 0; } @@ -279,7 +297,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { }; static -const OSSL_PARAM *ecdh_settable_ctx_params(void) +const OSSL_PARAM *ecdh_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } @@ -360,7 +378,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { }; static -const OSSL_PARAM *ecdh_gettable_ctx_params(void) +const OSSL_PARAM *ecdh_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -458,7 +476,6 @@ int ecdh_plain_derive(void *vpecdhctx, unsigned char *secret, return ret; } -#ifndef FIPS_MODULE static ossl_inline int ecdh_X9_63_kdf_derive(void *vpecdhctx, unsigned char *secret, size_t *psecretlen, size_t outlen) @@ -489,7 +506,8 @@ int ecdh_X9_63_kdf_derive(void *vpecdhctx, unsigned char *secret, stmp, stmplen, pecdhctx->kdf_ukm, pecdhctx->kdf_ukmlen, - pecdhctx->kdf_md)) + pecdhctx->kdf_md, + pecdhctx->libctx, NULL)) goto err; *psecretlen = pecdhctx->kdf_outlen; ret = 1; @@ -498,7 +516,6 @@ int ecdh_X9_63_kdf_derive(void *vpecdhctx, unsigned char *secret, OPENSSL_secure_clear_free(stmp, stmplen); return ret; } -#endif /* FIPS_MODULE */ static int ecdh_derive(void *vpecdhctx, unsigned char *secret, @@ -509,19 +526,15 @@ int ecdh_derive(void *vpecdhctx, unsigned char *secret, switch (pecdhctx->kdf_type) { case PROV_ECDH_KDF_NONE: return ecdh_plain_derive(vpecdhctx, secret, psecretlen, outlen); -#ifndef FIPS_MODULE case PROV_ECDH_KDF_X9_63: return ecdh_X9_63_kdf_derive(vpecdhctx, secret, psecretlen, outlen); - -#endif /* FIPS_MODULE */ default: break; } - return 0; } -const OSSL_DISPATCH ecdh_keyexch_functions[] = { +const OSSL_DISPATCH ecossl_dh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))ecdh_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))ecdh_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))ecdh_derive }, diff --git a/providers/implementations/exchange/ecx_exch.c b/providers/implementations/exchange/ecx_exch.c index 4840b8802f..db6aa90c03 100644 --- a/providers/implementations/exchange/ecx_exch.c +++ b/providers/implementations/exchange/ecx_exch.c @@ -15,6 +15,7 @@ #include "internal/cryptlib.h" #include "crypto/ecx.h" #include "prov/implementations.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #ifdef S390X_EC_ASM # include "s390x_arch.h" @@ -42,8 +43,12 @@ typedef struct { static void *ecx_newctx(void *provctx, size_t keylen) { - PROV_ECX_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_ECX_CTX)); + PROV_ECX_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(PROV_ECX_CTX)); if (ctx == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -69,6 +74,9 @@ static int ecx_init(void *vecxctx, void *vkey) PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx; ECX_KEY *key = vkey; + if (!ossl_prov_is_running()) + return 0; + if (ecxctx == NULL || key == NULL || key->keylen != ecxctx->keylen @@ -88,6 +96,9 @@ static int ecx_set_peer(void *vecxctx, void *vkey) PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx; ECX_KEY *key = vkey; + if (!ossl_prov_is_running()) + return 0; + if (ecxctx == NULL || key == NULL || key->keylen != ecxctx->keylen @@ -106,6 +117,9 @@ static int ecx_derive(void *vecxctx, unsigned char *secret, size_t *secretlen, { PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx; + if (!ossl_prov_is_running()) + return 0; + if (ecxctx->key == NULL || ecxctx->key->privkey == NULL || ecxctx->peerkey == NULL) { @@ -179,6 +193,9 @@ static void *ecx_dupctx(void *vecxctx) PROV_ECX_CTX *srcctx = (PROV_ECX_CTX *)vecxctx; PROV_ECX_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); @@ -202,7 +219,7 @@ static void *ecx_dupctx(void *vecxctx) return dstctx; } -const OSSL_DISPATCH x25519_keyexch_functions[] = { +const OSSL_DISPATCH ossl_x25519_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))x25519_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))ecx_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))ecx_derive }, @@ -212,7 +229,7 @@ const OSSL_DISPATCH x25519_keyexch_functions[] = { { 0, NULL } }; -const OSSL_DISPATCH x448_keyexch_functions[] = { +const OSSL_DISPATCH ossl_x448_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))x448_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))ecx_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))ecx_derive }, diff --git a/providers/implementations/exchange/kdf_exch.c b/providers/implementations/exchange/kdf_exch.c new file mode 100644 index 0000000000..c022a35107 --- /dev/null +++ b/providers/implementations/exchange/kdf_exch.c @@ -0,0 +1,187 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include "prov/implementations.h" +#include "prov/provider_ctx.h" +#include "prov/kdfexchange.h" +#include "prov/providercommon.h" + +static OSSL_FUNC_keyexch_newctx_fn kdf_tls1_prf_newctx; +static OSSL_FUNC_keyexch_newctx_fn kdf_hkdf_newctx; +static OSSL_FUNC_keyexch_newctx_fn kdf_scrypt_newctx; +static OSSL_FUNC_keyexch_init_fn kdf_init; +static OSSL_FUNC_keyexch_derive_fn kdf_derive; +static OSSL_FUNC_keyexch_freectx_fn kdf_freectx; +static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx; +static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params; +static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params; +static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; +static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_scrypt_settable_ctx_params; + +typedef struct { + void *provctx; + EVP_KDF_CTX *kdfctx; + KDF_DATA *kdfdata; +} PROV_KDF_CTX; + +static void *kdf_newctx(const char *kdfname, void *provctx) +{ + PROV_KDF_CTX *kdfctx; + EVP_KDF *kdf = NULL; + + if (!ossl_prov_is_running()) + return NULL; + + kdfctx = OPENSSL_zalloc(sizeof(PROV_KDF_CTX)); + if (kdfctx == NULL) + return NULL; + + kdfctx->provctx = provctx; + + kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, NULL); + if (kdf == NULL) + goto err; + kdfctx->kdfctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + + if (kdfctx->kdfctx == NULL) + goto err; + + return kdfctx; +err: + OPENSSL_free(kdfctx); + return NULL; +} + +#define KDF_NEWCTX(funcname, kdfname) \ + static void *kdf_##funcname##_newctx(void *provctx) \ + { \ + return kdf_newctx(kdfname, provctx); \ + } + +KDF_NEWCTX(tls1_prf, "TLS1-PRF") +KDF_NEWCTX(hkdf, "HKDF") +KDF_NEWCTX(scrypt, "SCRYPT") + +static int kdf_init(void *vpkdfctx, void *vkdf) +{ + PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; + + if (!ossl_prov_is_running() + || pkdfctx == NULL + || vkdf == NULL + || !kdf_data_up_ref(vkdf)) + return 0; + pkdfctx->kdfdata = vkdf; + + return 1; +} + +static int kdf_derive(void *vpkdfctx, unsigned char *secret, size_t *secretlen, + size_t outlen) +{ + PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; + + if (!ossl_prov_is_running()) + return 0; + return EVP_KDF_derive(pkdfctx->kdfctx, secret, *secretlen); +} + +static void kdf_freectx(void *vpkdfctx) +{ + PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; + + EVP_KDF_CTX_free(pkdfctx->kdfctx); + kdf_data_free(pkdfctx->kdfdata); + + OPENSSL_free(pkdfctx); +} + +static void *kdf_dupctx(void *vpkdfctx) +{ + PROV_KDF_CTX *srcctx = (PROV_KDF_CTX *)vpkdfctx; + PROV_KDF_CTX *dstctx; + + if (!ossl_prov_is_running()) + return NULL; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + + dstctx->kdfctx = EVP_KDF_CTX_dup(srcctx->kdfctx); + if (dstctx->kdfctx == NULL) { + OPENSSL_free(dstctx); + return NULL; + } + if (!kdf_data_up_ref(dstctx->kdfdata)) { + EVP_KDF_CTX_free(dstctx->kdfctx); + OPENSSL_free(dstctx); + return NULL; + } + + return dstctx; +} + +static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[]) +{ + PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx; + + return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params); +} + +static const OSSL_PARAM *kdf_settable_ctx_params(void *provctx, + const char *kdfname) +{ + EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, + NULL); + const OSSL_PARAM *params; + + if (kdf == NULL) + return NULL; + + params = EVP_KDF_settable_ctx_params(kdf); + EVP_KDF_free(kdf); + + return params; +} + +#define KDF_SETTABLE_CTX_PARAMS(funcname, kdfname) \ + static const OSSL_PARAM *kdf_##funcname##_settable_ctx_params(void *provctx) \ + { \ + return kdf_settable_ctx_params(provctx, kdfname); \ + } + +KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF") +KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF") +KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT") + +#define KDF_KEYEXCH_FUNCTIONS(funcname) \ + const OSSL_DISPATCH ossl_kdf_##funcname##_keyexch_functions[] = { \ + { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \ + { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))kdf_init }, \ + { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))kdf_derive }, \ + { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \ + { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \ + { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \ + { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \ + (void (*)(void))kdf_##funcname##_settable_ctx_params }, \ + { 0, NULL } \ + }; + +KDF_KEYEXCH_FUNCTIONS(tls1_prf) +KDF_KEYEXCH_FUNCTIONS(hkdf) +KDF_KEYEXCH_FUNCTIONS(scrypt) diff --git a/providers/implementations/include/prov/ciphercommon.h b/providers/implementations/include/prov/ciphercommon.h index 7e8143fae0..c034528448 100644 --- a/providers/implementations/include/prov/ciphercommon.h +++ b/providers/implementations/include/prov/ciphercommon.h @@ -81,7 +81,7 @@ struct prov_cipher_ctx_st { unsigned char iv[GENERIC_BLOCK_SIZE]; const PROV_CIPHER_HW *hw; /* hardware specific functions */ const void *ks; /* Pointer to algorithm specific key data */ - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; }; struct prov_cipher_hw_st { @@ -90,103 +90,104 @@ struct prov_cipher_hw_st { void (*copyctx)(PROV_CIPHER_CTX *dst, const PROV_CIPHER_CTX *src); }; -void cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx); -OSSL_FUNC_cipher_encrypt_init_fn cipher_generic_einit; -OSSL_FUNC_cipher_decrypt_init_fn cipher_generic_dinit; -OSSL_FUNC_cipher_update_fn cipher_generic_block_update; -OSSL_FUNC_cipher_final_fn cipher_generic_block_final; -OSSL_FUNC_cipher_update_fn cipher_generic_stream_update; -OSSL_FUNC_cipher_final_fn cipher_generic_stream_final; -OSSL_FUNC_cipher_cipher_fn cipher_generic_cipher; -OSSL_FUNC_cipher_get_ctx_params_fn cipher_generic_get_ctx_params; -OSSL_FUNC_cipher_set_ctx_params_fn cipher_generic_set_ctx_params; -OSSL_FUNC_cipher_gettable_params_fn cipher_generic_gettable_params; -OSSL_FUNC_cipher_gettable_ctx_params_fn cipher_generic_gettable_ctx_params; -OSSL_FUNC_cipher_settable_ctx_params_fn cipher_generic_settable_ctx_params; -OSSL_FUNC_cipher_set_ctx_params_fn cipher_var_keylen_set_ctx_params; -OSSL_FUNC_cipher_settable_ctx_params_fn cipher_var_keylen_settable_ctx_params; -OSSL_FUNC_cipher_gettable_ctx_params_fn cipher_aead_gettable_ctx_params; -OSSL_FUNC_cipher_settable_ctx_params_fn cipher_aead_settable_ctx_params; - -int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, +void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx); +OSSL_FUNC_cipher_encrypt_init_fn ossl_cipher_generic_einit; +OSSL_FUNC_cipher_decrypt_init_fn ossl_cipher_generic_dinit; +OSSL_FUNC_cipher_update_fn ossl_cipher_generic_block_update; +OSSL_FUNC_cipher_final_fn ossl_cipher_generic_block_final; +OSSL_FUNC_cipher_update_fn ossl_cipher_generic_stream_update; +OSSL_FUNC_cipher_final_fn ossl_cipher_generic_stream_final; +OSSL_FUNC_cipher_cipher_fn ossl_cipher_generic_cipher; +OSSL_FUNC_cipher_get_ctx_params_fn ossl_cipher_generic_get_ctx_params; +OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_generic_set_ctx_params; +OSSL_FUNC_cipher_gettable_params_fn ossl_cipher_generic_gettable_params; +OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_generic_gettable_ctx_params; +OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_generic_settable_ctx_params; +OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_var_keylen_set_ctx_params; +OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_var_keylen_settable_ctx_params; +OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_aead_gettable_ctx_params; +OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_aead_settable_ctx_params; + +int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, unsigned long flags, size_t kbits, size_t blkbits, size_t ivbits); -void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, +void ossl_cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits, size_t ivbits, unsigned int mode, uint64_t flags, const PROV_CIPHER_HW *hw, void *provctx); #define IMPLEMENT_generic_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits,\ blkbits, ivbits, typ) \ -const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit }, \ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit }, \ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_get_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_set_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_settable_ctx_params }, \ { 0, NULL } \ }; #define IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, \ kbits, blkbits, ivbits, typ) \ -const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, \ (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ - { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit }, \ - { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit }, \ - { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\ - { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final }, \ - { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher }, \ + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_cipher_generic_einit },\ + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_cipher_generic_dinit },\ + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))cipher_generic_get_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))cipher_var_keylen_set_ctx_params }, \ + (void (*)(void))ossl_cipher_var_keylen_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_generic_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_var_keylen_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_var_keylen_settable_ctx_params }, \ { 0, NULL } \ }; #define IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, \ kbits, blkbits, ivbits, typ) \ -static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ +static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags, \ - kbits, blkbits, ivbits); \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + flags, kbits, blkbits, ivbits); \ } \ -static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ +static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ { \ - PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + PROV_##UCALG##_CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx))\ + : NULL; \ if (ctx != NULL) { \ - cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ - EVP_CIPH_##UCMODE##_MODE, flags, \ - PROV_CIPHER_HW_##alg##_##lcmode(kbits), \ - provctx); \ + ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ + EVP_CIPH_##UCMODE##_MODE, flags, \ + ossl_prov_cipher_hw_##alg##_##lcmode(kbits),\ + provctx); \ } \ return ctx; \ } \ @@ -205,20 +206,20 @@ IMPLEMENT_generic_cipher_genfn(alg, UCALG, lcmode, UCMODE, flags, kbits, \ IMPLEMENT_var_keylen_cipher_func(alg, UCALG, lcmode, UCMODE, flags, kbits, \ blkbits, ivbits, typ) -PROV_CIPHER_HW_FN cipher_hw_generic_cbc; -PROV_CIPHER_HW_FN cipher_hw_generic_ecb; -PROV_CIPHER_HW_FN cipher_hw_generic_ofb128; -PROV_CIPHER_HW_FN cipher_hw_generic_cfb128; -PROV_CIPHER_HW_FN cipher_hw_generic_cfb8; -PROV_CIPHER_HW_FN cipher_hw_generic_cfb1; -PROV_CIPHER_HW_FN cipher_hw_generic_ctr; -PROV_CIPHER_HW_FN cipher_hw_chunked_cbc; -PROV_CIPHER_HW_FN cipher_hw_chunked_cfb8; -PROV_CIPHER_HW_FN cipher_hw_chunked_cfb128; -PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128; -#define cipher_hw_chunked_ecb cipher_hw_generic_ecb -#define cipher_hw_chunked_ctr cipher_hw_generic_ctr -#define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1 +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cbc; +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ecb; +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ofb128; +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb128; +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb8; +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_cfb1; +PROV_CIPHER_HW_FN ossl_cipher_hw_generic_ctr; +PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cbc; +PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb8; +PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_cfb128; +PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128; +#define ossl_cipher_hw_chunked_ecb ossl_cipher_hw_generic_ecb +#define ossl_cipher_hw_chunked_ctr ossl_cipher_hw_generic_ctr +#define ossl_cipher_hw_chunked_cfb1 ossl_cipher_hw_generic_cfb1 #define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX) \ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx, \ @@ -314,12 +315,13 @@ static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \ OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \ - OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \ + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV_STATE, NULL, 0), #define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \ OSSL_PARAM_END \ }; \ -const OSSL_PARAM * name##_gettable_ctx_params(void) \ +const OSSL_PARAM * name##_gettable_ctx_params(ossl_unused void *provctx) \ { \ return name##_known_gettable_ctx_params; \ } @@ -331,13 +333,13 @@ static const OSSL_PARAM name##_known_settable_ctx_params[] = { \ #define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \ OSSL_PARAM_END \ }; \ -const OSSL_PARAM * name##_settable_ctx_params(void) \ +const OSSL_PARAM * name##_settable_ctx_params(ossl_unused void *provctx) \ { \ return name##_known_settable_ctx_params; \ } -int cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, - size_t ivlen); +int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, + size_t ivlen); size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize, const unsigned char **in, size_t *inlen); diff --git a/providers/implementations/include/prov/ciphercommon_aead.h b/providers/implementations/include/prov/ciphercommon_aead.h index 1bf9b919f9..47175f7247 100644 --- a/providers/implementations/include/prov/ciphercommon_aead.h +++ b/providers/implementations/include/prov/ciphercommon_aead.h @@ -20,7 +20,7 @@ static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lc##_get_params; \ static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[]) \ { \ - return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ + return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ flags, kbits, blkbits, ivbits); \ } \ static OSSL_FUNC_cipher_newctx_fn alg##kbits##lc##_newctx; \ @@ -28,7 +28,7 @@ static void * alg##kbits##lc##_newctx(void *provctx) \ { \ return alg##_##lc##_newctx(provctx, kbits); \ } \ -const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ +const OSSL_DISPATCH ossl_##alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx }, \ { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx }, \ { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit }, \ @@ -43,10 +43,10 @@ const OSSL_DISPATCH alg##kbits##lc##_functions[] = { \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ (void (*)(void)) lc##_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))cipher_generic_gettable_params }, \ + (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_aead_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_aead_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))cipher_aead_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_aead_settable_ctx_params }, \ { 0, NULL } \ } diff --git a/providers/implementations/include/prov/ciphercommon_gcm.h b/providers/implementations/include/prov/ciphercommon_gcm.h index c7d8b3c0a3..dd914bdf25 100644 --- a/providers/implementations/include/prov/ciphercommon_gcm.h +++ b/providers/implementations/include/prov/ciphercommon_gcm.h @@ -14,7 +14,7 @@ typedef struct prov_gcm_hw_st PROV_GCM_HW; #define GCM_IV_DEFAULT_SIZE 12 /* IV's for AES_GCM should normally be 12 bytes */ -#define GCM_IV_MAX_SIZE 64 +#define GCM_IV_MAX_SIZE (1024 / 8) #define GCM_TAG_MAX_SIZE 16 #if defined(OPENSSL_CPUID_OBJ) && defined(__s390__) @@ -72,7 +72,7 @@ typedef struct prov_gcm_ctx_st { unsigned char iv[GCM_IV_MAX_SIZE]; /* Buffer to use for IV's */ unsigned char buf[AES_BLOCK_SIZE]; /* Buffer of partial blocks processed via update calls */ - OPENSSL_CTX *libctx; /* needed for rand calls */ + OSSL_LIB_CTX *libctx; /* needed for rand calls */ const PROV_GCM_HW *hw; /* hardware specific methods */ GCM128_CONTEXT gcm; ctr128_f ctr; diff --git a/providers/implementations/include/prov/digestcommon.h b/providers/implementations/include/prov/digestcommon.h index e6461d9d10..99004731fa 100644 --- a/providers/implementations/include/prov/digestcommon.h +++ b/providers/implementations/include/prov/digestcommon.h @@ -13,6 +13,7 @@ # include # include # include +# include "prov/providercommon.h" # ifdef __cplusplus extern "C" { @@ -37,7 +38,7 @@ static OSSL_FUNC_digest_freectx_fn name##_freectx; static OSSL_FUNC_digest_dupctx_fn name##_dupctx; \ static void *name##_newctx(void *prov_ctx) \ { \ - CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); \ + CTX *ctx = ossl_prov_is_running() ? OPENSSL_zalloc(sizeof(*ctx)) : NULL; \ return ctx; \ } \ static void name##_freectx(void *vctx) \ @@ -48,25 +49,30 @@ static void name##_freectx(void *vctx) \ static void *name##_dupctx(void *ctx) \ { \ CTX *in = (CTX *)ctx; \ - CTX *ret = OPENSSL_malloc(sizeof(*ret)); \ + CTX *ret = ossl_prov_is_running() ? OPENSSL_malloc(sizeof(*ret)) : NULL; \ if (ret != NULL) \ *ret = *in; \ return ret; \ } \ -static OSSL_FUNC_digest_final_fn name##_internal_final; \ +static OSSL_FUNC_digest_init_fn name##_internal_init; \ +static int name##_internal_init(void *ctx) \ +{ \ + return ossl_prov_is_running() ? init(ctx) : 0; \ +} \ +static OSSL_FUNC_digest_final_fn name##_internal_final; \ static int name##_internal_final(void *ctx, unsigned char *out, size_t *outl, \ size_t outsz) \ { \ - if (outsz >= dgstsize && fin(out, ctx)) { \ + if (ossl_prov_is_running() && outsz >= dgstsize && fin(out, ctx)) { \ *outl = dgstsize; \ return 1; \ } \ return 0; \ } \ PROV_FUNC_DIGEST_GET_PARAM(name, blksize, dgstsize, flags) \ -const OSSL_DISPATCH name##_functions[] = { \ +const OSSL_DISPATCH ossl_##name##_functions[] = { \ { OSSL_FUNC_DIGEST_NEWCTX, (void (*)(void))name##_newctx }, \ - { OSSL_FUNC_DIGEST_INIT, (void (*)(void))init }, \ + { OSSL_FUNC_DIGEST_INIT, (void (*)(void))name##_internal_init }, \ { OSSL_FUNC_DIGEST_UPDATE, (void (*)(void))upd }, \ { OSSL_FUNC_DIGEST_FINAL, (void (*)(void))name##_internal_final }, \ { OSSL_FUNC_DIGEST_FREECTX, (void (*)(void))name##_freectx }, \ @@ -93,7 +99,7 @@ PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_START(name, CTX, blksize, dgstsize, flags, \ PROV_DISPATCH_FUNC_DIGEST_CONSTRUCT_END -const OSSL_PARAM *digest_default_gettable_params(void); +const OSSL_PARAM *digest_default_gettable_params(void *provctx); int digest_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz, unsigned long flags); diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index 73d4a0225e..1db344b946 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -11,361 +11,365 @@ #include /* Digests */ -extern const OSSL_DISPATCH sha1_functions[]; -extern const OSSL_DISPATCH sha224_functions[]; -extern const OSSL_DISPATCH sha256_functions[]; -extern const OSSL_DISPATCH sha384_functions[]; -extern const OSSL_DISPATCH sha512_functions[]; -extern const OSSL_DISPATCH sha512_224_functions[]; -extern const OSSL_DISPATCH sha512_256_functions[]; -extern const OSSL_DISPATCH sha3_224_functions[]; -extern const OSSL_DISPATCH sha3_256_functions[]; -extern const OSSL_DISPATCH sha3_384_functions[]; -extern const OSSL_DISPATCH sha3_512_functions[]; -extern const OSSL_DISPATCH keccak_kmac_128_functions[]; -extern const OSSL_DISPATCH keccak_kmac_256_functions[]; -extern const OSSL_DISPATCH shake_128_functions[]; -extern const OSSL_DISPATCH shake_256_functions[]; -extern const OSSL_DISPATCH blake2s256_functions[]; -extern const OSSL_DISPATCH blake2b512_functions[]; -extern const OSSL_DISPATCH md5_functions[]; -extern const OSSL_DISPATCH md5_sha1_functions[]; -extern const OSSL_DISPATCH sm3_functions[]; -extern const OSSL_DISPATCH md2_functions[]; -extern const OSSL_DISPATCH md4_functions[]; -extern const OSSL_DISPATCH mdc2_functions[]; -extern const OSSL_DISPATCH wp_functions[]; -extern const OSSL_DISPATCH ripemd160_functions[]; +extern const OSSL_DISPATCH ossl_sha1_functions[]; +extern const OSSL_DISPATCH ossl_sha224_functions[]; +extern const OSSL_DISPATCH ossl_sha256_functions[]; +extern const OSSL_DISPATCH ossl_sha384_functions[]; +extern const OSSL_DISPATCH ossl_sha512_functions[]; +extern const OSSL_DISPATCH ossl_sha512_224_functions[]; +extern const OSSL_DISPATCH ossl_sha512_256_functions[]; +extern const OSSL_DISPATCH ossl_sha3_224_functions[]; +extern const OSSL_DISPATCH ossl_sha3_256_functions[]; +extern const OSSL_DISPATCH ossl_sha3_384_functions[]; +extern const OSSL_DISPATCH ossl_sha3_512_functions[]; +extern const OSSL_DISPATCH ossl_keccak_kmac_128_functions[]; +extern const OSSL_DISPATCH ossl_keccak_kmac_256_functions[]; +extern const OSSL_DISPATCH ossl_shake_128_functions[]; +extern const OSSL_DISPATCH ossl_shake_256_functions[]; +extern const OSSL_DISPATCH ossl_blake2s256_functions[]; +extern const OSSL_DISPATCH ossl_blake2b512_functions[]; +extern const OSSL_DISPATCH ossl_md5_functions[]; +extern const OSSL_DISPATCH ossl_md5_sha1_functions[]; +extern const OSSL_DISPATCH ossl_sm3_functions[]; +extern const OSSL_DISPATCH ossl_md2_functions[]; +extern const OSSL_DISPATCH ossl_md4_functions[]; +extern const OSSL_DISPATCH ossl_mdc2_functions[]; +extern const OSSL_DISPATCH ossl_wp_functions[]; +extern const OSSL_DISPATCH ossl_ripemd160_functions[]; /* Ciphers */ -extern const OSSL_DISPATCH null_functions[]; -extern const OSSL_DISPATCH aes256ecb_functions[]; -extern const OSSL_DISPATCH aes192ecb_functions[]; -extern const OSSL_DISPATCH aes128ecb_functions[]; -extern const OSSL_DISPATCH aes256cbc_functions[]; -extern const OSSL_DISPATCH aes192cbc_functions[]; -extern const OSSL_DISPATCH aes128cbc_functions[]; -extern const OSSL_DISPATCH aes256cbc_cts_functions[]; -extern const OSSL_DISPATCH aes192cbc_cts_functions[]; -extern const OSSL_DISPATCH aes128cbc_cts_functions[]; -extern const OSSL_DISPATCH aes256ofb_functions[]; -extern const OSSL_DISPATCH aes192ofb_functions[]; -extern const OSSL_DISPATCH aes128ofb_functions[]; -extern const OSSL_DISPATCH aes256cfb_functions[]; -extern const OSSL_DISPATCH aes192cfb_functions[]; -extern const OSSL_DISPATCH aes128cfb_functions[]; -extern const OSSL_DISPATCH aes256cfb1_functions[]; -extern const OSSL_DISPATCH aes192cfb1_functions[]; -extern const OSSL_DISPATCH aes128cfb1_functions[]; -extern const OSSL_DISPATCH aes256cfb8_functions[]; -extern const OSSL_DISPATCH aes192cfb8_functions[]; -extern const OSSL_DISPATCH aes128cfb8_functions[]; -extern const OSSL_DISPATCH aes256ctr_functions[]; -extern const OSSL_DISPATCH aes192ctr_functions[]; -extern const OSSL_DISPATCH aes128ctr_functions[]; -extern const OSSL_DISPATCH aes256xts_functions[]; -extern const OSSL_DISPATCH aes128xts_functions[]; +extern const OSSL_DISPATCH ossl_null_functions[]; +extern const OSSL_DISPATCH ossl_aes256ecb_functions[]; +extern const OSSL_DISPATCH ossl_aes192ecb_functions[]; +extern const OSSL_DISPATCH ossl_aes128ecb_functions[]; +extern const OSSL_DISPATCH ossl_aes256cbc_functions[]; +extern const OSSL_DISPATCH ossl_aes192cbc_functions[]; +extern const OSSL_DISPATCH ossl_aes128cbc_functions[]; +extern const OSSL_DISPATCH ossl_aes256cbc_cts_functions[]; +extern const OSSL_DISPATCH ossl_aes192cbc_cts_functions[]; +extern const OSSL_DISPATCH ossl_aes128cbc_cts_functions[]; +extern const OSSL_DISPATCH ossl_aes256ofb_functions[]; +extern const OSSL_DISPATCH ossl_aes192ofb_functions[]; +extern const OSSL_DISPATCH ossl_aes128ofb_functions[]; +extern const OSSL_DISPATCH ossl_aes256cfb_functions[]; +extern const OSSL_DISPATCH ossl_aes192cfb_functions[]; +extern const OSSL_DISPATCH ossl_aes128cfb_functions[]; +extern const OSSL_DISPATCH ossl_aes256cfb1_functions[]; +extern const OSSL_DISPATCH ossl_aes192cfb1_functions[]; +extern const OSSL_DISPATCH ossl_aes128cfb1_functions[]; +extern const OSSL_DISPATCH ossl_aes256cfb8_functions[]; +extern const OSSL_DISPATCH ossl_aes192cfb8_functions[]; +extern const OSSL_DISPATCH ossl_aes128cfb8_functions[]; +extern const OSSL_DISPATCH ossl_aes256ctr_functions[]; +extern const OSSL_DISPATCH ossl_aes192ctr_functions[]; +extern const OSSL_DISPATCH ossl_aes128ctr_functions[]; +extern const OSSL_DISPATCH ossl_aes256xts_functions[]; +extern const OSSL_DISPATCH ossl_aes128xts_functions[]; #ifndef OPENSSL_NO_OCB -extern const OSSL_DISPATCH aes256ocb_functions[]; -extern const OSSL_DISPATCH aes192ocb_functions[]; -extern const OSSL_DISPATCH aes128ocb_functions[]; +extern const OSSL_DISPATCH ossl_aes256ocb_functions[]; +extern const OSSL_DISPATCH ossl_aes192ocb_functions[]; +extern const OSSL_DISPATCH ossl_aes128ocb_functions[]; #endif /* OPENSSL_NO_OCB */ -extern const OSSL_DISPATCH aes256gcm_functions[]; -extern const OSSL_DISPATCH aes192gcm_functions[]; -extern const OSSL_DISPATCH aes128gcm_functions[]; -extern const OSSL_DISPATCH aes256ccm_functions[]; -extern const OSSL_DISPATCH aes192ccm_functions[]; -extern const OSSL_DISPATCH aes128ccm_functions[]; -extern const OSSL_DISPATCH aes256wrap_functions[]; -extern const OSSL_DISPATCH aes192wrap_functions[]; -extern const OSSL_DISPATCH aes128wrap_functions[]; -extern const OSSL_DISPATCH aes256wrappad_functions[]; -extern const OSSL_DISPATCH aes192wrappad_functions[]; -extern const OSSL_DISPATCH aes128wrappad_functions[]; -extern const OSSL_DISPATCH aes256cbc_hmac_sha1_functions[]; -extern const OSSL_DISPATCH aes128cbc_hmac_sha1_functions[]; -extern const OSSL_DISPATCH aes256cbc_hmac_sha256_functions[]; -extern const OSSL_DISPATCH aes128cbc_hmac_sha256_functions[]; +extern const OSSL_DISPATCH ossl_aes256gcm_functions[]; +extern const OSSL_DISPATCH ossl_aes192gcm_functions[]; +extern const OSSL_DISPATCH ossl_aes128gcm_functions[]; +extern const OSSL_DISPATCH ossl_aes256ccm_functions[]; +extern const OSSL_DISPATCH ossl_aes192ccm_functions[]; +extern const OSSL_DISPATCH ossl_aes128ccm_functions[]; +extern const OSSL_DISPATCH ossl_aes256wrap_functions[]; +extern const OSSL_DISPATCH ossl_aes192wrap_functions[]; +extern const OSSL_DISPATCH ossl_aes128wrap_functions[]; +extern const OSSL_DISPATCH ossl_aes256wrappad_functions[]; +extern const OSSL_DISPATCH ossl_aes192wrappad_functions[]; +extern const OSSL_DISPATCH ossl_aes128wrappad_functions[]; +extern const OSSL_DISPATCH ossl_aes256cbc_hmac_sha1_functions[]; +extern const OSSL_DISPATCH ossl_aes128cbc_hmac_sha1_functions[]; +extern const OSSL_DISPATCH ossl_aes256cbc_hmac_sha256_functions[]; +extern const OSSL_DISPATCH ossl_aes128cbc_hmac_sha256_functions[]; #ifndef OPENSSL_NO_ARIA -extern const OSSL_DISPATCH aria256gcm_functions[]; -extern const OSSL_DISPATCH aria192gcm_functions[]; -extern const OSSL_DISPATCH aria128gcm_functions[]; -extern const OSSL_DISPATCH aria256ccm_functions[]; -extern const OSSL_DISPATCH aria192ccm_functions[]; -extern const OSSL_DISPATCH aria128ccm_functions[]; -extern const OSSL_DISPATCH aria256ecb_functions[]; -extern const OSSL_DISPATCH aria192ecb_functions[]; -extern const OSSL_DISPATCH aria128ecb_functions[]; -extern const OSSL_DISPATCH aria256cbc_functions[]; -extern const OSSL_DISPATCH aria192cbc_functions[]; -extern const OSSL_DISPATCH aria128cbc_functions[]; -extern const OSSL_DISPATCH aria256ofb_functions[]; -extern const OSSL_DISPATCH aria192ofb_functions[]; -extern const OSSL_DISPATCH aria128ofb_functions[]; -extern const OSSL_DISPATCH aria256cfb_functions[]; -extern const OSSL_DISPATCH aria192cfb_functions[]; -extern const OSSL_DISPATCH aria128cfb_functions[]; -extern const OSSL_DISPATCH aria256cfb1_functions[]; -extern const OSSL_DISPATCH aria192cfb1_functions[]; -extern const OSSL_DISPATCH aria128cfb1_functions[]; -extern const OSSL_DISPATCH aria256cfb8_functions[]; -extern const OSSL_DISPATCH aria192cfb8_functions[]; -extern const OSSL_DISPATCH aria128cfb8_functions[]; -extern const OSSL_DISPATCH aria256ctr_functions[]; -extern const OSSL_DISPATCH aria192ctr_functions[]; -extern const OSSL_DISPATCH aria128ctr_functions[]; +extern const OSSL_DISPATCH ossl_aria256gcm_functions[]; +extern const OSSL_DISPATCH ossl_aria192gcm_functions[]; +extern const OSSL_DISPATCH ossl_aria128gcm_functions[]; +extern const OSSL_DISPATCH ossl_aria256ccm_functions[]; +extern const OSSL_DISPATCH ossl_aria192ccm_functions[]; +extern const OSSL_DISPATCH ossl_aria128ccm_functions[]; +extern const OSSL_DISPATCH ossl_aria256ecb_functions[]; +extern const OSSL_DISPATCH ossl_aria192ecb_functions[]; +extern const OSSL_DISPATCH ossl_aria128ecb_functions[]; +extern const OSSL_DISPATCH ossl_aria256cbc_functions[]; +extern const OSSL_DISPATCH ossl_aria192cbc_functions[]; +extern const OSSL_DISPATCH ossl_aria128cbc_functions[]; +extern const OSSL_DISPATCH ossl_aria256ofb_functions[]; +extern const OSSL_DISPATCH ossl_aria192ofb_functions[]; +extern const OSSL_DISPATCH ossl_aria128ofb_functions[]; +extern const OSSL_DISPATCH ossl_aria256cfb_functions[]; +extern const OSSL_DISPATCH ossl_aria192cfb_functions[]; +extern const OSSL_DISPATCH ossl_aria128cfb_functions[]; +extern const OSSL_DISPATCH ossl_aria256cfb1_functions[]; +extern const OSSL_DISPATCH ossl_aria192cfb1_functions[]; +extern const OSSL_DISPATCH ossl_aria128cfb1_functions[]; +extern const OSSL_DISPATCH ossl_aria256cfb8_functions[]; +extern const OSSL_DISPATCH ossl_aria192cfb8_functions[]; +extern const OSSL_DISPATCH ossl_aria128cfb8_functions[]; +extern const OSSL_DISPATCH ossl_aria256ctr_functions[]; +extern const OSSL_DISPATCH ossl_aria192ctr_functions[]; +extern const OSSL_DISPATCH ossl_aria128ctr_functions[]; #endif /* OPENSSL_NO_ARIA */ #ifndef OPENSSL_NO_CAMELLIA -extern const OSSL_DISPATCH camellia256ecb_functions[]; -extern const OSSL_DISPATCH camellia192ecb_functions[]; -extern const OSSL_DISPATCH camellia128ecb_functions[]; -extern const OSSL_DISPATCH camellia256cbc_functions[]; -extern const OSSL_DISPATCH camellia192cbc_functions[]; -extern const OSSL_DISPATCH camellia128cbc_functions[]; -extern const OSSL_DISPATCH camellia256ofb_functions[]; -extern const OSSL_DISPATCH camellia192ofb_functions[]; -extern const OSSL_DISPATCH camellia128ofb_functions[]; -extern const OSSL_DISPATCH camellia256cfb_functions[]; -extern const OSSL_DISPATCH camellia192cfb_functions[]; -extern const OSSL_DISPATCH camellia128cfb_functions[]; -extern const OSSL_DISPATCH camellia256cfb1_functions[]; -extern const OSSL_DISPATCH camellia192cfb1_functions[]; -extern const OSSL_DISPATCH camellia128cfb1_functions[]; -extern const OSSL_DISPATCH camellia256cfb8_functions[]; -extern const OSSL_DISPATCH camellia192cfb8_functions[]; -extern const OSSL_DISPATCH camellia128cfb8_functions[]; -extern const OSSL_DISPATCH camellia256ctr_functions[]; -extern const OSSL_DISPATCH camellia192ctr_functions[]; -extern const OSSL_DISPATCH camellia128ctr_functions[]; +extern const OSSL_DISPATCH ossl_camellia256ecb_functions[]; +extern const OSSL_DISPATCH ossl_camellia192ecb_functions[]; +extern const OSSL_DISPATCH ossl_camellia128ecb_functions[]; +extern const OSSL_DISPATCH ossl_camellia256cbc_functions[]; +extern const OSSL_DISPATCH ossl_camellia192cbc_functions[]; +extern const OSSL_DISPATCH ossl_camellia128cbc_functions[]; +extern const OSSL_DISPATCH ossl_camellia256ofb_functions[]; +extern const OSSL_DISPATCH ossl_camellia192ofb_functions[]; +extern const OSSL_DISPATCH ossl_camellia128ofb_functions[]; +extern const OSSL_DISPATCH ossl_camellia256cfb_functions[]; +extern const OSSL_DISPATCH ossl_camellia192cfb_functions[]; +extern const OSSL_DISPATCH ossl_camellia128cfb_functions[]; +extern const OSSL_DISPATCH ossl_camellia256cfb1_functions[]; +extern const OSSL_DISPATCH ossl_camellia192cfb1_functions[]; +extern const OSSL_DISPATCH ossl_camellia128cfb1_functions[]; +extern const OSSL_DISPATCH ossl_camellia256cfb8_functions[]; +extern const OSSL_DISPATCH ossl_camellia192cfb8_functions[]; +extern const OSSL_DISPATCH ossl_camellia128cfb8_functions[]; +extern const OSSL_DISPATCH ossl_camellia256ctr_functions[]; +extern const OSSL_DISPATCH ossl_camellia192ctr_functions[]; +extern const OSSL_DISPATCH ossl_camellia128ctr_functions[]; #endif /* OPENSSL_NO_CAMELLIA */ #ifndef OPENSSL_NO_BF -extern const OSSL_DISPATCH blowfish128ecb_functions[]; -extern const OSSL_DISPATCH blowfish128cbc_functions[]; -extern const OSSL_DISPATCH blowfish64ofb64_functions[]; -extern const OSSL_DISPATCH blowfish64cfb64_functions[]; +extern const OSSL_DISPATCH ossl_blowfish128ecb_functions[]; +extern const OSSL_DISPATCH ossl_blowfish128cbc_functions[]; +extern const OSSL_DISPATCH ossl_blowfish64ofb64_functions[]; +extern const OSSL_DISPATCH ossl_blowfish64cfb64_functions[]; #endif /* OPENSSL_NO_BF */ #ifndef OPENSSL_NO_IDEA -extern const OSSL_DISPATCH idea128ecb_functions[]; -extern const OSSL_DISPATCH idea128cbc_functions[]; -extern const OSSL_DISPATCH idea128ofb64_functions[]; -extern const OSSL_DISPATCH idea128cfb64_functions[]; +extern const OSSL_DISPATCH ossl_idea128ecb_functions[]; +extern const OSSL_DISPATCH ossl_idea128cbc_functions[]; +extern const OSSL_DISPATCH ossl_idea128ofb64_functions[]; +extern const OSSL_DISPATCH ossl_idea128cfb64_functions[]; #endif /* OPENSSL_NO_IDEA */ #ifndef OPENSSL_NO_CAST -extern const OSSL_DISPATCH cast5128ecb_functions[]; -extern const OSSL_DISPATCH cast5128cbc_functions[]; -extern const OSSL_DISPATCH cast5128ofb64_functions[]; -extern const OSSL_DISPATCH cast5128cfb64_functions[]; +extern const OSSL_DISPATCH ossl_cast5128ecb_functions[]; +extern const OSSL_DISPATCH ossl_cast5128cbc_functions[]; +extern const OSSL_DISPATCH ossl_cast5128ofb64_functions[]; +extern const OSSL_DISPATCH ossl_cast5128cfb64_functions[]; #endif /* OPENSSL_NO_CAST */ #ifndef OPENSSL_NO_SEED -extern const OSSL_DISPATCH seed128ecb_functions[]; -extern const OSSL_DISPATCH seed128cbc_functions[]; -extern const OSSL_DISPATCH seed128ofb128_functions[]; -extern const OSSL_DISPATCH seed128cfb128_functions[]; +extern const OSSL_DISPATCH ossl_seed128ecb_functions[]; +extern const OSSL_DISPATCH ossl_seed128cbc_functions[]; +extern const OSSL_DISPATCH ossl_seed128ofb128_functions[]; +extern const OSSL_DISPATCH ossl_seed128cfb128_functions[]; #endif /* OPENSSL_NO_SEED */ #ifndef OPENSSL_NO_SM4 -extern const OSSL_DISPATCH sm4128ecb_functions[]; -extern const OSSL_DISPATCH sm4128cbc_functions[]; -extern const OSSL_DISPATCH sm4128ctr_functions[]; -extern const OSSL_DISPATCH sm4128ofb128_functions[]; -extern const OSSL_DISPATCH sm4128cfb128_functions[]; +extern const OSSL_DISPATCH ossl_sm4128ecb_functions[]; +extern const OSSL_DISPATCH ossl_sm4128cbc_functions[]; +extern const OSSL_DISPATCH ossl_sm4128ctr_functions[]; +extern const OSSL_DISPATCH ossl_sm4128ofb128_functions[]; +extern const OSSL_DISPATCH ossl_sm4128cfb128_functions[]; #endif /* OPENSSL_NO_SM4 */ #ifndef OPENSSL_NO_RC5 -extern const OSSL_DISPATCH rc5128ecb_functions[]; -extern const OSSL_DISPATCH rc5128cbc_functions[]; -extern const OSSL_DISPATCH rc5128ofb64_functions[]; -extern const OSSL_DISPATCH rc5128cfb64_functions[]; +extern const OSSL_DISPATCH ossl_rc5128ecb_functions[]; +extern const OSSL_DISPATCH ossl_rc5128cbc_functions[]; +extern const OSSL_DISPATCH ossl_rc5128ofb64_functions[]; +extern const OSSL_DISPATCH ossl_rc5128cfb64_functions[]; #endif /* OPENSSL_NO_RC5 */ #ifndef OPENSSL_NO_RC2 -extern const OSSL_DISPATCH rc2128ecb_functions[]; -extern const OSSL_DISPATCH rc2128cbc_functions[]; -extern const OSSL_DISPATCH rc240cbc_functions[]; -extern const OSSL_DISPATCH rc264cbc_functions[]; -extern const OSSL_DISPATCH rc2128cfb128_functions[]; -extern const OSSL_DISPATCH rc2128ofb128_functions[]; +extern const OSSL_DISPATCH ossl_rc2128ecb_functions[]; +extern const OSSL_DISPATCH ossl_rc2128cbc_functions[]; +extern const OSSL_DISPATCH ossl_rc240cbc_functions[]; +extern const OSSL_DISPATCH ossl_rc264cbc_functions[]; +extern const OSSL_DISPATCH ossl_rc2128cfb128_functions[]; +extern const OSSL_DISPATCH ossl_rc2128ofb128_functions[]; #endif /* OPENSSL_NO_RC2 */ #ifndef OPENSSL_NO_DES -extern const OSSL_DISPATCH tdes_ede3_ecb_functions[]; -extern const OSSL_DISPATCH tdes_ede3_cbc_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede3_ecb_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede3_cbc_functions[]; # ifndef FIPS_MODULE -extern const OSSL_DISPATCH tdes_ede3_ofb_functions[]; -extern const OSSL_DISPATCH tdes_ede3_cfb_functions[]; -extern const OSSL_DISPATCH tdes_ede3_cfb8_functions[]; -extern const OSSL_DISPATCH tdes_ede3_cfb1_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede3_ofb_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede3_cfb_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede3_cfb8_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede3_cfb1_functions[]; -extern const OSSL_DISPATCH tdes_ede2_ecb_functions[]; -extern const OSSL_DISPATCH tdes_ede2_cbc_functions[]; -extern const OSSL_DISPATCH tdes_ede2_ofb_functions[]; -extern const OSSL_DISPATCH tdes_ede2_cfb_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede2_ecb_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede2_cbc_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede2_ofb_functions[]; +extern const OSSL_DISPATCH ossl_tdes_ede2_cfb_functions[]; -extern const OSSL_DISPATCH tdes_desx_cbc_functions[]; -extern const OSSL_DISPATCH tdes_wrap_cbc_functions[]; +extern const OSSL_DISPATCH ossl_tdes_desx_cbc_functions[]; +extern const OSSL_DISPATCH ossl_tdes_wrap_cbc_functions[]; -extern const OSSL_DISPATCH des_ecb_functions[]; -extern const OSSL_DISPATCH des_cbc_functions[]; -extern const OSSL_DISPATCH des_ofb64_functions[]; -extern const OSSL_DISPATCH des_cfb64_functions[]; -extern const OSSL_DISPATCH des_cfb1_functions[]; -extern const OSSL_DISPATCH des_cfb8_functions[]; +extern const OSSL_DISPATCH ossl_des_ecb_functions[]; +extern const OSSL_DISPATCH ossl_des_cbc_functions[]; +extern const OSSL_DISPATCH ossl_des_ofb64_functions[]; +extern const OSSL_DISPATCH ossl_des_cfb64_functions[]; +extern const OSSL_DISPATCH ossl_des_cfb1_functions[]; +extern const OSSL_DISPATCH ossl_des_cfb8_functions[]; # endif /* FIPS_MODULE */ #endif /* OPENSSL_NO_DES */ #ifndef OPENSSL_NO_RC4 -extern const OSSL_DISPATCH rc440_functions[]; -extern const OSSL_DISPATCH rc4128_functions[]; +extern const OSSL_DISPATCH ossl_rc440_functions[]; +extern const OSSL_DISPATCH ossl_rc4128_functions[]; # ifndef OPENSSL_NO_MD5 -extern const OSSL_DISPATCH rc4_hmac_md5_functions[]; +extern const OSSL_DISPATCH ossl_rc4_hmac_ossl_md5_functions[]; # endif /* OPENSSL_NO_MD5 */ #endif /* OPENSSL_NO_RC4 */ #ifndef OPENSSL_NO_CHACHA -extern const OSSL_DISPATCH chacha20_functions[]; +extern const OSSL_DISPATCH ossl_chacha20_functions[]; # ifndef OPENSSL_NO_POLY1305 -extern const OSSL_DISPATCH chacha20_poly1305_functions[]; +extern const OSSL_DISPATCH ossl_chacha20_ossl_poly1305_functions[]; # endif /* OPENSSL_NO_POLY1305 */ #endif /* OPENSSL_NO_CHACHA */ #ifndef OPENSSL_NO_SIV -extern const OSSL_DISPATCH aes128siv_functions[]; -extern const OSSL_DISPATCH aes192siv_functions[]; -extern const OSSL_DISPATCH aes256siv_functions[]; +extern const OSSL_DISPATCH ossl_aes128siv_functions[]; +extern const OSSL_DISPATCH ossl_aes192siv_functions[]; +extern const OSSL_DISPATCH ossl_aes256siv_functions[]; #endif /* OPENSSL_NO_SIV */ /* MACs */ -extern const OSSL_DISPATCH blake2bmac_functions[]; -extern const OSSL_DISPATCH blake2smac_functions[]; -extern const OSSL_DISPATCH cmac_functions[]; -extern const OSSL_DISPATCH gmac_functions[]; -extern const OSSL_DISPATCH hmac_functions[]; -extern const OSSL_DISPATCH kmac128_functions[]; -extern const OSSL_DISPATCH kmac256_functions[]; -extern const OSSL_DISPATCH siphash_functions[]; -extern const OSSL_DISPATCH poly1305_functions[]; +extern const OSSL_DISPATCH ossl_blake2bmac_functions[]; +extern const OSSL_DISPATCH ossl_blake2smac_functions[]; +extern const OSSL_DISPATCH ossl_cmac_functions[]; +extern const OSSL_DISPATCH ossl_gmac_functions[]; +extern const OSSL_DISPATCH ossl_hmac_functions[]; +extern const OSSL_DISPATCH ossl_kmac128_functions[]; +extern const OSSL_DISPATCH ossl_kmac256_functions[]; +extern const OSSL_DISPATCH ossl_siphash_functions[]; +extern const OSSL_DISPATCH ossl_poly1305_functions[]; /* KDFs / PRFs */ -extern const OSSL_DISPATCH kdf_pbkdf2_functions[]; +extern const OSSL_DISPATCH ossl_kdf_pbkdf2_functions[]; +extern const OSSL_DISPATCH ossl_kdf_pkcs12_functions[]; #ifndef OPENSSL_NO_SCRYPT -extern const OSSL_DISPATCH kdf_scrypt_functions[]; +extern const OSSL_DISPATCH ossl_kdf_scrypt_functions[]; #endif -extern const OSSL_DISPATCH kdf_tls1_prf_functions[]; -extern const OSSL_DISPATCH kdf_hkdf_functions[]; -extern const OSSL_DISPATCH kdf_sshkdf_functions[]; -extern const OSSL_DISPATCH kdf_sskdf_functions[]; -extern const OSSL_DISPATCH kdf_x963_kdf_functions[]; -extern const OSSL_DISPATCH kdf_kbkdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_tls1_prf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_hkdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_sshkdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_sskdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_kbkdf_functions[]; #ifndef OPENSSL_NO_CMS -extern const OSSL_DISPATCH kdf_x942_kdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[]; #endif -extern const OSSL_DISPATCH kdf_krb5kdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_krb5kdf_functions[]; /* RNGs */ -extern const OSSL_DISPATCH test_rng_functions[]; -extern const OSSL_DISPATCH drbg_hash_functions[]; -extern const OSSL_DISPATCH drbg_hmac_functions[]; -extern const OSSL_DISPATCH drbg_ctr_functions[]; +extern const OSSL_DISPATCH ossl_test_rng_functions[]; +extern const OSSL_DISPATCH ossl_drbg_hash_functions[]; +extern const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[]; +extern const OSSL_DISPATCH ossl_drbg_ctr_functions[]; extern const OSSL_DISPATCH crngt_functions[]; /* Key management */ -extern const OSSL_DISPATCH dh_keymgmt_functions[]; -extern const OSSL_DISPATCH dsa_keymgmt_functions[]; -extern const OSSL_DISPATCH rsa_keymgmt_functions[]; -extern const OSSL_DISPATCH rsapss_keymgmt_functions[]; -extern const OSSL_DISPATCH x25519_keymgmt_functions[]; -extern const OSSL_DISPATCH x448_keymgmt_functions[]; -extern const OSSL_DISPATCH ed25519_keymgmt_functions[]; -extern const OSSL_DISPATCH ed448_keymgmt_functions[]; -extern const OSSL_DISPATCH ec_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_dh_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_dhx_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_dsa_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_rsa_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_x25519_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_x448_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_ed25519_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_ed448_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_ec_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_kdf_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mac_legacy_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_cossl_mac_legacy_keymgmt_functions[]; +#ifndef OPENSSL_NO_SM2 +extern const OSSL_DISPATCH sm2_keymgmt_functions[]; +#endif /* Key Exchange */ -extern const OSSL_DISPATCH dh_keyexch_functions[]; -extern const OSSL_DISPATCH x25519_keyexch_functions[]; -extern const OSSL_DISPATCH x448_keyexch_functions[]; -extern const OSSL_DISPATCH ecdh_keyexch_functions[]; +extern const OSSL_DISPATCH ossl_dh_keyexch_functions[]; +extern const OSSL_DISPATCH ossl_x25519_keyexch_functions[]; +extern const OSSL_DISPATCH ossl_x448_keyexch_functions[]; +extern const OSSL_DISPATCH ecossl_dh_keyexch_functions[]; +extern const OSSL_DISPATCH ossl_kdf_tls1_prf_keyexch_functions[]; +extern const OSSL_DISPATCH ossl_kdf_hkdf_keyexch_functions[]; +extern const OSSL_DISPATCH ossl_kdf_scrypt_keyexch_functions[]; /* Signature */ -extern const OSSL_DISPATCH dsa_signature_functions[]; -extern const OSSL_DISPATCH rsa_signature_functions[]; -extern const OSSL_DISPATCH ed25519_signature_functions[]; -extern const OSSL_DISPATCH ed448_signature_functions[]; -extern const OSSL_DISPATCH ecdsa_signature_functions[]; - +extern const OSSL_DISPATCH ossl_dsa_signature_functions[]; +extern const OSSL_DISPATCH ossl_rsa_signature_functions[]; +extern const OSSL_DISPATCH ossl_ed25519_signature_functions[]; +extern const OSSL_DISPATCH ossl_ed448_signature_functions[]; +extern const OSSL_DISPATCH ecossl_dsa_signature_functions[]; +extern const OSSL_DISPATCH ossl_mac_legacy_hmac_signature_functions[]; +extern const OSSL_DISPATCH ossl_mac_legacy_siphash_signature_functions[]; +extern const OSSL_DISPATCH ossl_mac_legacy_poly1305_signature_functions[]; +extern const OSSL_DISPATCH ossl_mac_legacy_cmac_signature_functions[]; +extern const OSSL_DISPATCH sm2_signature_functions[]; /* Asym Cipher */ -extern const OSSL_DISPATCH rsa_asym_cipher_functions[]; +extern const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[]; +#ifndef OPENSSL_NO_SM2 +extern const OSSL_DISPATCH sm2_asym_cipher_functions[]; +#endif + +/* Asym Key encapsulation */ +extern const OSSL_DISPATCH ossl_rsa_asym_kem_functions[]; + +/* Encoders */ +extern const OSSL_DISPATCH ossl_rsa_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_rsa_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_rsa_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_rsapss_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_rsapss_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_rsapss_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_dh_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_dh_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_dh_to_text_encoder_functions[]; -/* Serializers */ -extern const OSSL_DISPATCH rsa_priv_text_serializer_functions[]; -extern const OSSL_DISPATCH rsa_pub_text_serializer_functions[]; -extern const OSSL_DISPATCH rsa_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH rsa_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH rsa_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH rsa_pub_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_dhx_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_dhx_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_dhx_to_text_encoder_functions[]; -extern const OSSL_DISPATCH dh_priv_text_serializer_functions[]; -extern const OSSL_DISPATCH dh_pub_text_serializer_functions[]; -extern const OSSL_DISPATCH dh_param_text_serializer_functions[]; -extern const OSSL_DISPATCH dh_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH dh_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH dh_param_der_serializer_functions[]; -extern const OSSL_DISPATCH dh_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH dh_pub_pem_serializer_functions[]; -extern const OSSL_DISPATCH dh_param_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_dsa_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_dsa_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_dsa_to_text_encoder_functions[]; -extern const OSSL_DISPATCH dsa_priv_text_serializer_functions[]; -extern const OSSL_DISPATCH dsa_pub_text_serializer_functions[]; -extern const OSSL_DISPATCH dsa_param_text_serializer_functions[]; -extern const OSSL_DISPATCH dsa_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH dsa_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH dsa_param_der_serializer_functions[]; -extern const OSSL_DISPATCH dsa_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH dsa_pub_pem_serializer_functions[]; -extern const OSSL_DISPATCH dsa_param_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_x25519_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_x25519_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_x25519_to_text_encoder_functions[]; -extern const OSSL_DISPATCH x25519_priv_print_serializer_functions[]; -extern const OSSL_DISPATCH x25519_pub_print_serializer_functions[]; -extern const OSSL_DISPATCH x25519_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH x25519_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH x25519_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH x25519_pub_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_x448_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_x448_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_x448_to_text_encoder_functions[]; -extern const OSSL_DISPATCH x448_priv_print_serializer_functions[]; -extern const OSSL_DISPATCH x448_pub_print_serializer_functions[]; -extern const OSSL_DISPATCH x448_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH x448_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH x448_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH x448_pub_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_ed25519_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_ed25519_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_ed25519_to_text_encoder_functions[]; -extern const OSSL_DISPATCH ed25519_priv_print_serializer_functions[]; -extern const OSSL_DISPATCH ed25519_pub_print_serializer_functions[]; -extern const OSSL_DISPATCH ed25519_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH ed25519_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH ed25519_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH ed25519_pub_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_ed448_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_ed448_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_ed448_to_text_encoder_functions[]; -extern const OSSL_DISPATCH ed448_priv_print_serializer_functions[]; -extern const OSSL_DISPATCH ed448_pub_print_serializer_functions[]; -extern const OSSL_DISPATCH ed448_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH ed448_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH ed448_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH ed448_pub_pem_serializer_functions[]; +extern const OSSL_DISPATCH ossl_ec_to_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_ec_to_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_ec_to_text_encoder_functions[]; -extern const OSSL_DISPATCH ec_priv_text_serializer_functions[]; -extern const OSSL_DISPATCH ec_pub_text_serializer_functions[]; -extern const OSSL_DISPATCH ec_param_text_serializer_functions[]; -extern const OSSL_DISPATCH ec_priv_der_serializer_functions[]; -extern const OSSL_DISPATCH ec_pub_der_serializer_functions[]; -extern const OSSL_DISPATCH ec_param_der_serializer_functions[]; -extern const OSSL_DISPATCH ec_priv_pem_serializer_functions[]; -extern const OSSL_DISPATCH ec_pub_pem_serializer_functions[]; -extern const OSSL_DISPATCH ec_param_pem_serializer_functions[]; +/* Decoders */ +extern const OSSL_DISPATCH ossl_der_to_dh_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_dhx_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_dsa_decoder_functions[]; +extern const OSSL_DISPATCH ossl_msblob_to_dsa_decoder_functions[]; +extern const OSSL_DISPATCH ossl_pvk_to_dsa_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_ec_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_x25519_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_x448_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_ed25519_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_ed448_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_rsa_decoder_functions[]; +extern const OSSL_DISPATCH ossl_der_to_rsapss_decoder_functions[]; +extern const OSSL_DISPATCH ossl_msblob_to_rsa_decoder_functions[]; +extern const OSSL_DISPATCH ossl_pvk_to_rsa_decoder_functions[]; +extern const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[]; -extern const OSSL_DISPATCH der_to_dh_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_dsa_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_ec_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_x25519_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_x448_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_ed25519_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_ed448_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_rsa_deserializer_functions[]; -extern const OSSL_DISPATCH der_to_rsapss_deserializer_functions[]; -extern const OSSL_DISPATCH pem_to_der_deserializer_functions[]; +extern const OSSL_DISPATCH ossl_file_store_functions[]; diff --git a/providers/implementations/include/prov/kdfexchange.h b/providers/implementations/include/prov/kdfexchange.h new file mode 100644 index 0000000000..3770487bff --- /dev/null +++ b/providers/implementations/include/prov/kdfexchange.h @@ -0,0 +1,24 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/refcount.h" + +struct kdf_data_st { + OSSL_LIB_CTX *libctx; + CRYPTO_REF_COUNT refcnt; + CRYPTO_RWLOCK *lock; +}; + +typedef struct kdf_data_st KDF_DATA; + +KDF_DATA *kdf_data_new(void *provctx); +void kdf_data_free(KDF_DATA *kdfdata); +int kdf_data_up_ref(KDF_DATA *kdfdata); diff --git a/providers/implementations/include/prov/macsignature.h b/providers/implementations/include/prov/macsignature.h new file mode 100644 index 0000000000..1e59884cbc --- /dev/null +++ b/providers/implementations/include/prov/macsignature.h @@ -0,0 +1,30 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "internal/refcount.h" +#include "prov/provider_util.h" + +struct mac_key_st { + CRYPTO_RWLOCK *lock; + OSSL_LIB_CTX *libctx; + CRYPTO_REF_COUNT refcnt; + unsigned char *priv_key; + size_t priv_key_len; + PROV_CIPHER cipher; + char *properties; + int cmac; +}; + +typedef struct mac_key_st MAC_KEY; + +MAC_KEY *mac_key_new(OSSL_LIB_CTX *libctx, int cmac); +void mac_key_free(MAC_KEY *mackey); +int mac_key_up_ref(MAC_KEY *mackey); diff --git a/providers/implementations/include/prov/rand_pool.h b/providers/implementations/include/prov/rand_pool.h index f476604770..9c5c92e365 100644 --- a/providers/implementations/include/prov/rand_pool.h +++ b/providers/implementations/include/prov/rand_pool.h @@ -11,7 +11,7 @@ # define OSSL_PROVIDER_RAND_POOL_H # include -# include +# include /* * Maximum allocation size for RANDOM_POOL buffers diff --git a/providers/implementations/kdfs/build.info b/providers/implementations/kdfs/build.info index 3b3884436a..459005def5 100644 --- a/providers/implementations/kdfs/build.info +++ b/providers/implementations/kdfs/build.info @@ -6,6 +6,7 @@ $HKDF_GOAL=../../libimplementations.a $KBKDF_GOAL=../../libimplementations.a $KRB5KDF_GOAL=../../libimplementations.a $PBKDF2_GOAL=../../libimplementations.a +$PKCS12KDF_GOAL=../../libimplementations.a $SSKDF_GOAL=../../libimplementations.a $SCRYPT_GOAL=../../libimplementations.a $SSHKDF_GOAL=../../libimplementations.a @@ -25,6 +26,8 @@ SOURCE[$PBKDF2_GOAL]=pbkdf2.c SOURCE[../../libfips.a]=pbkdf2_fips.c SOURCE[../../libnonfips.a]=pbkdf2_fips.c +SOURCE[$PKCS12KDF_GOAL]=pkcs12kdf.c + SOURCE[$SSKDF_GOAL]=sskdf.c SOURCE[$SCRYPT_GOAL]=scrypt.c diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c index 0b1a6e9b7e..a985c85440 100644 --- a/providers/implementations/kdfs/hkdf.c +++ b/providers/implementations/kdfs/hkdf.c @@ -24,6 +24,7 @@ #include "internal/numbers.h" #include "crypto/evp.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_util.h" @@ -70,6 +71,9 @@ static void *kdf_hkdf_new(void *provctx) { KDF_HKDF *ctx; + if (!ossl_prov_is_running()) + return NULL; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); else @@ -122,8 +126,12 @@ static size_t kdf_hkdf_size(KDF_HKDF *ctx) static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_HKDF *ctx = (KDF_HKDF *)vctx; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md; + + if (!ossl_prov_is_running()) + return 0; + md = ossl_prov_digest_md(&ctx->digest); if (md == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; @@ -132,6 +140,10 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen) ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); return 0; } + if (keylen == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } switch (ctx->mode) { case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: @@ -156,7 +168,7 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; KDF_HKDF *ctx = vctx; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); int n; if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) @@ -225,7 +237,7 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(void) +static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), @@ -250,7 +262,7 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(void) +static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -259,7 +271,7 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_hkdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset }, diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c index d25da76d17..cf3b90c19c 100644 --- a/providers/implementations/kdfs/kbkdf.c +++ b/providers/implementations/kdfs/kbkdf.c @@ -41,6 +41,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "e_os.h" @@ -76,6 +77,8 @@ static OSSL_FUNC_kdf_reset_fn kbkdf_reset; static OSSL_FUNC_kdf_derive_fn kbkdf_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn kbkdf_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn kbkdf_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn kbkdf_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn kbkdf_get_ctx_params; /* Not all platforms have htobe32(). */ static uint32_t be32(uint32_t host) @@ -97,6 +100,9 @@ static void *kbkdf_new(void *provctx) { KBKDF *ctx; + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); @@ -190,6 +196,9 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen) uint32_t l = be32(keylen * 8); size_t h = 0; + if (!ossl_prov_is_running()) + return 0; + /* label, context, and iv are permitted to be empty. Check everything * else. */ if (ctx->ctx_init == NULL) { @@ -203,6 +212,12 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen) return 0; } + /* Fail if the output length is zero */ + if (keylen == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + h = EVP_MAC_size(ctx->ctx_init); if (h == 0) goto done; @@ -239,7 +254,7 @@ static int kbkdf_set_buffer(unsigned char **out, size_t *out_len, static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { KBKDF *ctx = (KBKDF *)vctx; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); const OSSL_PARAM *p; OSSL_PARAM mparams[2]; @@ -296,7 +311,7 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *kbkdf_settable_ctx_params(void) +static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), @@ -326,14 +341,14 @@ static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return OSSL_PARAM_set_size_t(p, SIZE_MAX); } -static const OSSL_PARAM *kbkdf_gettable_ctx_params(void) +static const OSSL_PARAM *kbkdf_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END }; return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_kbkdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_kbkdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kbkdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kbkdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))kbkdf_reset }, diff --git a/providers/implementations/kdfs/krb5kdf.c b/providers/implementations/kdfs/krb5kdf.c index 25462f3c1d..cdf8a15415 100644 --- a/providers/implementations/kdfs/krb5kdf.c +++ b/providers/implementations/kdfs/krb5kdf.c @@ -28,6 +28,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" /* KRB5 KDF defined in RFC 3961, Section 5.1 */ @@ -59,6 +60,9 @@ static void *krb5kdf_new(void *provctx) { KRB5KDF_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ctx->provctx = provctx; @@ -99,9 +103,13 @@ static int krb5kdf_derive(void *vctx, unsigned char *key, size_t keylen) { KRB5KDF_CTX *ctx = (KRB5KDF_CTX *)vctx; - const EVP_CIPHER *cipher = ossl_prov_cipher_cipher(&ctx->cipher); - ENGINE *engine = ossl_prov_cipher_engine(&ctx->cipher); + const EVP_CIPHER *cipher; + ENGINE *engine; + if (!ossl_prov_is_running()) + return 0; + + cipher = ossl_prov_cipher_cipher(&ctx->cipher); if (cipher == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER); return 0; @@ -114,6 +122,7 @@ static int krb5kdf_derive(void *vctx, unsigned char *key, ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONSTANT); return 0; } + engine = ossl_prov_cipher_engine(&ctx->cipher); return KRB5KDF(cipher, engine, ctx->key, ctx->key_len, ctx->constant, ctx->constant_len, key, keylen); @@ -123,7 +132,7 @@ static int krb5kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; KRB5KDF_CTX *ctx = vctx; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); if (!ossl_prov_cipher_load_from_params(&ctx->cipher, params, provctx)) return 0; @@ -140,7 +149,7 @@ static int krb5kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *krb5kdf_settable_ctx_params(void) +static const OSSL_PARAM *krb5kdf_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), @@ -170,7 +179,7 @@ static int krb5kdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *krb5kdf_gettable_ctx_params(void) +static const OSSL_PARAM *krb5kdf_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -179,7 +188,7 @@ static const OSSL_PARAM *krb5kdf_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_krb5kdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_krb5kdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))krb5kdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))krb5kdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))krb5kdf_reset }, diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c index e6956fe155..37a81f00ba 100644 --- a/providers/implementations/kdfs/pbkdf2.c +++ b/providers/implementations/kdfs/pbkdf2.c @@ -24,6 +24,7 @@ #include "internal/numbers.h" #include "crypto/evp.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_util.h" @@ -41,6 +42,8 @@ static OSSL_FUNC_kdf_reset_fn kdf_pbkdf2_reset; static OSSL_FUNC_kdf_derive_fn kdf_pbkdf2_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_pbkdf2_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn kdf_pbkdf2_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_pbkdf2_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn kdf_pbkdf2_get_ctx_params; static int pbkdf2_derive(const char *pass, size_t passlen, const unsigned char *salt, int saltlen, uint64_t iter, @@ -64,6 +67,9 @@ static void *kdf_pbkdf2_new(void *provctx) { KDF_PBKDF2 *ctx; + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); @@ -105,7 +111,7 @@ static void kdf_pbkdf2_reset(void *vctx) static void kdf_pbkdf2_init(KDF_PBKDF2 *ctx) { OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); params[0] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha1, 0); @@ -137,7 +143,10 @@ static int kdf_pbkdf2_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_PBKDF2 *ctx = (KDF_PBKDF2 *)vctx; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md; + + if (!ossl_prov_is_running()) + return 0; if (ctx->pass == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_PASS); @@ -149,6 +158,7 @@ static int kdf_pbkdf2_derive(void *vctx, unsigned char *key, return 0; } + md = ossl_prov_digest_md(&ctx->digest); return pbkdf2_derive((char *)ctx->pass, ctx->pass_len, ctx->salt, ctx->salt_len, ctx->iter, md, key, keylen, ctx->lower_bound_checks); @@ -158,7 +168,7 @@ static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; KDF_PBKDF2 *ctx = vctx; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); int pkcs5; uint64_t iter, min_iter; @@ -198,7 +208,7 @@ static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *kdf_pbkdf2_settable_ctx_params(void) +static const OSSL_PARAM *kdf_pbkdf2_settable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), @@ -221,7 +231,7 @@ static int kdf_pbkdf2_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(void) +static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -230,7 +240,7 @@ static const OSSL_PARAM *kdf_pbkdf2_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_pbkdf2_functions[] = { +const OSSL_DISPATCH ossl_kdf_pbkdf2_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_pbkdf2_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_pbkdf2_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_pbkdf2_reset }, diff --git a/providers/implementations/kdfs/pkcs12kdf.c b/providers/implementations/kdfs/pkcs12kdf.c new file mode 100644 index 0000000000..b058005e1d --- /dev/null +++ b/providers/implementations/kdfs/pkcs12kdf.c @@ -0,0 +1,293 @@ +/* + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "internal/cryptlib.h" +#include "internal/numbers.h" +#include "crypto/evp.h" +#include "prov/provider_ctx.h" +#include "prov/providercommon.h" +#include "prov/providercommonerr.h" +#include "prov/implementations.h" +#include "prov/provider_util.h" + +static OSSL_FUNC_kdf_newctx_fn kdf_pkcs12_new; +static OSSL_FUNC_kdf_freectx_fn kdf_pkcs12_free; +static OSSL_FUNC_kdf_reset_fn kdf_pkcs12_reset; +static OSSL_FUNC_kdf_derive_fn kdf_pkcs12_derive; +static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_pkcs12_settable_ctx_params; +static OSSL_FUNC_kdf_set_ctx_params_fn kdf_pkcs12_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_pkcs12_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn kdf_pkcs12_get_ctx_params; + +typedef struct { + void *provctx; + PROV_DIGEST digest; + unsigned char *pass; + size_t pass_len; + unsigned char *salt; + size_t salt_len; + uint64_t iter; + int id; +} KDF_PKCS12; + +/* PKCS12 compatible key/IV generation */ + +static int pkcs12kdf_derive(const unsigned char *pass, size_t passlen, + const unsigned char *salt, size_t saltlen, + int id, uint64_t iter, const EVP_MD *md_type, + unsigned char *out, size_t n) +{ + unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL; + size_t Slen, Plen, Ilen; + size_t i, j, k, u, v; + uint64_t iter_cnt; + int ret = 0, ui, vi; + EVP_MD_CTX *ctx = NULL; + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto end; + } + vi = EVP_MD_block_size(md_type); + ui = EVP_MD_size(md_type); + if (ui < 0 || vi <= 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE); + goto end; + } + u = (size_t)ui; + v = (size_t)vi; + D = OPENSSL_malloc(v); + Ai = OPENSSL_malloc(u); + B = OPENSSL_malloc(v + 1); + Slen = v * ((saltlen + v - 1) / v); + if (passlen != 0) + Plen = v * ((passlen + v - 1) / v); + else + Plen = 0; + Ilen = Slen + Plen; + I = OPENSSL_malloc(Ilen); + if (D == NULL || Ai == NULL || B == NULL || I == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto end; + } + for (i = 0; i < v; i++) + D[i] = id; + p = I; + for (i = 0; i < Slen; i++) + *p++ = salt[i % saltlen]; + for (i = 0; i < Plen; i++) + *p++ = pass[i % passlen]; + for (;;) { + if (!EVP_DigestInit_ex(ctx, md_type, NULL) + || !EVP_DigestUpdate(ctx, D, v) + || !EVP_DigestUpdate(ctx, I, Ilen) + || !EVP_DigestFinal_ex(ctx, Ai, NULL)) + goto end; + for (iter_cnt = 1; iter_cnt < iter; iter_cnt++) { + if (!EVP_DigestInit_ex(ctx, md_type, NULL) + || !EVP_DigestUpdate(ctx, Ai, u) + || !EVP_DigestFinal_ex(ctx, Ai, NULL)) + goto end; + } + memcpy(out, Ai, n < u ? n : u); + if (u >= n) { + ret = 1; + break; + } + n -= u; + out += u; + for (j = 0; j < v; j++) + B[j] = Ai[j % u]; + for (j = 0; j < Ilen; j += v) { + unsigned char *Ij = I + j; + uint16_t c = 1; + + /* Work out Ij = Ij + B + 1 */ + for (k = v; k > 0;) { + k--; + c += Ij[k] + B[k]; + Ij[k] = (unsigned char)c; + c >>= 8; + } + } + } + + end: + OPENSSL_free(Ai); + OPENSSL_free(B); + OPENSSL_free(D); + OPENSSL_free(I); + EVP_MD_CTX_free(ctx); + return ret; +} + +static void *kdf_pkcs12_new(void *provctx) +{ + KDF_PKCS12 *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + ctx->provctx = provctx; + return ctx; +} + +static void kdf_pkcs12_cleanup(KDF_PKCS12 *ctx) +{ + ossl_prov_digest_reset(&ctx->digest); + OPENSSL_free(ctx->salt); + OPENSSL_clear_free(ctx->pass, ctx->pass_len); + memset(ctx, 0, sizeof(*ctx)); +} + +static void kdf_pkcs12_free(void *vctx) +{ + KDF_PKCS12 *ctx = (KDF_PKCS12 *)vctx; + + if (ctx != NULL) { + kdf_pkcs12_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +static void kdf_pkcs12_reset(void *vctx) +{ + KDF_PKCS12 *ctx = (KDF_PKCS12 *)vctx; + void *provctx = ctx->provctx; + + kdf_pkcs12_cleanup(ctx); + ctx->provctx = provctx; +} + +static int pkcs12kdf_set_membuf(unsigned char **buffer, size_t *buflen, + const OSSL_PARAM *p) +{ + OPENSSL_clear_free(*buffer, *buflen); + if (p->data_size == 0) { + if ((*buffer = OPENSSL_malloc(1)) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + } else if (p->data != NULL) { + *buffer = NULL; + if (!OSSL_PARAM_get_octet_string(p, (void **)buffer, 0, buflen)) + return 0; + } + return 1; +} + +static int kdf_pkcs12_derive(void *vctx, unsigned char *key, + size_t keylen) +{ + KDF_PKCS12 *ctx = (KDF_PKCS12 *)vctx; + const EVP_MD *md; + + if (!ossl_prov_is_running()) + return 0; + + if (ctx->pass == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_PASS); + return 0; + } + + if (ctx->salt == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SALT); + return 0; + } + + md = ossl_prov_digest_md(&ctx->digest); + return pkcs12kdf_derive(ctx->pass, ctx->pass_len, ctx->salt, ctx->salt_len, + ctx->id, ctx->iter, md, key, keylen); +} + +static int kdf_pkcs12_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + KDF_PKCS12 *ctx = vctx; + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); + + if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL) + if (!pkcs12kdf_set_membuf(&ctx->pass, &ctx->pass_len, p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) + if (!pkcs12kdf_set_membuf(&ctx->salt, &ctx->salt_len,p)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PKCS12_ID)) != NULL) + if (!OSSL_PARAM_get_int(p, &ctx->id)) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_ITER)) != NULL) + if (!OSSL_PARAM_get_uint64(p, &ctx->iter)) + return 0; + return 1; +} + +static const OSSL_PARAM *kdf_pkcs12_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), + OSSL_PARAM_uint64(OSSL_KDF_PARAM_ITER, NULL), + OSSL_PARAM_int(OSSL_KDF_PARAM_PKCS12_ID, NULL), + OSSL_PARAM_END + }; + return known_settable_ctx_params; +} + +static int kdf_pkcs12_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) + return OSSL_PARAM_set_size_t(p, SIZE_MAX); + return -2; +} + +static const OSSL_PARAM *kdf_pkcs12_gettable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), + OSSL_PARAM_END + }; + return known_gettable_ctx_params; +} + +const OSSL_DISPATCH ossl_kdf_pkcs12_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_pkcs12_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_pkcs12_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_pkcs12_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_pkcs12_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))kdf_pkcs12_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_pkcs12_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))kdf_pkcs12_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_pkcs12_get_ctx_params }, + { 0, NULL } +}; diff --git a/providers/implementations/kdfs/scrypt.c b/providers/implementations/kdfs/scrypt.c index 77869f957d..678a882fcd 100644 --- a/providers/implementations/kdfs/scrypt.c +++ b/providers/implementations/kdfs/scrypt.c @@ -18,6 +18,7 @@ #include "internal/numbers.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" @@ -29,14 +30,18 @@ static OSSL_FUNC_kdf_reset_fn kdf_scrypt_reset; static OSSL_FUNC_kdf_derive_fn kdf_scrypt_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_scrypt_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn kdf_scrypt_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_scrypt_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn kdf_scrypt_get_ctx_params; static int scrypt_alg(const char *pass, size_t passlen, const unsigned char *salt, size_t saltlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, - unsigned char *key, size_t keylen, EVP_MD *sha256); + unsigned char *key, size_t keylen, EVP_MD *sha256, + OSSL_LIB_CTX *libctx, const char *propq); typedef struct { - void *provctx; + OSSL_LIB_CTX *libctx; + char *propq; unsigned char *pass; size_t pass_len; unsigned char *salt; @@ -53,19 +58,15 @@ static void *kdf_scrypt_new(void *provctx) { KDF_SCRYPT *ctx; + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } - ctx->provctx = provctx; - ctx->sha256 = EVP_MD_fetch(PROV_LIBRARY_CONTEXT_OF(provctx), - "sha256", NULL); - if (ctx->sha256 == NULL) { - OPENSSL_free(ctx); - ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256); - return NULL; - } + ctx->libctx = PROV_LIBCTX_OF(provctx); kdf_scrypt_init(ctx); return ctx; } @@ -75,6 +76,7 @@ static void kdf_scrypt_free(void *vctx) KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx; if (ctx != NULL) { + OPENSSL_free(ctx->propq); EVP_MD_free(ctx->sha256); kdf_scrypt_reset(ctx); OPENSSL_free(ctx); @@ -119,11 +121,40 @@ static int scrypt_set_membuf(unsigned char **buffer, size_t *buflen, return 1; } +static int set_digest(KDF_SCRYPT *ctx) +{ + EVP_MD_free(ctx->sha256); + ctx->sha256 = EVP_MD_fetch(ctx->libctx, "sha256", ctx->propq); + if (ctx->sha256 == NULL) { + OPENSSL_free(ctx); + ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256); + return 0; + } + return 1; +} + +static int set_property_query(KDF_SCRYPT *ctx, const char *propq) +{ + OPENSSL_free(ctx->propq); + ctx->propq = NULL; + if (propq != NULL) { + ctx->propq = OPENSSL_strdup(propq); + if (ctx->propq == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + static int kdf_scrypt_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_SCRYPT *ctx = (KDF_SCRYPT *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (ctx->pass == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_PASS); return 0; @@ -134,9 +165,13 @@ static int kdf_scrypt_derive(void *vctx, unsigned char *key, return 0; } + if (ctx->sha256 == NULL && !set_digest(ctx)) + return 0; + return scrypt_alg((char *)ctx->pass, ctx->pass_len, ctx->salt, ctx->salt_len, ctx->N, ctx->r, ctx->p, - ctx->maxmem_bytes, key, keylen, ctx->sha256); + ctx->maxmem_bytes, key, keylen, ctx->sha256, + ctx->libctx, ctx->propq); } static int is_power_of_two(uint64_t value) @@ -187,10 +222,18 @@ static int kdf_scrypt_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; ctx->maxmem_bytes = u64_value; } + + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING + || !set_property_query(ctx, p->data) + || !set_digest(ctx)) + return 0; + } return 1; } -static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(void) +static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD, NULL, 0), @@ -199,6 +242,7 @@ static const OSSL_PARAM *kdf_scrypt_settable_ctx_params(void) OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_R, NULL), OSSL_PARAM_uint32(OSSL_KDF_PARAM_SCRYPT_P, NULL), OSSL_PARAM_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, NULL), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END }; return known_settable_ctx_params; @@ -213,7 +257,7 @@ static int kdf_scrypt_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *kdf_scrypt_gettable_ctx_params(void) +static const OSSL_PARAM *kdf_scrypt_gettable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -222,7 +266,7 @@ static const OSSL_PARAM *kdf_scrypt_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_scrypt_functions[] = { +const OSSL_DISPATCH ossl_kdf_scrypt_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_scrypt_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_scrypt_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_scrypt_reset }, @@ -359,7 +403,8 @@ static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N, static int scrypt_alg(const char *pass, size_t passlen, const unsigned char *salt, size_t saltlen, uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem, - unsigned char *key, size_t keylen, EVP_MD *sha256) + unsigned char *key, size_t keylen, EVP_MD *sha256, + OSSL_LIB_CTX *libctx, const char *propq) { int rv = 0; unsigned char *B; @@ -443,15 +488,15 @@ static int scrypt_alg(const char *pass, size_t passlen, X = (uint32_t *)(B + Blen); T = X + 32 * r; V = T + 32 * r; - if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, sha256, - (int)Blen, B) == 0) + if (pkcs5_pbkdf2_hmac_ex(pass, passlen, salt, saltlen, 1, sha256, (int)Blen, + B, libctx, propq) == 0) goto err; for (i = 0; i < p; i++) scryptROMix(B + 128 * r * i, r, N, X, T, V); - if (PKCS5_PBKDF2_HMAC(pass, passlen, B, (int)Blen, 1, sha256, - keylen, key) == 0) + if (pkcs5_pbkdf2_hmac_ex(pass, passlen, B, (int)Blen, 1, sha256, keylen, + key, libctx, propq) == 0) goto err; rv = 1; err: diff --git a/providers/implementations/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c index 72d7c607dc..daf0dd2e87 100644 --- a/providers/implementations/kdfs/sshkdf.c +++ b/providers/implementations/kdfs/sshkdf.c @@ -17,9 +17,10 @@ #include "internal/numbers.h" #include "crypto/evp.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" -# include "prov/provider_util.h" +#include "prov/provider_util.h" /* See RFC 4253, Section 7.2 */ static OSSL_FUNC_kdf_newctx_fn kdf_sshkdf_new; @@ -53,6 +54,9 @@ static void *kdf_sshkdf_new(void *provctx) { KDF_SSHKDF *ctx; + if (!ossl_prov_is_running()) + return NULL; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ctx->provctx = provctx; @@ -94,8 +98,12 @@ static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_SSHKDF *ctx = (KDF_SSHKDF *)vctx; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md; + + if (!ossl_prov_is_running()) + return 0; + md = ossl_prov_digest_md(&ctx->digest); if (md == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; @@ -126,7 +134,7 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; KDF_SSHKDF *ctx = vctx; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); int t; if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) @@ -160,7 +168,7 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *kdf_sshkdf_settable_ctx_params(void) +static const OSSL_PARAM *kdf_sshkdf_settable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), @@ -183,7 +191,7 @@ static int kdf_sshkdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(void) +static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -192,7 +200,7 @@ static const OSSL_PARAM *kdf_sshkdf_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_sshkdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_sshkdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_sshkdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_sshkdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_sshkdf_reset }, diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c index 5ef73644f0..6cfde97842 100644 --- a/providers/implementations/kdfs/sskdf.c +++ b/providers/implementations/kdfs/sskdf.c @@ -46,6 +46,7 @@ #include "internal/numbers.h" #include "crypto/evp.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_util.h" @@ -293,6 +294,9 @@ static void *sskdf_new(void *provctx) { KDF_SSKDF *ctx; + if (!ossl_prov_is_running()) + return NULL; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ctx->provctx = provctx; @@ -349,12 +353,15 @@ static size_t sskdf_size(KDF_SSKDF *ctx) static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_SSKDF *ctx = (KDF_SSKDF *)vctx; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md; + if (!ossl_prov_is_running()) + return 0; if (ctx->secret == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET); return 0; } + md = ossl_prov_digest_md(&ctx->digest); if (ctx->macctx != NULL) { /* H(x) = KMAC or H(x) = HMAC */ @@ -364,11 +371,6 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen) int default_salt_len; EVP_MAC *mac = EVP_MAC_CTX_mac(ctx->macctx); - /* - * TODO(3.0) investigate the necessity to have all these controls. - * Why does KMAC require a salt length that's shorter than the MD - * block size? - */ if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_HMAC)) { /* H(x) = HMAC(x, salt, hash) */ if (md == NULL) { @@ -420,7 +422,10 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen) static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_SSKDF *ctx = (KDF_SSKDF *)vctx; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md; + + if (!ossl_prov_is_running()) + return 0; if (ctx->secret == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET); @@ -433,6 +438,7 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen) } /* H(x) = hash */ + md = ossl_prov_digest_md(&ctx->digest); if (md == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; @@ -446,7 +452,7 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; KDF_SSKDF *ctx = vctx; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); size_t sz; if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) @@ -478,7 +484,7 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *sskdf_settable_ctx_params(void) +static const OSSL_PARAM *sskdf_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0), @@ -504,7 +510,7 @@ static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *sskdf_gettable_ctx_params(void) +static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -513,7 +519,7 @@ static const OSSL_PARAM *sskdf_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_sskdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_sskdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset }, @@ -527,7 +533,7 @@ const OSSL_DISPATCH kdf_sskdf_functions[] = { { 0, NULL } }; -const OSSL_DISPATCH kdf_x963_kdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))sskdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))sskdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))sskdf_reset }, diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c index 73437531f6..315971a96e 100644 --- a/providers/implementations/kdfs/tls1_prf.c +++ b/providers/implementations/kdfs/tls1_prf.c @@ -56,6 +56,7 @@ #include "internal/numbers.h" #include "crypto/evp.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_util.h" @@ -67,6 +68,8 @@ static OSSL_FUNC_kdf_reset_fn kdf_tls1_prf_reset; static OSSL_FUNC_kdf_derive_fn kdf_tls1_prf_derive; static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_prf_set_ctx_params; +static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_tls1_prf_gettable_ctx_params; +static OSSL_FUNC_kdf_get_ctx_params_fn kdf_tls1_prf_get_ctx_params; static int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, const unsigned char *sec, size_t slen, @@ -96,6 +99,9 @@ static void *kdf_tls1_prf_new(void *provctx) { TLS1_PRF *ctx; + if (!ossl_prov_is_running()) + return NULL; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ctx->provctx = provctx; @@ -130,6 +136,9 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, { TLS1_PRF *ctx = (TLS1_PRF *)vctx; + if (!ossl_prov_is_running()) + return 0; + if (ctx->P_hash == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; @@ -142,6 +151,10 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SEED); return 0; } + if (keylen == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } return tls1_prf_alg(ctx->P_hash, ctx->P_sha1, ctx->sec, ctx->seclen, @@ -153,7 +166,7 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { const OSSL_PARAM *p; TLS1_PRF *ctx = vctx; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) { if (strcasecmp(p->data, SN_md5_sha1) == 0) { @@ -181,9 +194,6 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) } /* The seed fields concatenate, so process them all */ if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) { - OPENSSL_cleanse(ctx->seed, ctx->seedlen); - ctx->seedlen = 0; - for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, OSSL_KDF_PARAM_SEED)) { const void *q = ctx->seed + ctx->seedlen; @@ -201,7 +211,7 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(void) +static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(ossl_unused void *ctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), @@ -222,7 +232,7 @@ static int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(void) +static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(ossl_unused void *ctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -231,7 +241,7 @@ static const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_tls1_prf_functions[] = { +const OSSL_DISPATCH ossl_kdf_tls1_prf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_tls1_prf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_tls1_prf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_tls1_prf_reset }, diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c index cf0ad0bcda..f19e014927 100644 --- a/providers/implementations/kdfs/x942kdf.c +++ b/providers/implementations/kdfs/x942kdf.c @@ -17,6 +17,7 @@ #include "internal/packet.h" #include "internal/der.h" #include "prov/provider_ctx.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_util.h" @@ -57,22 +58,26 @@ static const struct { size_t oid_len; size_t keklen; /* size in bytes */ } kek_algs[] = { - { "AES-128-WRAP", der_oid_id_aes128_wrap, DER_OID_SZ_id_aes128_wrap, 16 }, - { "AES-192-WRAP", der_oid_id_aes192_wrap, DER_OID_SZ_id_aes192_wrap, 24 }, - { "AES-256-WRAP", der_oid_id_aes256_wrap, DER_OID_SZ_id_aes256_wrap, 32 }, -#ifndef FIPS_MODULE - { "DES3-WRAP", der_oid_id_alg_CMS3DESwrap, DER_OID_SZ_id_alg_CMS3DESwrap, + { "AES-128-WRAP", ossl_der_oid_id_aes128_wrap, DER_OID_SZ_id_aes128_wrap, + 16 }, + { "AES-192-WRAP", ossl_der_oid_id_aes192_wrap, DER_OID_SZ_id_aes192_wrap, 24 }, + { "AES-256-WRAP", ossl_der_oid_id_aes256_wrap, DER_OID_SZ_id_aes256_wrap, + 32 }, +#ifndef FIPS_MODULE + { "DES3-WRAP", ossl_der_oid_id_alg_CMS3DESwrap, + DER_OID_SZ_id_alg_CMS3DESwrap, 24 }, #endif }; -static int find_alg_id(OPENSSL_CTX *libctx, const char *algname, size_t *id) +static int find_alg_id(OSSL_LIB_CTX *libctx, const char *algname, + const char *propq, size_t *id) { int ret = 1; size_t i; EVP_CIPHER *cipher; - cipher = EVP_CIPHER_fetch(libctx, algname, NULL); + cipher = EVP_CIPHER_fetch(libctx, algname, propq); if (cipher != NULL) { for (i = 0; i < OSSL_NELEM(kek_algs); i++) { if (EVP_CIPHER_is_a(cipher, kek_algs[i].name)) { @@ -92,14 +97,14 @@ static int DER_w_keyinfo(WPACKET *pkt, const unsigned char *der_oid, size_t der_oidlen, unsigned char **pcounter) { - return DER_w_begin_sequence(pkt, -1) + return ossl_DER_w_begin_sequence(pkt, -1) /* Store the initial value of 1 into the counter */ - && DER_w_octet_string_uint32(pkt, -1, 1) + && ossl_DER_w_octet_string_uint32(pkt, -1, 1) /* Remember where we stored the counter in the buffer */ && (pcounter == NULL || (*pcounter = WPACKET_get_curr(pkt)) != NULL) - && DER_w_precompiled(pkt, -1, der_oid, der_oidlen) - && DER_w_end_sequence(pkt, -1); + && ossl_DER_w_precompiled(pkt, -1, der_oid, der_oidlen) + && ossl_DER_w_end_sequence(pkt, -1); } static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen, @@ -109,11 +114,11 @@ static int der_encode_sharedinfo(WPACKET *pkt, unsigned char *buf, size_t buflen { return (buf != NULL ? WPACKET_init_der(pkt, buf, buflen) : WPACKET_init_null_der(pkt)) - && DER_w_begin_sequence(pkt, -1) - && DER_w_octet_string_uint32(pkt, 2, keylen_bits) - && (ukm == NULL || DER_w_octet_string(pkt, 0, ukm, ukmlen)) + && ossl_DER_w_begin_sequence(pkt, -1) + && ossl_DER_w_octet_string_uint32(pkt, 2, keylen_bits) + && (ukm == NULL || ossl_DER_w_octet_string(pkt, 0, ukm, ukmlen)) && DER_w_keyinfo(pkt, der_oid, der_oidlen, pcounter) - && DER_w_end_sequence(pkt, -1) + && ossl_DER_w_end_sequence(pkt, -1) && WPACKET_finish(pkt); } @@ -164,7 +169,7 @@ static int x942_encode_otherinfo(size_t keylen, /* keylenbits must fit into 4 bytes */ if (keylen > 0xFFFFFF) - goto err; + return 0; keylen_bits = 8 * keylen; /* Calculate the size of the buffer */ @@ -276,6 +281,9 @@ static void *x942kdf_new(void *provctx) { KDF_X942 *ctx; + if (!ossl_prov_is_running()) + return 0; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); ctx->provctx = provctx; @@ -331,16 +339,20 @@ static size_t x942kdf_size(KDF_X942 *ctx) static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen) { KDF_X942 *ctx = (KDF_X942 *)vctx; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md; int ret = 0; unsigned char *ctr; unsigned char *der = NULL; size_t der_len = 0; + if (!ossl_prov_is_running()) + return 0; + if (ctx->secret == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET); return 0; } + md = ossl_prov_digest_md(&ctx->digest); if (md == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; @@ -373,9 +385,10 @@ static int x942kdf_derive(void *vctx, unsigned char *key, size_t keylen) static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { - const OSSL_PARAM *p; + const OSSL_PARAM *p, *pq; KDF_X942 *ctx = vctx; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(ctx->provctx); + const char *propq = NULL; size_t id; if (!ossl_prov_digest_load_from_params(&ctx->digest, params, provctx)) @@ -393,7 +406,14 @@ static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_CEK_ALG)) != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING) return 0; - if (find_alg_id(provctx, p->data, &id) == 0) + pq = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_PROPERTIES); + /* + * We already grab the properties during ossl_prov_digest_load_from_params() + * so there is no need to check the validity again.. + */ + if (pq != NULL) + propq = p->data; + if (find_alg_id(provctx, p->data, propq, &id) == 0) return 0; ctx->cek_oid = kek_algs[id].oid; ctx->cek_oid_len = kek_algs[id].oid_len; @@ -402,7 +422,7 @@ static int x942kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -static const OSSL_PARAM *x942kdf_settable_ctx_params(void) +static const OSSL_PARAM *x942kdf_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), @@ -426,7 +446,7 @@ static int x942kdf_get_ctx_params(void *vctx, OSSL_PARAM params[]) return -2; } -static const OSSL_PARAM *x942kdf_gettable_ctx_params(void) +static const OSSL_PARAM *x942kdf_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), @@ -435,7 +455,7 @@ static const OSSL_PARAM *x942kdf_gettable_ctx_params(void) return known_gettable_ctx_params; } -const OSSL_DISPATCH kdf_x942_kdf_functions[] = { +const OSSL_DISPATCH ossl_kdf_x942_kdf_functions[] = { { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))x942kdf_new }, { OSSL_FUNC_KDF_FREECTX, (void(*)(void))x942kdf_free }, { OSSL_FUNC_KDF_RESET, (void(*)(void))x942kdf_reset }, diff --git a/providers/implementations/kem/build.info b/providers/implementations/kem/build.info new file mode 100644 index 0000000000..e9f91cba43 --- /dev/null +++ b/providers/implementations/kem/build.info @@ -0,0 +1,6 @@ +# We make separate GOAL variables for each algorithm, to make it easy to +# switch each to the Legacy provider when needed. + +$RSA_KEM_GOAL=../../libimplementations.a + +SOURCE[$RSA_KEM_GOAL]=rsa_kem.c diff --git a/providers/implementations/kem/rsa_kem.c b/providers/implementations/kem/rsa_kem.c new file mode 100644 index 0000000000..58a223fe42 --- /dev/null +++ b/providers/implementations/kem/rsa_kem.c @@ -0,0 +1,356 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + +#include "e_os.h" /* strcasecmp */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "prov/providercommonerr.h" +#include "prov/provider_ctx.h" +#include "prov/implementations.h" +#include "prov/securitycheck.h" + +static OSSL_FUNC_kem_newctx_fn rsakem_newctx; +static OSSL_FUNC_kem_encapsulate_init_fn rsakem_encapsulate_init; +static OSSL_FUNC_kem_encapsulate_fn rsakem_generate; +static OSSL_FUNC_kem_decapsulate_init_fn rsakem_decapsulate_init; +static OSSL_FUNC_kem_decapsulate_fn rsakem_recover; +static OSSL_FUNC_kem_freectx_fn rsakem_freectx; +static OSSL_FUNC_kem_dupctx_fn rsakem_dupctx; +static OSSL_FUNC_kem_get_ctx_params_fn rsakem_get_ctx_params; +static OSSL_FUNC_kem_gettable_ctx_params_fn rsakem_gettable_ctx_params; +static OSSL_FUNC_kem_set_ctx_params_fn rsakem_set_ctx_params; +static OSSL_FUNC_kem_settable_ctx_params_fn rsakem_settable_ctx_params; + +/* + * Only the KEM for RSASVE as defined in SP800-56b r2 is implemented + * currently. + */ +#define KEM_OP_UNDEFINED -1 +#define KEM_OP_RSASVE 0 + +/* + * What's passed as an actual key is defined by the KEYMGMT interface. + * We happen to know that our KEYMGMT simply passes RSA structures, so + * we use that here too. + */ +typedef struct { + OSSL_LIB_CTX *libctx; + RSA *rsa; + int op; +} PROV_RSA_CTX; + +static const OSSL_ITEM rsakem_opname_id_map[] = { + { KEM_OP_RSASVE, OSSL_KEM_PARAM_OPERATION_RSASVE }, +}; + +static int name2id(const char *name, const OSSL_ITEM *map, size_t sz) +{ + size_t i; + + if (name == NULL) + return -1; + + for (i = 0; i < sz; ++i) { + if (strcasecmp(map[i].ptr, name) == 0) + return map[i].id; + } + return -1; +} + +static int rsakem_opname2id(const char *name) +{ + return name2id(name, rsakem_opname_id_map, OSSL_NELEM(rsakem_opname_id_map)); +} + +static void *rsakem_newctx(void *provctx) +{ + PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); + + if (prsactx == NULL) + return NULL; + prsactx->libctx = PROV_LIBCTX_OF(provctx); + prsactx->op = KEM_OP_UNDEFINED; + + return prsactx; +} + +static void rsakem_freectx(void *vprsactx) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + RSA_free(prsactx->rsa); + OPENSSL_free(prsactx); +} + +static void *rsakem_dupctx(void *vprsactx) +{ + PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; + PROV_RSA_CTX *dstctx; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + if (dstctx->rsa != NULL && !RSA_up_ref(dstctx->rsa)) { + OPENSSL_free(dstctx); + return NULL; + } + return dstctx; +} + +static int rsakem_init(void *vprsactx, void *vrsa, int operation) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx == NULL || vrsa == NULL || !RSA_up_ref(vrsa)) + return 0; + RSA_free(prsactx->rsa); + prsactx->rsa = vrsa; + + if (!ossl_rsa_check_key(vrsa, operation == EVP_PKEY_OP_ENCAPSULATE)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + return 1; +} + +static int rsakem_encapsulate_init(void *vprsactx, void *vrsa) +{ + return rsakem_init(vprsactx, vrsa, EVP_PKEY_OP_ENCAPSULATE); +} + +static int rsakem_decapsulate_init(void *vprsactx, void *vrsa) +{ + return rsakem_init(vprsactx, vrsa, EVP_PKEY_OP_DECAPSULATE); +} + +static int rsakem_get_ctx_params(void *vprsactx, OSSL_PARAM *params) +{ + PROV_RSA_CTX *ctx = (PROV_RSA_CTX *)vprsactx; + + if (ctx == NULL || params == NULL) + return 0; + return 1; +} + +static const OSSL_PARAM known_gettable_rsakem_ctx_params[] = { + OSSL_PARAM_END +}; + +static const OSSL_PARAM *rsakem_gettable_ctx_params(ossl_unused void *provctx) +{ + return known_gettable_rsakem_ctx_params; +} + +static int rsakem_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + const OSSL_PARAM *p; + int op; + + if (prsactx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_KEM_PARAM_OPERATION); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + op = rsakem_opname2id(p->data); + if (op < 0) + return 0; + prsactx->op = op; + } + return 1; +} + +static const OSSL_PARAM known_settable_rsakem_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_KEM_PARAM_OPERATION, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *rsakem_settable_ctx_params(ossl_unused void *provctx) +{ + return known_settable_rsakem_ctx_params; +} + +/* + * NIST.SP.800-56Br2 + * 7.2.1.2 RSASVE Generate Operation (RSASVE.GENERATE). + * + * Generate a random in the range 1 < z < (n – 1) + */ +static int rsasve_gen_rand_bytes(RSA *rsa_pub, + unsigned char *out, int outlen) +{ + int ret = 0; + BN_CTX *bnctx; + BIGNUM *z, *nminus3; + + bnctx = BN_CTX_secure_new_ex(ossl_rsa_get0_libctx(rsa_pub)); + if (bnctx == NULL) + return 0; + + /* + * Generate a random in the range 1 < z < (n – 1). + * Since BN_priv_rand_range_ex() returns a value in range 0 <= r < max + * We can achieve this by adding 2.. but then we need to subtract 3 from + * the upper bound i.e: 2 + (0 <= r < (n - 3)) + */ + BN_CTX_start(bnctx); + nminus3 = BN_CTX_get(bnctx); + z = BN_CTX_get(bnctx); + ret = (z != NULL + && (BN_copy(nminus3, RSA_get0_n(rsa_pub)) != NULL) + && BN_sub_word(nminus3, 3) + && BN_priv_rand_range_ex(z, nminus3, bnctx) + && BN_add_word(z, 2) + && (BN_bn2binpad(z, out, outlen) == outlen)); + BN_CTX_end(bnctx); + BN_CTX_free(bnctx); + return ret; +} + +/* + * NIST.SP.800-56Br2 + * 7.2.1.2 RSASVE Generate Operation (RSASVE.GENERATE). + */ +static int rsasve_generate(PROV_RSA_CTX *prsactx, + unsigned char *out, size_t *outlen, + unsigned char *secret, size_t *secretlen) +{ + int ret; + size_t nlen; + + /* Step (1): nlen = Ceil(len(n)/8) */ + nlen = RSA_size(prsactx->rsa); + + if (out == NULL) { + if (nlen == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + if (outlen == NULL && secretlen == NULL) + return 0; + if (outlen != NULL) + *outlen = nlen; + if (secretlen != NULL) + *secretlen = nlen; + return 1; + } + /* + * Step (2): Generate a random byte string z of nlen bytes where + * 1 < z < n - 1 + */ + if (!rsasve_gen_rand_bytes(prsactx->rsa, secret, nlen)) + return 0; + + /* Step(3): out = RSAEP((n,e), z) */ + ret = RSA_public_encrypt(nlen, secret, out, prsactx->rsa, RSA_NO_PADDING); + if (ret) { + ret = 1; + if (outlen != NULL) + *outlen = nlen; + if (secretlen != NULL) + *secretlen = nlen; + } else { + OPENSSL_cleanse(secret, nlen); + } + return ret; +} + +/* + * NIST.SP.800-56Br2 + * 7.2.1.3 RSASVE Recovery Operation (RSASVE.RECOVER). + */ +static int rsasve_recover(PROV_RSA_CTX *prsactx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + size_t nlen; + + /* Step (1): get the byte length of n */ + nlen = RSA_size(prsactx->rsa); + + if (out == NULL) { + if (nlen == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + *outlen = nlen; + return 1; + } + + /* Step (2): check the input ciphertext 'inlen' matches the nlen */ + if (inlen != nlen) { + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_LENGTH); + return 0; + } + /* Step (3): out = RSADP((n,d), in) */ + return (RSA_private_decrypt(inlen, in, out, prsactx->rsa, RSA_NO_PADDING) > 0); +} + +static int rsakem_generate(void *vprsactx, unsigned char *out, size_t *outlen, + unsigned char *secret, size_t *secretlen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + switch (prsactx->op) { + case KEM_OP_RSASVE: + return rsasve_generate(prsactx, out, outlen, secret, secretlen); + default: + return -2; + } +} + +static int rsakem_recover(void *vprsactx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + switch (prsactx->op) { + case KEM_OP_RSASVE: + return rsasve_recover(prsactx, out, outlen, in, inlen); + default: + return -2; + } +} + +const OSSL_DISPATCH ossl_rsa_asym_kem_functions[] = { + { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))rsakem_newctx }, + { OSSL_FUNC_KEM_ENCAPSULATE_INIT, + (void (*)(void))rsakem_encapsulate_init }, + { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))rsakem_generate }, + { OSSL_FUNC_KEM_DECAPSULATE_INIT, + (void (*)(void))rsakem_decapsulate_init }, + { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))rsakem_recover }, + { OSSL_FUNC_KEM_FREECTX, (void (*)(void))rsakem_freectx }, + { OSSL_FUNC_KEM_DUPCTX, (void (*)(void))rsakem_dupctx }, + { OSSL_FUNC_KEM_GET_CTX_PARAMS, + (void (*)(void))rsakem_get_ctx_params }, + { OSSL_FUNC_KEM_GETTABLE_CTX_PARAMS, + (void (*)(void))rsakem_gettable_ctx_params }, + { OSSL_FUNC_KEM_SET_CTX_PARAMS, + (void (*)(void))rsakem_set_ctx_params }, + { OSSL_FUNC_KEM_SETTABLE_CTX_PARAMS, + (void (*)(void))rsakem_settable_ctx_params }, + { 0, NULL } +}; diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info index 73597c7cea..978cd706ae 100644 --- a/providers/implementations/keymgmt/build.info +++ b/providers/implementations/keymgmt/build.info @@ -5,6 +5,7 @@ $DH_GOAL=../../libimplementations.a $DSA_GOAL=../../libimplementations.a $EC_GOAL=../../libimplementations.a $ECX_GOAL=../../libimplementations.a +$KDF_GOAL=../../libimplementations.a IF[{- !$disabled{dh} -}] SOURCE[$DH_GOAL]=dh_kmgmt.c @@ -33,3 +34,8 @@ ENDIF SOURCE[../../libfips.a]=rsa_kmgmt.c SOURCE[../../libnonfips.a]=rsa_kmgmt.c + +SOURCE[$KDF_GOAL]=kdf_legacy_kmgmt.c + +SOURCE[../../libfips.a]=mac_legacy_kmgmt.c +SOURCE[../../libnonfips.a]=mac_legacy_kmgmt.c diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index 2a8b7f8521..3cca031963 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -29,6 +29,7 @@ static OSSL_FUNC_keymgmt_new_fn dh_newdata; static OSSL_FUNC_keymgmt_free_fn dh_freedata; static OSSL_FUNC_keymgmt_gen_init_fn dh_gen_init; +static OSSL_FUNC_keymgmt_gen_init_fn dhx_gen_init; static OSSL_FUNC_keymgmt_gen_set_template_fn dh_gen_set_template; static OSSL_FUNC_keymgmt_gen_set_params_fn dh_gen_set_params; static OSSL_FUNC_keymgmt_gen_settable_params_fn dh_gen_settable_params; @@ -51,7 +52,7 @@ static OSSL_FUNC_keymgmt_export_types_fn dh_export_types; (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) struct dh_gen_ctx { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; FFC_PARAMS *ffc_params; int selection; @@ -73,6 +74,7 @@ struct dh_gen_ctx { const char *mdprops; OSSL_CALLBACK *cb; void *cbarg; + int dh_type; }; typedef struct dh_name2id_st{ @@ -131,7 +133,28 @@ static int dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) static void *dh_newdata(void *provctx) { - return dh_new_with_libctx(PROV_LIBRARY_CONTEXT_OF(provctx)); + DH *dh = NULL; + + if (ossl_prov_is_running()) { + dh = dh_new_ex(PROV_LIBCTX_OF(provctx)); + if (dh != NULL) { + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, DH_FLAG_TYPE_DH); + } + } + return dh; +} + +static void *dhx_newdata(void *provctx) +{ + DH *dh = NULL; + + dh = dh_new_ex(PROV_LIBCTX_OF(provctx)); + if (dh != NULL) { + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, DH_FLAG_TYPE_DHX); + } + return dh; } static void dh_freedata(void *keydata) @@ -144,7 +167,7 @@ static int dh_has(void *keydata, int selection) DH *dh = keydata; int ok = 0; - if (dh != NULL) { + if (ossl_prov_is_running() && dh != NULL) { if ((selection & DH_POSSIBLE_SELECTIONS) != 0) ok = 1; @@ -164,6 +187,9 @@ static int dh_match(const void *keydata1, const void *keydata2, int selection) const DH *dh2 = keydata2; int ok = 1; + if (!ossl_prov_is_running()) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) ok = ok && BN_cmp(DH_get0_pub_key(dh1), DH_get0_pub_key(dh2)) == 0; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) @@ -172,7 +198,7 @@ static int dh_match(const void *keydata1, const void *keydata2, int selection) FFC_PARAMS *dhparams1 = dh_get0_params((DH *)dh1); FFC_PARAMS *dhparams2 = dh_get0_params((DH *)dh2); - ok = ok && ffc_params_cmp(dhparams1, dhparams2, 1); + ok = ok && ossl_ffc_params_cmp(dhparams1, dhparams2, 1); } return ok; } @@ -182,7 +208,7 @@ static int dh_import(void *keydata, int selection, const OSSL_PARAM params[]) DH *dh = keydata; int ok = 1; - if (dh == NULL) + if (!ossl_prov_is_running() || dh == NULL) return 0; if ((selection & DH_POSSIBLE_SELECTIONS) == 0) @@ -205,7 +231,7 @@ static int dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, OSSL_PARAM *params = NULL; int ok = 1; - if (dh == NULL) + if (!ossl_prov_is_running() || dh == NULL) return 0; tmpl = OSSL_PARAM_BLD_new(); @@ -213,7 +239,7 @@ static int dh_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, return 0; if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) - ok = ok && ffc_params_todata(dh_get0_params(dh), tmpl, NULL); + ok = ok && ossl_ffc_params_todata(dh_get0_params(dh), tmpl, NULL); if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) ok = ok && dh_key_todata(dh, tmpl, NULL); @@ -311,7 +337,7 @@ static ossl_inline int dh_get_params(void *key, OSSL_PARAM params[]) return 0; } - return ffc_params_todata(dh_get0_params(dh), NULL, params) + return ossl_ffc_params_todata(dh_get0_params(dh), NULL, params) && dh_key_todata(dh, NULL, params); } @@ -326,7 +352,7 @@ static const OSSL_PARAM dh_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *dh_gettable_params(void) +static const OSSL_PARAM *dh_gettable_params(void *provctx) { return dh_params; } @@ -336,7 +362,7 @@ static const OSSL_PARAM dh_known_settable_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *dh_settable_params(void) +static const OSSL_PARAM *dh_settable_params(void *provctx) { return dh_known_settable_params; } @@ -381,6 +407,9 @@ static int dh_validate(void *keydata, int selection) DH *dh = keydata; int ok = 0; + if (!ossl_prov_is_running()) + return 0; + if ((selection & DH_POSSIBLE_SELECTIONS) != 0) ok = 1; @@ -399,11 +428,14 @@ static int dh_validate(void *keydata, int selection) return ok; } -static void *dh_gen_init(void *provctx, int selection) +static void *dh_gen_init_base(void *provctx, int selection, int type) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); struct dh_gen_ctx *gctx = NULL; + if (!ossl_prov_is_running()) + return NULL; + if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) == 0) return NULL; @@ -419,16 +451,27 @@ static void *dh_gen_init(void *provctx, int selection) gctx->hindex = 0; gctx->pcounter = -1; gctx->generator = DH_GENERATOR_2; + gctx->dh_type = type; } return gctx; } +static void *dh_gen_init(void *provctx, int selection) +{ + return dh_gen_init_base(provctx, selection, DH_FLAG_TYPE_DH); +} + +static void *dhx_gen_init(void *provctx, int selection) +{ + return dh_gen_init_base(provctx, selection, DH_FLAG_TYPE_DHX); +} + static int dh_gen_set_template(void *genctx, void *templ) { struct dh_gen_ctx *gctx = genctx; DH *dh = templ; - if (gctx == NULL || dh == NULL) + if (!ossl_prov_is_running() || gctx == NULL || dh == NULL) return 0; gctx->ffc_params = dh_get0_params(dh); return 1; @@ -468,7 +511,7 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING - || ((gctx->group_nid = ffc_named_group_to_uid(p->data)) == NID_undef)) { + || ((gctx->group_nid = ossl_ffc_named_group_to_uid(p->data)) == NID_undef)) { ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); return 0; } @@ -555,7 +598,7 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) BN_GENCB *gencb = NULL; FFC_PARAMS *ffc; - if (gctx == NULL) + if (!ossl_prov_is_running() || gctx == NULL) return NULL; /* For parameter generation - If there is a group name just create it */ @@ -565,32 +608,32 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) gctx->group_nid = dh_get_named_group_uid_from_size(gctx->pbits); if (gctx->group_nid == NID_undef) return NULL; - dh = dh_new_by_nid_with_libctx(gctx->libctx, gctx->group_nid); + dh = dh_new_by_nid_ex(gctx->libctx, gctx->group_nid); if (dh == NULL) return NULL; ffc = dh_get0_params(dh); } else { - dh = dh_new_with_libctx(gctx->libctx); + dh = dh_new_ex(gctx->libctx); if (dh == NULL) return NULL; ffc = dh_get0_params(dh); /* Copy the template value if one was passed */ if (gctx->ffc_params != NULL - && !ffc_params_copy(ffc, gctx->ffc_params)) + && !ossl_ffc_params_copy(ffc, gctx->ffc_params)) goto end; - if (!ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) + if (!ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) goto end; if (gctx->gindex != -1) { - ffc_params_set_gindex(ffc, gctx->gindex); + ossl_ffc_params_set_gindex(ffc, gctx->gindex); if (gctx->pcounter != -1) - ffc_params_set_pcounter(ffc, gctx->pcounter); + ossl_ffc_params_set_pcounter(ffc, gctx->pcounter); } else if (gctx->hindex != 0) { - ffc_params_set_h(ffc, gctx->hindex); + ossl_ffc_params_set_h(ffc, gctx->hindex); } if (gctx->mdname != NULL) { - if (!ffc_set_digest(ffc, gctx->mdname, gctx->mdprops)) + if (!ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops)) goto end; } gctx->cb = osslcb; @@ -621,9 +664,14 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) goto end; if (gctx->priv_len > 0) DH_set_length(dh, (long)gctx->priv_len); + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY, + gctx->gen_type == DH_PARAMGEN_TYPE_FIPS_186_2); if (DH_generate_key(dh) <= 0) goto end; } + DH_clear_flags(dh, DH_FLAG_TYPE_MASK); + DH_set_flags(dh, gctx->dh_type); + ret = 1; end: if (ret <= 0) { @@ -649,7 +697,7 @@ void *dh_load(const void *reference, size_t reference_sz) { DH *dh = NULL; - if (reference_sz == sizeof(dh)) { + if (ossl_prov_is_running() && reference_sz == sizeof(dh)) { /* The contents of the reference is the address to our object */ dh = *(DH **)reference; /* We grabbed, so we detach it */ @@ -659,7 +707,7 @@ void *dh_load(const void *reference, size_t reference_sz) return NULL; } -const OSSL_DISPATCH dh_keymgmt_functions[] = { +const OSSL_DISPATCH ossl_dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dh_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dh_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dh_gen_set_template }, @@ -683,3 +731,36 @@ const OSSL_DISPATCH dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types }, { 0, NULL } }; + +/* For any DH key, we use the "DH" algorithms regardless of sub-type. */ +static const char *dhx_query_operation_name(int operation_id) +{ + return "DH"; +} + +const OSSL_DISPATCH ossl_dhx_keymgmt_functions[] = { + { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dhx_newdata }, + { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dhx_gen_init }, + { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dh_gen_set_template }, + { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))dh_gen_set_params }, + { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, + (void (*)(void))dh_gen_settable_params }, + { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))dh_gen }, + { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))dh_gen_cleanup }, + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))dh_load }, + { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dh_freedata }, + { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dh_get_params }, + { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dh_gettable_params }, + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))dh_set_params }, + { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))dh_settable_params }, + { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dh_has }, + { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dh_match }, + { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dh_validate }, + { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))dh_import }, + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))dh_import_types }, + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))dh_export }, + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))dh_export_types }, + { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, + (void (*)(void))dhx_query_operation_name }, + { 0, NULL } +}; diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index 58e9fc564f..0fe6760856 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -50,7 +50,7 @@ static OSSL_FUNC_keymgmt_export_types_fn dsa_export_types; (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) struct dsa_gen_ctx { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; FFC_PARAMS *ffc_params; int selection; @@ -111,7 +111,9 @@ static int dsa_key_todata(DSA *dsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) static void *dsa_newdata(void *provctx) { - return dsa_new_with_ctx(PROV_LIBRARY_CONTEXT_OF(provctx)); + if (!ossl_prov_is_running()) + return NULL; + return dsa_new_with_ctx(PROV_LIBCTX_OF(provctx)); } static void dsa_freedata(void *keydata) @@ -124,7 +126,7 @@ static int dsa_has(void *keydata, int selection) DSA *dsa = keydata; int ok = 0; - if (dsa != NULL) { + if (ossl_prov_is_running() && dsa != NULL) { if ((selection & DSA_POSSIBLE_SELECTIONS) != 0) ok = 1; @@ -144,6 +146,9 @@ static int dsa_match(const void *keydata1, const void *keydata2, int selection) const DSA *dsa2 = keydata2; int ok = 1; + if (!ossl_prov_is_running()) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) ok = ok && BN_cmp(DSA_get0_pub_key(dsa1), DSA_get0_pub_key(dsa2)) == 0; @@ -154,7 +159,7 @@ static int dsa_match(const void *keydata1, const void *keydata2, int selection) FFC_PARAMS *dsaparams1 = dsa_get0_params((DSA *)dsa1); FFC_PARAMS *dsaparams2 = dsa_get0_params((DSA *)dsa2); - ok = ok && ffc_params_cmp(dsaparams1, dsaparams2, 1); + ok = ok && ossl_ffc_params_cmp(dsaparams1, dsaparams2, 1); } return ok; } @@ -164,7 +169,7 @@ static int dsa_import(void *keydata, int selection, const OSSL_PARAM params[]) DSA *dsa = keydata; int ok = 1; - if (dsa == NULL) + if (!ossl_prov_is_running() || dsa == NULL) return 0; if ((selection & DSA_POSSIBLE_SELECTIONS) == 0) @@ -186,11 +191,11 @@ static int dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, OSSL_PARAM *params = NULL; int ok = 1; - if (dsa == NULL) + if (!ossl_prov_is_running() || dsa == NULL) goto err; if ((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) - ok = ok && ffc_params_todata(dsa_get0_params(dsa), tmpl, NULL); + ok = ok && ossl_ffc_params_todata(dsa_get0_params(dsa), tmpl, NULL); if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) ok = ok && dsa_key_todata(dsa, tmpl, NULL); @@ -280,7 +285,7 @@ static ossl_inline int dsa_get_params(void *key, OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL && !OSSL_PARAM_set_utf8_string(p, DSA_DEFAULT_MD)) return 0; - return ffc_params_todata(dsa_get0_params(dsa), NULL, params) + return ossl_ffc_params_todata(dsa_get0_params(dsa), NULL, params) && dsa_key_todata(dsa, NULL, params); } @@ -295,7 +300,7 @@ static const OSSL_PARAM dsa_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *dsa_gettable_params(void) +static const OSSL_PARAM *dsa_gettable_params(void *provctx) { return dsa_params; } @@ -334,6 +339,9 @@ static int dsa_validate(void *keydata, int selection) DSA *dsa = keydata; int ok = 0; + if (!ossl_prov_is_running()) + return 0; + if ((selection & DSA_POSSIBLE_SELECTIONS) != 0) ok = 1; @@ -355,10 +363,10 @@ static int dsa_validate(void *keydata, int selection) static void *dsa_gen_init(void *provctx, int selection) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); struct dsa_gen_ctx *gctx = NULL; - if ((selection & DSA_POSSIBLE_SELECTIONS) == 0) + if (!ossl_prov_is_running() || (selection & DSA_POSSIBLE_SELECTIONS) == 0) return NULL; if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { @@ -379,7 +387,7 @@ static int dsa_gen_set_template(void *genctx, void *templ) struct dsa_gen_ctx *gctx = genctx; DSA *dsa = templ; - if (gctx == NULL || dsa == NULL) + if (!ossl_prov_is_running() || gctx == NULL || dsa == NULL) return 0; gctx->ffc_params = dsa_get0_params(dsa); return 1; @@ -490,7 +498,7 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) int ret = 0; FFC_PARAMS *ffc; - if (gctx == NULL) + if (!ossl_prov_is_running() || gctx == NULL) return NULL; dsa = dsa_new_with_ctx(gctx->libctx); if (dsa == NULL) @@ -505,21 +513,21 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) ffc = dsa_get0_params(dsa); /* Copy the template value if one was passed */ if (gctx->ffc_params != NULL - && !ffc_params_copy(ffc, gctx->ffc_params)) + && !ossl_ffc_params_copy(ffc, gctx->ffc_params)) goto end; if (gctx->seed != NULL - && !ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) + && !ossl_ffc_params_set_seed(ffc, gctx->seed, gctx->seedlen)) goto end; if (gctx->gindex != -1) { - ffc_params_set_gindex(ffc, gctx->gindex); + ossl_ffc_params_set_gindex(ffc, gctx->gindex); if (gctx->pcounter != -1) - ffc_params_set_pcounter(ffc, gctx->pcounter); + ossl_ffc_params_set_pcounter(ffc, gctx->pcounter); } else if (gctx->hindex != 0) { - ffc_params_set_h(ffc, gctx->hindex); + ossl_ffc_params_set_h(ffc, gctx->hindex); } if (gctx->mdname != NULL) { - if (!ffc_set_digest(ffc, gctx->mdname, gctx->mdprops)) + if (!ossl_ffc_set_digest(ffc, gctx->mdname, gctx->mdprops)) goto end; } if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { @@ -529,6 +537,8 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) gencb) <= 0) goto end; } + ossl_ffc_params_enable_flags(ffc, FFC_PARAM_FLAG_VALIDATE_LEGACY, + gctx->gen_type == DSA_PARAMGEN_TYPE_FIPS_186_2); if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { if (ffc->p == NULL || ffc->q == NULL @@ -562,7 +572,7 @@ void *dsa_load(const void *reference, size_t reference_sz) { DSA *dsa = NULL; - if (reference_sz == sizeof(dsa)) { + if (ossl_prov_is_running() && reference_sz == sizeof(dsa)) { /* The contents of the reference is the address to our object */ dsa = *(DSA **)reference; /* We grabbed, so we detach it */ @@ -572,7 +582,7 @@ void *dsa_load(const void *reference, size_t reference_sz) return NULL; } -const OSSL_DISPATCH dsa_keymgmt_functions[] = { +const OSSL_DISPATCH ossl_dsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))dsa_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))dsa_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, (void (*)(void))dsa_gen_set_template }, diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index 4d040a1902..7508a794ad 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -13,6 +13,8 @@ */ #include "internal/deprecated.h" +#include "e_os.h" /* strcasecmp */ +#include #include #include #include @@ -25,6 +27,7 @@ #include "prov/providercommonerr.h" #include "prov/provider_ctx.h" #include "internal/param_build_set.h" +#include "crypto/sm2.h" static OSSL_FUNC_keymgmt_new_fn ec_newdata; static OSSL_FUNC_keymgmt_gen_init_fn ec_gen_init; @@ -47,10 +50,19 @@ static OSSL_FUNC_keymgmt_import_types_fn ec_import_types; static OSSL_FUNC_keymgmt_export_fn ec_export; static OSSL_FUNC_keymgmt_export_types_fn ec_export_types; static OSSL_FUNC_keymgmt_query_operation_name_fn ec_query_operation_name; +#ifndef OPENSSL_NO_SM2 +static OSSL_FUNC_keymgmt_gen_fn sm2_gen; +static OSSL_FUNC_keymgmt_get_params_fn sm2_get_params; +static OSSL_FUNC_keymgmt_gettable_params_fn sm2_gettable_params; +static OSSL_FUNC_keymgmt_settable_params_fn sm2_settable_params; +static OSSL_FUNC_keymgmt_import_fn sm2_import; +static OSSL_FUNC_keymgmt_query_operation_name_fn sm2_query_operation_name; +#endif #define EC_DEFAULT_MD "SHA256" #define EC_POSSIBLE_SELECTIONS \ (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) +#define SM2_DEFAULT_MD "SM3" static const char *ec_query_operation_name(int operation_id) @@ -64,40 +76,17 @@ const char *ec_query_operation_name(int operation_id) return NULL; } -static ossl_inline -int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[]) +#ifndef OPENSSL_NO_SM2 +static +const char *sm2_query_operation_name(int operation_id) { - const EC_GROUP *ecg; - int curve_nid; - - if (ec == NULL) - return 0; - - ecg = EC_KEY_get0_group(ec); - if (ecg == NULL) - return 0; - - curve_nid = EC_GROUP_get_curve_name(ecg); - - if (curve_nid == NID_undef) { - /* TODO(3.0): should we support explicit parameters curves? */ - return 0; - } else { - /* named curve */ - const char *curve_name = NULL; - - if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL) - return 0; - if (!ossl_param_build_set_utf8_string(tmpl, params, - OSSL_PKEY_PARAM_GROUP_NAME, - curve_name)) - - return 0; + switch (operation_id) { + case OSSL_OP_SIGNATURE: + return "SM2"; } - - return 1; + return NULL; } +#endif /* * Callers of key_to_params MUST make sure that domparams_to_params is also @@ -245,7 +234,9 @@ int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl, static void *ec_newdata(void *provctx) { - return EC_KEY_new_with_libctx(PROV_LIBRARY_CONTEXT_OF(provctx), NULL); + if (!ossl_prov_is_running()) + return NULL; + return EC_KEY_new_ex(PROV_LIBCTX_OF(provctx), NULL); } static @@ -260,7 +251,7 @@ int ec_has(void *keydata, int selection) EC_KEY *ec = keydata; int ok = 0; - if (ec != NULL) { + if (ossl_prov_is_running() && ec != NULL) { if ((selection & EC_POSSIBLE_SELECTIONS) != 0) ok = 1; @@ -285,11 +276,19 @@ static int ec_match(const void *keydata1, const void *keydata2, int selection) const EC_KEY *ec2 = keydata2; const EC_GROUP *group_a = EC_KEY_get0_group(ec1); const EC_GROUP *group_b = EC_KEY_get0_group(ec2); + BN_CTX *ctx = NULL; int ok = 1; + if (!ossl_prov_is_running()) + return 0; + + ctx = BN_CTX_new_ex(ec_key_get_libctx(ec1)); + if (ctx == NULL) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) ok = ok && group_a != NULL && group_b != NULL - && EC_GROUP_cmp(group_a, group_b, NULL) == 0; + && EC_GROUP_cmp(group_a, group_b, ctx) == 0; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { const BIGNUM *pa = EC_KEY_get0_private_key(ec1); const BIGNUM *pb = EC_KEY_get0_private_key(ec2); @@ -300,24 +299,27 @@ static int ec_match(const void *keydata1, const void *keydata2, int selection) const EC_POINT *pa = EC_KEY_get0_public_key(ec1); const EC_POINT *pb = EC_KEY_get0_public_key(ec2); - ok = ok && EC_POINT_cmp(group_b, pa, pb, NULL) == 0; + ok = ok && EC_POINT_cmp(group_b, pa, pb, ctx) == 0; } + BN_CTX_free(ctx); return ok; } static -int ec_import(void *keydata, int selection, const OSSL_PARAM params[]) +int common_import(void *keydata, int selection, const OSSL_PARAM params[], + int sm2_curve) { EC_KEY *ec = keydata; + const EC_GROUP *ecg = NULL; int ok = 1; - if (ec == NULL) + if (!ossl_prov_is_running() || ec == NULL) return 0; /* * In this implementation, we can export/import only keydata in the * following combinations: - * - domain parameters only + * - domain parameters (+optional other params) * - public key with associated domain parameters (+optional other params) * - private key with associated public key and domain parameters * (+optional other params) @@ -325,19 +327,25 @@ int ec_import(void *keydata, int selection, const OSSL_PARAM params[]) * This means: * - domain parameters must always be requested * - private key must be requested alongside public key - * - other parameters must be requested only alongside a key + * - other parameters are always optional */ if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0) return 0; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0) return 0; - if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0 - && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) - return 0; if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) - ok = ok && ec_key_domparams_fromdata(ec, params); + ok = ok && ec_group_fromdata(ec, params); + + /* + * sm2_curve: import the keys or domparams only on SM2 Curve + * !sm2_curve: import the keys or domparams only not on SM2 Curve + */ + if ((ecg = EC_KEY_get0_group(ec)) == NULL + || (sm2_curve ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2))) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; @@ -350,23 +358,38 @@ int ec_import(void *keydata, int selection, const OSSL_PARAM params[]) return ok; } +static +int ec_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + return common_import(keydata, selection, params, 0); +} + +#ifndef OPENSSL_NO_SM2 +static +int sm2_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + return common_import(keydata, selection, params, 1); +} +#endif + static int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, void *cbarg) { EC_KEY *ec = keydata; - OSSL_PARAM_BLD *tmpl; + OSSL_PARAM_BLD *tmpl = NULL; OSSL_PARAM *params = NULL; - unsigned char *pub_key = NULL; + unsigned char *pub_key = NULL, *genbuf = NULL; + BN_CTX *bnctx = NULL; int ok = 1; - if (ec == NULL) + if (!ossl_prov_is_running() || ec == NULL) return 0; /* * In this implementation, we can export/import only keydata in the * following combinations: - * - domain parameters only + * - domain parameters (+optional other params) * - public key with associated domain parameters (+optional other params) * - private key with associated public key and domain parameters * (+optional other params) @@ -374,7 +397,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, * This means: * - domain parameters must always be requested * - private key must be requested alongside public key - * - other parameters must be requested only alongside a key + * - other parameters are always optional */ if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0) return 0; @@ -389,8 +412,17 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, if (tmpl == NULL) return 0; - if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) - ok = ok && domparams_to_params(ec, tmpl, NULL); + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { + bnctx = BN_CTX_new_ex(ec_key_get_libctx(ec)); + if (bnctx == NULL) { + ok = 0; + goto end; + } + BN_CTX_start(bnctx); + ok = ok && ec_group_todata(EC_KEY_get0_group(ec), tmpl, NULL, + ec_key_get_libctx(ec), ec_key_get0_propq(ec), + bnctx, &genbuf); + } if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { int include_private = @@ -403,22 +435,35 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, if (ok && (params = OSSL_PARAM_BLD_to_param(tmpl)) != NULL) ok = param_cb(params, cbarg); - +end: OSSL_PARAM_BLD_free_params(params); OSSL_PARAM_BLD_free(tmpl); OPENSSL_free(pub_key); + OPENSSL_free(genbuf); + BN_CTX_end(bnctx); + BN_CTX_free(bnctx); return ok; } /* IMEXPORT = IMPORT + EXPORT */ -# define EC_IMEXPORTABLE_DOM_PARAMETERS \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0) -# define EC_IMEXPORTABLE_PUBLIC_KEY \ +# define EC_IMEXPORTABLE_DOM_PARAMETERS \ + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), \ + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), \ + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), \ + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), \ + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), \ + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), \ + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), \ + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), \ + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), \ + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0) + +# define EC_IMEXPORTABLE_PUBLIC_KEY \ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) -# define EC_IMEXPORTABLE_PRIVATE_KEY \ +# define EC_IMEXPORTABLE_PRIVATE_KEY \ OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) -# define EC_IMEXPORTABLE_OTHER_PARAMETERS \ +# define EC_IMEXPORTABLE_OTHER_PARAMETERS \ OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL) /* @@ -463,25 +508,87 @@ const OSSL_PARAM *ec_export_types(int selection) return ec_imexport_types(selection); } +static int ec_get_ecm_params(const EC_GROUP *group, OSSL_PARAM params[]) +{ +#ifdef OPENSSL_NO_EC2M + return 1; +#else + int ret = 0, m; + unsigned int k1 = 0, k2 = 0, k3 = 0; + int basis_nid; + const char *basis_name = NULL; + int fid = EC_GROUP_get_field_type(group); + + if (fid != NID_X9_62_characteristic_two_field) + return 1; + + basis_nid = EC_GROUP_get_basis_type(group); + if (basis_nid == NID_X9_62_tpBasis) + basis_name = SN_X9_62_tpBasis; + else if (basis_nid == NID_X9_62_ppBasis) + basis_name = SN_X9_62_ppBasis; + else + goto err; + + m = EC_GROUP_get_degree(group); + if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m) + || !ossl_param_build_set_utf8_string(NULL, params, + OSSL_PKEY_PARAM_EC_CHAR2_TYPE, + basis_name)) + goto err; + + if (basis_nid == NID_X9_62_tpBasis) { + if (!EC_GROUP_get_trinomial_basis(group, &k1) + || !ossl_param_build_set_int(NULL, params, + OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, + (int)k1)) + goto err; + } else { + if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3) + || !ossl_param_build_set_int(NULL, params, + OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1) + || !ossl_param_build_set_int(NULL, params, + OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2) + || !ossl_param_build_set_int(NULL, params, + OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3)) + goto err; + } + ret = 1; +err: + return ret; +#endif /* OPENSSL_NO_EC2M */ +} + static -int ec_get_params(void *key, OSSL_PARAM params[]) +int common_get_params(void *key, OSSL_PARAM params[], int sm2) { - int ret; + int ret = 0; EC_KEY *eck = key; const EC_GROUP *ecg = NULL; OSSL_PARAM *p; - unsigned char *pub_key = NULL; + unsigned char *pub_key = NULL, *genbuf = NULL; + OSSL_LIB_CTX *libctx; + const char *propq; + BN_CTX *bnctx = NULL; ecg = EC_KEY_get0_group(eck); if (ecg == NULL) return 0; + libctx = ec_key_get_libctx(eck); + propq = ec_key_get0_propq(eck); + + bnctx = BN_CTX_new_ex(libctx); + if (bnctx == NULL) + return 0; + BN_CTX_start(bnctx); + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL && !OSSL_PARAM_set_int(p, ECDSA_size(eck))) - return 0; + goto err; if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg))) - return 0; + goto err; if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) { int ecbits, sec_bits; @@ -517,50 +624,78 @@ int ec_get_params(void *key, OSSL_PARAM params[]) sec_bits = ecbits / 2; if (!OSSL_PARAM_set_int(p, sec_bits)) - return 0; + goto err; } - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL - && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD)) - return 0; + if (!sm2) { + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL + && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD)) + goto err; + } else { + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL + && !OSSL_PARAM_set_utf8_string(p, SM2_DEFAULT_MD)) + goto err; + } - p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); - if (p != NULL) { - int ecdh_cofactor_mode = 0; + /* SM2 doesn't support this PARAM */ + if (!sm2) { + p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); + if (p != NULL) { + int ecdh_cofactor_mode = 0; - ecdh_cofactor_mode = - (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; + ecdh_cofactor_mode = + (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; - if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode)) - return 0; + if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode)) + goto err; + } } if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) { - BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(key)); - - if (ctx == NULL) - return 0; p->return_size = EC_POINT_point2oct(EC_KEY_get0_group(key), EC_KEY_get0_public_key(key), POINT_CONVERSION_UNCOMPRESSED, - p->data, p->return_size, ctx); - BN_CTX_free(ctx); + p->data, p->return_size, bnctx); if (p->return_size == 0) - return 0; + goto err; } - ret = domparams_to_params(eck, NULL, params) + ret = ec_get_ecm_params(ecg, params) + && ec_group_todata(ecg, NULL, params, libctx, propq, bnctx, &genbuf) && key_to_params(eck, NULL, params, 1, &pub_key) && otherparams_to_params(eck, NULL, params); +err: + OPENSSL_free(genbuf); OPENSSL_free(pub_key); + BN_CTX_end(bnctx); + BN_CTX_free(bnctx); return ret; } +static +int ec_get_params(void *key, OSSL_PARAM params[]) +{ + return common_get_params(key, params, 0); +} + +#ifndef OPENSSL_NO_EC2M +# define EC2M_GETTABLE_DOM_PARAMS \ + OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_M, NULL), \ + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_CHAR2_TYPE, NULL, 0), \ + OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, NULL), \ + OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, NULL), \ + OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, NULL), \ + OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, NULL), +#else +# define EC2M_GETTABLE_DOM_PARAMS +#endif + static const OSSL_PARAM ec_known_gettable_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), EC_IMEXPORTABLE_DOM_PARAMETERS, + EC2M_GETTABLE_DOM_PARAMS EC_IMEXPORTABLE_PUBLIC_KEY, OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), @@ -570,7 +705,7 @@ static const OSSL_PARAM ec_known_gettable_params[] = { }; static -const OSSL_PARAM *ec_gettable_params(void) +const OSSL_PARAM *ec_gettable_params(void *provctx) { return ec_known_gettable_params; } @@ -582,7 +717,7 @@ static const OSSL_PARAM ec_known_settable_params[] = { }; static -const OSSL_PARAM *ec_settable_params(void) +const OSSL_PARAM *ec_settable_params(void *provctx) { return ec_known_settable_params; } @@ -610,14 +745,56 @@ int ec_set_params(void *key, const OSSL_PARAM params[]) return ec_key_otherparams_fromdata(eck, params); } +#ifndef OPENSSL_NO_SM2 +static +int sm2_get_params(void *key, OSSL_PARAM params[]) +{ + return common_get_params(key, params, 1); +} + +static const OSSL_PARAM sm2_known_gettable_params[] = { + OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), + EC_IMEXPORTABLE_DOM_PARAMETERS, + EC_IMEXPORTABLE_PUBLIC_KEY, + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), + EC_IMEXPORTABLE_PRIVATE_KEY, + OSSL_PARAM_END +}; + +static +const OSSL_PARAM *sm2_gettable_params(ossl_unused void *provctx) +{ + return sm2_known_gettable_params; +} + +static const OSSL_PARAM sm2_known_settable_params[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), + OSSL_PARAM_END +}; + +static +const OSSL_PARAM *sm2_settable_params(ossl_unused void *provctx) +{ + return sm2_known_settable_params; +} +#endif + static int ec_validate(void *keydata, int selection) { EC_KEY *eck = keydata; int ok = 0; - BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(eck)); + BN_CTX *ctx = NULL; - if (ctx == NULL) + if (!ossl_prov_is_running()) + return 0; + + ctx = BN_CTX_new_ex(ec_key_get_libctx(eck)); + if (ctx == NULL) return 0; if ((selection & EC_POSSIBLE_SELECTIONS) != 0) @@ -640,35 +817,40 @@ int ec_validate(void *keydata, int selection) } struct ec_gen_ctx { - OPENSSL_CTX *libctx; - EC_GROUP *gen_group; + OSSL_LIB_CTX *libctx; + char *group_name; + char *encoding; + char *field_type; + BIGNUM *p, *a, *b, *order, *cofactor; + unsigned char *gen, *seed; + size_t gen_len, seed_len; int selection; int ecdh_mode; + EC_GROUP *gen_group; }; static void *ec_gen_init(void *provctx, int selection) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); struct ec_gen_ctx *gctx = NULL; - if ((selection & (EC_POSSIBLE_SELECTIONS)) == 0) + if (!ossl_prov_is_running() || (selection & (EC_POSSIBLE_SELECTIONS)) == 0) return NULL; if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { gctx->libctx = libctx; - gctx->gen_group = NULL; gctx->selection = selection; gctx->ecdh_mode = 0; } return gctx; } -static int ec_gen_set_group(void *genctx, int nid) +static int ec_gen_set_group(void *genctx, const EC_GROUP *src) { struct ec_gen_ctx *gctx = genctx; EC_GROUP *group; - group = EC_GROUP_new_by_curve_name_with_libctx(gctx->libctx, NULL, nid); + group = EC_GROUP_dup(src); if (group == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); return 0; @@ -677,58 +859,155 @@ static int ec_gen_set_group(void *genctx, int nid) gctx->gen_group = group; return 1; } + static int ec_gen_set_template(void *genctx, void *templ) { struct ec_gen_ctx *gctx = genctx; EC_KEY *ec = templ; const EC_GROUP *ec_group; - if (gctx == NULL || ec == NULL) + if (!ossl_prov_is_running() || gctx == NULL || ec == NULL) return 0; if ((ec_group = EC_KEY_get0_group(ec)) == NULL) return 0; - return ec_gen_set_group(gctx, EC_GROUP_get_curve_name(ec_group)); + return ec_gen_set_group(gctx, ec_group); +} + +#define COPY_INT_PARAM(params, key, val) \ +p = OSSL_PARAM_locate_const(params, key); \ +if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \ + goto err; + +#define COPY_UTF8_PARAM(params, key, val) \ +p = OSSL_PARAM_locate_const(params, key); \ +if (p != NULL) { \ + if (p->data_type != OSSL_PARAM_UTF8_STRING) \ + goto err; \ + OPENSSL_free(val); \ + val = OPENSSL_strdup(p->data); \ + if (val == NULL) \ + goto err; \ +} + +#define COPY_OCTET_PARAM(params, key, val, len) \ +p = OSSL_PARAM_locate_const(params, key); \ +if (p != NULL) { \ + if (p->data_type != OSSL_PARAM_OCTET_STRING) \ + goto err; \ + OPENSSL_free(val); \ + len = p->data_size; \ + val = OPENSSL_memdup(p->data, p->data_size); \ + if (val == NULL) \ + goto err; \ +} + +#define COPY_BN_PARAM(params, key, bn) \ +p = OSSL_PARAM_locate_const(params, key); \ +if (p != NULL) { \ + if (bn == NULL) \ + bn = BN_new(); \ + if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \ + goto err; \ } static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) { + int ret = 0; struct ec_gen_ctx *gctx = genctx; const OSSL_PARAM *p; + EC_GROUP *group = NULL; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH)) - != NULL) { - if (!OSSL_PARAM_get_int(p, &gctx->ecdh_mode)) - return 0; - } - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME)) - != NULL) { - const char *curve_name = NULL; - int ret = 0; - - switch (p->data_type) { - case OSSL_PARAM_UTF8_STRING: - /* The OSSL_PARAM functions have no support for this */ - curve_name = p->data; - ret = (curve_name != NULL); - break; - case OSSL_PARAM_UTF8_PTR: - ret = OSSL_PARAM_get_utf8_ptr(p, &curve_name); - break; - } + COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode); - if (ret) { - int nid = ec_curve_name2nid(curve_name); + COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name); + COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type); + COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding); - if (nid == NID_undef) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE); - ret = 0; - } else { - ret = ec_gen_set_group(gctx, nid); - } - } - return ret; + COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p); + COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a); + COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b); + COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order); + COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor); + + COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len); + COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen, + gctx->gen_len); + + ret = 1; +err: + EC_GROUP_free(group); + return ret; +} + +static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx) +{ + int ret = 0; + OSSL_PARAM_BLD *bld; + OSSL_PARAM *params = NULL; + EC_GROUP *group = NULL; + + bld = OSSL_PARAM_BLD_new(); + if (bld == NULL) + return 0; + + if (gctx->encoding != NULL + && !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_ENCODING, + gctx->encoding, 0)) + goto err; + + if (gctx->group_name != NULL) { + if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME, + gctx->group_name, 0)) + goto err; + /* Ignore any other parameters if there is a group name */ + goto build; + } else if (gctx->field_type != NULL) { + if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE, + gctx->field_type, 0)) + goto err; + } else { + goto err; } - return 1; + if (gctx->p == NULL + || gctx->a == NULL + || gctx->b == NULL + || gctx->order == NULL + || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, gctx->p) + || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, gctx->a) + || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, gctx->b) + || !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, gctx->order)) + goto err; + + if (gctx->cofactor != NULL + && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, + gctx->cofactor)) + goto err; + + if (gctx->seed != NULL + && !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_SEED, + gctx->seed, gctx->seed_len)) + goto err; + + if (gctx->gen == NULL + || !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR, + gctx->gen, gctx->gen_len)) + goto err; +build: + params = OSSL_PARAM_BLD_to_param(bld); + if (params == NULL) + goto err; + group = EC_GROUP_new_from_params(params, gctx->libctx, NULL); + if (group == NULL) + goto err; + + EC_GROUP_free(gctx->gen_group); + gctx->gen_group = group; + + ret = 1; +err: + OSSL_PARAM_BLD_free_params(params); + OSSL_PARAM_BLD_free(bld); + return ret; } static const OSSL_PARAM *ec_gen_settable_params(void *provctx) @@ -736,6 +1015,15 @@ static const OSSL_PARAM *ec_gen_settable_params(void *provctx) static OSSL_PARAM settable[] = { OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), + OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), OSSL_PARAM_END }; @@ -758,14 +1046,28 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { struct ec_gen_ctx *gctx = genctx; EC_KEY *ec = NULL; - int ret = 1; /* Start optimistically */ + int ret = 0; - if (gctx == NULL - || (ec = EC_KEY_new_with_libctx(gctx->libctx, NULL)) == NULL) + if (!ossl_prov_is_running() + || gctx == NULL + || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL) return NULL; + if (gctx->gen_group == NULL) { + if (!ec_gen_set_group_from_params(gctx)) + goto err; + } else { + if (gctx->encoding) { + int flags = ec_encoding_name2id(gctx->encoding); + if (flags < 0) + goto err; + EC_GROUP_set_asn1_flag(gctx->gen_group, flags); + } + } + /* We must always assign a group, no matter what */ ret = ec_gen_assign_group(ec, gctx->gen_group); + /* Whether you want it or not, you get a keypair, not just one half */ if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) ret = ret && EC_KEY_generate_key(ec); @@ -775,11 +1077,59 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) if (ret) return ec; +err: + /* Something went wrong, throw the key away */ + EC_KEY_free(ec); + return NULL; +} + +#ifndef OPENSSL_NO_SM2 +/* + * The callback arguments (osslcb & cbarg) are not used by EC_KEY generation + */ +static void *sm2_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) +{ + struct ec_gen_ctx *gctx = genctx; + EC_KEY *ec = NULL; + int ret = 1; + + if (gctx == NULL + || (ec = EC_KEY_new_ex(gctx->libctx, NULL)) == NULL) + return NULL; + + if (gctx->gen_group == NULL) { + if (!ec_gen_set_group_from_params(gctx)) + goto err; + } else { + if (gctx->encoding) { + int flags = ec_encoding_name2id(gctx->encoding); + if (flags < 0) + goto err; + EC_GROUP_set_asn1_flag(gctx->gen_group, flags); + } + } + + /* We must always assign a group, no matter what */ + ret = ec_gen_assign_group(ec, gctx->gen_group); + /* Whether you want it or not, you get a keypair, not just one half */ + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { + /* + * For SM2, we need a new flag to indicate the 'generate' function + * to use a new range + */ + EC_KEY_set_flags(ec, EC_FLAG_SM2_RANGE); + ret = ret && EC_KEY_generate_key(ec); + } + + if (ret) + return ec; +err: /* Something went wrong, throw the key away */ EC_KEY_free(ec); return NULL; } +#endif static void ec_gen_cleanup(void *genctx) { @@ -789,6 +1139,16 @@ static void ec_gen_cleanup(void *genctx) return; EC_GROUP_free(gctx->gen_group); + BN_free(gctx->p); + BN_free(gctx->a); + BN_free(gctx->b); + BN_free(gctx->order); + BN_free(gctx->cofactor); + OPENSSL_free(gctx->group_name); + OPENSSL_free(gctx->field_type);; + OPENSSL_free(gctx->encoding); + OPENSSL_free(gctx->seed); + OPENSSL_free(gctx->gen); OPENSSL_free(gctx); } @@ -796,7 +1156,7 @@ void *ec_load(const void *reference, size_t reference_sz) { EC_KEY *ec = NULL; - if (reference_sz == sizeof(ec)) { + if (ossl_prov_is_running() && reference_sz == sizeof(ec)) { /* The contents of the reference is the address to our object */ ec = *(EC_KEY **)reference; /* We grabbed, so we detach it */ @@ -806,7 +1166,7 @@ void *ec_load(const void *reference, size_t reference_sz) return NULL; } -const OSSL_DISPATCH ec_keymgmt_functions[] = { +const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, @@ -833,3 +1193,32 @@ const OSSL_DISPATCH ec_keymgmt_functions[] = { (void (*)(void))ec_query_operation_name }, { 0, NULL } }; + +#ifndef OPENSSL_NO_SM2 +const OSSL_DISPATCH sm2_keymgmt_functions[] = { + { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, + { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, + { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, + (void (*)(void))ec_gen_set_template }, + { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params }, + { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, + (void (*)(void))ec_gen_settable_params }, + { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))sm2_gen }, + { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, + { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata }, + { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))sm2_get_params }, + { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))sm2_gettable_params }, + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))ec_set_params }, + { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))sm2_settable_params }, + { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has }, + { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match }, + { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))ec_validate }, + { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sm2_import }, + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types }, + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export }, + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types }, + { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, + (void (*)(void))sm2_query_operation_name }, + { 0, NULL } +}; +#endif diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index a1e1edbf5a..f4e59b3322 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -68,7 +68,8 @@ static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types; #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR) struct ecx_gen_ctx { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; + char *propq; ECX_KEY_TYPE type; int selection; }; @@ -82,22 +83,34 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx); static void *x25519_new_key(void *provctx) { - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X25519, 0); + if (!ossl_prov_is_running()) + return 0; + return ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0, + NULL); } static void *x448_new_key(void *provctx) { - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X448, 0); + if (!ossl_prov_is_running()) + return 0; + return ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X448, 0, + NULL); } static void *ed25519_new_key(void *provctx) { - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED25519, 0); + if (!ossl_prov_is_running()) + return 0; + return ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED25519, 0, + NULL); } static void *ed448_new_key(void *provctx) { - return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED448, 0); + if (!ossl_prov_is_running()) + return 0; + return ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED448, 0, + NULL); } static int ecx_has(void *keydata, int selection) @@ -105,7 +118,7 @@ static int ecx_has(void *keydata, int selection) ECX_KEY *key = keydata; int ok = 0; - if (key != NULL) { + if (ossl_prov_is_running() && key != NULL) { /* * ECX keys always have all the parameters they need (i.e. none). * Therefore we always return with 1, if asked about parameters. @@ -127,6 +140,9 @@ static int ecx_match(const void *keydata1, const void *keydata2, int selection) const ECX_KEY *key2 = keydata2; int ok = 1; + if (!ossl_prov_is_running()) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) ok = ok && key1->type == key2->type; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { @@ -157,7 +173,7 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[]) int ok = 1; int include_private = 0; - if (key == NULL) + if (!ossl_prov_is_running() || key == NULL) return 0; if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) @@ -197,7 +213,7 @@ static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, OSSL_PARAM *params = NULL; int ret = 0; - if (key == NULL) + if (!ossl_prov_is_running() || key == NULL) return 0; tmpl = OSSL_PARAM_BLD_new(); @@ -314,26 +330,40 @@ static const OSSL_PARAM ed_gettable_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *x25519_gettable_params(void) +static const OSSL_PARAM *x25519_gettable_params(void *provctx) { return ecx_gettable_params; } -static const OSSL_PARAM *x448_gettable_params(void) +static const OSSL_PARAM *x448_gettable_params(void *provctx) { return ecx_gettable_params; } -static const OSSL_PARAM *ed25519_gettable_params(void) +static const OSSL_PARAM *ed25519_gettable_params(void *provctx) { return ed_gettable_params; } -static const OSSL_PARAM *ed448_gettable_params(void) +static const OSSL_PARAM *ed448_gettable_params(void *provctx) { return ed_gettable_params; } +static int set_property_query(ECX_KEY *ecxkey, const char *propq) +{ + OPENSSL_free(ecxkey->propq); + ecxkey->propq = NULL; + if (propq != NULL) { + ecxkey->propq = OPENSSL_strdup(propq); + if (ecxkey->propq == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + static int ecx_set_params(void *key, const OSSL_PARAM params[]) { ECX_KEY *ecxkey = key; @@ -351,6 +381,12 @@ static int ecx_set_params(void *key, const OSSL_PARAM params[]) ecxkey->privkey = NULL; ecxkey->haspubkey = 1; } + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING + || !set_property_query(ecxkey, p->data)) + return 0; + } return 1; } @@ -377,6 +413,7 @@ static int ed448_set_params(void *key, const OSSL_PARAM params[]) static const OSSL_PARAM ecx_settable_params[] = { OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END }; @@ -384,32 +421,35 @@ static const OSSL_PARAM ed_settable_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *x25519_settable_params(void) +static const OSSL_PARAM *x25519_settable_params(void *provctx) { return ecx_settable_params; } -static const OSSL_PARAM *x448_settable_params(void) +static const OSSL_PARAM *x448_settable_params(void *provctx) { return ecx_settable_params; } -static const OSSL_PARAM *ed25519_settable_params(void) +static const OSSL_PARAM *ed25519_settable_params(void *provctx) { return ed_settable_params; } -static const OSSL_PARAM *ed448_settable_params(void) +static const OSSL_PARAM *ed448_settable_params(void *provctx) { return ed_settable_params; } static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); struct ecx_gen_ctx *gctx = NULL; - if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) { + if (!ossl_prov_is_running()) + return NULL; + + if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { gctx->libctx = libctx; gctx->type = type; gctx->selection = selection; @@ -472,6 +512,15 @@ static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[]) return 0; } } + p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + OPENSSL_free(gctx->propq); + gctx->propq = OPENSSL_strdup(p->data); + if (gctx->propq == NULL) + return 0; + } return 1; } @@ -480,6 +529,7 @@ static const OSSL_PARAM *ecx_gen_settable_params(void *provctx) { static OSSL_PARAM settable[] = { OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END }; return settable; @@ -492,7 +542,7 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx) if (gctx == NULL) return NULL; - if ((key = ecx_key_new(gctx->libctx, gctx->type, 0)) == NULL) { + if ((key = ecx_key_new(gctx->libctx, gctx->type, 0, gctx->propq)) == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; } @@ -520,11 +570,13 @@ static void *ecx_gen(struct ecx_gen_ctx *gctx) X448_public_from_private(key->pubkey, privkey); break; case ECX_KEY_TYPE_ED25519: - if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey)) + if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey, + gctx->propq)) goto err; break; case ECX_KEY_TYPE_ED448: - if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey)) + if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey, + gctx->propq)) goto err; break; } @@ -539,6 +591,9 @@ static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { struct ecx_gen_ctx *gctx = genctx; + if (!ossl_prov_is_running()) + return 0; + #ifdef S390X_EC_ASM if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) return s390x_ecx_keygen25519(gctx); @@ -550,6 +605,9 @@ static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { struct ecx_gen_ctx *gctx = genctx; + if (!ossl_prov_is_running()) + return 0; + #ifdef S390X_EC_ASM if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) return s390x_ecx_keygen448(gctx); @@ -560,6 +618,10 @@ static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { struct ecx_gen_ctx *gctx = genctx; + + if (!ossl_prov_is_running()) + return 0; + #ifdef S390X_EC_ASM if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519) && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519) @@ -574,6 +636,9 @@ static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) { struct ecx_gen_ctx *gctx = genctx; + if (!ossl_prov_is_running()) + return 0; + #ifdef S390X_EC_ASM if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448) && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448) @@ -587,6 +652,7 @@ static void ecx_gen_cleanup(void *genctx) { struct ecx_gen_ctx *gctx = genctx; + OPENSSL_free(gctx->propq); OPENSSL_free(gctx); } @@ -594,7 +660,7 @@ void *ecx_load(const void *reference, size_t reference_sz) { ECX_KEY *key = NULL; - if (reference_sz == sizeof(key)) { + if (ossl_prov_is_running() && reference_sz == sizeof(key)) { /* The contents of the reference is the address to our object */ key = *(ECX_KEY **)reference; /* We grabbed, so we detach it */ @@ -605,7 +671,7 @@ void *ecx_load(const void *reference, size_t reference_sz) } #define MAKE_KEYMGMT_FUNCTIONS(alg) \ - const OSSL_DISPATCH alg##_keymgmt_functions[] = { \ + const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \ @@ -643,7 +709,7 @@ static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -688,7 +754,7 @@ static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; if (key == NULL) { @@ -736,7 +802,7 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, }; unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH]; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; unsigned int sz; EVP_MD *sha = NULL; @@ -762,7 +828,7 @@ static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx) if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0) goto err; - sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL); + sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq); if (sha == NULL) goto err; j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL); @@ -803,7 +869,7 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00 }; unsigned char x_dst[57], buff[114]; - ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1); + ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1, gctx->propq); unsigned char *privkey = NULL, *pubkey; EVP_MD_CTX *hashctx = NULL; EVP_MD *shake = NULL; @@ -825,7 +891,7 @@ static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx) goto err; } - shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL); + shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq); if (shake == NULL) goto err; if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0) diff --git a/providers/implementations/keymgmt/kdf_legacy_kmgmt.c b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c new file mode 100644 index 0000000000..f7f8f479af --- /dev/null +++ b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c @@ -0,0 +1,104 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * This implemments a dummy key manager for legacy KDFs that still support the + * old way of performing a KDF via EVP_PKEY_derive(). New KDFs should not be + * implemented this way. In reality there is no key data for such KDFs, so this + * key manager does very little. + */ + +#include +#include +#include +#include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/provider_ctx.h" +#include "prov/kdfexchange.h" + +static OSSL_FUNC_keymgmt_new_fn kdf_newdata; +static OSSL_FUNC_keymgmt_free_fn kdf_freedata; +static OSSL_FUNC_keymgmt_has_fn kdf_has; + +KDF_DATA *kdf_data_new(void *provctx) +{ + KDF_DATA *kdfdata; + + if (!ossl_prov_is_running()) + return NULL; + + kdfdata = OPENSSL_zalloc(sizeof(*kdfdata)); + if (kdfdata == NULL) + return NULL; + + kdfdata->lock = CRYPTO_THREAD_lock_new(); + if (kdfdata->lock == NULL) { + OPENSSL_free(kdfdata); + return NULL; + } + kdfdata->libctx = PROV_LIBCTX_OF(provctx); + kdfdata->refcnt = 1; + + return kdfdata; +} + +void kdf_data_free(KDF_DATA *kdfdata) +{ + int ref = 0; + + if (kdfdata == NULL) + return; + + CRYPTO_DOWN_REF(&kdfdata->refcnt, &ref, kdfdata->lock); + if (ref > 0) + return; + + CRYPTO_THREAD_lock_free(kdfdata->lock); + OPENSSL_free(kdfdata); +} + +int kdf_data_up_ref(KDF_DATA *kdfdata) +{ + int ref = 0; + + /* This is effectively doing a new operation on the KDF_DATA and should be + * adequately guarded again modules' error states. However, both current + * calls here are guarded propery in exchange/kdf_exch.c. Thus, it + * could be removed here. The concern is that something in the future + * might call this function without adequate guards. It's a cheap call, + * it seems best to leave it even though it is currently redundant. + */ + if (!ossl_prov_is_running()) + return 0; + + CRYPTO_UP_REF(&kdfdata->refcnt, &ref, kdfdata->lock); + return 1; +} + +static void *kdf_newdata(void *provctx) +{ + return kdf_data_new(provctx); +} + +static void kdf_freedata(void *kdfdata) +{ + kdf_data_free(kdfdata); +} + +static int kdf_has(void *keydata, int selection) +{ + return 0; +} + +const OSSL_DISPATCH ossl_kdf_keymgmt_functions[] = { + { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))kdf_newdata }, + { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))kdf_freedata }, + { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))kdf_has }, + { 0, NULL } +}; diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c new file mode 100644 index 0000000000..969b266c68 --- /dev/null +++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c @@ -0,0 +1,543 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include +#include +#include +#include +#include +#include +#include "openssl/param_build.h" +#include "internal/param_build_set.h" +#include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/provider_ctx.h" +#include "prov/macsignature.h" +#include "e_os.h" /* strcasecmp */ + +static OSSL_FUNC_keymgmt_new_fn mac_new; +static OSSL_FUNC_keymgmt_free_fn mac_free; +static OSSL_FUNC_keymgmt_gen_init_fn mac_gen_init; +static OSSL_FUNC_keymgmt_gen_fn mac_gen; +static OSSL_FUNC_keymgmt_gen_cleanup_fn mac_gen_cleanup; +static OSSL_FUNC_keymgmt_gen_set_params_fn mac_gen_set_params; +static OSSL_FUNC_keymgmt_gen_settable_params_fn mac_gen_settable_params; +static OSSL_FUNC_keymgmt_get_params_fn mac_get_params; +static OSSL_FUNC_keymgmt_gettable_params_fn mac_gettable_params; +static OSSL_FUNC_keymgmt_set_params_fn mac_set_params; +static OSSL_FUNC_keymgmt_settable_params_fn mac_settable_params; +static OSSL_FUNC_keymgmt_has_fn mac_has; +static OSSL_FUNC_keymgmt_match_fn mac_match; +static OSSL_FUNC_keymgmt_import_fn mac_import; +static OSSL_FUNC_keymgmt_import_types_fn mac_imexport_types; +static OSSL_FUNC_keymgmt_export_fn mac_export; +static OSSL_FUNC_keymgmt_export_types_fn mac_imexport_types; + +static OSSL_FUNC_keymgmt_new_fn mac_new_cmac; +static OSSL_FUNC_keymgmt_gettable_params_fn cmac_gettable_params; +static OSSL_FUNC_keymgmt_import_types_fn cmac_imexport_types; +static OSSL_FUNC_keymgmt_export_types_fn cmac_imexport_types; +static OSSL_FUNC_keymgmt_gen_set_params_fn cmac_gen_set_params; +static OSSL_FUNC_keymgmt_gen_settable_params_fn cmac_gen_settable_params; + +struct mac_gen_ctx { + OSSL_LIB_CTX *libctx; + int selection; + unsigned char *priv_key; + size_t priv_key_len; + PROV_CIPHER cipher; +}; + +MAC_KEY *mac_key_new(OSSL_LIB_CTX *libctx, int cmac) +{ + MAC_KEY *mackey; + + if (!ossl_prov_is_running()) + return NULL; + + mackey = OPENSSL_zalloc(sizeof(*mackey)); + if (mackey == NULL) + return NULL; + + mackey->lock = CRYPTO_THREAD_lock_new(); + if (mackey->lock == NULL) { + OPENSSL_free(mackey); + return NULL; + } + mackey->libctx = libctx; + mackey->refcnt = 1; + mackey->cmac = cmac; + + return mackey; +} + +void mac_key_free(MAC_KEY *mackey) +{ + int ref = 0; + + if (mackey == NULL) + return; + + CRYPTO_DOWN_REF(&mackey->refcnt, &ref, mackey->lock); + if (ref > 0) + return; + + OPENSSL_secure_clear_free(mackey->priv_key, mackey->priv_key_len); + OPENSSL_free(mackey->properties); + ossl_prov_cipher_reset(&mackey->cipher); + CRYPTO_THREAD_lock_free(mackey->lock); + OPENSSL_free(mackey); +} + +int mac_key_up_ref(MAC_KEY *mackey) +{ + int ref = 0; + + /* This is effectively doing a new operation on the MAC_KEY and should be + * adequately guarded again modules' error states. However, both current + * calls here are guarded propery in signature/mac_legacy.c. Thus, it + * could be removed here. The concern is that something in the future + * might call this function without adequate guards. It's a cheap call, + * it seems best to leave it even though it is currently redundant. + */ + if (!ossl_prov_is_running()) + return 0; + + CRYPTO_UP_REF(&mackey->refcnt, &ref, mackey->lock); + return 1; +} + +static void *mac_new(void *provctx) +{ + return mac_key_new(PROV_LIBCTX_OF(provctx), 0); +} + +static void *mac_new_cmac(void *provctx) +{ + return mac_key_new(PROV_LIBCTX_OF(provctx), 1); +} + +static void mac_free(void *mackey) +{ + mac_key_free(mackey); +} + +static int mac_has(void *keydata, int selection) +{ + MAC_KEY *key = keydata; + int ok = 0; + + if (ossl_prov_is_running() && key != NULL) { + /* + * MAC keys always have all the parameters they need (i.e. none). + * Therefore we always return with 1, if asked about parameters. + * Similarly for public keys. + */ + ok = 1; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + ok = key->priv_key != NULL; + } + return ok; +} + +static int mac_match(const void *keydata1, const void *keydata2, int selection) +{ + const MAC_KEY *key1 = keydata1; + const MAC_KEY *key2 = keydata2; + int ok = 1; + + if (!ossl_prov_is_running()) + return 0; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if ((key1->priv_key == NULL && key2->priv_key != NULL) + || (key1->priv_key != NULL && key2->priv_key == NULL) + || key1->priv_key_len != key2->priv_key_len + || (key1->cipher.cipher == NULL && key2->cipher.cipher != NULL) + || (key1->cipher.cipher != NULL && key2->cipher.cipher == NULL)) + ok = 0; + else + ok = ok && (key1->priv_key == NULL /* implies key2->privkey == NULL */ + || CRYPTO_memcmp(key1->priv_key, key2->priv_key, + key1->priv_key_len) == 0); + if (key1->cipher.cipher != NULL) + ok = ok && EVP_CIPHER_is_a(key1->cipher.cipher, + EVP_CIPHER_name(key2->cipher.cipher)); + } + return ok; +} + +static int mac_key_fromdata(MAC_KEY *key, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + OPENSSL_secure_clear_free(key->priv_key, key->priv_key_len); + key->priv_key = OPENSSL_secure_malloc(p->data_size); + if (key->priv_key == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(key->priv_key, p->data, p->data_size); + key->priv_key_len = p->data_size; + } + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + OPENSSL_free(key->properties); + key->properties = OPENSSL_strdup(p->data); + if (key->properties == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (key->cmac && !ossl_prov_cipher_load_from_params(&key->cipher, params, + key->libctx)) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + if (key->priv_key != NULL) + return 1; + + return 0; +} + +static int mac_import(void *keydata, int selection, const OSSL_PARAM params[]) +{ + MAC_KEY *key = keydata; + + if (!ossl_prov_is_running() || key == NULL) + return 0; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) == 0) + return 0; + + return mac_key_fromdata(key, params); +} + +static int key_to_params(MAC_KEY *key, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[]) +{ + if (key == NULL) + return 0; + + if (key->priv_key != NULL + && !ossl_param_build_set_octet_string(tmpl, params, + OSSL_PKEY_PARAM_PRIV_KEY, + key->priv_key, key->priv_key_len)) + return 0; + + if (key->cipher.cipher != NULL + && !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_CIPHER, + EVP_CIPHER_name(key->cipher.cipher))) + return 0; + +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (key->cipher.engine != NULL + && !ossl_param_build_set_utf8_string(tmpl, params, + OSSL_PKEY_PARAM_ENGINE, + ENGINE_get_id(key->cipher.engine))) + return 0; +#endif + + return 1; +} + +static int mac_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, + void *cbarg) +{ + MAC_KEY *key = keydata; + OSSL_PARAM_BLD *tmpl; + OSSL_PARAM *params = NULL; + int ret = 0; + + if (!ossl_prov_is_running() || key == NULL) + return 0; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL) + return 0; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 + && !key_to_params(key, tmpl, NULL)) + goto err; + + params = OSSL_PARAM_BLD_to_param(tmpl); + if (params == NULL) + goto err; + + ret = param_cb(params, cbarg); + OSSL_PARAM_BLD_free_params(params); +err: + OSSL_PARAM_BLD_free(tmpl); + return ret; +} + +static const OSSL_PARAM mac_key_types[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END +}; +static const OSSL_PARAM *mac_imexport_types(int selection) +{ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + return mac_key_types; + return NULL; +} + +static const OSSL_PARAM cmac_key_types[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END +}; +static const OSSL_PARAM *cmac_imexport_types(int selection) +{ + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + return cmac_key_types; + return NULL; +} + +static int mac_get_params(void *key, OSSL_PARAM params[]) +{ + return key_to_params(key, NULL, params); +} + +static const OSSL_PARAM *mac_gettable_params(void *provctx) +{ + static const OSSL_PARAM gettable_params[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_END + }; + return gettable_params; +} + +static const OSSL_PARAM *cmac_gettable_params(void *provctx) +{ + static const OSSL_PARAM gettable_params[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_ENGINE, NULL, 0), + OSSL_PARAM_END + }; + return gettable_params; +} + +static int mac_set_params(void *keydata, const OSSL_PARAM params[]) +{ + MAC_KEY *key = keydata; + const OSSL_PARAM *p; + + if (key == NULL) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + if (p != NULL) + return mac_key_fromdata(key, params); + + return 1; +} + +static const OSSL_PARAM *mac_settable_params(void *provctx) +{ + static const OSSL_PARAM settable_params[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_END + }; + return settable_params; +} + +static void *mac_gen_init(void *provctx, int selection) +{ + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); + struct mac_gen_ctx *gctx = NULL; + + if (!ossl_prov_is_running()) + return NULL; + + if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { + gctx->libctx = libctx; + gctx->selection = selection; + } + return gctx; +} + +static int mac_gen_set_params(void *genctx, const OSSL_PARAM params[]) +{ + struct mac_gen_ctx *gctx = genctx; + const OSSL_PARAM *p; + + if (gctx == NULL) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + if (p != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + gctx->priv_key = OPENSSL_secure_malloc(p->data_size); + if (gctx->priv_key == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(gctx->priv_key, p->data, p->data_size); + gctx->priv_key_len = p->data_size; + } + + return 1; +} + +static int cmac_gen_set_params(void *genctx, const OSSL_PARAM params[]) +{ + struct mac_gen_ctx *gctx = genctx; + + if (!mac_gen_set_params(genctx, params)) + return 0; + + if (!ossl_prov_cipher_load_from_params(&gctx->cipher, params, + gctx->libctx)) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + return 1; +} + +static const OSSL_PARAM *mac_gen_settable_params(void *provctx) +{ + static OSSL_PARAM settable[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_END + }; + return settable; +} + +static const OSSL_PARAM *cmac_gen_settable_params(void *provctx) +{ + static OSSL_PARAM settable[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_CIPHER, NULL, 0), + OSSL_PARAM_END + }; + return settable; +} + +static void *mac_gen(void *genctx, OSSL_CALLBACK *cb, void *cbarg) +{ + struct mac_gen_ctx *gctx = genctx; + MAC_KEY *key; + + if (!ossl_prov_is_running() || gctx == NULL) + return NULL; + + if ((key = mac_key_new(gctx->libctx, 0)) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* If we're doing parameter generation then we just return a blank key */ + if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) + return key; + + if (gctx->priv_key == NULL) { + ERR_raise(ERR_LIB_PROV, EVP_R_INVALID_KEY); + mac_key_free(key); + return NULL; + } + + /* + * This is horrible but required for backwards compatibility. We don't + * actually do real key generation at all. We simply copy the key that was + * previously set in the gctx. Hopefully at some point in the future all + * of this can be removed and we will only support the EVP_KDF APIs. + */ + if (!ossl_prov_cipher_copy(&key->cipher, &gctx->cipher)) { + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); + return NULL; + } + ossl_prov_cipher_reset(&gctx->cipher); + key->priv_key = gctx->priv_key; + key->priv_key_len = gctx->priv_key_len; + gctx->priv_key_len = 0; + gctx->priv_key = NULL; + + return key; +} + +static void mac_gen_cleanup(void *genctx) +{ + struct mac_gen_ctx *gctx = genctx; + + OPENSSL_secure_clear_free(gctx->priv_key, gctx->priv_key_len); + ossl_prov_cipher_reset(&gctx->cipher); + OPENSSL_free(gctx); +} + +const OSSL_DISPATCH ossl_mac_legacy_keymgmt_functions[] = { + { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new }, + { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free }, + { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params }, + { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))mac_gettable_params }, + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params }, + { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params }, + { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has }, + { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match }, + { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import }, + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))mac_imexport_types }, + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export }, + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))mac_imexport_types }, + { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))mac_gen_init }, + { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))mac_gen_set_params }, + { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, + (void (*)(void))mac_gen_settable_params }, + { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen }, + { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup }, + { 0, NULL } +}; + +const OSSL_DISPATCH ossl_cossl_mac_legacy_keymgmt_functions[] = { + { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))mac_new_cmac }, + { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))mac_free }, + { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))mac_get_params }, + { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))cmac_gettable_params }, + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))mac_set_params }, + { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))mac_settable_params }, + { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))mac_has }, + { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))mac_match }, + { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))mac_import }, + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))cmac_imexport_types }, + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))mac_export }, + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))cmac_imexport_types }, + { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))mac_gen_init }, + { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))cmac_gen_set_params }, + { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, + (void (*)(void))cmac_gen_settable_params }, + { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))mac_gen }, + { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))mac_gen_cleanup }, + { 0, NULL } +}; + diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 7ed280e861..8c45758ff7 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -46,7 +46,7 @@ static OSSL_FUNC_keymgmt_import_fn rsa_import; static OSSL_FUNC_keymgmt_import_types_fn rsa_import_types; static OSSL_FUNC_keymgmt_export_fn rsa_export; static OSSL_FUNC_keymgmt_export_types_fn rsa_export_types; -static OSSL_FUNC_keymgmt_query_operation_name_fn rsapss_query_operation_name; +static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_query_operation_name; #define RSA_DEFAULT_MD "SHA256" #define RSA_PSS_DEFAULT_MD OSSL_DIGEST_NAME_SHA1 @@ -58,14 +58,14 @@ DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) static int pss_params_fromdata(RSA_PSS_PARAMS_30 *pss_params, const OSSL_PARAM params[], int rsa_type, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { - if (!rsa_pss_params_30_fromdata(pss_params, params, libctx)) + if (!ossl_rsa_pss_params_30_fromdata(pss_params, params, libctx)) return 0; /* If not a PSS type RSA, sending us PSS parameters is wrong */ if (rsa_type != RSA_FLAG_TYPE_RSASSAPSS - && !rsa_pss_params_30_is_unrestricted(pss_params)) + && !ossl_rsa_pss_params_30_is_unrestricted(pss_params)) return 0; return 1; @@ -73,9 +73,13 @@ static int pss_params_fromdata(RSA_PSS_PARAMS_30 *pss_params, static void *rsa_newdata(void *provctx) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); - RSA *rsa = rsa_new_with_ctx(libctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); + RSA *rsa; + if (!ossl_prov_is_running()) + return NULL; + + rsa = ossl_rsa_new_with_ctx(libctx); if (rsa != NULL) { RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); @@ -85,9 +89,13 @@ static void *rsa_newdata(void *provctx) static void *rsapss_newdata(void *provctx) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); - RSA *rsa = rsa_new_with_ctx(libctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); + RSA *rsa; + + if (!ossl_prov_is_running()) + return NULL; + rsa = ossl_rsa_new_with_ctx(libctx); if (rsa != NULL) { RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); @@ -105,7 +113,7 @@ static int rsa_has(void *keydata, int selection) RSA *rsa = keydata; int ok = 0; - if (rsa != NULL) { + if (rsa != NULL && ossl_prov_is_running()) { if ((selection & RSA_POSSIBLE_SELECTIONS) != 0) ok = 1; @@ -128,6 +136,9 @@ static int rsa_match(const void *keydata1, const void *keydata2, int selection) const RSA *rsa2 = keydata2; int ok = 1; + if (!ossl_prov_is_running()) + return 0; + /* There is always an |e| */ ok = ok && BN_cmp(RSA_get0_e(rsa1), RSA_get0_e(rsa2)) == 0; if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) @@ -143,7 +154,7 @@ static int rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) int rsa_type; int ok = 1; - if (rsa == NULL) + if (!ossl_prov_is_running() || rsa == NULL) return 0; if ((selection & RSA_POSSIBLE_SELECTIONS) == 0) @@ -154,10 +165,10 @@ static int rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) /* TODO(3.0) OAEP should bring on parameters as well */ if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) - ok = ok && pss_params_fromdata(rsa_get0_pss_params_30(rsa), params, - rsa_type, rsa_get0_libctx(rsa)); + ok = ok && pss_params_fromdata(ossl_rsa_get0_pss_params_30(rsa), params, + rsa_type, ossl_rsa_get0_libctx(rsa)); if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) - ok = ok && rsa_fromdata(rsa, params); + ok = ok && ossl_rsa_fromdata(rsa, params); return ok; } @@ -166,12 +177,12 @@ static int rsa_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { RSA *rsa = keydata; - const RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa); + const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa); OSSL_PARAM_BLD *tmpl; OSSL_PARAM *params = NULL; int ok = 1; - if (rsa == NULL) + if (!ossl_prov_is_running() || rsa == NULL) return 0; /* TODO(3.0) OAEP should bring on parameters */ @@ -181,10 +192,10 @@ static int rsa_export(void *keydata, int selection, return 0; if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) - ok = ok && (rsa_pss_params_30_is_unrestricted(pss_params) - || rsa_pss_params_30_todata(pss_params, NULL, tmpl, NULL)); + ok = ok && (ossl_rsa_pss_params_30_is_unrestricted(pss_params) + || ossl_rsa_pss_params_30_todata(pss_params, tmpl, NULL)); if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) - ok = ok && rsa_todata(rsa, tmpl, NULL); + ok = ok && ossl_rsa_todata(rsa, tmpl, NULL); if (!ok || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) @@ -286,7 +297,7 @@ static const OSSL_PARAM *rsa_export_types(int selection) static int rsa_get_params(void *key, OSSL_PARAM params[]) { RSA *rsa = key; - const RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa); + const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa); int rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK); OSSL_PARAM *p; @@ -319,17 +330,17 @@ static int rsa_get_params(void *key, OSSL_PARAM params[]) && rsa_type == RSA_FLAG_TYPE_RSASSAPSS) { const char *mdname = RSA_PSS_DEFAULT_MD; - if (!rsa_pss_params_30_is_unrestricted(pss_params)) { + if (!ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { mdname = - rsa_oaeppss_nid2name(rsa_pss_params_30_hashalg(pss_params)); + ossl_rsa_oaeppss_nid2name(ossl_rsa_pss_params_30_hashalg(pss_params)); if (mdname == NULL || !OSSL_PARAM_set_utf8_string(p, mdname)) return 0; } } return (rsa_type != RSA_FLAG_TYPE_RSASSAPSS - || rsa_pss_params_30_todata(pss_params, NULL, NULL, params)) - && rsa_todata(rsa, NULL, params); + || ossl_rsa_pss_params_30_todata(pss_params, NULL, params)) + && ossl_rsa_todata(rsa, NULL, params); } static const OSSL_PARAM rsa_params[] = { @@ -341,7 +352,7 @@ static const OSSL_PARAM rsa_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_gettable_params(void) +static const OSSL_PARAM *rsa_gettable_params(void *provctx) { return rsa_params; } @@ -351,24 +362,28 @@ static int rsa_validate(void *keydata, int selection) RSA *rsa = keydata; int ok = 0; + if (!ossl_prov_is_running()) + return 0; + if ((selection & RSA_POSSIBLE_SELECTIONS) != 0) ok = 1; /* If the whole key is selected, we do a pairwise validation */ if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR) { - ok = ok && rsa_validate_pairwise(rsa); + ok = ok && ossl_rsa_validate_pairwise(rsa); } else { if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) - ok = ok && rsa_validate_private(rsa); + ok = ok && ossl_rsa_validate_private(rsa); if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) - ok = ok && rsa_validate_public(rsa); + ok = ok && ossl_rsa_validate_public(rsa); } return ok; } struct rsa_gen_ctx { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; + const char *propq; int rsa_type; @@ -401,9 +416,12 @@ static int rsa_gencb(int p, int n, BN_GENCB *cb) static void *gen_init(void *provctx, int selection, int rsa_type) { - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); struct rsa_gen_ctx *gctx = NULL; + if (!ossl_prov_is_running()) + return NULL; + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) return NULL; @@ -471,11 +489,12 @@ static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0) /* - * The following must be kept in sync with rsa_pss_params_30_fromdata() + * The following must be kept in sync with ossl_rsa_pss_params_30_fromdata() * in crypto/rsa/rsa_backend.c */ #define rsa_gen_pss \ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST, NULL, 0), \ + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, NULL, 0), \ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_MASKGENFUNC, NULL, 0), \ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, NULL, 0), \ OSSL_PARAM_int(OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, NULL) @@ -507,13 +526,13 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) RSA *rsa = NULL, *rsa_tmp = NULL; BN_GENCB *gencb = NULL; - if (gctx == NULL) + if (!ossl_prov_is_running() || gctx == NULL) return NULL; switch (gctx->rsa_type) { case RSA_FLAG_TYPE_RSA: /* For plain RSA keys, PSS parameters must not be set */ - if (!rsa_pss_params_30_is_unrestricted(&gctx->pss_params)) + if (!ossl_rsa_pss_params_30_is_unrestricted(&gctx->pss_params)) goto err; break; case RSA_FLAG_TYPE_RSASSAPSS: @@ -527,7 +546,7 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) return NULL; } - if ((rsa_tmp = rsa_new_with_ctx(gctx->libctx)) == NULL) + if ((rsa_tmp = ossl_rsa_new_with_ctx(gctx->libctx)) == NULL) return NULL; gctx->cb = osslcb; @@ -548,8 +567,8 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) gctx->pub_exp, gencb)) goto err; - if (!rsa_pss_params_30_copy(rsa_get0_pss_params_30(rsa_tmp), - &gctx->pss_params)) + if (!ossl_rsa_pss_params_30_copy(ossl_rsa_get0_pss_params_30(rsa_tmp), + &gctx->pss_params)) goto err; RSA_clear_flags(rsa_tmp, RSA_FLAG_TYPE_MASK); @@ -581,7 +600,7 @@ void *rsa_load(const void *reference, size_t reference_sz) { RSA *rsa = NULL; - if (reference_sz == sizeof(rsa)) { + if (ossl_prov_is_running() && reference_sz == sizeof(rsa)) { /* The contents of the reference is the address to our object */ rsa = *(RSA **)reference; /* We grabbed, so we detach it */ @@ -592,12 +611,12 @@ void *rsa_load(const void *reference, size_t reference_sz) } /* For any RSA key, we use the "RSA" algorithms regardless of sub-type. */ -static const char *rsapss_query_operation_name(int operation_id) +static const char *rsa_query_operation_name(int operation_id) { return "RSA"; } -const OSSL_DISPATCH rsa_keymgmt_functions[] = { +const OSSL_DISPATCH ossl_rsa_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))rsa_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))rsa_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, @@ -620,7 +639,7 @@ const OSSL_DISPATCH rsa_keymgmt_functions[] = { { 0, NULL } }; -const OSSL_DISPATCH rsapss_keymgmt_functions[] = { +const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))rsapss_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))rsapss_gen_init }, { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))rsa_gen_set_params }, @@ -640,6 +659,6 @@ const OSSL_DISPATCH rsapss_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export }, { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types }, { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, - (void (*)(void))rsapss_query_operation_name }, + (void (*)(void))rsa_query_operation_name }, { 0, NULL } }; diff --git a/providers/implementations/macs/blake2_mac_impl.c b/providers/implementations/macs/blake2_mac_impl.c index 9fd7f2c0ba..f7b6bd3e4f 100644 --- a/providers/implementations/macs/blake2_mac_impl.c +++ b/providers/implementations/macs/blake2_mac_impl.c @@ -15,6 +15,7 @@ #include "internal/cryptlib.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -42,8 +43,12 @@ static size_t blake2_mac_size(void *vmacctx); static void *blake2_mac_new(void *unused_provctx) { - struct blake2_mac_data_st *macctx = OPENSSL_zalloc(sizeof(*macctx)); + struct blake2_mac_data_st *macctx; + if (!ossl_prov_is_running()) + return NULL; + + macctx = OPENSSL_zalloc(sizeof(*macctx)); if (macctx != NULL) { BLAKE2_PARAM_INIT(&macctx->params); /* ctx initialization is deferred to BLAKE2b_Init() */ @@ -56,6 +61,9 @@ static void *blake2_mac_dup(void *vsrc) struct blake2_mac_data_st *dst; struct blake2_mac_data_st *src = vsrc; + if (!ossl_prov_is_running()) + return NULL; + dst = OPENSSL_zalloc(sizeof(*dst)); if (dst == NULL) return NULL; @@ -78,6 +86,9 @@ static int blake2_mac_init(void *vmacctx) { struct blake2_mac_data_st *macctx = vmacctx; + if (!ossl_prov_is_running()) + return 0; + /* Check key has been set */ if (macctx->params.key_length == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); @@ -92,6 +103,9 @@ static int blake2_mac_update(void *vmacctx, { struct blake2_mac_data_st *macctx = vmacctx; + if (datalen == 0) + return 1; + return BLAKE2_UPDATE(&macctx->ctx, data, datalen); } @@ -101,6 +115,10 @@ static int blake2_mac_final(void *vmacctx, { struct blake2_mac_data_st *macctx = vmacctx; + if (!ossl_prov_is_running()) + return 0; + + *outl = blake2_mac_size(macctx); return BLAKE2_FINAL(out, &macctx->ctx); } @@ -108,7 +126,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *blake2_gettable_ctx_params(void) +static const OSSL_PARAM *blake2_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -130,7 +148,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_MAC_PARAM_SALT, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *blake2_mac_settable_ctx_params() +static const OSSL_PARAM *blake2_mac_settable_ctx_params(ossl_unused void *p_ctx) { return known_settable_ctx_params; } diff --git a/providers/implementations/macs/blake2b_mac.c b/providers/implementations/macs/blake2b_mac.c index aa1a8dee1f..31c3dd03b3 100644 --- a/providers/implementations/macs/blake2b_mac.c +++ b/providers/implementations/macs/blake2b_mac.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,7 +26,7 @@ #define BLAKE2_PARAM_SET_SALT blake2b_param_set_salt /* OSSL_DISPATCH symbol */ -#define BLAKE2_FUNCTIONS blake2bmac_functions +#define BLAKE2_FUNCTIONS ossl_blake2bmac_functions #include "blake2_mac_impl.c" diff --git a/providers/implementations/macs/blake2s_mac.c b/providers/implementations/macs/blake2s_mac.c index ccd7035523..54db7e3a92 100644 --- a/providers/implementations/macs/blake2s_mac.c +++ b/providers/implementations/macs/blake2s_mac.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,6 +26,6 @@ #define BLAKE2_PARAM_SET_SALT blake2s_param_set_salt /* OSSL_DISPATCH symbol */ -#define BLAKE2_FUNCTIONS blake2smac_functions +#define BLAKE2_FUNCTIONS ossl_blake2smac_functions #include "blake2_mac_impl.c" diff --git a/providers/implementations/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c index 8ae6a89ad6..9a8b71220f 100644 --- a/providers/implementations/macs/cmac_prov.c +++ b/providers/implementations/macs/cmac_prov.c @@ -23,6 +23,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -52,6 +53,9 @@ static void *cmac_new(void *provctx) { struct cmac_data_st *macctx; + if (!ossl_prov_is_running()) + return NULL; + if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL || (macctx->ctx = CMAC_CTX_new()) == NULL) { OPENSSL_free(macctx); @@ -77,8 +81,12 @@ static void cmac_free(void *vmacctx) static void *cmac_dup(void *vsrc) { struct cmac_data_st *src = vsrc; - struct cmac_data_st *dst = cmac_new(src->provctx); + struct cmac_data_st *dst; + if (!ossl_prov_is_running()) + return NULL; + + dst = cmac_new(src->provctx); if (!CMAC_CTX_copy(dst->ctx, src->ctx) || !ossl_prov_cipher_copy(&dst->cipher, &src->cipher)) { cmac_free(dst); @@ -97,9 +105,14 @@ static size_t cmac_size(void *vmacctx) static int cmac_init(void *vmacctx) { struct cmac_data_st *macctx = vmacctx; - int rv = CMAC_Init(macctx->ctx, NULL, 0, - ossl_prov_cipher_cipher(&macctx->cipher), - ossl_prov_cipher_engine(&macctx->cipher)); + int rv; + + if (!ossl_prov_is_running()) + return 0; + + rv = CMAC_Init(macctx->ctx, NULL, 0, + ossl_prov_cipher_cipher(&macctx->cipher), + ossl_prov_cipher_engine(&macctx->cipher)); ossl_prov_cipher_reset(&macctx->cipher); return rv; @@ -118,6 +131,9 @@ static int cmac_final(void *vmacctx, unsigned char *out, size_t *outl, { struct cmac_data_st *macctx = vmacctx; + if (!ossl_prov_is_running()) + return 0; + return CMAC_Final(macctx->ctx, out, outl); } @@ -125,7 +141,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *cmac_gettable_ctx_params(void) +static const OSSL_PARAM *cmac_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -146,7 +162,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *cmac_settable_ctx_params(void) +static const OSSL_PARAM *cmac_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } @@ -157,7 +173,7 @@ static const OSSL_PARAM *cmac_settable_ctx_params(void) static int cmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) { struct cmac_data_st *macctx = vmacctx; - OPENSSL_CTX *ctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx); + OSSL_LIB_CTX *ctx = PROV_LIBCTX_OF(macctx->provctx); const OSSL_PARAM *p; if (!ossl_prov_cipher_load_from_params(&macctx->cipher, params, ctx)) @@ -177,7 +193,7 @@ static int cmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) return 1; } -const OSSL_DISPATCH cmac_functions[] = { +const OSSL_DISPATCH ossl_cmac_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))cmac_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))cmac_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))cmac_free }, diff --git a/providers/implementations/macs/gmac_prov.c b/providers/implementations/macs/gmac_prov.c index 845ea87527..d9790dcd6c 100644 --- a/providers/implementations/macs/gmac_prov.c +++ b/providers/implementations/macs/gmac_prov.c @@ -19,6 +19,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -61,6 +62,9 @@ static void *gmac_new(void *provctx) { struct gmac_data_st *macctx; + if (!ossl_prov_is_running()) + return NULL; + if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL || (macctx->ctx = EVP_CIPHER_CTX_new()) == NULL) { gmac_free(macctx); @@ -74,8 +78,12 @@ static void *gmac_new(void *provctx) static void *gmac_dup(void *vsrc) { struct gmac_data_st *src = vsrc; - struct gmac_data_st *dst = gmac_new(src->provctx); + struct gmac_data_st *dst; + + if (!ossl_prov_is_running()) + return NULL; + dst = gmac_new(src->provctx); if (dst == NULL) return NULL; @@ -89,7 +97,7 @@ static void *gmac_dup(void *vsrc) static int gmac_init(void *vmacctx) { - return 1; + return ossl_prov_is_running(); } static int gmac_update(void *vmacctx, const unsigned char *data, @@ -99,6 +107,9 @@ static int gmac_update(void *vmacctx, const unsigned char *data, EVP_CIPHER_CTX *ctx = macctx->ctx; int outlen; + if (datalen == 0) + return 1; + while (datalen > INT_MAX) { if (!EVP_EncryptUpdate(ctx, NULL, &outlen, data, INT_MAX)) return 0; @@ -114,6 +125,9 @@ static int gmac_final(void *vmacctx, unsigned char *out, size_t *outl, struct gmac_data_st *macctx = vmacctx; int hlen = 0; + if (!ossl_prov_is_running()) + return 0; + if (!EVP_EncryptFinal_ex(macctx->ctx, out, &hlen)) return 0; @@ -136,7 +150,7 @@ static const OSSL_PARAM known_gettable_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *gmac_gettable_params(void) +static const OSSL_PARAM *gmac_gettable_params(void *provctx) { return known_gettable_params; } @@ -158,7 +172,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_MAC_PARAM_IV, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *gmac_settable_ctx_params(void) +static const OSSL_PARAM *gmac_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } @@ -170,7 +184,7 @@ static int gmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) { struct gmac_data_st *macctx = vmacctx; EVP_CIPHER_CTX *ctx = macctx->ctx; - OPENSSL_CTX *provctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx); + OSSL_LIB_CTX *provctx = PROV_LIBCTX_OF(macctx->provctx); const OSSL_PARAM *p; if (ctx == NULL @@ -210,7 +224,7 @@ static int gmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) return 1; } -const OSSL_DISPATCH gmac_functions[] = { +const OSSL_DISPATCH ossl_gmac_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))gmac_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))gmac_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))gmac_free }, diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c index 5260995861..b5d3f110f4 100644 --- a/providers/implementations/macs/hmac_prov.c +++ b/providers/implementations/macs/hmac_prov.c @@ -13,6 +13,8 @@ */ #include "internal/deprecated.h" +#include + #include #include #include @@ -23,6 +25,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -47,14 +50,36 @@ struct hmac_data_st { void *provctx; HMAC_CTX *ctx; /* HMAC context */ PROV_DIGEST digest; + unsigned char *key; + size_t keylen; + /* Length of full TLS record including the MAC and any padding */ + size_t tls_data_size; + unsigned char tls_header[13]; + int tls_header_set; + unsigned char tls_mac_out[EVP_MAX_MD_SIZE]; + size_t tls_mac_out_size; }; +/* Defined in ssl/s3_cbc.c */ +int ssl3_cbc_digest_record(const EVP_MD *md, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + size_t mac_secret_length, char is_sslv3); + static size_t hmac_size(void *vmacctx); static void *hmac_new(void *provctx) { struct hmac_data_st *macctx; + if (!ossl_prov_is_running()) + return NULL; + if ((macctx = OPENSSL_zalloc(sizeof(*macctx))) == NULL || (macctx->ctx = HMAC_CTX_new()) == NULL) { OPENSSL_free(macctx); @@ -73,6 +98,7 @@ static void hmac_free(void *vmacctx) if (macctx != NULL) { HMAC_CTX_free(macctx->ctx); ossl_prov_digest_reset(&macctx->digest); + OPENSSL_secure_clear_free(macctx->key, macctx->keylen); OPENSSL_free(macctx); } } @@ -80,16 +106,34 @@ static void hmac_free(void *vmacctx) static void *hmac_dup(void *vsrc) { struct hmac_data_st *src = vsrc; - struct hmac_data_st *dst = hmac_new(src->provctx); + struct hmac_data_st *dst; + HMAC_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + dst = hmac_new(src->provctx); if (dst == NULL) return NULL; + ctx = dst->ctx; + *dst = *src; + dst->ctx = ctx; + dst->key = NULL; + if (!HMAC_CTX_copy(dst->ctx, src->ctx) || !ossl_prov_digest_copy(&dst->digest, &src->digest)) { hmac_free(dst); return NULL; } + if (src->key != NULL) { + /* There is no "secure" OPENSSL_memdup */ + dst->key = OPENSSL_secure_malloc(src->keylen > 0 ? src->keylen : 1); + if (dst->key == NULL) { + hmac_free(dst); + return 0; + } + memcpy(dst->key, src->key, src->keylen); + } return dst; } @@ -103,14 +147,18 @@ static size_t hmac_size(void *vmacctx) static int hmac_init(void *vmacctx) { struct hmac_data_st *macctx = vmacctx; - const EVP_MD *digest = ossl_prov_digest_md(&macctx->digest); + const EVP_MD *digest; int rv = 1; + if (!ossl_prov_is_running()) + return 0; + + digest = ossl_prov_digest_md(&macctx->digest); /* HMAC_Init_ex doesn't tolerate all zero params, so we must be careful */ - if (digest != NULL) + if (macctx->tls_data_size == 0 && digest != NULL) rv = HMAC_Init_ex(macctx->ctx, NULL, 0, digest, ossl_prov_digest_engine(&macctx->digest)); - ossl_prov_digest_reset(&macctx->digest); + return rv; } @@ -119,6 +167,32 @@ static int hmac_update(void *vmacctx, const unsigned char *data, { struct hmac_data_st *macctx = vmacctx; + if (macctx->tls_data_size > 0) { + /* We're doing a TLS HMAC */ + if (!macctx->tls_header_set) { + /* We expect the first update call to contain the TLS header */ + if (datalen != sizeof(macctx->tls_header)) + return 0; + memcpy(macctx->tls_header, data, datalen); + macctx->tls_header_set = 1; + return 1; + } + /* macctx->tls_data_size is datalen plus the padding length */ + if (macctx->tls_data_size < datalen) + return 0; + + return ssl3_cbc_digest_record(ossl_prov_digest_md(&macctx->digest), + macctx->tls_mac_out, + &macctx->tls_mac_out_size, + macctx->tls_header, + data, + datalen, + macctx->tls_data_size, + macctx->key, + macctx->keylen, + 0); + } + return HMAC_Update(macctx->ctx, data, datalen); } @@ -128,10 +202,19 @@ static int hmac_final(void *vmacctx, unsigned char *out, size_t *outl, unsigned int hlen; struct hmac_data_st *macctx = vmacctx; + if (!ossl_prov_is_running()) + return 0; + if (macctx->tls_data_size > 0) { + if (macctx->tls_mac_out_size == 0) + return 0; + if (outl != NULL) + *outl = macctx->tls_mac_out_size; + memcpy(out, macctx->tls_mac_out, macctx->tls_mac_out_size); + return 1; + } if (!HMAC_Final(macctx->ctx, out, &hlen)) return 0; - if (outl != NULL) - *outl = hlen; + *outl = hlen; return 1; } @@ -139,7 +222,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *hmac_gettable_ctx_params(void) +static const OSSL_PARAM *hmac_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -159,9 +242,10 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), OSSL_PARAM_int(OSSL_MAC_PARAM_FLAGS, NULL), + OSSL_PARAM_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *hmac_settable_ctx_params(void) +static const OSSL_PARAM *hmac_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } @@ -172,7 +256,7 @@ static const OSSL_PARAM *hmac_settable_ctx_params(void) static int hmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) { struct hmac_data_st *macctx = vmacctx; - OPENSSL_CTX *ctx = PROV_LIBRARY_CONTEXT_OF(macctx->provctx); + OSSL_LIB_CTX *ctx = PROV_LIBCTX_OF(macctx->provctx); const OSSL_PARAM *p; if (!ossl_prov_digest_load_from_params(&macctx->digest, params, ctx)) @@ -191,17 +275,30 @@ static int hmac_set_ctx_params(void *vmacctx, const OSSL_PARAM params[]) if (p->data_type != OSSL_PARAM_OCTET_STRING) return 0; + if (macctx->keylen > 0) + OPENSSL_secure_clear_free(macctx->key, macctx->keylen); + /* Keep a copy of the key if we need it for TLS HMAC */ + macctx->key = OPENSSL_secure_malloc(p->data_size > 0 ? p->data_size : 1); + if (macctx->key == NULL) + return 0; + memcpy(macctx->key, p->data, p->data_size); + macctx->keylen = p->data_size; + if (!HMAC_Init_ex(macctx->ctx, p->data, p->data_size, ossl_prov_digest_md(&macctx->digest), NULL /* ENGINE */)) return 0; - ossl_prov_digest_reset(&macctx->digest); + } + if ((p = OSSL_PARAM_locate_const(params, + OSSL_MAC_PARAM_TLS_DATA_SIZE)) != NULL) { + if (!OSSL_PARAM_get_size_t(p, &macctx->tls_data_size)) + return 0; } return 1; } -const OSSL_DISPATCH hmac_functions[] = { +const OSSL_DISPATCH ossl_hmac_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))hmac_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))hmac_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))hmac_free }, diff --git a/providers/implementations/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c index bc37ad34cb..eb60510b96 100644 --- a/providers/implementations/macs/kmac_prov.c +++ b/providers/implementations/macs/kmac_prov.c @@ -58,6 +58,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -158,6 +159,9 @@ static struct kmac_data_st *kmac_new(void *provctx) { struct kmac_data_st *kctx; + if (!ossl_prov_is_running()) + return NULL; + if ((kctx = OPENSSL_zalloc(sizeof(*kctx))) == NULL || (kctx->ctx = EVP_MD_CTX_new()) == NULL) { kmac_free(kctx); @@ -174,7 +178,7 @@ static void *kmac_fetch_new(void *provctx, const OSSL_PARAM *params) if (kctx == NULL) return 0; if (!ossl_prov_digest_load_from_params(&kctx->digest, params, - PROV_LIBRARY_CONTEXT_OF(provctx))) { + PROV_LIBCTX_OF(provctx))) { kmac_free(kctx); return 0; } @@ -206,8 +210,12 @@ static void *kmac256_new(void *provctx) static void *kmac_dup(void *vsrc) { struct kmac_data_st *src = vsrc; - struct kmac_data_st *dst = kmac_new(src->provctx); + struct kmac_data_st *dst; + + if (!ossl_prov_is_running()) + return NULL; + dst = kmac_new(src->provctx); if (dst == NULL) return NULL; @@ -239,6 +247,8 @@ static int kmac_init(void *vmacctx) unsigned char out[KMAC_MAX_BLOCKSIZE]; int out_len, block_len; + if (!ossl_prov_is_running()) + return 0; /* Check key has been set */ if (kctx->key_len == 0) { @@ -292,14 +302,16 @@ static int kmac_final(void *vmacctx, unsigned char *out, size_t *outl, unsigned char encoded_outlen[KMAC_MAX_ENCODED_HEADER_LEN]; int ok; + if (!ossl_prov_is_running()) + return 0; + /* KMAC XOF mode sets the encoded length to 0 */ lbits = (kctx->xof_mode ? 0 : (kctx->out_len * 8)); ok = right_encode(encoded_outlen, &len, lbits) && EVP_DigestUpdate(ctx, encoded_outlen, len) && EVP_DigestFinalXOF(ctx, out, kctx->out_len); - if (ok && outl != NULL) - *outl = kctx->out_len; + *outl = kctx->out_len; return ok; } @@ -307,7 +319,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *kmac_gettable_ctx_params(void) +static const OSSL_PARAM *kmac_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -329,7 +341,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_MAC_PARAM_CUSTOM, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *kmac_settable_ctx_params(void) +static const OSSL_PARAM *kmac_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } @@ -512,7 +524,7 @@ static int kmac_bytepad_encode_key(unsigned char *out, int *out_len, return bytepad(out, out_len, tmp, tmp_len, NULL, 0, w); } -const OSSL_DISPATCH kmac128_functions[] = { +const OSSL_DISPATCH ossl_kmac128_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac128_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free }, @@ -528,7 +540,7 @@ const OSSL_DISPATCH kmac128_functions[] = { { 0, NULL } }; -const OSSL_DISPATCH kmac256_functions[] = { +const OSSL_DISPATCH ossl_kmac256_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))kmac256_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))kmac_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))kmac_free }, diff --git a/providers/implementations/macs/poly1305_prov.c b/providers/implementations/macs/poly1305_prov.c index aa0b7df7ee..1b248f141e 100644 --- a/providers/implementations/macs/poly1305_prov.c +++ b/providers/implementations/macs/poly1305_prov.c @@ -17,6 +17,7 @@ #include "prov/providercommonerr.h" #include "prov/implementations.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -43,8 +44,11 @@ static size_t poly1305_size(void); static void *poly1305_new(void *provctx) { - struct poly1305_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + struct poly1305_data_st *ctx; + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) ctx->provctx = provctx; return ctx; @@ -58,8 +62,11 @@ static void poly1305_free(void *vmacctx) static void *poly1305_dup(void *vsrc) { struct poly1305_data_st *src = vsrc; - struct poly1305_data_st *dst = poly1305_new(src->provctx); + struct poly1305_data_st *dst; + if (!ossl_prov_is_running()) + return NULL; + dst = poly1305_new(src->provctx); if (dst == NULL) return NULL; @@ -75,7 +82,7 @@ static size_t poly1305_size(void) static int poly1305_init(void *vmacctx) { /* initialize the context in MAC_ctrl function */ - return 1; + return ossl_prov_is_running(); } static int poly1305_update(void *vmacctx, const unsigned char *data, @@ -83,6 +90,9 @@ static int poly1305_update(void *vmacctx, const unsigned char *data, { struct poly1305_data_st *ctx = vmacctx; + if (datalen == 0) + return 1; + /* poly1305 has nothing to return in its update function */ Poly1305_Update(&ctx->poly1305, data, datalen); return 1; @@ -93,7 +103,10 @@ static int poly1305_final(void *vmacctx, unsigned char *out, size_t *outl, { struct poly1305_data_st *ctx = vmacctx; + if (!ossl_prov_is_running()) + return 0; Poly1305_Final(&ctx->poly1305, out); + *outl = poly1305_size(); return 1; } @@ -101,7 +114,7 @@ static const OSSL_PARAM known_gettable_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *poly1305_gettable_params(void) +static const OSSL_PARAM *poly1305_gettable_params(void *provctx) { return known_gettable_params; } @@ -120,7 +133,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *poly1305_settable_ctx_params(void) +static const OSSL_PARAM *poly1305_settable_ctx_params(ossl_unused void *provctx) { return known_settable_ctx_params; } @@ -141,7 +154,7 @@ static int poly1305_set_ctx_params(void *vmacctx, const OSSL_PARAM *params) return 1; } -const OSSL_DISPATCH poly1305_functions[] = { +const OSSL_DISPATCH ossl_poly1305_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))poly1305_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))poly1305_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))poly1305_free }, diff --git a/providers/implementations/macs/siphash_prov.c b/providers/implementations/macs/siphash_prov.c index 64ac70f567..01100b51d6 100644 --- a/providers/implementations/macs/siphash_prov.c +++ b/providers/implementations/macs/siphash_prov.c @@ -24,6 +24,7 @@ #include "prov/providercommonerr.h" #include "prov/implementations.h" +#include "prov/providercommon.h" /* * Forward declaration of everything implemented here. This is not strictly @@ -49,8 +50,11 @@ struct siphash_data_st { static void *siphash_new(void *provctx) { - struct siphash_data_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + struct siphash_data_st *ctx; + if (!ossl_prov_is_running()) + return NULL; + ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) ctx->provctx = provctx; return ctx; @@ -64,8 +68,11 @@ static void siphash_free(void *vmacctx) static void *siphash_dup(void *vsrc) { struct siphash_data_st *ssrc = vsrc; - struct siphash_data_st *sdst = siphash_new(ssrc->provctx); + struct siphash_data_st *sdst; + if (!ossl_prov_is_running()) + return NULL; + sdst = siphash_new(ssrc->provctx); if (sdst == NULL) return NULL; @@ -83,7 +90,7 @@ static size_t siphash_size(void *vmacctx) static int siphash_init(void *vmacctx) { /* Not much to do here, actual initialization happens through controls */ - return 1; + return ossl_prov_is_running(); } static int siphash_update(void *vmacctx, const unsigned char *data, @@ -91,6 +98,9 @@ static int siphash_update(void *vmacctx, const unsigned char *data, { struct siphash_data_st *ctx = vmacctx; + if (datalen == 0) + return 1; + SipHash_Update(&ctx->siphash, data, datalen); return 1; } @@ -101,7 +111,7 @@ static int siphash_final(void *vmacctx, unsigned char *out, size_t *outl, struct siphash_data_st *ctx = vmacctx; size_t hlen = siphash_size(ctx); - if (outsize < hlen) + if (!ossl_prov_is_running() || outsize < hlen) return 0; *outl = hlen; @@ -112,7 +122,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *siphash_gettable_ctx_params(void) +static const OSSL_PARAM *siphash_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -132,7 +142,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_MAC_PARAM_KEY, NULL, 0), OSSL_PARAM_END }; -static const OSSL_PARAM *siphash_settable_params(void) +static const OSSL_PARAM *siphash_settable_params(void *provctx) { return known_settable_ctx_params; } @@ -157,7 +167,7 @@ static int siphash_set_params(void *vmacctx, const OSSL_PARAM *params) return 1; } -const OSSL_DISPATCH siphash_functions[] = { +const OSSL_DISPATCH ossl_siphash_functions[] = { { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))siphash_new }, { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))siphash_dup }, { OSSL_FUNC_MAC_FREECTX, (void (*)(void))siphash_free }, diff --git a/providers/implementations/rands/crngt.c b/providers/implementations/rands/crngt.c index 538de37468..5f613f1c4e 100644 --- a/providers/implementations/rands/crngt.c +++ b/providers/implementations/rands/crngt.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "prov/providercommon.h" #include "prov/provider_ctx.h" #include "internal/cryptlib.h" @@ -28,7 +29,7 @@ typedef struct crng_test_global_st { RAND_POOL *crngt_pool; } CRNG_TEST_GLOBAL; -static int crngt_get_entropy(OPENSSL_CTX *ctx, RAND_POOL *pool, +static int crngt_get_entropy(OSSL_LIB_CTX *ctx, RAND_POOL *pool, unsigned char *buf, unsigned char *md, unsigned int *md_size) { @@ -64,7 +65,7 @@ static void rand_crng_ossl_ctx_free(void *vcrngt_glob) OPENSSL_free(crngt_glob); } -static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx) +static void *rand_crng_ossl_ctx_new(OSSL_LIB_CTX *ctx) { unsigned char buf[CRNGT_BUFSIZ]; CRNG_TEST_GLOBAL *crngt_glob = OPENSSL_zalloc(sizeof(*crngt_glob)); @@ -87,11 +88,22 @@ static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx) return NULL; } -static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = { +static const OSSL_LIB_CTX_METHOD rand_crng_ossl_ctx_method = { rand_crng_ossl_ctx_new, rand_crng_ossl_ctx_free, }; +static int prov_crngt_compare_previous(const unsigned char *prev, + const unsigned char *cur, + size_t sz) +{ + const int res = memcmp(prev, cur, sz) != 0; + + if (!res) + ossl_set_error_state(OSSL_SELF_TEST_TYPE_CRNG); + return res; +} + size_t prov_crngt_get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len, @@ -101,11 +113,14 @@ size_t prov_crngt_get_entropy(PROV_DRBG *drbg, unsigned int sz; RAND_POOL *pool; size_t q, r = 0, s, t = 0; - int attempts = 3; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(drbg->provctx); + int attempts = 3, crng_test_pass = 1; + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(drbg->provctx); CRNG_TEST_GLOBAL *crngt_glob - = openssl_ctx_get_data(libctx, OPENSSL_CTX_RAND_CRNGT_INDEX, - &rand_crng_ossl_ctx_method); + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_RAND_CRNGT_INDEX, + &rand_crng_ossl_ctx_method); + OSSL_CALLBACK *stcb = NULL; + void *stcbarg = NULL; + OSSL_SELF_TEST *st = NULL; if (crngt_glob == NULL) return 0; @@ -113,12 +128,27 @@ size_t prov_crngt_get_entropy(PROV_DRBG *drbg, if ((pool = rand_pool_new(entropy, 1, min_len, max_len)) == NULL) return 0; + OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg); + if (stcb != NULL) { + st = OSSL_SELF_TEST_new(stcb, stcbarg); + if (st == NULL) + goto err; + OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_CRNG, + OSSL_SELF_TEST_DESC_RNG); + } + while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) { s = q > sizeof(buf) ? sizeof(buf) : q; - if (!crngt_get_entropy(libctx, crngt_glob->crngt_pool, buf, md, - &sz) - || memcmp(crngt_glob->crngt_prev, md, sz) == 0 - || !rand_pool_add(pool, buf, s, s * 8)) + if (!crngt_get_entropy(libctx, crngt_glob->crngt_pool, buf, md, &sz)) + goto err; + /* Force a failure here if the callback returns 1 */ + if (OSSL_SELF_TEST_oncorrupt_byte(st, md)) + memcpy(md, crngt_glob->crngt_prev, sz); + if (!prov_crngt_compare_previous(crngt_glob->crngt_prev, md, sz)) { + crng_test_pass = 0; + goto err; + } + if (!rand_pool_add(pool, buf, s, s * 8)) goto err; memcpy(crngt_glob->crngt_prev, md, sz); t += s; @@ -127,6 +157,8 @@ size_t prov_crngt_get_entropy(PROV_DRBG *drbg, r = t; *pout = rand_pool_detach(pool); err: + OSSL_SELF_TEST_onend(st, crng_test_pass); + OSSL_SELF_TEST_free(st); OPENSSL_cleanse(buf, sizeof(buf)); rand_pool_free(pool); return r; diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index 929b32e708..ba630bbd79 100644 --- a/providers/implementations/rands/drbg.c +++ b/providers/implementations/rands/drbg.c @@ -20,6 +20,7 @@ #include "prov/rand_pool.h" #include "prov/provider_ctx.h" #include "prov/providercommonerr.h" +#include "prov/providercommon.h" /* * Support framework for NIST SP 800-90A DRBG @@ -111,7 +112,7 @@ static unsigned int get_parent_reseed_count(PROV_DRBG *drbg) void *parent = drbg->parent; unsigned int r; - *params = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_CTR, &r); + *params = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_COUNTER, &r); if (!drbg_lock_parent(drbg)) { ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT); goto err; @@ -132,10 +133,10 @@ static unsigned int get_parent_reseed_count(PROV_DRBG *drbg) } /* - * Implements the get_entropy() callback (see RAND_DRBG_set_callbacks()) + * Implements the get_entropy() callback * * If the DRBG has a parent, then the required amount of entropy input - * is fetched using the parent's RAND_DRBG_generate(). + * is fetched using the parent's ossl_prov_drbg_generate(). * * Otherwise, the entropy is polled from the system entropy sources * using prov_pool_acquire_entropy(). @@ -183,17 +184,23 @@ static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout, if (buffer != NULL) { size_t bytes = 0; + if (drbg->parent_generate == NULL) + goto err; /* - * Get random data from parent. Include our address as additional input, - * in order to provide some additional distinction between different - * DRBG child instances. * Our lock is already held, but we need to lock our parent before * generating bits from it. (Note: taking the lock will be a no-op * if locking if drbg->parent->lock == NULL.) */ - if (drbg->parent_generate == NULL) - goto err; drbg_lock_parent(drbg); + /* + * Get random data from parent. Include our DRBG address as + * additional input, in order to provide a distinction between + * different DRBG child instances. + * + * Note: using the sizeof() operator on a pointer triggers + * a warning in some static code analyzers, but it's + * intentional and correct here. + */ if (drbg->parent_generate(drbg->parent, buffer, bytes_needed, drbg->strength, prediction_resistance, (unsigned char *)&drbg, @@ -222,25 +229,13 @@ static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout, } /* - * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks()) + * Implements the cleanup_entropy() callback * */ static void prov_drbg_cleanup_entropy(PROV_DRBG *drbg, unsigned char *out, size_t outlen) { - OSSL_PARAM params[3], *p = params; - - if (drbg->get_entropy_fn != NULL) { - if (drbg->cleanup_entropy_fn != NULL) { - *p++ = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_SIZE, - &outlen); - *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_DRBG_PARAM_RANDOM_DATA, - (void **)&out, 0); - *p = OSSL_PARAM_construct_end(); - - drbg->cleanup_entropy_fn(params, drbg->callback_arg); - } - } else if (drbg->seed_pool == NULL) { + if (drbg->seed_pool == NULL) { OPENSSL_secure_clear_free(out, outlen); } } @@ -249,28 +244,6 @@ static size_t get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len, int prediction_resistance) { - if (drbg->get_entropy_fn != NULL) { - OSSL_PARAM params[6], *p = params; - OSSL_PARAM out[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - - *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_ENTROPY_REQUIRED, - &entropy); - *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_PREDICTION_RESISTANCE, - &prediction_resistance); - *p++ = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MIN_LENGTH, - &min_len); - *p++ = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_LENGTH, - &max_len); - *p = OSSL_PARAM_construct_end(); - *out = OSSL_PARAM_construct_octet_ptr(OSSL_DRBG_PARAM_RANDOM_DATA, - (void **)pout, 0); - - if (drbg->get_entropy_fn(params, out, drbg->callback_arg)) - return out->return_size; - ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_ENTROPY); - return 0; - } - #ifdef FIPS_MODULE if (drbg->parent == NULL) return prov_crngt_get_entropy(drbg, pout, entropy, min_len, max_len, @@ -299,12 +272,12 @@ typedef struct prov_drbg_nonce_global_st { /* * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce() - * which needs to get the rand_nonce_lock out of the OPENSSL_CTX...but since + * which needs to get the rand_nonce_lock out of the OSSL_LIB_CTX...but since * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock * to be in a different global data object. Otherwise we will go into an * infinite recursion loop. */ -static void *prov_drbg_nonce_ossl_ctx_new(OPENSSL_CTX *libctx) +static void *prov_drbg_nonce_ossl_ctx_new(OSSL_LIB_CTX *libctx) { PROV_DRBG_NONCE_GLOBAL *dngbl = OPENSSL_zalloc(sizeof(*dngbl)); @@ -332,7 +305,7 @@ static void prov_drbg_nonce_ossl_ctx_free(void *vdngbl) OPENSSL_free(dngbl); } -static const OPENSSL_CTX_METHOD drbg_nonce_ossl_ctx_method = { +static const OSSL_LIB_CTX_METHOD drbg_nonce_ossl_ctx_method = { prov_drbg_nonce_ossl_ctx_new, prov_drbg_nonce_ossl_ctx_free, }; @@ -345,12 +318,10 @@ static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, size_t ret = 0, n; RAND_POOL *pool; unsigned char *buf = NULL; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(drbg->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(drbg->provctx); PROV_DRBG_NONCE_GLOBAL *dngbl - = openssl_ctx_get_data(libctx, OPENSSL_CTX_DRBG_NONCE_INDEX, - &drbg_nonce_ossl_ctx_method); - OSSL_PARAM params[5], *p = params; - OSSL_PARAM out[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_NONCE_INDEX, + &drbg_nonce_ossl_ctx_method); struct { void *instance; int count; @@ -359,22 +330,6 @@ static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, if (dngbl == NULL) return 0; - if (drbg->get_nonce_fn != NULL) { - *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_ENTROPY_REQUIRED, - &entropy); - *p++ = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MIN_LENGTH, - &min_len); - *p++ = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_LENGTH, - &max_len); - *p = OSSL_PARAM_construct_end(); - *out = OSSL_PARAM_construct_octet_ptr(OSSL_DRBG_PARAM_RANDOM_DATA, - (void **)pout, 0); - - if (drbg->get_nonce_fn(params, out, drbg->callback_arg)) - return out->return_size; - ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_NONCE); - return 0; - } if (drbg->parent != NULL) { if (drbg->parent_nonce != NULL) { n = drbg->parent_nonce(drbg->parent, NULL, 0, drbg->min_noncelen, @@ -420,21 +375,7 @@ static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, static void prov_drbg_clear_nonce(PROV_DRBG *drbg, unsigned char *nonce, size_t noncelen) { - OSSL_PARAM params[3], *p = params; - - if (drbg->get_nonce_fn != NULL) { - if (drbg->cleanup_nonce_fn != NULL) { - *p++ = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_SIZE, - &noncelen); - *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_DRBG_PARAM_RANDOM_DATA, - (void **)&nonce, 0); - *p = OSSL_PARAM_construct_end(); - - drbg->cleanup_nonce_fn(params, drbg->callback_arg); - } - } else { - OPENSSL_clear_free(nonce, noncelen); - } + OPENSSL_clear_free(nonce, noncelen); } #else # define prov_drbg_clear_nonce(drbg, nonce, len) \ @@ -449,14 +390,17 @@ static void prov_drbg_clear_nonce(PROV_DRBG *drbg, unsigned char *nonce, * * Returns 1 on success, 0 on failure. */ -int PROV_DRBG_instantiate(PROV_DRBG *drbg, unsigned int strength, - int prediction_resistance, - const unsigned char *pers, size_t perslen) +int ossl_prov_drbg_instantiate(PROV_DRBG *drbg, unsigned int strength, + int prediction_resistance, + const unsigned char *pers, size_t perslen) { unsigned char *nonce = NULL, *entropy = NULL; size_t noncelen = 0, entropylen = 0; size_t min_entropy, min_entropylen, max_entropylen; + if (!ossl_prov_is_running()) + return 0; + if (strength > drbg->strength) { PROVerr(0, PROV_R_INSUFFICIENT_DRBG_STRENGTH); goto end; @@ -556,7 +500,7 @@ int PROV_DRBG_instantiate(PROV_DRBG *drbg, unsigned int strength, } drbg->state = EVP_RAND_STATE_READY; - drbg->reseed_gen_counter = 1; + drbg->generate_counter = 1; drbg->reseed_time = time(NULL); tsan_store(&drbg->reseed_counter, drbg->reseed_next_counter); @@ -576,7 +520,7 @@ int PROV_DRBG_instantiate(PROV_DRBG *drbg, unsigned int strength, * * Returns 1 on success, 0 on failure. */ -int PROV_DRBG_uninstantiate(PROV_DRBG *drbg) +int ossl_prov_drbg_uninstantiate(PROV_DRBG *drbg) { drbg->state = EVP_RAND_STATE_UNINITIALISED; return 1; @@ -589,13 +533,16 @@ int PROV_DRBG_uninstantiate(PROV_DRBG *drbg) * * Returns 1 on success, 0 on failure. */ -int PROV_DRBG_reseed(PROV_DRBG *drbg, int prediction_resistance, - const unsigned char *ent, size_t ent_len, - const unsigned char *adin, size_t adinlen) +int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adinlen) { unsigned char *entropy = NULL; size_t entropylen = 0; + if (!ossl_prov_is_running()) + return 0; + if (drbg->state != EVP_RAND_STATE_READY) { /* try to recover from previous errors */ rand_drbg_restart(drbg); @@ -640,7 +587,7 @@ int PROV_DRBG_reseed(PROV_DRBG *drbg, int prediction_resistance, } if (ent != NULL) { -#ifdef FIP_MODULE +#ifdef FIPS_MODULE /* * NIST SP-800-90A mandates that entropy *shall not* be provided * by the consuming application. Instead the data is added as additional @@ -677,7 +624,7 @@ int PROV_DRBG_reseed(PROV_DRBG *drbg, int prediction_resistance, goto end; drbg->state = EVP_RAND_STATE_READY; - drbg->reseed_gen_counter = 1; + drbg->generate_counter = 1; drbg->reseed_time = time(NULL); tsan_store(&drbg->reseed_counter, drbg->reseed_next_counter); if (drbg->parent != NULL) @@ -700,13 +647,16 @@ int PROV_DRBG_reseed(PROV_DRBG *drbg, int prediction_resistance, * Returns 1 on success, 0 on failure. * */ -int PROV_DRBG_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, - unsigned int strength, int prediction_resistance, - const unsigned char *adin, size_t adinlen) +int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, + unsigned int strength, int prediction_resistance, + const unsigned char *adin, size_t adinlen) { int fork_id; int reseed_required = 0; + if (!ossl_prov_is_running()) + return 0; + if (drbg->state != EVP_RAND_STATE_READY) { /* try to recover from previous errors */ rand_drbg_restart(drbg); @@ -742,7 +692,7 @@ int PROV_DRBG_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, } if (drbg->reseed_interval > 0) { - if (drbg->reseed_gen_counter >= drbg->reseed_interval) + if (drbg->generate_counter >= drbg->reseed_interval) reseed_required = 1; } if (drbg->reseed_time_interval > 0) { @@ -756,8 +706,8 @@ int PROV_DRBG_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, reseed_required = 1; if (reseed_required || prediction_resistance) { - if (!PROV_DRBG_reseed(drbg, prediction_resistance, NULL, 0, - adin, adinlen)) { + if (!ossl_prov_drbg_reseed(drbg, prediction_resistance, NULL, 0, + adin, adinlen)) { PROVerr(0, PROV_R_RESEED_ERROR); return 0; } @@ -771,7 +721,7 @@ int PROV_DRBG_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, return 0; } - drbg->reseed_gen_counter++; + drbg->generate_counter++; return 1; } @@ -810,7 +760,7 @@ static int rand_drbg_restart(PROV_DRBG *drbg) /* repair uninitialized state */ if (drbg->state == EVP_RAND_STATE_UNINITIALISED) /* reinstantiate drbg */ - PROV_DRBG_instantiate(drbg, drbg->strength, 0, NULL, 0); + ossl_prov_drbg_instantiate(drbg, drbg->strength, 0, NULL, 0); rand_pool_free(drbg->seed_pool); drbg->seed_pool = NULL; @@ -870,10 +820,14 @@ PROV_DRBG *prov_rand_drbg_new int (*generate)(PROV_DRBG *, unsigned char *out, size_t outlen, const unsigned char *adin, size_t adin_len)) { - PROV_DRBG *drbg = OPENSSL_zalloc(sizeof(*drbg)); + PROV_DRBG *drbg; unsigned int p_str; const OSSL_DISPATCH *pfunc; + if (!ossl_prov_is_running()) + return NULL; + + drbg = OPENSSL_zalloc(sizeof(*drbg)); if (drbg == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); return NULL; @@ -906,7 +860,7 @@ PROV_DRBG *prov_rand_drbg_new drbg->max_noncelen = DRBG_MAX_LENGTH; drbg->max_perslen = DRBG_MAX_LENGTH; drbg->max_adinlen = DRBG_MAX_LENGTH; - drbg->reseed_gen_counter = 1; + drbg->generate_counter = 1; drbg->reseed_counter = 1; drbg->reseed_interval = RESEED_INTERVAL; drbg->reseed_time_interval = TIME_INTERVAL; @@ -995,7 +949,7 @@ int drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time_interval)) return 0; - p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_CTR); + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_COUNTER); if (p != NULL && !OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter))) return 0; @@ -1015,22 +969,3 @@ int drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]) return 0; return 1; } - -int drbg_set_callbacks(void *vctx, OSSL_INOUT_CALLBACK *get_entropy_fn, - OSSL_CALLBACK *cleanup_entropy_fn, - OSSL_INOUT_CALLBACK *get_nonce_fn, - OSSL_CALLBACK *cleanup_nonce_fn, void *arg) -{ - PROV_DRBG *drbg = vctx; - - if (drbg->state != EVP_RAND_STATE_UNINITIALISED - || drbg->parent != NULL) - return 0; - - drbg->get_entropy_fn = get_entropy_fn; - drbg->cleanup_entropy_fn = cleanup_entropy_fn; - drbg->get_nonce_fn = get_nonce_fn; - drbg->cleanup_nonce_fn = cleanup_nonce_fn; - drbg->callback_arg = arg; - return 1; -} diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c index 48fb7ebd3d..be6ea5ebfe 100644 --- a/providers/implementations/rands/drbg_ctr.c +++ b/providers/implementations/rands/drbg_ctr.c @@ -330,8 +330,8 @@ static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength, { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); } static int drbg_ctr_reseed(PROV_DRBG *drbg, @@ -355,8 +355,8 @@ static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance, { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_reseed(drbg, prediction_resistance, ent, ent_len, - adin, adin_len); + return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len, + adin, adin_len); } static void ctr96_inc(unsigned char *counter) @@ -452,8 +452,8 @@ static int drbg_ctr_generate_wrapper { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_generate(drbg, out, outlen, strength, - prediction_resistance, adin, adin_len); + return ossl_prov_drbg_generate(drbg, out, outlen, strength, + prediction_resistance, adin, adin_len); } static int drbg_ctr_uninstantiate(PROV_DRBG *drbg) @@ -465,7 +465,7 @@ static int drbg_ctr_uninstantiate(PROV_DRBG *drbg) OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp)); OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX)); ctr->bltmp_pos = 0; - return PROV_DRBG_uninstantiate(drbg); + return ossl_prov_drbg_uninstantiate(drbg); } static int drbg_ctr_uninstantiate_wrapper(void *vdrbg) @@ -631,14 +631,29 @@ static void drbg_ctr_free(void *vdrbg) static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data; + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF); + if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER); + if (p != NULL) { + if (ctr->cipher_ctr == NULL + || !OSSL_PARAM_set_utf8_string(p, EVP_CIPHER_name(ctr->cipher_ctr))) + return 0; + } return drbg_get_ctx_params(drbg, params); } -static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(void) +static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_DRBG_GETABLE_CTX_COMMON, + OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0), + OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL), + OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_gettable_ctx_params; @@ -648,7 +663,7 @@ static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_DRBG *ctx = (PROV_DRBG *)vctx; PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); const OSSL_PARAM *p; char *ecb; const char *propquery = NULL; @@ -701,7 +716,7 @@ static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return drbg_set_ctx_params(ctx, params); } -static const OSSL_PARAM *drbg_ctr_settable_ctx_params(void) +static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0), @@ -714,13 +729,13 @@ static const OSSL_PARAM *drbg_ctr_settable_ctx_params(void) */ OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL), #endif - OSSL_PARAM_DRBG_SETABLE_CTX_COMMON, + OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_settable_ctx_params; } -const OSSL_DISPATCH drbg_ctr_functions[] = { +const OSSL_DISPATCH ossl_drbg_ctr_functions[] = { { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper }, { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free }, { OSSL_FUNC_RAND_INSTANTIATE, @@ -738,7 +753,6 @@ const OSSL_DISPATCH drbg_ctr_functions[] = { { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, (void(*)(void))drbg_ctr_gettable_ctx_params }, { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params }, - { OSSL_FUNC_RAND_SET_CALLBACKS, (void(*)(void))drbg_set_callbacks }, { OSSL_FUNC_RAND_VERIFY_ZEROIZATION, (void(*)(void))drbg_ctr_verify_zeroization }, { 0, NULL } diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c index f655dc57c6..2b7ac2bd5f 100644 --- a/providers/implementations/rands/drbg_hash.c +++ b/providers/implementations/rands/drbg_hash.c @@ -270,8 +270,8 @@ static int drbg_hash_instantiate_wrapper(void *vdrbg, unsigned int strength, { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); } /* @@ -304,8 +304,8 @@ static int drbg_hash_reseed_wrapper(void *vdrbg, int prediction_resistance, { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_reseed(drbg, prediction_resistance, ent, ent_len, - adin, adin_len); + return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len, + adin, adin_len); } /* @@ -323,7 +323,7 @@ static int drbg_hash_generate(PROV_DRBG *drbg, { PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)drbg->data; unsigned char counter[4]; - int reseed_counter = drbg->reseed_gen_counter; + int reseed_counter = drbg->generate_counter; counter[0] = (unsigned char)((reseed_counter >> 24) & 0xff); counter[1] = (unsigned char)((reseed_counter >> 16) & 0xff); @@ -352,8 +352,8 @@ static int drbg_hash_generate_wrapper { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_generate(drbg, out, outlen, strength, - prediction_resistance, adin, adin_len); + return ossl_prov_drbg_generate(drbg, out, outlen, strength, + prediction_resistance, adin, adin_len); } static int drbg_hash_uninstantiate(PROV_DRBG *drbg) @@ -363,7 +363,7 @@ static int drbg_hash_uninstantiate(PROV_DRBG *drbg) OPENSSL_cleanse(hash->V, sizeof(hash->V)); OPENSSL_cleanse(hash->C, sizeof(hash->C)); OPENSSL_cleanse(hash->vtmp, sizeof(hash->vtmp)); - return PROV_DRBG_uninstantiate(drbg); + return ossl_prov_drbg_uninstantiate(drbg); } static int drbg_hash_uninstantiate_wrapper(void *vdrbg) @@ -428,14 +428,25 @@ static void drbg_hash_free(void *vdrbg) static int drbg_hash_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)drbg->data; + const EVP_MD *md; + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST); + if (p != NULL) { + md = ossl_prov_digest_md(&hash->digest); + if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_name(md))) + return 0; + } return drbg_get_ctx_params(drbg, params); } -static const OSSL_PARAM *drbg_hash_gettable_ctx_params(void) +static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_DRBG_GETABLE_CTX_COMMON, + OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_gettable_ctx_params; @@ -445,7 +456,7 @@ static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_DRBG *ctx = (PROV_DRBG *)vctx; PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)ctx->data; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); const EVP_MD *md; if (!ossl_prov_digest_load_from_params(&hash->digest, params, libctx)) @@ -476,18 +487,18 @@ static int drbg_hash_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return drbg_set_ctx_params(ctx, params); } -static const OSSL_PARAM *drbg_hash_settable_ctx_params(void) +static const OSSL_PARAM *drbg_hash_settable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0), - OSSL_PARAM_DRBG_SETABLE_CTX_COMMON, + OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_settable_ctx_params; } -const OSSL_DISPATCH drbg_hash_functions[] = { +const OSSL_DISPATCH ossl_drbg_hash_functions[] = { { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_hash_new_wrapper }, { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_hash_free }, { OSSL_FUNC_RAND_INSTANTIATE, @@ -505,7 +516,6 @@ const OSSL_DISPATCH drbg_hash_functions[] = { { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, (void(*)(void))drbg_hash_gettable_ctx_params }, { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_hash_get_ctx_params }, - { OSSL_FUNC_RAND_SET_CALLBACKS, (void(*)(void))drbg_set_callbacks }, { OSSL_FUNC_RAND_VERIFY_ZEROIZATION, (void(*)(void))drbg_hash_verify_zeroization }, { 0, NULL } diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c index 7ddfae1568..95ee2a1db5 100644 --- a/providers/implementations/rands/drbg_hmac.c +++ b/providers/implementations/rands/drbg_hmac.c @@ -154,8 +154,8 @@ static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength, { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); } /* @@ -182,8 +182,8 @@ static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance, { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_reseed(drbg, prediction_resistance, ent, ent_len, - adin, adin_len); + return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len, + adin, adin_len); } /* @@ -251,8 +251,8 @@ static int drbg_hmac_generate_wrapper { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; - return PROV_DRBG_generate(drbg, out, outlen, strength, - prediction_resistance, adin, adin_len); + return ossl_prov_drbg_generate(drbg, out, outlen, strength, + prediction_resistance, adin, adin_len); } static int drbg_hmac_uninstantiate(PROV_DRBG *drbg) @@ -261,7 +261,7 @@ static int drbg_hmac_uninstantiate(PROV_DRBG *drbg) OPENSSL_cleanse(hmac->K, sizeof(hmac->K)); OPENSSL_cleanse(hmac->V, sizeof(hmac->V)); - return PROV_DRBG_uninstantiate(drbg); + return ossl_prov_drbg_uninstantiate(drbg); } static int drbg_hmac_uninstantiate_wrapper(void *vdrbg) @@ -325,14 +325,36 @@ static void drbg_hmac_free(void *vdrbg) static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) { PROV_DRBG *drbg = (PROV_DRBG *)vdrbg; + PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data; + const char *name; + const EVP_MD *md; + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAC); + if (p != NULL) { + if (hmac->ctx == NULL) + return 0; + name = EVP_MAC_name(EVP_MAC_CTX_mac(hmac->ctx)); + if (!OSSL_PARAM_set_utf8_string(p, name)) + return 0; + } + + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST); + if (p != NULL) { + md = ossl_prov_digest_md(&hmac->digest); + if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_name(md))) + return 0; + } return drbg_get_ctx_params(drbg, params); } -static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(void) +static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_DRBG_GETABLE_CTX_COMMON, + OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_gettable_ctx_params; @@ -342,7 +364,7 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_DRBG *ctx = (PROV_DRBG *)vctx; PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)ctx->data; - OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(ctx->provctx); + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); const EVP_MD *md; if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx)) @@ -378,19 +400,19 @@ static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return drbg_set_ctx_params(ctx, params); } -static const OSSL_PARAM *drbg_hmac_settable_ctx_params(void) +static const OSSL_PARAM *drbg_hmac_settable_ctx_params(ossl_unused void *p_ctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0), - OSSL_PARAM_DRBG_SETABLE_CTX_COMMON, + OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_settable_ctx_params; } -const OSSL_DISPATCH drbg_hmac_functions[] = { +const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[] = { { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_hmac_new_wrapper }, { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_hmac_free }, { OSSL_FUNC_RAND_INSTANTIATE, @@ -408,7 +430,6 @@ const OSSL_DISPATCH drbg_hmac_functions[] = { { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, (void(*)(void))drbg_hmac_gettable_ctx_params }, { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_hmac_get_ctx_params }, - { OSSL_FUNC_RAND_SET_CALLBACKS, (void(*)(void))drbg_set_callbacks }, { OSSL_FUNC_RAND_VERIFY_ZEROIZATION, (void(*)(void))drbg_hmac_verify_zeroization }, { 0, NULL } diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h index 06e2e95a69..40ca6fadaa 100644 --- a/providers/implementations/rands/drbg_local.h +++ b/providers/implementations/rands/drbg_local.h @@ -150,7 +150,7 @@ struct prov_drbg_st { * (Starts at 1). This value is the reseed_counter as defined in * NIST SP 800-90Ar1 */ - unsigned int reseed_gen_counter; + unsigned int generate_counter; /* * Maximum number of generate requests until a reseed is required. * This value is ignored if it is zero. @@ -205,28 +205,19 @@ PROV_DRBG *prov_rand_drbg_new const unsigned char *adin, size_t adin_len)); void prov_rand_drbg_free(PROV_DRBG *drbg); -int PROV_DRBG_instantiate(PROV_DRBG *drbg, unsigned int strength, - int prediction_resistance, - const unsigned char *pers, size_t perslen); +int ossl_prov_drbg_instantiate(PROV_DRBG *drbg, unsigned int strength, + int prediction_resistance, + const unsigned char *pers, size_t perslen); -int PROV_DRBG_uninstantiate(PROV_DRBG *drbg); +int ossl_prov_drbg_uninstantiate(PROV_DRBG *drbg); -int PROV_DRBG_reseed(PROV_DRBG *drbg, int prediction_resistance, - const unsigned char *ent, size_t ent_len, - const unsigned char *adin, size_t adinlen); +int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance, + const unsigned char *ent, size_t ent_len, + const unsigned char *adin, size_t adinlen); -int PROV_DRBG_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, - unsigned int strength, int prediction_resistance, - const unsigned char *adin, size_t adinlen); - -/* - * Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests. - * These need to be exposed for the unit tests. - */ -int drbg_set_callbacks(void *vctx, OSSL_INOUT_CALLBACK *get_entropy_fn, - OSSL_CALLBACK *cleanup_entropy_fn, - OSSL_INOUT_CALLBACK *get_nonce_fn, - OSSL_CALLBACK *cleanup_nonce_fn, void *arg); +int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen, + unsigned int strength, int prediction_resistance, + const unsigned char *adin, size_t adinlen); /* Verify that an array of numeric values is all zero */ #define PROV_DRBG_VERYIFY_ZEROIZATION(v) \ @@ -247,11 +238,11 @@ OSSL_FUNC_rand_unlock_fn drbg_unlock; int drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[]); int drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]); -#define OSSL_PARAM_DRBG_SETABLE_CTX_COMMON \ +#define OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON \ OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL), \ OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL) -#define OSSL_PARAM_DRBG_GETABLE_CTX_COMMON \ +#define OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON \ OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL), \ OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), \ OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_REQUEST, NULL), \ @@ -261,7 +252,7 @@ int drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[]); OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_NONCELEN, NULL), \ OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_PERSLEN, NULL), \ OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_ADINLEN, NULL), \ - OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_CTR, NULL), \ + OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_COUNTER, NULL), \ OSSL_PARAM_time_t(OSSL_DRBG_PARAM_RESEED_TIME, NULL), \ OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, NULL), \ OSSL_PARAM_uint64(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, NULL) diff --git a/providers/implementations/rands/seeding/rand_cpu_x86.c b/providers/implementations/rands/seeding/rand_cpu_x86.c index fd47de9ad0..46ced51af2 100644 --- a/providers/implementations/rands/seeding/rand_cpu_x86.c +++ b/providers/implementations/rands/seeding/rand_cpu_x86.c @@ -13,8 +13,15 @@ #include "prov/seeding.h" #ifdef OPENSSL_RAND_SEED_RDCPU +# if defined(OPENSSL_SYS_TANDEM) && defined(_TNS_X_TARGET) +# include /* _rdrand64 */ +# include /* memcpy */ +# else size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len); size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len); +# endif + +static size_t get_hardware_random_value(unsigned char *buf, size_t len); /* * Acquire entropy using Intel-specific cpu instructions @@ -38,17 +45,8 @@ size_t prov_acquire_entropy_from_cpu(RAND_POOL *pool) buffer = rand_pool_add_begin(pool, bytes_needed); if (buffer != NULL) { - /* Whichever comes first, use RDSEED, RDRAND or nothing */ - if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) { - if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed) - == bytes_needed) { - rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); - } - } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) { - if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed) - == bytes_needed) { - rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); - } + if (get_hardware_random_value(buffer, bytes_needed) == bytes_needed) { + rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed); } else { rand_pool_add_end(pool, 0, 0); } @@ -57,6 +55,53 @@ size_t prov_acquire_entropy_from_cpu(RAND_POOL *pool) return rand_pool_entropy_available(pool); } + +#if defined(OPENSSL_SYS_TANDEM) && defined(_TNS_X_TARGET) +/* Obtain random bytes from the x86 hardware random function in 64 bit chunks */ +static size_t get_hardware_random_value(unsigned char *buf, size_t len) +{ + size_t bytes_remaining = len; + + while (bytes_remaining > 0) { + /* Always use 64 bit fetch, then use the lower bytes as needed. */ + /* The platform is big-endian. */ + uint64_t random_value = 0; + + if (_rdrand64(&random_value) != 0) { + unsigned char *random_buffer = (unsigned char *)&random_value; + + if (bytes_remaining >= sizeof(random_value)) { + memcpy(buf, random_buffer, sizeof(random_value)); + bytes_remaining -= sizeof(random_value); + buf += sizeof(random_value); + } else { + memcpy(buf, + random_buffer + (sizeof(random_value) - bytes_remaining), + bytes_remaining); + bytes_remaining = 0; /* This will terminate the loop */ + } + } else + break; + } + if (bytes_remaining == 0) + return len; + return 0; +} +#else +static size_t get_hardware_random_value(unsigned char *buf, size_t len) { + /* Whichever comes first, use RDSEED, RDRAND or nothing */ + if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) { + if (OPENSSL_ia32_rdseed_bytes(buf, len) != len) + return 0; + } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) { + if (OPENSSL_ia32_rdrand_bytes(buf, len) != len) + return 0; + } else + return 0; + return len; +} +#endif + #else NON_EMPTY_TRANSLATION_UNIT #endif diff --git a/providers/implementations/rands/seeding/rand_unix.c b/providers/implementations/rands/seeding/rand_unix.c index 26d81d6054..ddd453fff8 100644 --- a/providers/implementations/rands/seeding/rand_unix.c +++ b/providers/implementations/rands/seeding/rand_unix.c @@ -376,12 +376,19 @@ static ssize_t syscall_random(void *buf, size_t buflen) * - OpenBSD since 5.6 * - Linux since 3.17 with glibc 2.25 * - FreeBSD since 12.0 (1200061) + * + * Note: Sometimes getentropy() can be provided but not implemented + * internally. So we need to check errno for ENOSYS */ # if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux) extern int getentropy(void *buffer, size_t length) __attribute__((weak)); - if (getentropy != NULL) - return getentropy(buf, buflen) == 0 ? (ssize_t)buflen : -1; + if (getentropy != NULL) { + if (getentropy(buf, buflen) == 0) + return (ssize_t)buflen; + if (errno != ENOSYS) + return -1; + } # elif !defined(FIPS_MODULE) union { void *p; diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c index 7303d36f2f..bb0d2a46a9 100644 --- a/providers/implementations/rands/test_rng.c +++ b/providers/implementations/rands/test_rng.c @@ -94,8 +94,8 @@ static int test_rng_instantiate_wrapper(void *vdrbg, unsigned int strength, if (pstr != NULL && pstr_len >= drbg->max_perslen) return 0; - return PROV_DRBG_instantiate(drbg, strength, prediction_resistance, - pstr, pstr_len); + return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance, + pstr, pstr_len); } static int test_rng_uninstantiate(PROV_DRBG *drbg) @@ -103,7 +103,7 @@ static int test_rng_uninstantiate(PROV_DRBG *drbg) PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data; t->entropy_pos = 0; - return PROV_DRBG_uninstantiate(drbg); + return ossl_prov_drbg_uninstantiate(drbg); } static int test_rng_uninstantiate_wrapper(void *vdrbg) @@ -186,10 +186,10 @@ static int test_rng_get_ctx_params(void *vdrbg, OSSL_PARAM params[]) return drbg_get_ctx_params(drbg, params); } -static const OSSL_PARAM *test_rng_gettable_ctx_params(void) +static const OSSL_PARAM *test_rng_gettable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_gettable_ctx_params[] = { - OSSL_PARAM_DRBG_GETABLE_CTX_COMMON, + OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_gettable_ctx_params; @@ -236,7 +236,7 @@ static int test_rng_set_ctx_params(void *vdrbg, const OSSL_PARAM params[]) t->nonce_len = size; } - p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_CTR); + p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_COUNTER); if (p != NULL) { if (!OSSL_PARAM_get_uint(p, &uint)) return 0; @@ -264,7 +264,7 @@ static int test_rng_set_ctx_params(void *vdrbg, const OSSL_PARAM params[]) return drbg_set_ctx_params(drbg, params); } -static const OSSL_PARAM *test_rng_settable_ctx_params(void) +static const OSSL_PARAM *test_rng_settable_ctx_params(ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, NULL, 0), @@ -277,9 +277,9 @@ static const OSSL_PARAM *test_rng_settable_ctx_params(void) OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_NONCELEN, NULL), OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_PERSLEN, NULL), OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_ADINLEN, NULL), - OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_CTR, NULL), + OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_COUNTER, NULL), OSSL_PARAM_time_t(OSSL_DRBG_PARAM_RESEED_TIME, NULL), - OSSL_PARAM_DRBG_SETABLE_CTX_COMMON, + OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON, OSSL_PARAM_END }; return known_settable_ctx_params; @@ -299,7 +299,7 @@ static void *test_rng_new_wrapper(void *provctx, void *parent, &test_rng_generate); } -const OSSL_DISPATCH test_rng_functions[] = { +const OSSL_DISPATCH ossl_test_rng_functions[] = { { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))test_rng_new_wrapper }, { OSSL_FUNC_RAND_FREECTX, (void(*)(void))test_rng_free }, { OSSL_FUNC_RAND_INSTANTIATE, diff --git a/providers/implementations/serializers/build.info b/providers/implementations/serializers/build.info deleted file mode 100644 index d660385163..0000000000 --- a/providers/implementations/serializers/build.info +++ /dev/null @@ -1,31 +0,0 @@ -# We make separate GOAL variables for each algorithm, to make it easy to -# switch each to the Legacy provider when needed. - -$SERIALIZER_GOAL=../../libimplementations.a -$DESERIALIZER_GOAL=../../libimplementations.a -$RSA_GOAL=../../libimplementations.a -$FFC_GOAL=../../libimplementations.a -$DH_GOAL=../../libimplementations.a -$DSA_GOAL=../../libimplementations.a -$ECX_GOAL=../../libimplementations.a -$EC_GOAL=../../libimplementations.a - -SOURCE[$SERIALIZER_GOAL]=serializer_common.c deserialize_common.c - -SOURCE[$RSA_GOAL]=deserialize_der2key.c deserialize_pem2der.c -SOURCE[$RSA_GOAL]=serializer_rsa.c serializer_rsa_priv.c serializer_rsa_pub.c -DEPEND[serializer_rsa.o]=../../common/include/prov/der_rsa.h - -IF[{- !$disabled{"dh"} || !$disabled{"dsa"} -}] - SOURCE[$FFC_GOAL]=serializer_ffc_params.c -ENDIF -IF[{- !$disabled{dh} -}] - SOURCE[$DH_GOAL]=serializer_dh.c serializer_dh_priv.c serializer_dh_pub.c serializer_dh_param.c -ENDIF -IF[{- !$disabled{dsa} -}] - SOURCE[$DSA_GOAL]=serializer_dsa.c serializer_dsa_priv.c serializer_dsa_pub.c serializer_dsa_param.c -ENDIF -IF[{- !$disabled{ec} -}] - SOURCE[$ECX_GOAL]=serializer_ecx.c serializer_ecx_priv.c serializer_ecx_pub.c - SOURCE[$EC_GOAL]=serializer_ec.c serializer_ec_priv.c serializer_ec_pub.c serializer_ec_param.c -ENDIF diff --git a/providers/implementations/serializers/deserialize_common.c b/providers/implementations/serializers/deserialize_common.c deleted file mode 100644 index 1a9d3d4a77..0000000000 --- a/providers/implementations/serializers/deserialize_common.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "internal/cryptlib.h" -#include "crypto/asn1.h" -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */ -#include "serializer_local.h" - -int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - unsigned char **data, long *len) -{ - BUF_MEM *mem = NULL; - BIO *in = bio_new_from_core_bio(provctx, cin); - int ok = (asn1_d2i_read_bio(in, &mem) >= 0); - - if (ok) { - *data = (unsigned char *)mem->data; - *len = (long)mem->length; - OPENSSL_free(mem); - } - BIO_free(in); - return ok; -} - -int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - char **pem_name, char **pem_header, - unsigned char **data, long *len) -{ - BIO *in = bio_new_from_core_bio(provctx, cin); - int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0); - - BIO_free(in); - return ok; -} - -int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len, - unsigned char *input_der, long input_der_len, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) -{ - const unsigned char *derp; - X509_SIG *p8 = NULL; - int ok = 0; - - if (!ossl_assert(new_der != NULL && *new_der == NULL) - || !ossl_assert(new_der_len != NULL)) - return 0; - - derp = input_der; - if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) { - char pbuf[PEM_BUFSIZE]; - size_t plen = 0; - - if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) { - ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); - } else { - const X509_ALGOR *alg = NULL; - const ASN1_OCTET_STRING *oct = NULL; - int len = 0; - - X509_SIG_get0(p8, &alg, &oct); - if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length, - new_der, &len, 0) != NULL) - ok = 1; - *new_der_len = len; - } - } - X509_SIG_free(p8); - return ok; -} diff --git a/providers/implementations/serializers/deserialize_pem2der.c b/providers/implementations/serializers/deserialize_pem2der.c deleted file mode 100644 index cbd0867da9..0000000000 --- a/providers/implementations/serializers/deserialize_pem2der.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * RSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include - -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "serializer_local.h" - -static OSSL_FUNC_deserializer_newctx_fn pem2der_newctx; -static OSSL_FUNC_deserializer_freectx_fn pem2der_freectx; -static OSSL_FUNC_deserializer_gettable_params_fn pem2der_gettable_params; -static OSSL_FUNC_deserializer_get_params_fn pem2der_get_params; -static OSSL_FUNC_deserializer_deserialize_fn pem2der_deserialize; - -/* - * Context used for PEM to DER deserialization. - */ -struct pem2der_ctx_st { - PROV_CTX *provctx; -}; - -static void *pem2der_newctx(void *provctx) -{ - struct pem2der_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) - ctx->provctx = provctx; - return ctx; -} - -static void pem2der_freectx(void *vctx) -{ - struct pem2der_ctx_st *ctx = vctx; - - OPENSSL_free(ctx); -} - -static const OSSL_PARAM *pem2der_gettable_params(void) -{ - static const OSSL_PARAM gettables[] = { - { OSSL_DESERIALIZER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, - OSSL_PARAM_END, - }; - - return gettables; -} - -static int pem2der_get_params(OSSL_PARAM params[]) -{ - OSSL_PARAM *p; - - p = OSSL_PARAM_locate(params, OSSL_DESERIALIZER_PARAM_INPUT_TYPE); - if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "PEM")) - return 0; - - return 1; -} - -/* pem_password_cb compatible function */ -struct pem2der_pass_data_st { - OSSL_PASSPHRASE_CALLBACK *cb; - void *cbarg; -}; - -static int pem2der_pass_helper(char *buf, int num, int w, void *data) -{ - struct pem2der_pass_data_st *pass_data = data; - size_t plen; - - if (pass_data == NULL - || pass_data->cb == NULL - || !pass_data->cb(buf, num, &plen, NULL, pass_data->cbarg)) - return -1; - return (int)plen; -} - -static int pem2der_deserialize(void *vctx, OSSL_CORE_BIO *cin, - OSSL_CALLBACK *data_cb, void *data_cbarg, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) -{ - struct pem2der_ctx_st *ctx = vctx; - char *pem_name = NULL, *pem_header = NULL; - unsigned char *der = NULL; - long der_len = 0; - int ok = 0; - - if (ossl_prov_read_pem(ctx->provctx, cin, &pem_name, &pem_header, - &der, &der_len) <= 0) - return 0; - - /* - * 10 is the number of characters in "Proc-Type:", which - * PEM_get_EVP_CIPHER_INFO() requires to be present. - * If the PEM header has less characters than that, it's - * not worth spending cycles on it. - */ - if (strlen(pem_header) > 10) { - EVP_CIPHER_INFO cipher; - struct pem2der_pass_data_st pass_data; - - pass_data.cb = pw_cb; - pass_data.cbarg = pw_cbarg; - if (!PEM_get_EVP_CIPHER_INFO(pem_header, &cipher) - || !PEM_do_header(&cipher, der, &der_len, - pem2der_pass_helper, &pass_data)) - goto end; - } - - { - OSSL_PARAM params[3]; - - params[0] = - OSSL_PARAM_construct_utf8_string(OSSL_DESERIALIZER_PARAM_DATA_TYPE, - pem_name, 0); - params[1] = - OSSL_PARAM_construct_octet_string(OSSL_DESERIALIZER_PARAM_DATA, - der, der_len); - params[2] = OSSL_PARAM_construct_end(); - - ok = data_cb(params, data_cbarg); - } - - end: - OPENSSL_free(pem_name); - OPENSSL_free(pem_header); - OPENSSL_free(der); - return ok; -} - -const OSSL_DISPATCH pem_to_der_deserializer_functions[] = { - { OSSL_FUNC_DESERIALIZER_NEWCTX, (void (*)(void))pem2der_newctx }, - { OSSL_FUNC_DESERIALIZER_FREECTX, (void (*)(void))pem2der_freectx }, - { OSSL_FUNC_DESERIALIZER_GETTABLE_PARAMS, - (void (*)(void))pem2der_gettable_params }, - { OSSL_FUNC_DESERIALIZER_GET_PARAMS, - (void (*)(void))pem2der_get_params }, - { OSSL_FUNC_DESERIALIZER_DESERIALIZE, (void (*)(void))pem2der_deserialize }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_common.c b/providers/implementations/serializers/serializer_common.c deleted file mode 100644 index 58d7a27e60..0000000000 --- a/providers/implementations/serializers/serializer_common.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include /* SIXTY_FOUR_BIT_LONG, ... */ -#include -#include /* PEM_BUFSIZE */ -#include /* PKCS8_encrypt() */ -#include -#include /* i2d_X509_PUBKEY_bio() */ -#include "crypto/bn.h" /* bn_get_words() */ -#include "crypto/ctype.h" -#include "crypto/ecx.h" -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/implementations.h" -#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */ -#include "serializer_local.h" - -static PKCS8_PRIV_KEY_INFO * -ossl_prov_p8info_from_obj(const void *obj, int obj_nid, - void *params, - int params_type, - int (*k2d)(const void *obj, - unsigned char **pder)) -{ - /* der, derlen store the key DER output and its length */ - unsigned char *der = NULL; - int derlen; - /* The final PKCS#8 info */ - PKCS8_PRIV_KEY_INFO *p8info = NULL; - - - if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL - || (derlen = k2d(obj, &der)) <= 0 - || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(obj_nid), 0, - params_type, params, der, derlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - PKCS8_PRIV_KEY_INFO_free(p8info); - OPENSSL_free(der); - p8info = NULL; - } - - return p8info; -} - -static X509_SIG *ossl_prov_encp8_from_p8info(PKCS8_PRIV_KEY_INFO *p8info, - struct pkcs8_encrypt_ctx_st *ctx) -{ - X509_SIG *p8 = NULL; - char buf[PEM_BUFSIZE]; - const void *kstr = ctx->cipher_pass; - size_t klen = ctx->cipher_pass_length; - - if (ctx->cipher == NULL) - return NULL; - - if (kstr == NULL) { - if (!ctx->cb(buf, sizeof(buf), &klen, NULL, ctx->cbarg)) { - ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY); - return NULL; - } - kstr = buf; - } - /* NID == -1 means "standard" */ - p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info); - if (kstr == buf) - OPENSSL_cleanse(buf, klen); - return p8; -} - -static X509_SIG *ossl_prov_encp8_from_obj(const void *obj, int obj_nid, - void *params, - int params_type, - int (*k2d)(const void *obj, - unsigned char **pder), - struct pkcs8_encrypt_ctx_st *ctx) -{ - PKCS8_PRIV_KEY_INFO *p8info = - ossl_prov_p8info_from_obj(obj, obj_nid, params, params_type, k2d); - X509_SIG *p8 = ossl_prov_encp8_from_p8info(p8info, ctx); - - PKCS8_PRIV_KEY_INFO_free(p8info); - return p8; -} - -static X509_PUBKEY *ossl_prov_pubkey_from_obj(const void *obj, int obj_nid, - void *params, - int params_type, - int (*k2d)(const void *obj, - unsigned char **pder)) -{ - /* der, derlen store the key DER output and its length */ - unsigned char *der = NULL; - int derlen; - /* The final X509_PUBKEY */ - X509_PUBKEY *xpk = NULL; - - - if ((xpk = X509_PUBKEY_new()) == NULL - || (derlen = k2d(obj, &der)) <= 0 - || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(obj_nid), - params_type, params, der, derlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - X509_PUBKEY_free(xpk); - OPENSSL_free(der); - xpk = NULL; - } - - return xpk; -} - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns) -{ - /* Pilfer the keymgmt dispatch table */ - for (; fns->function_id != 0; fns++) - if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW) - return OSSL_FUNC_keymgmt_new(fns); - - return NULL; -} - -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns) -{ - /* Pilfer the keymgmt dispatch table */ - for (; fns->function_id != 0; fns++) - if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE) - return OSSL_FUNC_keymgmt_free(fns); - - return NULL; -} - -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns) -{ - /* Pilfer the keymgmt dispatch table */ - for (; fns->function_id != 0; fns++) - if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT) - return OSSL_FUNC_keymgmt_import(fns); - - return NULL; -} - -OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns) -{ - /* Pilfer the keymgmt dispatch table */ - for (; fns->function_id != 0; fns++) - if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT) - return OSSL_FUNC_keymgmt_export(fns); - - return NULL; -} - -# ifdef SIXTY_FOUR_BIT_LONG -# define BN_FMTu "%lu" -# define BN_FMTx "%lx" -# endif - -# ifdef SIXTY_FOUR_BIT -# define BN_FMTu "%llu" -# define BN_FMTx "%llx" -# endif - -# ifdef THIRTY_TWO_BIT -# define BN_FMTu "%u" -# define BN_FMTx "%x" -# endif - -int ossl_prov_print_labeled_bignum(BIO *out, const char *label, - const BIGNUM *bn) -{ - int ret = 0, use_sep = 0; - char *hex_str = NULL, *p; - const char spaces[] = " "; - const char *post_label_spc = " "; - - const char *neg = ""; - int bytes; - - if (bn == NULL) - return 0; - if (label == NULL) { - label = ""; - post_label_spc = ""; - } - - if (BN_is_zero(bn)) - return BIO_printf(out, "%s%s0\n", label, post_label_spc); - - if (BN_num_bytes(bn) <= BN_BYTES) { - BN_ULONG *words = bn_get_words(bn); - - if (BN_is_negative(bn)) - neg = "-"; - - return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", - label, post_label_spc, neg, words[0], neg, words[0]); - } - - hex_str = BN_bn2hex(bn); - p = hex_str; - if (*p == '-') { - ++p; - neg = " (Negative)"; - } - if (BIO_printf(out, "%s%s\n", label, neg) <= 0) - goto err; - - /* Keep track of how many bytes we have printed out so far */ - bytes = 0; - - if (BIO_printf(out, "%s", spaces) <= 0) - goto err; - - /* Add a leading 00 if the top bit is set */ - if (*p >= '8') { - if (BIO_printf(out, "%02x", 0) <= 0) - goto err; - ++bytes; - use_sep = 1; - } - while (*p != '\0') { - /* Do a newline after every 15 hex bytes + add the space indent */ - if ((bytes % 15) == 0 && bytes > 0) { - if (BIO_printf(out, ":\n%s", spaces) <= 0) - goto err; - use_sep = 0; /* The first byte on the next line doesnt have a : */ - } - if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", - ossl_tolower(p[0]), ossl_tolower(p[1])) <= 0) - goto err; - ++bytes; - p += 2; - use_sep = 1; - } - if (BIO_printf(out, "\n") <= 0) - goto err; - ret = 1; -err: - OPENSSL_free(hex_str); - return ret; -} - -/* Number of octets per line */ -#define LABELED_BUF_PRINT_WIDTH 15 - -int ossl_prov_print_labeled_buf(BIO *out, const char *label, - const unsigned char *buf, size_t buflen) -{ - size_t i; - - if (BIO_printf(out, "%s\n", label) <= 0) - return 0; - - for (i = 0; i < buflen; i++) { - if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { - if (i > 0 && BIO_printf(out, "\n") <= 0) - return 0; - if (BIO_printf(out, " ") <= 0) - return 0; - } - - if (BIO_printf(out, "%02x%s", buf[i], - (i == buflen - 1) ? "" : ":") <= 0) - return 0; - } - if (BIO_printf(out, "\n") <= 0) - return 0; - - return 1; -} - -/* p2s = param to asn1, k2d = key to der */ -int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder), - struct pkcs8_encrypt_ctx_st *ctx) -{ - int ret = 0; - void *str = NULL; - int strtype = V_ASN1_UNDEF; - - if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) - return 0; - - if (ctx->cipher_intent) { - X509_SIG *p8 = - ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype, k2d, ctx); - - if (p8 != NULL) - ret = i2d_PKCS8_bio(out, p8); - - X509_SIG_free(p8); - } else { - PKCS8_PRIV_KEY_INFO *p8info = - ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d); - - if (p8info != NULL) - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); - - PKCS8_PRIV_KEY_INFO_free(p8info); - } - - return ret; -} - -int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder), - struct pkcs8_encrypt_ctx_st *ctx) -{ - int ret = 0; - void *str = NULL; - int strtype = V_ASN1_UNDEF; - - if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) - return 0; - - if (ctx->cipher_intent) { - X509_SIG *p8 = ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype, - k2d, ctx); - - if (p8 != NULL) - ret = PEM_write_bio_PKCS8(out, p8); - - X509_SIG_free(p8); - } else { - PKCS8_PRIV_KEY_INFO *p8info = - ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d); - - if (p8info != NULL) - ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); - - PKCS8_PRIV_KEY_INFO_free(p8info); - } - - return ret; -} - -int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder)) -{ - int ret = 0; - void *str = NULL; - int strtype = V_ASN1_UNDEF; - X509_PUBKEY *xpk = NULL; - - if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) - return 0; - - xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d); - - if (xpk != NULL) - ret = i2d_X509_PUBKEY_bio(out, xpk); - - /* Also frees |str| */ - X509_PUBKEY_free(xpk); - return ret; -} - -int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder)) -{ - int ret = 0; - void *str = NULL; - int strtype = V_ASN1_UNDEF; - X509_PUBKEY *xpk = NULL; - - if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype)) - return 0; - - xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d); - - if (xpk != NULL) - ret = PEM_write_bio_X509_PUBKEY(out, xpk); - - /* Also frees |str| */ - X509_PUBKEY_free(xpk); - return ret; -} diff --git a/providers/implementations/serializers/serializer_dh.c b/providers/implementations/serializers/serializer_dh.c deleted file mode 100644 index 03bb874a64..0000000000 --- a/providers/implementations/serializers/serializer_dh.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DH low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/implementations.h" /* rsa_keymgmt_functions */ -#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */ -#include "internal/ffc.h" -#include "crypto/dh.h" -#include "serializer_local.h" - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void) -{ - return ossl_prov_get_keymgmt_new(dh_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void) -{ - return ossl_prov_get_keymgmt_free(dh_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void) -{ - return ossl_prov_get_keymgmt_import(dh_keymgmt_functions); -} - -int ossl_prov_print_dh(BIO *out, DH *dh, enum dh_print_type type) -{ - const char *type_label = NULL; - const BIGNUM *priv_key = NULL, *pub_key = NULL; - const BIGNUM *p = NULL; - - switch (type) { - case dh_print_priv: - type_label = "DH Private-Key"; - break; - case dh_print_pub: - type_label = "DH Public-Key"; - break; - case dh_print_params: - type_label = "DH Parameters"; - break; - } - - if (type == dh_print_priv) { - priv_key = DH_get0_priv_key(dh); - if (priv_key == NULL) - goto null_err; - } - - if (type == dh_print_priv || type == dh_print_pub) { - pub_key = DH_get0_pub_key(dh); - if (pub_key == NULL) - goto null_err; - } - - p = DH_get0_p(dh); - if (p == NULL) - goto null_err; - - if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) - <= 0) - goto err; - if (priv_key != NULL - && !ossl_prov_print_labeled_bignum(out, "private-key:", priv_key)) - goto err; - if (pub_key != NULL - && !ossl_prov_print_labeled_bignum(out, "public-key:", pub_key)) - goto err; - if (!ffc_params_prov_print(out, dh_get0_params(dh))) - goto err; - - return 1; - err: - return 0; - null_err: - ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); - goto err; -} - -int ossl_prov_prepare_dh_params(const void *dh, int nid, - void **pstr, int *pstrtype) -{ - ASN1_STRING *params = ASN1_STRING_new(); - - if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (nid == EVP_PKEY_DHX) - params->length = i2d_DHxparams(dh, ¶ms->data); - else - params->length = i2d_DHparams(dh, ¶ms->data); - - if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(params); - return 0; - } - params->type = V_ASN1_SEQUENCE; - - *pstr = params; - *pstrtype = V_ASN1_SEQUENCE; - return 1; -} - -int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder) -{ - ASN1_INTEGER *pub_key = BN_to_ASN1_INTEGER(DH_get0_pub_key(dh), NULL); - int ret; - - if (pub_key == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); - return 0; - } - - ret = i2d_ASN1_INTEGER(pub_key, pder); - - ASN1_STRING_clear_free(pub_key); - return ret; -} - -int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder) -{ - ASN1_INTEGER *priv_key = BN_to_ASN1_INTEGER(DH_get0_priv_key(dh), NULL); - int ret; - - if (priv_key == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); - return 0; - } - - ret = i2d_ASN1_INTEGER(priv_key, pder); - - ASN1_STRING_clear_free(priv_key); - return ret; -} - diff --git a/providers/implementations/serializers/serializer_dh_param.c b/providers/implementations/serializers/serializer_dh_param.c deleted file mode 100644 index 49c0857734..0000000000 --- a/providers/implementations/serializers/serializer_dh_param.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DH low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn dh_param_newctx; -static OSSL_FUNC_serializer_freectx_fn dh_param_freectx; -static OSSL_FUNC_serializer_serialize_data_fn dh_param_der_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_param_der; -static OSSL_FUNC_serializer_serialize_data_fn dh_param_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_param_pem; - -static OSSL_FUNC_serializer_serialize_data_fn dh_param_print_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_param_print; - -/* Parameters : context */ - -/* - * There's no specific implementation context, so we use the provider context - */ -static void *dh_param_newctx(void *provctx) -{ - return provctx; -} - -static void dh_param_freectx(void *ctx) -{ -} - -/* Public key : DER */ -static int dh_param_der_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - /* ctx == provctx */ - if ((dh = dh_new(ctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && dh_param_der(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_param_der(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - ret = i2d_DHparams_bio(out, dh); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int dh_param_pem_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - /* ctx == provctx */ - if ((dh = dh_new(ctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && dh_param_pem(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_param_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = PEM_write_bio_DHparams(out, dh); - BIO_free(out); - - return ret; -} - -static int dh_param_print_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - /* ctx == provctx */ - if ((dh = dh_new(ctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && dh_param_print(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_param_print(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_dh(out, dh, dh_print_params); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH dh_param_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_param_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_param_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH dh_param_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_param_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_param_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH dh_param_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_param_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))dh_param_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_dh_priv.c b/providers/implementations/serializers/serializer_dh_priv.c deleted file mode 100644 index 2399052f7e..0000000000 --- a/providers/implementations/serializers/serializer_dh_priv.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DH low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn dh_priv_newctx; -static OSSL_FUNC_serializer_freectx_fn dh_priv_freectx; -static OSSL_FUNC_serializer_set_ctx_params_fn dh_priv_set_ctx_params; -static OSSL_FUNC_serializer_settable_ctx_params_fn dh_priv_settable_ctx_params; -static OSSL_FUNC_serializer_serialize_data_fn dh_priv_der_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_priv_der; -static OSSL_FUNC_serializer_serialize_data_fn dh_pem_priv_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_pem_priv; - -static OSSL_FUNC_serializer_newctx_fn dh_print_newctx; -static OSSL_FUNC_serializer_freectx_fn dh_print_freectx; -static OSSL_FUNC_serializer_serialize_data_fn dh_priv_print_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_priv_print; - - /* - * Context used for private key serialization. - */ -struct dh_priv_ctx_st { - void *provctx; - - struct pkcs8_encrypt_ctx_st sc; -}; - -/* Private key : context */ -static void *dh_priv_newctx(void *provctx) -{ - struct dh_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) { - ctx->provctx = provctx; - - /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */ - ctx->sc.pbe_nid = -1; - } - return ctx; -} - -static void dh_priv_freectx(void *vctx) -{ - struct dh_priv_ctx_st *ctx = vctx; - - EVP_CIPHER_free(ctx->sc.cipher); - OPENSSL_free(ctx->sc.cipher_pass); - OPENSSL_free(ctx); -} - -static const OSSL_PARAM *dh_priv_settable_ctx_params(void) -{ - static const OSSL_PARAM settables[] = { - OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0), - OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0), - OSSL_PARAM_END, - }; - - return settables; -} - -static int dh_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - struct dh_priv_ctx_st *ctx = vctx; - const OSSL_PARAM *p; - - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_CIPHER)) - != NULL) { - const OSSL_PARAM *propsp = - OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES); - const char *props = NULL; - - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - props = (propsp != NULL ? propsp->data : NULL); - - EVP_CIPHER_free(ctx->sc.cipher); - ctx->sc.cipher_intent = p->data != NULL; - if (p->data != NULL - && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props)) - == NULL)) - return 0; - } - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS)) - != NULL) { - OPENSSL_free(ctx->sc.cipher_pass); - ctx->sc.cipher_pass = NULL; - if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0, - &ctx->sc.cipher_pass_length)) - return 0; - } - return 1; -} - -/* Private key : DER */ -static int dh_priv_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dh_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - if ((dh = dh_new(ctx->provctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dh_priv_der(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_priv_der(void *vctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dh_priv_ctx_st *ctx = vctx; - int ret; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_der_from_obj(out, dh, EVP_PKEY_DH, - ossl_prov_prepare_dh_params, - ossl_prov_dh_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* Private key : PEM */ -static int dh_pem_priv_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dh_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - if ((dh = dh_new(ctx->provctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dh_pem_priv(ctx->provctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_pem_priv(void *vctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dh_priv_ctx_st *ctx = vctx; - int ret; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_pem_from_obj(out, dh, EVP_PKEY_DH, - ossl_prov_prepare_dh_params, - ossl_prov_dh_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* - * There's no specific print context, so we use the provider context - */ -static void *dh_print_newctx(void *provctx) -{ - return provctx; -} - -static void dh_print_freectx(void *ctx) -{ -} - -static int dh_priv_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dh_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - if ((dh = dh_new(ctx->provctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dh_priv_print(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_priv_print(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_dh(out, dh, dh_print_priv); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH dh_priv_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))dh_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))dh_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_priv_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_priv_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH dh_priv_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))dh_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))dh_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_pem_priv_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pem_priv }, - { 0, NULL } -}; - -const OSSL_DISPATCH dh_priv_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_print_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_print_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_priv_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))dh_priv_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_dh_pub.c b/providers/implementations/serializers/serializer_dh_pub.c deleted file mode 100644 index 6ca79c9444..0000000000 --- a/providers/implementations/serializers/serializer_dh_pub.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DH low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn dh_pub_newctx; -static OSSL_FUNC_serializer_freectx_fn dh_pub_freectx; -static OSSL_FUNC_serializer_serialize_data_fn dh_pub_der_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_pub_der; -static OSSL_FUNC_serializer_serialize_data_fn dh_pub_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_pub_pem; - -static OSSL_FUNC_serializer_serialize_data_fn dh_pub_print_data; -static OSSL_FUNC_serializer_serialize_object_fn dh_pub_print; - -/* Public key : context */ - -/* - * There's no specific implementation context, so we use the provider context - */ -static void *dh_pub_newctx(void *provctx) -{ - return provctx; -} - -static void dh_pub_freectx(void *ctx) -{ -} - -/* Public key : DER */ -static int dh_pub_der_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - /* ctx == provctx */ - if ((dh = dh_new(ctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dh_pub_der(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_pub_der(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_der_from_obj(out, dh, EVP_PKEY_DH, - ossl_prov_prepare_dh_params, - ossl_prov_dh_pub_to_der); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int dh_pub_pem_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - /* ctx == provctx */ - if ((dh = dh_new(ctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dh_pub_pem(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_pub_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_pem_from_obj(out, dh, EVP_PKEY_DH, - ossl_prov_prepare_dh_params, - ossl_prov_dh_pub_to_der); - BIO_free(out); - - return ret; -} - -static int dh_pub_print_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new(); - OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free(); - OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import(); - int ok = 0; - - if (dh_import != NULL) { - DH *dh; - - /* ctx == provctx */ - if ((dh = dh_new(ctx)) != NULL - && dh_import(dh, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dh_pub_print(ctx, dh, out, cb, cbarg)) - ok = 1; - dh_free(dh); - } - return ok; -} - -static int dh_pub_print(void *ctx, void *dh, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_dh(out, dh, dh_print_pub); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH dh_pub_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_pub_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pub_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH dh_pub_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dh_pub_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pub_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH dh_pub_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dh_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dh_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dh_pub_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))dh_pub_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_dsa.c b/providers/implementations/serializers/serializer_dsa.c deleted file mode 100644 index 4389bded99..0000000000 --- a/providers/implementations/serializers/serializer_dsa.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/implementations.h" /* rsa_keymgmt_functions */ -#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */ -#include "serializer_local.h" -#include "internal/ffc.h" -#include "crypto/dsa.h" - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void) -{ - return ossl_prov_get_keymgmt_new(dsa_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dsa_free(void) -{ - return ossl_prov_get_keymgmt_free(dsa_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dsa_import(void) -{ - return ossl_prov_get_keymgmt_import(dsa_keymgmt_functions); -} - -int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type) -{ - const char *type_label = NULL; - const BIGNUM *priv_key = NULL, *pub_key = NULL; - const BIGNUM *p = NULL; - - - switch (type) { - case dsa_print_priv: - type_label = "Private-Key"; - break; - case dsa_print_pub: - type_label = "Public-Key"; - break; - case dsa_print_params: - type_label = "DSA-Parameters"; - break; - } - - if (type == dsa_print_priv) { - priv_key = DSA_get0_priv_key(dsa); - if (priv_key == NULL) - goto null_err; - } - - if (type == dsa_print_priv || type == dsa_print_pub) { - pub_key = DSA_get0_pub_key(dsa); - if (pub_key == NULL) - goto null_err; - } - - - p = DSA_get0_p(dsa); - if (p == NULL) - goto null_err; - - if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) - goto err; - if (priv_key != NULL - && !ossl_prov_print_labeled_bignum(out, "priv:", priv_key)) - goto err; - if (pub_key != NULL - && !ossl_prov_print_labeled_bignum(out, "pub: ", pub_key)) - goto err; - if (!ffc_params_prov_print(out, dsa_get0_params(dsa))) - goto err; - - return 1; - err: - return 0; - null_err: - ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); - goto err; -} - -int ossl_prov_prepare_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype) -{ - ASN1_STRING *params = ASN1_STRING_new(); - - if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return 0; - } - - params->length = i2d_DSAparams(dsa, ¶ms->data); - - if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(params); - return 0; - } - - *pstrtype = V_ASN1_SEQUENCE; - *pstr = params; - return 1; -} - -int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype) -{ - const BIGNUM *p = DSA_get0_p(dsa); - const BIGNUM *q = DSA_get0_q(dsa); - const BIGNUM *g = DSA_get0_g(dsa); - - if (p != NULL && q != NULL && g != NULL) - return ossl_prov_prepare_dsa_params(dsa, nid, pstr, pstrtype); - - *pstr = NULL; - *pstrtype = V_ASN1_UNDEF; - return 1; -} - -int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder) -{ - ASN1_INTEGER *pub_key = BN_to_ASN1_INTEGER(DSA_get0_pub_key(dsa), NULL); - int ret; - - if (pub_key == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); - return 0; - } - - ret = i2d_ASN1_INTEGER(pub_key, pder); - - ASN1_STRING_clear_free(pub_key); - return ret; -} - -int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder) -{ - ASN1_INTEGER *priv_key = BN_to_ASN1_INTEGER(DSA_get0_priv_key(dsa), NULL); - int ret; - - if (priv_key == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR); - return 0; - } - - ret = i2d_ASN1_INTEGER(priv_key, pder); - - ASN1_STRING_clear_free(priv_key); - return ret; -} diff --git a/providers/implementations/serializers/serializer_dsa_param.c b/providers/implementations/serializers/serializer_dsa_param.c deleted file mode 100644 index fff577df39..0000000000 --- a/providers/implementations/serializers/serializer_dsa_param.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn dsa_param_newctx; -static OSSL_FUNC_serializer_freectx_fn dsa_param_freectx; -static OSSL_FUNC_serializer_serialize_data_fn dsa_param_der_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_param_der; -static OSSL_FUNC_serializer_serialize_data_fn dsa_param_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_param_pem; - -static OSSL_FUNC_serializer_serialize_data_fn dsa_param_print_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_param_print; - -/* Parameters : context */ - -/* - * There's no specific implementation context, so we use the provider context - */ -static void *dsa_param_newctx(void *provctx) -{ - return provctx; -} - -static void dsa_param_freectx(void *ctx) -{ -} - -/* Public key : DER */ -static int dsa_param_der_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - /* ctx == provctx */ - if ((dsa = dsa_new(ctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && dsa_param_der(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_param_der(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = i2d_DSAparams_bio(out, dsa); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int dsa_param_pem_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - /* ctx == provctx */ - if ((dsa = dsa_new(ctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && dsa_param_pem(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_param_pem(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = PEM_write_bio_DSAparams(out, dsa); - BIO_free(out); - - return ret; -} - -static int dsa_param_print_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - /* ctx == provctx */ - if ((dsa = dsa_new(ctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && dsa_param_print(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_param_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_dsa(out, dsa, dsa_print_params); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH dsa_param_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_param_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_param_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH dsa_param_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_param_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_param_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH dsa_param_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_param_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))dsa_param_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_dsa_priv.c b/providers/implementations/serializers/serializer_dsa_priv.c deleted file mode 100644 index 637b1126b1..0000000000 --- a/providers/implementations/serializers/serializer_dsa_priv.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn dsa_priv_newctx; -static OSSL_FUNC_serializer_freectx_fn dsa_priv_freectx; -static OSSL_FUNC_serializer_set_ctx_params_fn dsa_priv_set_ctx_params; -static OSSL_FUNC_serializer_settable_ctx_params_fn dsa_priv_settable_ctx_params; -static OSSL_FUNC_serializer_serialize_data_fn dsa_priv_der_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_priv_der; -static OSSL_FUNC_serializer_serialize_data_fn dsa_pem_priv_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_pem_priv; - -static OSSL_FUNC_serializer_newctx_fn dsa_print_newctx; -static OSSL_FUNC_serializer_freectx_fn dsa_print_freectx; -static OSSL_FUNC_serializer_serialize_data_fn dsa_priv_print_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_priv_print; - - /* - * Context used for private key serialization. - */ -struct dsa_priv_ctx_st { - void *provctx; - - struct pkcs8_encrypt_ctx_st sc; -}; - -/* Private key : context */ -static void *dsa_priv_newctx(void *provctx) -{ - struct dsa_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) { - ctx->provctx = provctx; - - /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */ - ctx->sc.pbe_nid = -1; - } - return ctx; -} - -static void dsa_priv_freectx(void *vctx) -{ - struct dsa_priv_ctx_st *ctx = vctx; - - EVP_CIPHER_free(ctx->sc.cipher); - OPENSSL_free(ctx->sc.cipher_pass); - OPENSSL_free(ctx); -} - -static const OSSL_PARAM *dsa_priv_settable_ctx_params(void) -{ - static const OSSL_PARAM settables[] = { - OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0), - OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0), - OSSL_PARAM_END, - }; - - return settables; -} - -static int dsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - struct dsa_priv_ctx_st *ctx = vctx; - const OSSL_PARAM *p; - - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_CIPHER)) - != NULL) { - const OSSL_PARAM *propsp = - OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES); - const char *props = NULL; - - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - props = (propsp != NULL ? propsp->data : NULL); - - EVP_CIPHER_free(ctx->sc.cipher); - ctx->sc.cipher_intent = p->data != NULL; - if (p->data != NULL - && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props)) - == NULL)) - return 0; - } - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS)) - != NULL) { - OPENSSL_free(ctx->sc.cipher_pass); - ctx->sc.cipher_pass = NULL; - if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0, - &ctx->sc.cipher_pass_length)) - return 0; - } - return 1; -} - -/* Private key : DER */ -static int dsa_priv_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dsa_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - if ((dsa = dsa_new(ctx->provctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dsa_priv_der(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_priv_der(void *vctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dsa_priv_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_der_from_obj(out, dsa, EVP_PKEY_DSA, - ossl_prov_prepare_dsa_params, - ossl_prov_dsa_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* Private key : PEM */ -static int dsa_pem_priv_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dsa_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - if ((dsa = dsa_new(ctx->provctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dsa_pem_priv(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_pem_priv(void *vctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dsa_priv_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_pem_from_obj(out, dsa, EVP_PKEY_DSA, - ossl_prov_prepare_dsa_params, - ossl_prov_dsa_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* - * There's no specific print context, so we use the provider context - */ -static void *dsa_print_newctx(void *provctx) -{ - return provctx; -} - -static void dsa_print_freectx(void *ctx) -{ -} - -static int dsa_priv_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct dsa_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - if ((dsa = dsa_new(ctx->provctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dsa_priv_print(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_priv_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_dsa(out, dsa, dsa_print_priv); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH dsa_priv_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))dsa_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))dsa_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_priv_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_priv_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH dsa_priv_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))dsa_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))dsa_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_pem_priv_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pem_priv }, - { 0, NULL } -}; - -const OSSL_DISPATCH dsa_priv_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_print_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_print_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_priv_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))dsa_priv_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_dsa_pub.c b/providers/implementations/serializers/serializer_dsa_pub.c deleted file mode 100644 index 787bbb541e..0000000000 --- a/providers/implementations/serializers/serializer_dsa_pub.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * DSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn dsa_pub_newctx; -static OSSL_FUNC_serializer_freectx_fn dsa_pub_freectx; -static OSSL_FUNC_serializer_serialize_data_fn dsa_pub_der_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_pub_der; -static OSSL_FUNC_serializer_serialize_data_fn dsa_pub_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_pub_pem; - -static OSSL_FUNC_serializer_serialize_data_fn dsa_pub_print_data; -static OSSL_FUNC_serializer_serialize_object_fn dsa_pub_print; - -/* Public key : context */ - -/* - * There's no specific implementation context, so we use the provider context - */ -static void *dsa_pub_newctx(void *provctx) -{ - return provctx; -} - -static void dsa_pub_freectx(void *ctx) -{ -} - -/* Public key : DER */ -static int dsa_pub_der_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - /* ctx == provctx */ - if ((dsa = dsa_new(ctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dsa_pub_der(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_pub_der(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - /* - * TODO(v3.0) implement setting save_parameters, see dsa_pub_encode() - * in crypto/dsa/dsa_ameth.c - */ - int save_parameters = 1; - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = - save_parameters - ? ossl_prov_write_pub_der_from_obj(out, dsa, EVP_PKEY_DSA, - ossl_prov_prepare_all_dsa_params, - ossl_prov_dsa_pub_to_der) - : ossl_prov_write_pub_der_from_obj(out, dsa, EVP_PKEY_DSA, - ossl_prov_prepare_dsa_params, - ossl_prov_dsa_pub_to_der); - - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int dsa_pub_pem_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - /* ctx == provctx */ - if ((dsa = dsa_new(ctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dsa_pub_pem(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_pub_pem(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_pem_from_obj(out, dsa, EVP_PKEY_DSA, - ossl_prov_prepare_dsa_params, - ossl_prov_dsa_pub_to_der); - - BIO_free(out); - - return ret; -} - -static int dsa_pub_print_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new(); - OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free(); - OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import(); - int ok = 0; - - if (dsa_import != NULL) { - DSA *dsa; - - /* ctx == provctx */ - if ((dsa = dsa_new(ctx)) != NULL - && dsa_import(dsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && dsa_pub_print(ctx, dsa, out, cb, cbarg)) - ok = 1; - dsa_free(dsa); - } - return ok; -} - -static int dsa_pub_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_dsa(out, dsa, 0); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH dsa_pub_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_pub_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pub_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH dsa_pub_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))dsa_pub_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pub_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH dsa_pub_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))dsa_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))dsa_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))dsa_pub_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))dsa_pub_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_ec.c b/providers/implementations/serializers/serializer_ec.c deleted file mode 100644 index 0dbc889d34..0000000000 --- a/providers/implementations/serializers/serializer_ec.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "crypto/ec.h" -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/implementations.h" /* ec_keymgmt_functions */ -#include "prov/providercommonerr.h" /* PROV_R_MISSING_OID */ -#include "serializer_local.h" - -void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new, - OSSL_FUNC_keymgmt_free_fn **ec_free, - OSSL_FUNC_keymgmt_import_fn **ec_import) -{ - *ec_new = ossl_prov_get_keymgmt_new(ec_keymgmt_functions); - *ec_free = ossl_prov_get_keymgmt_free(ec_keymgmt_functions); - *ec_import = ossl_prov_get_keymgmt_import(ec_keymgmt_functions); -} - -static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group) -{ - const char *curve_name; - int curve_nid = EC_GROUP_get_curve_name(group); - - /* TODO(3.0): Explicit parameters are currently not supported */ - if (curve_nid == NID_undef) - return 0; - - if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0) - return 0; - - /* TODO(3.0): Only named curves are currently supported */ - curve_name = EC_curve_nid2nist(curve_nid); - return (curve_name == NULL - || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0); -} - -int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type) -{ - int ret = 0; - const char *type_label = NULL; - unsigned char *priv = NULL, *pub = NULL; - size_t priv_len = 0, pub_len = 0; - const EC_GROUP *group; - - if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) - goto null_err; - - switch (type) { - case ec_print_priv: - type_label = "Private-Key"; - break; - case ec_print_pub: - type_label = "Public-Key"; - break; - case ec_print_params: - type_label = "EC-Parameters"; - break; - } - - if (type == ec_print_priv) { - const BIGNUM *priv_key = EC_KEY_get0_private_key(eckey); - - if (priv_key == NULL) - goto null_err; - priv_len = EC_KEY_priv2buf(eckey, &priv); - if (priv_len == 0) - goto err; - } - - if (type == ec_print_priv || type == ec_print_pub) { - const EC_POINT *pub_pt = EC_KEY_get0_public_key(eckey); - - if (pub_pt == NULL) - goto null_err; - - pub_len = EC_KEY_key2buf(eckey, EC_KEY_get_conv_form(eckey), &pub, NULL); - if (pub_len == 0) - goto err; - } - - if (BIO_printf(out, "%s: (%d bit)\n", type_label, - EC_GROUP_order_bits(group)) <= 0) - goto err; - if (priv != NULL - && !ossl_prov_print_labeled_buf(out, "priv:", priv, priv_len)) - goto err; - if (pub != NULL - && !ossl_prov_print_labeled_buf(out, "pub:", pub, pub_len)) - goto err; - ret = ossl_prov_print_ec_param(out, group); -err: - OPENSSL_clear_free(priv, priv_len); - OPENSSL_free(pub); - return ret; -null_err: - ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); - goto err; -} - -int ossl_prov_prepare_ec_params(const void *eckey, int nid, - void **pstr, int *pstrtype) -{ - int curve_nid; - const EC_GROUP *group = EC_KEY_get0_group(eckey); - ASN1_OBJECT *params; - - if (group == NULL - || ((curve_nid = EC_GROUP_get_curve_name(group)) == NID_undef) - || ((params = OBJ_nid2obj(curve_nid)) == NULL)) { - /* TODO(3.0): Explicit curves are not supported */ - return 0; - } - - if (OBJ_length(params) == 0) { - /* Some curves might not have an associated OID */ - ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID); - ASN1_OBJECT_free(params); - return 0; - } - - *pstr = params; - *pstrtype = V_ASN1_OBJECT; - return 1; -} - -int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder) -{ - return i2o_ECPublicKey(eckey, pder); -} - -int ossl_prov_ec_priv_to_der(const void *veckey, unsigned char **pder) -{ - EC_KEY *eckey = (EC_KEY *)veckey; - unsigned int old_flags; - int ret = 0; - - /* - * For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object - * as the pkeyalg->parameter field. (For a named curve this is an OID) - * The pkey field is an octet string that holds the encoded - * ECPrivateKey SEQUENCE with the optional parameters field omitted. - * We omit this by setting the EC_PKEY_NO_PARAMETERS flag. - */ - old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */ - EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS); - ret = i2d_ECPrivateKey(eckey, pder); - EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */ - return ret; /* return the length of the der encoded data */ -} diff --git a/providers/implementations/serializers/serializer_ec_param.c b/providers/implementations/serializers/serializer_ec_param.c deleted file mode 100644 index 95fbd555a0..0000000000 --- a/providers/implementations/serializers/serializer_ec_param.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn ec_param_newctx; -static OSSL_FUNC_serializer_freectx_fn ec_param_freectx; -static OSSL_FUNC_serializer_serialize_data_fn ec_param_der_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_param_der; -static OSSL_FUNC_serializer_serialize_data_fn ec_param_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_param_pem; - -static OSSL_FUNC_serializer_serialize_data_fn ec_param_print_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_param_print; - - -/* There is no specific implementation context, so use the provider context */ -static void *ec_param_newctx(void *provctx) -{ - return provctx; -} - -static void ec_param_freectx(void *vctx) -{ -} - -/* Public key : DER */ -static int ec_param_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - /* vctx == provctx */ - if ((eckey = ec_new(vctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && ec_param_der(vctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_param_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(vctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey)); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int ec_param_pem_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - /* vctx == provctx */ - if ((eckey = ec_new(vctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && ec_param_pem(vctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_param_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(vctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey)); - BIO_free(out); - - return ret; -} - -static int ec_param_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - /* vctx == provctx */ - if ((eckey = ec_new(vctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params) - && ec_param_print(vctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_param_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(vctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_eckey(out, eckey, ec_print_params); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH ec_param_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH ec_param_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_param_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH ec_param_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_param_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_param_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_param_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))ec_param_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_ec_priv.c b/providers/implementations/serializers/serializer_ec_priv.c deleted file mode 100644 index 9a315dfbcf..0000000000 --- a/providers/implementations/serializers/serializer_ec_priv.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn ec_priv_newctx; -static OSSL_FUNC_serializer_freectx_fn ec_priv_freectx; -static OSSL_FUNC_serializer_set_ctx_params_fn ec_priv_set_ctx_params; -static OSSL_FUNC_serializer_settable_ctx_params_fn ec_priv_settable_ctx_params; -static OSSL_FUNC_serializer_serialize_data_fn ec_priv_der_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_priv_der; -static OSSL_FUNC_serializer_serialize_data_fn ec_pem_priv_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_pem_priv; - -static OSSL_FUNC_serializer_newctx_fn ec_print_newctx; -static OSSL_FUNC_serializer_freectx_fn ec_print_freectx; -static OSSL_FUNC_serializer_serialize_data_fn ec_priv_print_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_priv_print; - - /* - * Context used for private key serialization. - */ -struct ec_priv_ctx_st { - void *provctx; - - struct pkcs8_encrypt_ctx_st sc; -}; - -/* Private key : context */ -static void *ec_priv_newctx(void *provctx) -{ - struct ec_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) { - ctx->provctx = provctx; - - /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */ - ctx->sc.pbe_nid = -1; - } - return ctx; -} - -static void ec_priv_freectx(void *vctx) -{ - struct ec_priv_ctx_st *ctx = vctx; - - EVP_CIPHER_free(ctx->sc.cipher); - OPENSSL_free(ctx->sc.cipher_pass); - OPENSSL_free(ctx); -} - -static const OSSL_PARAM *ec_priv_settable_ctx_params(void) -{ - static const OSSL_PARAM settables[] = { - OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0), - OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0), - OSSL_PARAM_END, - }; - - return settables; -} - -static int ec_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - struct ec_priv_ctx_st *ctx = vctx; - const OSSL_PARAM *p; - - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_CIPHER)) - != NULL) { - const OSSL_PARAM *propsp = - OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES); - const char *props = NULL; - - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - props = (propsp != NULL ? propsp->data : NULL); - - EVP_CIPHER_free(ctx->sc.cipher); - ctx->sc.cipher_intent = p->data != NULL; - if (p->data != NULL - && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props)) - == NULL)) - return 0; - } - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS)) - != NULL) { - OPENSSL_free(ctx->sc.cipher_pass); - ctx->sc.cipher_pass = NULL; - if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0, - &ctx->sc.cipher_pass_length)) - return 0; - } - return 1; -} - -/* Private key : DER */ -static int ec_priv_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ec_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - if ((eckey = ec_new(ctx->provctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ec_priv_der(ctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_priv_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ec_priv_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_der_from_obj(out, eckey, EVP_PKEY_EC, - ossl_prov_prepare_ec_params, - ossl_prov_ec_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* Private key : PEM */ -static int ec_pem_priv_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ec_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - if ((eckey = ec_new(ctx->provctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ec_pem_priv(ctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_pem_priv(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ec_priv_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_pem_from_obj(out, eckey, EVP_PKEY_EC, - ossl_prov_prepare_ec_params, - ossl_prov_ec_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* - * There's no specific print context, so we use the provider context - */ -static void *ec_print_newctx(void *provctx) -{ - return provctx; -} - -static void ec_print_freectx(void *ctx) -{ -} - -static int ec_priv_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ec_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - if ((eckey = ec_new(ctx->provctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ec_priv_print(ctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_priv_print(void *ctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_eckey(out, eckey, ec_print_priv); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH ec_priv_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))ec_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))ec_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_priv_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_priv_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH ec_priv_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))ec_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))ec_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_pem_priv_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pem_priv }, - { 0, NULL } -}; - -const OSSL_DISPATCH ec_priv_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_print_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_print_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_priv_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))ec_priv_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_ec_pub.c b/providers/implementations/serializers/serializer_ec_pub.c deleted file mode 100644 index d3f67fd762..0000000000 --- a/providers/implementations/serializers/serializer_ec_pub.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn ec_pub_newctx; -static OSSL_FUNC_serializer_freectx_fn ec_pub_freectx; -static OSSL_FUNC_serializer_serialize_data_fn ec_pub_der_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_pub_der; -static OSSL_FUNC_serializer_serialize_data_fn ec_pub_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_pub_pem; - -static OSSL_FUNC_serializer_serialize_data_fn ec_pub_print_data; -static OSSL_FUNC_serializer_serialize_object_fn ec_pub_print; - -/* Public key : context */ - -/* - * There's no specific implementation context, so we use the provider context - */ -static void *ec_pub_newctx(void *provctx) -{ - return provctx; -} - -static void ec_pub_freectx(void *ctx) -{ -} - -/* Public key : DER */ -static int ec_pub_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - /* vctx == provctx */ - if ((eckey = ec_new(vctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ec_pub_der(vctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_pub_der(void *ctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_der_from_obj(out, eckey, EVP_PKEY_EC, - ossl_prov_prepare_ec_params, - ossl_prov_ec_pub_to_der); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int ec_pub_pem_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - /* ctx == provctx */ - if ((eckey = ec_new(vctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ec_pub_pem(vctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_pub_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(vctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_pem_from_obj(out, eckey, EVP_PKEY_EC, - ossl_prov_prepare_ec_params, - ossl_prov_ec_pub_to_der); - BIO_free(out); - - return ret; -} - -static int ec_pub_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *ec_new; - OSSL_FUNC_keymgmt_free_fn *ec_free; - OSSL_FUNC_keymgmt_import_fn *ec_import; - int ok = 0; - - ec_get_new_free_import(&ec_new, &ec_free, &ec_import); - - if (ec_import != NULL) { - EC_KEY *eckey; - - /* ctx == provctx */ - if ((eckey = ec_new(vctx)) != NULL - && ec_import(eckey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ec_pub_print(vctx, eckey, out, cb, cbarg)) - ok = 1; - ec_free(eckey); - } - return ok; -} - -static int ec_pub_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(vctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_eckey(out, eckey, ec_print_pub); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH ec_pub_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_pub_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pub_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH ec_pub_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))ec_pub_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pub_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH ec_pub_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))ec_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ec_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))ec_pub_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))ec_pub_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_ecx.c b/providers/implementations/serializers/serializer_ecx.c deleted file mode 100644 index ef16d97b97..0000000000 --- a/providers/implementations/serializers/serializer_ecx.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "crypto/ecx.h" -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/implementations.h" /* ecx_keymgmt_functions */ -#include "serializer_local.h" - -void ecx_get_new_free_import(ECX_KEY_TYPE type, - OSSL_FUNC_keymgmt_new_fn **ecx_new, - OSSL_FUNC_keymgmt_free_fn **ecx_free, - OSSL_FUNC_keymgmt_import_fn **ecx_import) -{ - if (type == ECX_KEY_TYPE_X25519) { - *ecx_new = ossl_prov_get_keymgmt_new(x25519_keymgmt_functions); - *ecx_free = ossl_prov_get_keymgmt_free(x25519_keymgmt_functions); - *ecx_import = ossl_prov_get_keymgmt_import(x25519_keymgmt_functions); - } else if (type == ECX_KEY_TYPE_X448) { - *ecx_new = ossl_prov_get_keymgmt_new(x448_keymgmt_functions); - *ecx_free = ossl_prov_get_keymgmt_free(x448_keymgmt_functions); - *ecx_import = ossl_prov_get_keymgmt_import(x448_keymgmt_functions); - } else if (type == ECX_KEY_TYPE_ED25519) { - *ecx_new = ossl_prov_get_keymgmt_new(ed25519_keymgmt_functions); - *ecx_free = ossl_prov_get_keymgmt_free(ed25519_keymgmt_functions); - *ecx_import = ossl_prov_get_keymgmt_import(ed25519_keymgmt_functions); - } else if (type == ECX_KEY_TYPE_ED448) { - *ecx_new = ossl_prov_get_keymgmt_new(ed448_keymgmt_functions); - *ecx_free = ossl_prov_get_keymgmt_free(ed448_keymgmt_functions); - *ecx_import = ossl_prov_get_keymgmt_import(ed448_keymgmt_functions); - } else { - *ecx_new = NULL; - *ecx_free = NULL; - *ecx_import = NULL; - } -} - - -int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type) -{ - const char *type_label = NULL; - - switch (type) { - case ecx_print_priv: - switch (ecxkey->type) { - case ECX_KEY_TYPE_X25519: - type_label = "X25519 Private-Key"; - break; - case ECX_KEY_TYPE_X448: - type_label = "X448 Private-Key"; - break; - case ECX_KEY_TYPE_ED25519: - type_label = "ED25519 Private-Key"; - break; - case ECX_KEY_TYPE_ED448: - type_label = "ED448 Private-Key"; - break; - } - break; - case ecx_print_pub: - switch (ecxkey->type) { - case ECX_KEY_TYPE_X25519: - type_label = "X25519 Public-Key"; - break; - case ECX_KEY_TYPE_X448: - type_label = "X448 Public-Key"; - break; - case ECX_KEY_TYPE_ED25519: - type_label = "ED25519 Public-Key"; - break; - case ECX_KEY_TYPE_ED448: - type_label = "ED448 Public-Key"; - break; - } - break; - } - - if (type == ecx_print_priv && ecxkey->privkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (BIO_printf(out, "%s:\n", type_label) <= 0) - return 0; - if (type == ecx_print_priv - && !ossl_prov_print_labeled_buf(out, "priv:", ecxkey->privkey, - ecxkey->keylen)) - return 0; - if (!ossl_prov_print_labeled_buf(out, "pub:", ecxkey->pubkey, - ecxkey->keylen)) - return 0; - - return 1; -} - - -int ossl_prov_ecx_pub_to_der(const void *vecxkey, unsigned char **pder) -{ - const ECX_KEY *ecxkey = vecxkey; - unsigned char *keyblob; - - if (ecxkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen); - if (keyblob == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return 0; - } - - *pder = keyblob; - return ecxkey->keylen; -} - -int ossl_prov_ecx_priv_to_der(const void *vecxkey, unsigned char **pder) -{ - const ECX_KEY *ecxkey = vecxkey; - ASN1_OCTET_STRING oct; - int keybloblen; - - if (ecxkey == NULL || ecxkey->privkey == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - oct.data = ecxkey->privkey; - oct.length = ecxkey->keylen; - oct.flags = 0; - - keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); - if (keybloblen < 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); - return 0; - } - - return keybloblen; -} diff --git a/providers/implementations/serializers/serializer_ecx_priv.c b/providers/implementations/serializers/serializer_ecx_priv.c deleted file mode 100644 index b74404a886..0000000000 --- a/providers/implementations/serializers/serializer_ecx_priv.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include -#include "crypto/ecx.h" -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn x25519_priv_newctx; -static OSSL_FUNC_serializer_newctx_fn x448_priv_newctx; -static OSSL_FUNC_serializer_newctx_fn ed25519_priv_newctx; -static OSSL_FUNC_serializer_newctx_fn ed448_priv_newctx; -static OSSL_FUNC_serializer_freectx_fn ecx_priv_freectx; -static OSSL_FUNC_serializer_set_ctx_params_fn ecx_priv_set_ctx_params; -static OSSL_FUNC_serializer_settable_ctx_params_fn ecx_priv_settable_ctx_params; -static OSSL_FUNC_serializer_serialize_data_fn ecx_priv_der_data; -static OSSL_FUNC_serializer_serialize_object_fn ecx_priv_der; -static OSSL_FUNC_serializer_serialize_data_fn ecx_priv_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn ecx_priv_pem; - -static OSSL_FUNC_serializer_serialize_data_fn ecx_priv_print_data; -static OSSL_FUNC_serializer_serialize_object_fn ecx_priv_print; - - /* - * Context used for private key serialization. - */ -struct ecx_priv_ctx_st { - void *provctx; - - struct pkcs8_encrypt_ctx_st sc; - ECX_KEY_TYPE type; -}; - -/* Private key : context */ -static void *ecx_priv_newctx(void *provctx, ECX_KEY_TYPE type) -{ - struct ecx_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) { - ctx->provctx = provctx; - - /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */ - ctx->sc.pbe_nid = -1; - ctx->type = type; - } - return ctx; -} - -static void *x25519_priv_newctx(void *provctx) -{ - return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X25519); -} - -static void *x448_priv_newctx(void *provctx) -{ - return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X448); -} - -static void *ed25519_priv_newctx(void *provctx) -{ - return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED25519); -} - -static void *ed448_priv_newctx(void *provctx) -{ - return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED448); -} - -static void ecx_priv_freectx(void *vctx) -{ - struct ecx_priv_ctx_st *ctx = vctx; - - EVP_CIPHER_free(ctx->sc.cipher); - OPENSSL_free(ctx->sc.cipher_pass); - OPENSSL_free(ctx); -} - -static const OSSL_PARAM *ecx_priv_settable_ctx_params(void) -{ - static const OSSL_PARAM settables[] = { - OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0), - OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0), - OSSL_PARAM_END, - }; - - return settables; -} - -static int ecx_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - struct ecx_priv_ctx_st *ctx = vctx; - const OSSL_PARAM *p; - - p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_CIPHER); - if (p != NULL) { - const OSSL_PARAM *propsp = - OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES); - const char *props; - - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - props = (propsp != NULL ? propsp->data : NULL); - - EVP_CIPHER_free(ctx->sc.cipher); - ctx->sc.cipher_intent = p->data != NULL; - if (p->data != NULL - && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props)) - == NULL)) - return 0; - } - p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS); - if (p != NULL) { - OPENSSL_free(ctx->sc.cipher_pass); - ctx->sc.cipher_pass = NULL; - if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0, - &ctx->sc.cipher_pass_length)) - return 0; - } - return 1; -} - -/* Private key : DER */ -static int ecx_priv_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ecx_new; - OSSL_FUNC_keymgmt_free_fn *ecx_free; - OSSL_FUNC_keymgmt_import_fn *ecx_import; - int ok = 0; - - ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import); - - if (ecx_import != NULL) { - ECX_KEY *ecxkey; - - if ((ecxkey = ecx_new(ctx->provctx)) != NULL - && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ecx_priv_der(ctx, ecxkey, out, cb, cbarg)) - ok = 1; - ecx_free(ecxkey); - } - return ok; -} - -static int ecx_priv_der(void *vctx, void *vecxkey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_priv_ctx_st *ctx = vctx; - ECX_KEY *ecxkey = vecxkey; - int ret; - int nid = KEYTYPE2NID(ctx->type); - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_der_from_obj(out, ecxkey, - nid, - NULL, - ossl_prov_ecx_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* Private key : PEM */ -static int ecx_priv_pem_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ecx_new; - OSSL_FUNC_keymgmt_free_fn *ecx_free; - OSSL_FUNC_keymgmt_import_fn *ecx_import; - int ok = 0; - - ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import); - - if (ecx_import != NULL) { - ECX_KEY *ecxkey; - - if ((ecxkey = ecx_new(ctx->provctx)) != NULL - && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ecx_priv_pem(ctx->provctx, ecxkey, out, cb, cbarg)) - ok = 1; - ecx_free(ecxkey); - } - return ok; -} - -static int ecx_priv_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_priv_ctx_st *ctx = vctx; - int ret; - int nid = KEYTYPE2NID(ctx->type); - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_pem_from_obj(out, ecxkey, - nid, - NULL, - ossl_prov_ecx_priv_to_der, - &ctx->sc); - BIO_free(out); - - return ret; -} - -static int ecx_priv_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ecx_new; - OSSL_FUNC_keymgmt_free_fn *ecx_free; - OSSL_FUNC_keymgmt_import_fn *ecx_import; - int ok = 0; - - ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import); - - if (ecx_import != NULL) { - ECX_KEY *ecxkey; - - if ((ecxkey = ecx_new(ctx->provctx)) != NULL - && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ecx_priv_print(ctx, ecxkey, out, cb, cbarg)) - ok = 1; - ecx_free(ecxkey); - } - return ok; -} - -static int ecx_priv_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_priv_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_priv); - BIO_free(out); - - return ret; -} - -#define MAKE_SERIALIZER_FUNCTIONS(alg, type) \ - const OSSL_DISPATCH alg##_priv_##type##_serializer_functions[] = { \ - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \ - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_priv_freectx }, \ - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, \ - (void (*)(void))ecx_priv_set_ctx_params }, \ - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))ecx_priv_settable_ctx_params }, \ - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \ - (void (*)(void))ecx_priv_##type##_data }, \ - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \ - (void (*)(void))ecx_priv_##type }, \ - { 0, NULL } \ - }; - -#define MAKE_SERIALIZER_FUNCTIONS_GROUP(alg) \ - MAKE_SERIALIZER_FUNCTIONS(alg, der) \ - MAKE_SERIALIZER_FUNCTIONS(alg, pem) \ - const OSSL_DISPATCH alg##_priv_print_serializer_functions[] = { \ - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \ - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_priv_freectx }, \ - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \ - (void (*)(void))ecx_priv_print }, \ - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \ - (void (*)(void))ecx_priv_print_data }, \ - { 0, NULL } \ - }; - -MAKE_SERIALIZER_FUNCTIONS_GROUP(x25519) -MAKE_SERIALIZER_FUNCTIONS_GROUP(x448) -MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519) -MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448) diff --git a/providers/implementations/serializers/serializer_ecx_pub.c b/providers/implementations/serializers/serializer_ecx_pub.c deleted file mode 100644 index fa15e5a8c4..0000000000 --- a/providers/implementations/serializers/serializer_ecx_pub.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include -#include "crypto/ecx.h" -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn x25519_pub_newctx; -static OSSL_FUNC_serializer_newctx_fn x448_pub_newctx; -static OSSL_FUNC_serializer_newctx_fn ed25519_pub_newctx; -static OSSL_FUNC_serializer_newctx_fn ed448_pub_newctx; -static OSSL_FUNC_serializer_freectx_fn ecx_pub_freectx; -static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_der_data; -static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_der; -static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_pem; - -static OSSL_FUNC_serializer_serialize_data_fn ecx_pub_print_data; -static OSSL_FUNC_serializer_serialize_object_fn ecx_pub_print; - -/* - * Context used for public key serialization. - */ -struct ecx_pub_ctx_st { - void *provctx; - ECX_KEY_TYPE type; -}; - -/* Public key : context */ -static void *ecx_pub_newctx(void *provctx, ECX_KEY_TYPE type) -{ - struct ecx_pub_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) { - ctx->provctx = provctx; - ctx->type = type; - } - return ctx; -} - -static void *x25519_pub_newctx(void *provctx) -{ - return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X25519); -} - -static void *x448_pub_newctx(void *provctx) -{ - return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X448); -} - -static void *ed25519_pub_newctx(void *provctx) -{ - return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED25519); -} - -static void *ed448_pub_newctx(void *provctx) -{ - return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED448); -} - -static void ecx_pub_freectx(void *ctx) -{ - OPENSSL_free(ctx); -} - -/* Public key : DER */ -static int ecx_pub_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_pub_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ecx_new; - OSSL_FUNC_keymgmt_free_fn *ecx_free; - OSSL_FUNC_keymgmt_import_fn *ecx_import; - int ok = 0; - - ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import); - - if (ecx_import != NULL) { - ECX_KEY *ecxkey; - - if ((ecxkey = ecx_new(ctx->provctx)) != NULL - && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ecx_pub_der(ctx, ecxkey, out, cb, cbarg)) - ok = 1; - ecx_free(ecxkey); - } - return ok; -} - -static int ecx_pub_der(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_pub_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_der_from_obj(out, ecxkey, - KEYTYPE2NID(ctx->type), - NULL, - ossl_prov_ecx_pub_to_der); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int ecx_pub_pem_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_pub_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ecx_new; - OSSL_FUNC_keymgmt_free_fn *ecx_free; - OSSL_FUNC_keymgmt_import_fn *ecx_import; - int ok = 0; - - ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import); - - if (ecx_import != NULL) { - ECX_KEY *ecxkey; - - if ((ecxkey = ecx_new(ctx->provctx)) != NULL - && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ecx_pub_pem(ctx, ecxkey, out, cb, cbarg)) - ok = 1; - ecx_free(ecxkey); - } - return ok; -} - -static int ecx_pub_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_pub_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_pem_from_obj(out, ecxkey, - KEYTYPE2NID(ctx->type), - NULL, - ossl_prov_ecx_pub_to_der); - BIO_free(out); - - return ret; -} - -static int ecx_pub_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_pub_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *ecx_new; - OSSL_FUNC_keymgmt_free_fn *ecx_free; - OSSL_FUNC_keymgmt_import_fn *ecx_import; - int ok = 0; - - ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import); - - if (ecx_import != NULL) { - ECX_KEY *ecxkey; - - if ((ecxkey = ecx_new(ctx)) != NULL - && ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && ecx_pub_print(ctx, ecxkey, out, cb, cbarg)) - ok = 1; - ecx_free(ecxkey); - } - return ok; -} - -static int ecx_pub_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct ecx_pub_ctx_st *ctx = vctx; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_pub); - BIO_free(out); - - return ret; -} - -#define MAKE_SERIALIZER_FUNCTIONS(alg, type) \ - const OSSL_DISPATCH alg##_pub_##type##_serializer_functions[] = { \ - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))alg##_pub_newctx }, \ - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))ecx_pub_freectx }, \ - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, \ - (void (*)(void))ecx_pub_##type##_data }, \ - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, \ - (void (*)(void))ecx_pub_##type }, \ - { 0, NULL } \ - }; - -#define MAKE_SERIALIZER_FUNCTIONS_GROUP(alg) \ - MAKE_SERIALIZER_FUNCTIONS(alg, der) \ - MAKE_SERIALIZER_FUNCTIONS(alg, pem) \ - MAKE_SERIALIZER_FUNCTIONS(alg, print) - -MAKE_SERIALIZER_FUNCTIONS_GROUP(x25519) -MAKE_SERIALIZER_FUNCTIONS_GROUP(x448) -MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519) -MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448) diff --git a/providers/implementations/serializers/serializer_ffc_params.c b/providers/implementations/serializers/serializer_ffc_params.c deleted file mode 100644 index ad96c4ddd0..0000000000 --- a/providers/implementations/serializers/serializer_ffc_params.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* Utility function for printing DSA/DH params. */ - -#include "prov/bio.h" -#include "serializer_local.h" - -int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc) -{ - if (ffc->nid != NID_undef) { -#ifndef OPENSSL_NO_DH - const char *name = ffc_named_group_from_uid(ffc->nid); - - if (name == NULL) - goto err; - if (BIO_printf(out, "GROUP: %s\n", name) <= 0) - goto err; - return 1; -#else - /* How could this be? We should not have a nid in a no-dh build. */ - goto err; -#endif - } - - if (!ossl_prov_print_labeled_bignum(out, "P: ", ffc->p)) - goto err; - if (ffc->q != NULL) { - if (!ossl_prov_print_labeled_bignum(out, "Q: ", ffc->q)) - goto err; - } - if (!ossl_prov_print_labeled_bignum(out, "G: ", ffc->g)) - goto err; - if (ffc->j != NULL) { - if (!ossl_prov_print_labeled_bignum(out, "J: ", ffc->j)) - goto err; - } - if (ffc->seed != NULL) { - if (!ossl_prov_print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) - goto err; - } - if (ffc->gindex != -1) { - if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) - goto err; - } - if (ffc->pcounter != -1) { - if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) - goto err; - } - if (ffc->h != 0) { - if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) - goto err; - } - return 1; -err: - return 0; -} diff --git a/providers/implementations/serializers/serializer_local.h b/providers/implementations/serializers/serializer_local.h deleted file mode 100644 index d1359f7f4d..0000000000 --- a/providers/implementations/serializers/serializer_local.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include /* i2d_of_void */ -#include /* X509_SIG */ -#include -#include -#include "internal/ffc.h" - -struct pkcs8_encrypt_ctx_st { - /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */ - int cipher_intent; - - EVP_CIPHER *cipher; - int pbe_nid; /* For future variation */ - - /* Passphrase that was passed by the caller */ - void *cipher_pass; - size_t cipher_pass_length; - - /* This callback is only used of |cipher_pass| is NULL */ - OSSL_PASSPHRASE_CALLBACK *cb; - void *cbarg; -}; - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns); -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns); -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns); -OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns); - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void); -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void); -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void); -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void); -OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void); -OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void); -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void); -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void); -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void); -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void); -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dsa_free(void); -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dsa_import(void); - -void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new, - OSSL_FUNC_keymgmt_free_fn **ec_free, - OSSL_FUNC_keymgmt_import_fn **ec_import); - -int ossl_prov_prepare_ec_params(const void *eckey, int nid, - void **pstr, int *pstrtype); -int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder); -int ossl_prov_ec_priv_to_der(const void *eckey, unsigned char **pder); - -int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc); -int ossl_prov_prepare_dh_params(const void *dh, int nid, - void **pstr, int *pstrtype); -int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder); -int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder); - -#ifndef OPENSSL_NO_EC -void ecx_get_new_free_import(ECX_KEY_TYPE type, - OSSL_FUNC_keymgmt_new_fn **ecx_new, - OSSL_FUNC_keymgmt_free_fn **ecx_free, - OSSL_FUNC_keymgmt_import_fn **ecx_import); -int ossl_prov_ecx_pub_to_der(const void *ecxkey, unsigned char **pder); -int ossl_prov_ecx_priv_to_der(const void *ecxkey, unsigned char **pder); -#endif - -int ossl_prov_prepare_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype); -/* - * Special variant of ossl_prov_prepare_dsa_params() that requires all - * three parameters (P, Q and G) to be set. This is used when serializing - * the public key. - */ -int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid, - void **pstr, int *pstrtype); -int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder); -int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder); - -/* - * ossl_prov_prepare_rsa_params() is designed to work with the ossl_prov_write_ - * functions, hence 'void *rsa' rather than 'RSA *rsa'. - */ -int ossl_prov_prepare_rsa_params(const void *rsa, int nid, - void **pstr, int *pstrtype); -int ossl_prov_rsa_type_to_evp(const RSA *rsa); - -int ossl_prov_print_labeled_bignum(BIO *out, const char *label, - const BIGNUM *bn); -int ossl_prov_print_labeled_buf(BIO *out, const char *label, - const unsigned char *buf, size_t buflen); -int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv); - -enum dh_print_type { - dh_print_priv, - dh_print_pub, - dh_print_params -}; - -int ossl_prov_print_dh(BIO *out, DH *dh, enum dh_print_type type); - -#ifndef OPENSSL_NO_EC -enum ec_print_type { - ec_print_priv, - ec_print_pub, - ec_print_params -}; - -int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type); -#endif /* OPENSSL_NO_EC */ - -enum dsa_print_type { - dsa_print_priv, - dsa_print_pub, - dsa_print_params -}; - -int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type); - -enum ecx_print_type { - ecx_print_priv, - ecx_print_pub -}; - -#ifndef OPENSSL_NO_EC -int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type); -#endif - -int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder), - struct pkcs8_encrypt_ctx_st *ctx); -int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder), - struct pkcs8_encrypt_ctx_st *ctx); -int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder)); -int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid, - int (*p2s)(const void *obj, int nid, - void **str, - int *strtype), - int (*k2d)(const void *obj, - unsigned char **pder)); - -int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - unsigned char **data, long *len); -int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - char **pem_name, char **pem_header, - unsigned char **data, long *len); - -int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len, - unsigned char *input_der, long input_der_len, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg); - diff --git a/providers/implementations/serializers/serializer_rsa.c b/providers/implementations/serializers/serializer_rsa.c deleted file mode 100644 index 9250d49735..0000000000 --- a/providers/implementations/serializers/serializer_rsa.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * RSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include "internal/packet.h" -#include "crypto/rsa.h" /* rsa_get0_all_params() */ -#include "prov/bio.h" /* ossl_prov_bio_printf() */ -#include "prov/der_rsa.h" /* DER_w_RSASSA_PSS_params() */ -#include "prov/implementations.h" /* rsa_keymgmt_functions */ -#include "serializer_local.h" - -DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void) -{ - return ossl_prov_get_keymgmt_new(rsa_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void) -{ - return ossl_prov_get_keymgmt_new(rsapss_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void) -{ - return ossl_prov_get_keymgmt_free(rsa_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void) -{ - return ossl_prov_get_keymgmt_import(rsa_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void) -{ - return ossl_prov_get_keymgmt_export(rsa_keymgmt_functions); -} - -OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void) -{ - return ossl_prov_get_keymgmt_export(rsapss_keymgmt_functions); -} - -int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv) -{ - const char *modulus_label; - const char *exponent_label; - const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; - STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null(); - STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null(); - STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null(); - RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa); - int ret = 0; - - if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL) - goto err; - - RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); - rsa_get0_all_params(rsa, factors, exps, coeffs); - - if (priv && rsa_d != NULL) { - if (BIO_printf(out, "Private-Key: (%d bit, %d primes)\n", - BN_num_bits(rsa_n), - sk_BIGNUM_const_num(factors)) <= 0) - goto err; - modulus_label = "modulus:"; - exponent_label = "publicExponent:"; - } else { - if (BIO_printf(out, "Public-Key: (%d bit)\n", BN_num_bits(rsa_n)) <= 0) - goto err; - modulus_label = "Modulus:"; - exponent_label = "Exponent:"; - } - if (!ossl_prov_print_labeled_bignum(out, modulus_label, rsa_n)) - goto err; - if (!ossl_prov_print_labeled_bignum(out, exponent_label, rsa_e)) - goto err; - if (priv) { - int i; - - if (!ossl_prov_print_labeled_bignum(out, "privateExponent:", rsa_d)) - goto err; - if (!ossl_prov_print_labeled_bignum(out, "prime1:", - sk_BIGNUM_const_value(factors, 0))) - goto err; - if (!ossl_prov_print_labeled_bignum(out, "prime2:", - sk_BIGNUM_const_value(factors, 1))) - goto err; - if (!ossl_prov_print_labeled_bignum(out, "exponent1:", - sk_BIGNUM_const_value(exps, 0))) - goto err; - if (!ossl_prov_print_labeled_bignum(out, "exponent2:", - sk_BIGNUM_const_value(exps, 1))) - goto err; - if (!ossl_prov_print_labeled_bignum(out, "coefficient:", - sk_BIGNUM_const_value(coeffs, 0))) - goto err; - for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { - if (BIO_printf(out, "prime%d:", i + 1) <= 0) - goto err; - if (!ossl_prov_print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(factors, - i))) - goto err; - if (BIO_printf(out, "exponent%d:", i + 1) <= 0) - goto err; - if (!ossl_prov_print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(exps, i))) - goto err; - if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) - goto err; - if (!ossl_prov_print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(coeffs, - i - 1))) - goto err; - } - } - - switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { - case RSA_FLAG_TYPE_RSA: - if (!rsa_pss_params_30_is_unrestricted(pss_params)) { - if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0) - goto err; - } - break; - case RSA_FLAG_TYPE_RSASSAPSS: - if (rsa_pss_params_30_is_unrestricted(pss_params)) { - if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0) - goto err; - } else { - int hashalg_nid = rsa_pss_params_30_hashalg(pss_params); - int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params); - int maskgenhashalg_nid = - rsa_pss_params_30_maskgenhashalg(pss_params); - int saltlen = rsa_pss_params_30_saltlen(pss_params); - int trailerfield = rsa_pss_params_30_trailerfield(pss_params); - - if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0) - goto err; - if (BIO_printf(out, " Hash Algorithm: %s%s\n", - rsa_oaeppss_nid2name(hashalg_nid), - (hashalg_nid == NID_sha1 - ? " (default)" : "")) <= 0) - goto err; - if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n", - rsa_mgf_nid2name(maskgenalg_nid), - rsa_oaeppss_nid2name(maskgenhashalg_nid), - (maskgenalg_nid == NID_mgf1 - && maskgenhashalg_nid == NID_sha1 - ? " (default)" : "")) <= 0) - goto err; - if (BIO_printf(out, " Minimum Salt Length: %d%s\n", - saltlen, - (saltlen == 20 ? " (default)" : "")) <= 0) - goto err; - /* - * TODO(3.0) Should we show the ASN.1 trailerField value, or - * the actual trailerfield byte (i.e. 0xBC for 1)? - * crypto/rsa/rsa_ameth.c isn't very clear on that, as it - * does display 0xBC when the default applies, but the ASN.1 - * trailerField value otherwise... - */ - if (BIO_printf(out, " Trailer Field: 0x%x%s\n", - trailerfield, - (trailerfield == 1 ? " (default)" : "")) - <= 0) - goto err; - } - break; - } - - ret = 1; - err: - sk_BIGNUM_const_free(factors); - sk_BIGNUM_const_free(exps); - sk_BIGNUM_const_free(coeffs); - return ret; -} - -/* - * Helper functions to prepare RSA-PSS params for serialization. We would - * have simply written the whole AlgorithmIdentifier, but existing libcrypto - * functionality doesn't allow that. - */ - -int ossl_prov_prepare_rsa_params(const void *rsa, int nid, - void **pstr, int *pstrtype) -{ - const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa); - - *pstr = NULL; - - switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { - case RSA_FLAG_TYPE_RSA: - /* If plain RSA, the parameters shall be NULL */ - *pstrtype = V_ASN1_NULL; - return 1; - case RSA_FLAG_TYPE_RSASSAPSS: - if (rsa_pss_params_30_is_unrestricted(pss)) { - *pstrtype = V_ASN1_UNDEF; - return 1; - } else { - ASN1_STRING *astr = NULL; - WPACKET pkt; - unsigned char *str = NULL; - size_t str_sz = 0; - int i; - - for (i = 0; i < 2; i++) { - switch (i) { - case 0: - if (!WPACKET_init_null_der(&pkt)) - goto err; - break; - case 1: - if ((str = OPENSSL_malloc(str_sz)) == NULL - || !WPACKET_init_der(&pkt, str, str_sz)) { - goto err; - } - break; - } - if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss) - || !WPACKET_finish(&pkt) - || !WPACKET_get_total_written(&pkt, &str_sz)) - goto err; - WPACKET_cleanup(&pkt); - - /* - * If no PSS parameters are going to be written, there's no - * point going for another iteration. - * This saves us from getting |str| allocated just to have it - * immediately de-allocated. - */ - if (str_sz == 0) - break; - } - - if ((astr = ASN1_STRING_new()) == NULL) - goto err; - *pstrtype = V_ASN1_SEQUENCE; - ASN1_STRING_set0(astr, str, (int)str_sz); - *pstr = astr; - - return 1; - err: - OPENSSL_free(str); - return 0; - } - } - - /* Currently unsupported RSA key type */ - return 0; -} - -int ossl_prov_rsa_type_to_evp(const RSA *rsa) -{ - switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { - case RSA_FLAG_TYPE_RSA: - return EVP_PKEY_RSA; - case RSA_FLAG_TYPE_RSASSAPSS: - return EVP_PKEY_RSA_PSS; - } - - /* Currently unsupported RSA key type */ - return EVP_PKEY_NONE; -} diff --git a/providers/implementations/serializers/serializer_rsa_priv.c b/providers/implementations/serializers/serializer_rsa_priv.c deleted file mode 100644 index c9bdfaa3fc..0000000000 --- a/providers/implementations/serializers/serializer_rsa_priv.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * RSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include "crypto/rsa.h" -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn rsa_priv_newctx; -static OSSL_FUNC_serializer_freectx_fn rsa_priv_freectx; -static OSSL_FUNC_serializer_set_ctx_params_fn rsa_priv_set_ctx_params; -static OSSL_FUNC_serializer_settable_ctx_params_fn rsa_priv_settable_ctx_params; -static OSSL_FUNC_serializer_serialize_data_fn rsa_priv_der_data; -static OSSL_FUNC_serializer_serialize_object_fn rsa_priv_der; -static OSSL_FUNC_serializer_serialize_data_fn rsa_pem_priv_data; -static OSSL_FUNC_serializer_serialize_object_fn rsa_pem_priv; - -static OSSL_FUNC_serializer_newctx_fn rsa_print_newctx; -static OSSL_FUNC_serializer_freectx_fn rsa_print_freectx; -static OSSL_FUNC_serializer_serialize_data_fn rsa_priv_print_data; -static OSSL_FUNC_serializer_serialize_object_fn rsa_priv_print; - - /* - * Context used for private key serialization. - */ -struct rsa_priv_ctx_st { - void *provctx; - - struct pkcs8_encrypt_ctx_st sc; -}; - -/* Private key : context */ -static void *rsa_priv_newctx(void *provctx) -{ - struct rsa_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx != NULL) { - ctx->provctx = provctx; - /* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */ - ctx->sc.pbe_nid = -1; - } - return ctx; -} - -static void rsa_priv_freectx(void *vctx) -{ - struct rsa_priv_ctx_st *ctx = vctx; - - EVP_CIPHER_free(ctx->sc.cipher); - OPENSSL_free(ctx->sc.cipher_pass); - OPENSSL_free(ctx); -} - -static const OSSL_PARAM *rsa_priv_settable_ctx_params(void) -{ - static const OSSL_PARAM settables[] = { - OSSL_PARAM_utf8_string(OSSL_SERIALIZER_PARAM_CIPHER, NULL, 0), - OSSL_PARAM_octet_string(OSSL_SERIALIZER_PARAM_PASS, NULL, 0), - OSSL_PARAM_END, - }; - - return settables; -} - -static int rsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - struct rsa_priv_ctx_st *ctx = vctx; - const OSSL_PARAM *p; - - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_CIPHER)) - != NULL) { - const OSSL_PARAM *propsp = - OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PROPERTIES); - const char *props = NULL; - - if (p->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - props = (propsp != NULL ? propsp->data : NULL); - - EVP_CIPHER_free(ctx->sc.cipher); - ctx->sc.cipher_intent = p->data != NULL; - if (p->data != NULL - && ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props)) - == NULL)) - return 0; - } - if ((p = OSSL_PARAM_locate_const(params, OSSL_SERIALIZER_PARAM_PASS)) - != NULL) { - OPENSSL_free(ctx->sc.cipher_pass); - ctx->sc.cipher_pass = NULL; - if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0, - &ctx->sc.cipher_pass_length)) - return 0; - } - return 1; -} - -/* Private key : DER */ -static int rsa_priv_der_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct rsa_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new(); - OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free(); - OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import(); - int ok = 0; - - if (rsa_import != NULL) { - RSA *rsa; - - if ((rsa = rsa_new(ctx->provctx)) != NULL - && rsa_import(rsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && rsa_priv_der(ctx, rsa, out, cb, cbarg)) - ok = 1; - rsa_free(rsa); - } - return ok; -} - -static int rsa_priv_der(void *vctx, void *rsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct rsa_priv_ctx_st *ctx = vctx; - int ret; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_der_from_obj(out, rsa, - ossl_prov_rsa_type_to_evp(rsa), - ossl_prov_prepare_rsa_params, - (i2d_of_void *)i2d_RSAPrivateKey, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* Private key : PEM */ -static int rsa_pem_priv_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct rsa_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new(); - OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free(); - OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import(); - int ok = 0; - - if (rsa_import != NULL) { - RSA *rsa; - - if ((rsa = rsa_new(ctx->provctx)) != NULL - && rsa_import(rsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && rsa_pem_priv(ctx, rsa, out, cb, cbarg)) - ok = 1; - rsa_free(rsa); - } - return ok; -} - -static int rsa_pem_priv(void *vctx, void *rsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct rsa_priv_ctx_st *ctx = vctx; - int ret; - BIO *out = bio_new_from_core_bio(ctx->provctx, cout); - - if (out == NULL) - return 0; - - ctx->sc.cb = cb; - ctx->sc.cbarg = cbarg; - - ret = ossl_prov_write_priv_pem_from_obj(out, rsa, - ossl_prov_rsa_type_to_evp(rsa), - ossl_prov_prepare_rsa_params, - (i2d_of_void *)i2d_RSAPrivateKey, - &ctx->sc); - BIO_free(out); - - return ret; -} - -/* - * There's no specific print context, so we use the provider context - */ -static void *rsa_print_newctx(void *provctx) -{ - return provctx; -} - -static void rsa_print_freectx(void *ctx) -{ -} - -static int rsa_priv_print_data(void *vctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - struct rsa_priv_ctx_st *ctx = vctx; - OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new(); - OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free(); - OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import(); - int ok = 0; - - if (rsa_import != NULL) { - RSA *rsa; - - if ((rsa = rsa_new(ctx->provctx)) != NULL - && rsa_import(rsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && rsa_priv_print(ctx, rsa, out, cb, cbarg)) - ok = 1; - rsa_free(rsa); - } - return ok; -} - -static int rsa_priv_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_rsa(out, rsa, 1); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH rsa_priv_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))rsa_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))rsa_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_priv_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_priv_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH rsa_priv_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_priv_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_priv_freectx }, - { OSSL_FUNC_SERIALIZER_SET_CTX_PARAMS, - (void (*)(void))rsa_priv_set_ctx_params }, - { OSSL_FUNC_SERIALIZER_SETTABLE_CTX_PARAMS, - (void (*)(void))rsa_priv_settable_ctx_params }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_pem_priv_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pem_priv }, - { 0, NULL } -}; - -const OSSL_DISPATCH rsa_priv_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_print_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_print_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_priv_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))rsa_priv_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/serializers/serializer_rsa_pub.c b/providers/implementations/serializers/serializer_rsa_pub.c deleted file mode 100644 index 72c290ee44..0000000000 --- a/providers/implementations/serializers/serializer_rsa_pub.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* - * RSA low level APIs are deprecated for public use, but still ok for - * internal use. - */ -#include "internal/deprecated.h" - -#include -#include -#include -#include -#include -#include "prov/bio.h" -#include "prov/implementations.h" -#include "prov/providercommonerr.h" -#include "prov/provider_ctx.h" -#include "serializer_local.h" - -static OSSL_FUNC_serializer_newctx_fn rsa_pub_newctx; -static OSSL_FUNC_serializer_freectx_fn rsa_pub_freectx; -static OSSL_FUNC_serializer_serialize_data_fn rsa_pub_der_data; -static OSSL_FUNC_serializer_serialize_object_fn rsa_pub_der; -static OSSL_FUNC_serializer_serialize_data_fn rsa_pub_pem_data; -static OSSL_FUNC_serializer_serialize_object_fn rsa_pub_pem; - -static OSSL_FUNC_serializer_serialize_data_fn rsa_pub_print_data; -static OSSL_FUNC_serializer_serialize_object_fn rsa_pub_print; - -/* Public key : context */ - -/* - * There's no specific implementation context, so we use the provider context - */ -static void *rsa_pub_newctx(void *provctx) -{ - return provctx; -} - -static void rsa_pub_freectx(void *ctx) -{ -} - -/* Public key : DER */ -static int rsa_pub_der_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new(); - OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free(); - OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import(); - int ok = 0; - - if (rsa_import != NULL) { - RSA *rsa; - - /* ctx == provctx */ - if ((rsa = rsa_new(ctx)) != NULL - && rsa_import(rsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && rsa_pub_der(ctx, rsa, out, cb, cbarg)) - ok = 1; - rsa_free(rsa); - } - return ok; -} - -static int rsa_pub_der(void *ctx, void *rsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_der_from_obj(out, rsa, - ossl_prov_rsa_type_to_evp(rsa), - ossl_prov_prepare_rsa_params, - (i2d_of_void *)i2d_RSAPublicKey); - BIO_free(out); - - return ret; -} - -/* Public key : PEM */ -static int rsa_pub_pem_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new(); - OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free(); - OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import(); - int ok = 0; - - if (rsa_import != NULL) { - RSA *rsa; - - /* ctx == provctx */ - if ((rsa = rsa_new(ctx)) != NULL - && rsa_import(rsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && rsa_pub_pem(ctx, rsa, out, cb, cbarg)) - ok = 1; - rsa_free(rsa); - } - return ok; -} - -static int rsa_pub_pem(void *ctx, void *rsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_write_pub_pem_from_obj(out, rsa, - ossl_prov_rsa_type_to_evp(rsa), - ossl_prov_prepare_rsa_params, - (i2d_of_void *)i2d_RSAPublicKey); - BIO_free(out); - - return ret; -} - -static int rsa_pub_print_data(void *ctx, const OSSL_PARAM params[], - OSSL_CORE_BIO *out, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new(); - OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free(); - OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import(); - int ok = 0; - - if (rsa_import != NULL) { - RSA *rsa; - - /* ctx == provctx */ - if ((rsa = rsa_new(ctx)) != NULL - && rsa_import(rsa, OSSL_KEYMGMT_SELECT_KEYPAIR, params) - && rsa_pub_print(ctx, rsa, out, cb, cbarg)) - ok = 1; - rsa_free(rsa); - } - return ok; -} - -static int rsa_pub_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout, - OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) -{ - BIO *out = bio_new_from_core_bio(ctx, cout); - int ret; - - if (out == NULL) - return 0; - - ret = ossl_prov_print_rsa(out, rsa, 0); - BIO_free(out); - - return ret; -} - -const OSSL_DISPATCH rsa_pub_der_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_pub_der_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pub_der }, - { 0, NULL } -}; - -const OSSL_DISPATCH rsa_pub_pem_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, (void (*)(void))rsa_pub_pem_data }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pub_pem }, - { 0, NULL } -}; - -const OSSL_DISPATCH rsa_pub_text_serializer_functions[] = { - { OSSL_FUNC_SERIALIZER_NEWCTX, (void (*)(void))rsa_pub_newctx }, - { OSSL_FUNC_SERIALIZER_FREECTX, (void (*)(void))rsa_pub_freectx }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_OBJECT, (void (*)(void))rsa_pub_print }, - { OSSL_FUNC_SERIALIZER_SERIALIZE_DATA, - (void (*)(void))rsa_pub_print_data }, - { 0, NULL } -}; diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 0e7765ae24..84c5d905b2 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -3,15 +3,18 @@ $DSA_GOAL=../../libimplementations.a $EC_GOAL=../../libimplementations.a +$SM2SIG_GOAL=../../libimplementations.a IF[{- !$disabled{dsa} -}] SOURCE[$DSA_GOAL]=dsa.c ENDIF IF[{- !$disabled{ec} -}] - SOURCE[$EC_GOAL]=eddsa.c - SOURCE[../../libfips.a]=ecdsa.c - SOURCE[../../libnonfips.a]=ecdsa.c + SOURCE[$EC_GOAL]=eddsa.c ecdsa.c +ENDIF + +IF[{- !$disabled{sm2} -}] + SOURCE[$SM2SIG_GOAL]=sm2sig.c ENDIF SOURCE[../../libfips.a]=rsa.c @@ -20,3 +23,8 @@ SOURCE[../../libnonfips.a]=rsa.c DEPEND[rsa.o]=../../common/include/prov/der_rsa.h DEPEND[dsa.o]=../../common/include/prov/der_dsa.h DEPEND[ecdsa.o]=../../common/include/prov/der_ec.h +DEPEND[eddsa.o]=../../common/include/prov/der_ecx.h +DEPEND[sm2sig.o]=../../common/include/prov/der_sm2.h + +SOURCE[../../libfips.a]=mac_legacy.c +SOURCE[../../libnonfips.a]=mac_legacy.c diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c index e7a19620fa..a1621acf62 100644 --- a/providers/implementations/signature/dsa.c +++ b/providers/implementations/signature/dsa.c @@ -26,22 +26,23 @@ #include "internal/nelem.h" #include "internal/sizes.h" #include "internal/cryptlib.h" -#include "prov/providercommonerr.h" +#include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/providercommonerr.h" #include "prov/provider_ctx.h" +#include "prov/securitycheck.h" #include "crypto/dsa.h" #include "prov/der_dsa.h" static OSSL_FUNC_signature_newctx_fn dsa_newctx; -static OSSL_FUNC_signature_sign_init_fn dsa_signature_init; -static OSSL_FUNC_signature_verify_init_fn dsa_signature_init; +static OSSL_FUNC_signature_sign_init_fn dsa_sign_init; +static OSSL_FUNC_signature_verify_init_fn dsa_verify_init; static OSSL_FUNC_signature_sign_fn dsa_sign; static OSSL_FUNC_signature_verify_fn dsa_verify; -static OSSL_FUNC_signature_digest_sign_init_fn dsa_digest_signverify_init; +static OSSL_FUNC_signature_digest_sign_init_fn dsa_digest_sign_init; static OSSL_FUNC_signature_digest_sign_update_fn dsa_digest_signverify_update; static OSSL_FUNC_signature_digest_sign_final_fn dsa_digest_sign_final; -static OSSL_FUNC_signature_digest_verify_init_fn dsa_digest_signverify_init; +static OSSL_FUNC_signature_digest_verify_init_fn dsa_digest_verify_init; static OSSL_FUNC_signature_digest_verify_update_fn dsa_digest_signverify_update; static OSSL_FUNC_signature_digest_verify_final_fn dsa_digest_verify_final; static OSSL_FUNC_signature_freectx_fn dsa_freectx; @@ -62,7 +63,7 @@ static OSSL_FUNC_signature_settable_ctx_md_params_fn dsa_settable_ctx_md_params; */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; DSA *dsa; @@ -85,8 +86,10 @@ typedef struct { EVP_MD *md; EVP_MD_CTX *mdctx; size_t mdsize; + int operation; } PROV_DSA_CTX; + static size_t dsa_get_md_size(const PROV_DSA_CTX *pdsactx) { if (pdsactx->md != NULL) @@ -94,52 +97,18 @@ static size_t dsa_get_md_size(const PROV_DSA_CTX *pdsactx) return 0; } -static int dsa_get_md_nid(const EVP_MD *md) -{ - /* - * Because the DSA library deals with NIDs, we need to translate. - * We do so using EVP_MD_is_a(), and therefore need a name to NID - * map. - */ - static const OSSL_ITEM name_to_nid[] = { - { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, - { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, - { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, - { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, - { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, - { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, - { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, - { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, - { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, - }; - size_t i; - int mdnid = NID_undef; - - if (md == NULL) - goto end; - - for (i = 0; i < OSSL_NELEM(name_to_nid); i++) { - if (EVP_MD_is_a(md, name_to_nid[i].ptr)) { - mdnid = (int)name_to_nid[i].id; - break; - } - } - - if (mdnid == NID_undef) - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); - - end: - return mdnid; -} - static void *dsa_newctx(void *provctx, const char *propq) { - PROV_DSA_CTX *pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX)); + PROV_DSA_CTX *pdsactx; + + if (!ossl_prov_is_running()) + return NULL; + pdsactx = OPENSSL_zalloc(sizeof(PROV_DSA_CTX)); if (pdsactx == NULL) return NULL; - pdsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + pdsactx->libctx = PROV_LIBCTX_OF(provctx); pdsactx->flag_allow_md = 1; if (propq != NULL && (pdsactx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(pdsactx); @@ -156,11 +125,22 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx, mdprops = ctx->propq; if (mdname != NULL) { - EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); - int md_nid = dsa_get_md_nid(md); + int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); WPACKET pkt; + EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); + int md_nid = digest_get_approved_nid_with_sha1(md, sha1_allowed); + size_t mdname_len = strlen(mdname); if (md == NULL || md_nid == NID_undef) { + if (md == NULL) + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "%s could not be fetched", mdname); + if (md_nid == NID_undef) + ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, + "digest=%s", mdname); + if (mdname_len >= sizeof(ctx->mdname)) + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "%s exceeds name buffer length", mdname); EVP_MD_free(md); return 0; } @@ -177,8 +157,8 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx, */ ctx->aid_len = 0; if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) - && DER_w_algorithmIdentifier_DSA_with_MD(&pkt, -1, ctx->dsa, - md_nid) + && ossl_DER_w_algorithmIdentifier_DSA_with_MD(&pkt, -1, ctx->dsa, + md_nid) && WPACKET_finish(&pkt)) { WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = WPACKET_get_curr(&pkt); @@ -192,17 +172,35 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx, return 1; } -static int dsa_signature_init(void *vpdsactx, void *vdsa) +static int dsa_signverify_init(void *vpdsactx, void *vdsa, int operation) { PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; - if (pdsactx == NULL || vdsa == NULL || !DSA_up_ref(vdsa)) + if (!ossl_prov_is_running() + || pdsactx == NULL + || vdsa == NULL + || !DSA_up_ref(vdsa)) return 0; DSA_free(pdsactx->dsa); pdsactx->dsa = vdsa; + pdsactx->operation = operation; + if (!dsa_check_key(vdsa, operation == EVP_PKEY_OP_SIGN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } return 1; } +static int dsa_sign_init(void *vpdsactx, void *vdsa) +{ + return dsa_signverify_init(vpdsactx, vdsa, EVP_PKEY_OP_SIGN); +} + +static int dsa_verify_init(void *vpdsactx, void *vdsa) +{ + return dsa_signverify_init(vpdsactx, vdsa, EVP_PKEY_OP_VERIFY); +} + static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, size_t sigsize, const unsigned char *tbs, size_t tbslen) { @@ -212,6 +210,9 @@ static int dsa_sign(void *vpdsactx, unsigned char *sig, size_t *siglen, size_t dsasize = DSA_size(pdsactx->dsa); size_t mdsize = dsa_get_md_size(pdsactx); + if (!ossl_prov_is_running()) + return 0; + if (sig == NULL) { *siglen = dsasize; return 1; @@ -237,19 +238,22 @@ static int dsa_verify(void *vpdsactx, const unsigned char *sig, size_t siglen, PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; size_t mdsize = dsa_get_md_size(pdsactx); - if (mdsize != 0 && tbslen != mdsize) + if (!ossl_prov_is_running() || (mdsize != 0 && tbslen != mdsize)) return 0; return DSA_verify(0, tbs, tbslen, sig, siglen, pdsactx->dsa); } static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, - void *vdsa) + void *vdsa, int operation) { PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx; + if (!ossl_prov_is_running()) + return 0; + pdsactx->flag_allow_md = 0; - if (!dsa_signature_init(vpdsactx, vdsa)) + if (!dsa_signverify_init(vpdsactx, vdsa, operation)) return 0; if (!dsa_setup_md(pdsactx, mdname, NULL)) @@ -272,6 +276,17 @@ static int dsa_digest_signverify_init(void *vpdsactx, const char *mdname, return 0; } +static int dsa_digest_sign_init(void *vpdsactx, const char *mdname, + void *vdsa) +{ + return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, EVP_PKEY_OP_SIGN); +} + +static int dsa_digest_verify_init(void *vpdsactx, const char *mdname, void *vdsa) +{ + return dsa_digest_signverify_init(vpdsactx, mdname, vdsa, EVP_PKEY_OP_VERIFY); +} + int dsa_digest_signverify_update(void *vpdsactx, const unsigned char *data, size_t datalen) { @@ -290,7 +305,7 @@ int dsa_digest_sign_final(void *vpdsactx, unsigned char *sig, size_t *siglen, unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; - if (pdsactx == NULL || pdsactx->mdctx == NULL) + if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) return 0; /* @@ -320,7 +335,7 @@ int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig, unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; - if (pdsactx == NULL || pdsactx->mdctx == NULL) + if (!ossl_prov_is_running() || pdsactx == NULL || pdsactx->mdctx == NULL) return 0; /* @@ -356,6 +371,9 @@ static void *dsa_dupctx(void *vpdsactx) PROV_DSA_CTX *srcctx = (PROV_DSA_CTX *)vpdsactx; PROV_DSA_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; @@ -412,7 +430,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *dsa_gettable_ctx_params(void) +static const OSSL_PARAM *dsa_gettable_ctx_params(ossl_unused void *vctx) { return known_gettable_ctx_params; } @@ -454,13 +472,19 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *dsa_settable_ctx_params(void) +static const OSSL_PARAM *dsa_settable_ctx_params(ossl_unused void *provctx) { /* * TODO(3.0): Should this function return a different set of settable ctx * params if the ctx is being used for a DigestSign/DigestVerify? In that * case it is not allowed to set the digest size/digest name because the * digest is explicitly set as part of the init. + * NOTE: Ideally we would check pdsactx->flag_allow_md, but this is + * problematic because there is no nice way of passing the + * PROV_DSA_CTX down to this function... + * Because we have API's that dont know about their parent.. + * e.g: EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig). + * We could pass NULL for that case (but then how useful is the check?). */ return known_settable_ctx_params; } @@ -505,20 +529,20 @@ static const OSSL_PARAM *dsa_settable_ctx_md_params(void *vpdsactx) return EVP_MD_settable_ctx_params(pdsactx->md); } -const OSSL_DISPATCH dsa_signature_functions[] = { +const OSSL_DISPATCH ossl_dsa_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))dsa_newctx }, - { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_signature_init }, + { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))dsa_sign_init }, { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))dsa_sign }, - { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_signature_init }, + { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))dsa_verify_init }, { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))dsa_verify }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, - (void (*)(void))dsa_digest_signverify_init }, + (void (*)(void))dsa_digest_sign_init }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, (void (*)(void))dsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))dsa_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, - (void (*)(void))dsa_digest_signverify_init }, + (void (*)(void))dsa_digest_verify_init }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, (void (*)(void))dsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, diff --git a/providers/implementations/signature/ecdsa.c b/providers/implementations/signature/ecdsa.c index e6da05c1e1..b956917e49 100644 --- a/providers/implementations/signature/ecdsa.c +++ b/providers/implementations/signature/ecdsa.c @@ -24,21 +24,23 @@ #include "internal/nelem.h" #include "internal/sizes.h" #include "internal/cryptlib.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" +#include "prov/securitycheck.h" #include "crypto/ec.h" #include "prov/der_ec.h" static OSSL_FUNC_signature_newctx_fn ecdsa_newctx; -static OSSL_FUNC_signature_sign_init_fn ecdsa_signature_init; -static OSSL_FUNC_signature_verify_init_fn ecdsa_signature_init; +static OSSL_FUNC_signature_sign_init_fn ecdsa_sign_init; +static OSSL_FUNC_signature_verify_init_fn ecdsa_verify_init; static OSSL_FUNC_signature_sign_fn ecdsa_sign; static OSSL_FUNC_signature_verify_fn ecdsa_verify; -static OSSL_FUNC_signature_digest_sign_init_fn ecdsa_digest_signverify_init; +static OSSL_FUNC_signature_digest_sign_init_fn ecdsa_digest_sign_init; static OSSL_FUNC_signature_digest_sign_update_fn ecdsa_digest_signverify_update; static OSSL_FUNC_signature_digest_sign_final_fn ecdsa_digest_sign_final; -static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_signverify_init; +static OSSL_FUNC_signature_digest_verify_init_fn ecdsa_digest_verify_init; static OSSL_FUNC_signature_digest_verify_update_fn ecdsa_digest_signverify_update; static OSSL_FUNC_signature_digest_verify_final_fn ecdsa_digest_verify_final; static OSSL_FUNC_signature_freectx_fn ecdsa_freectx; @@ -59,7 +61,7 @@ static OSSL_FUNC_signature_settable_ctx_md_params_fn ecdsa_settable_ctx_md_param */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; EC_KEY *ec; char mdname[OSSL_MAX_NAME_SIZE]; @@ -69,6 +71,7 @@ typedef struct { unsigned char *aid; size_t aid_len; size_t mdsize; + int operation; EVP_MD *md; EVP_MD_CTX *mdctx; @@ -81,7 +84,7 @@ typedef struct { */ BIGNUM *kinv; BIGNUM *r; -#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) +#if !defined(OPENSSL_NO_ACVP_TESTS) /* * This indicates that KAT (CAVS) test is running. Externally an app will * override the random callback such that the generated private key and k @@ -95,12 +98,16 @@ typedef struct { static void *ecdsa_newctx(void *provctx, const char *propq) { - PROV_ECDSA_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX)); + PROV_ECDSA_CTX *ctx; + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(PROV_ECDSA_CTX)); if (ctx == NULL) return NULL; - ctx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + ctx->libctx = PROV_LIBCTX_OF(provctx); if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { OPENSSL_free(ctx); ctx = NULL; @@ -109,15 +116,29 @@ static void *ecdsa_newctx(void *provctx, const char *propq) return ctx; } -static int ecdsa_signature_init(void *vctx, void *ec) +static int ecdsa_signverify_init(void *vctx, void *ec, int operation) { PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; - if (ctx == NULL || ec == NULL || !EC_KEY_up_ref(ec)) + if (!ossl_prov_is_running() + || ctx == NULL + || ec == NULL + || !EC_KEY_up_ref(ec)) return 0; EC_KEY_free(ctx->ec); ctx->ec = ec; - return 1; + ctx->operation = operation; + return ec_check_key(ec, operation == EVP_PKEY_OP_SIGN); +} + +static int ecdsa_sign_init(void *vctx, void *ec) +{ + return ecdsa_signverify_init(vctx, ec, EVP_PKEY_OP_SIGN); +} + +static int ecdsa_verify_init(void *vctx, void *ec) +{ + return ecdsa_signverify_init(vctx, ec, EVP_PKEY_OP_VERIFY); } static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen, @@ -128,12 +149,15 @@ static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen, unsigned int sltmp; size_t ecsize = ECDSA_size(ctx->ec); + if (!ossl_prov_is_running()) + return 0; + if (sig == NULL) { *siglen = ecsize; return 1; } -#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) +#if !defined(OPENSSL_NO_ACVP_TESTS) if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r)) return 0; #endif @@ -157,52 +181,12 @@ static int ecdsa_verify(void *vctx, const unsigned char *sig, size_t siglen, { PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; - if (ctx->mdsize != 0 && tbslen != ctx->mdsize) + if (!ossl_prov_is_running() || (ctx->mdsize != 0 && tbslen != ctx->mdsize)) return 0; return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->ec); } -static int get_md_nid(const EVP_MD *md) -{ - /* - * Because the ECDSA library deals with NIDs, we need to translate. - * We do so using EVP_MD_is_a(), and therefore need a name to NID - * map. - */ - static const OSSL_ITEM name_to_nid[] = { - { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, - { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, - { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, - { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, - { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, - { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, - { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, - { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, - { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, - /* TODO - Add SHAKE OIDS when they are standardized */ - - }; - size_t i; - int mdnid = NID_undef; - - if (md == NULL) - goto end; - - for (i = 0; i < OSSL_NELEM(name_to_nid); i++) { - if (EVP_MD_is_a(md, name_to_nid[i].ptr)) { - mdnid = (int)name_to_nid[i].id; - break; - } - } - - if (mdnid == NID_undef) - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); - - end: - return mdnid; -} - static void free_md(PROV_ECDSA_CTX *ctx) { OPENSSL_free(ctx->propq); @@ -215,19 +199,24 @@ static void free_md(PROV_ECDSA_CTX *ctx) } static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, - void *ec) + void *ec, int operation) { PROV_ECDSA_CTX *ctx = (PROV_ECDSA_CTX *)vctx; int md_nid = NID_undef; WPACKET pkt; + int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); + + if (!ossl_prov_is_running()) + return 0; free_md(ctx); - if (!ecdsa_signature_init(vctx, ec)) + if (!ecdsa_signverify_init(vctx, ec, operation)) return 0; ctx->md = EVP_MD_fetch(ctx->libctx, mdname, ctx->propq); - if ((md_nid = get_md_nid(ctx->md)) == NID_undef) + md_nid = digest_get_approved_nid_with_sha1(ctx->md, sha1_allowed); + if (md_nid == NID_undef) goto error; ctx->mdsize = EVP_MD_size(ctx->md); @@ -244,7 +233,8 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, */ ctx->aid_len = 0; if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) - && DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec, md_nid) + && ossl_DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec, + md_nid) && WPACKET_finish(&pkt)) { WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = WPACKET_get_curr(&pkt); @@ -259,6 +249,16 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, return 0; } +static int ecdsa_digest_sign_init(void *vctx, const char *mdname, void *ec) +{ + return ecdsa_digest_signverify_init(vctx, mdname, ec, EVP_PKEY_OP_SIGN); +} + +static int ecdsa_digest_verify_init(void *vctx, const char *mdname, void *ec) +{ + return ecdsa_digest_signverify_init(vctx, mdname, ec, EVP_PKEY_OP_VERIFY); +} + int ecdsa_digest_signverify_update(void *vctx, const unsigned char *data, size_t datalen) { @@ -277,7 +277,7 @@ int ecdsa_digest_sign_final(void *vctx, unsigned char *sig, size_t *siglen, unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; - if (ctx == NULL || ctx->mdctx == NULL) + if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL) return 0; /* @@ -304,7 +304,7 @@ int ecdsa_digest_verify_final(void *vctx, const unsigned char *sig, unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; - if (ctx == NULL || ctx->mdctx == NULL) + if (!ossl_prov_is_running() || ctx == NULL || ctx->mdctx == NULL) return 0; /* @@ -334,6 +334,9 @@ static void *ecdsa_dupctx(void *vctx) PROV_ECDSA_CTX *srcctx = (PROV_ECDSA_CTX *)vctx; PROV_ECDSA_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; @@ -399,7 +402,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *ecdsa_gettable_ctx_params(void) +static const OSSL_PARAM *ecdsa_gettable_ctx_params(ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -420,7 +423,7 @@ static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[]) */ return 1; } -#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) +#if !defined(OPENSSL_NO_ACVP_TESTS) p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT); if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest)) return 0; @@ -451,7 +454,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *ecdsa_settable_ctx_params(void) +static const OSSL_PARAM *ecdsa_settable_ctx_params(ossl_unused void *provctx) { /* * TODO(3.0): Should this function return a different set of settable ctx @@ -502,20 +505,20 @@ static const OSSL_PARAM *ecdsa_settable_ctx_md_params(void *vctx) return EVP_MD_settable_ctx_params(ctx->md); } -const OSSL_DISPATCH ecdsa_signature_functions[] = { +const OSSL_DISPATCH ecossl_dsa_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))ecdsa_newctx }, - { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_signature_init }, + { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))ecdsa_sign_init }, { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))ecdsa_sign }, - { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_signature_init }, + { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))ecdsa_verify_init }, { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))ecdsa_verify }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, - (void (*)(void))ecdsa_digest_signverify_init }, + (void (*)(void))ecdsa_digest_sign_init }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, (void (*)(void))ecdsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, (void (*)(void))ecdsa_digest_sign_final }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, - (void (*)(void))ecdsa_digest_signverify_init }, + (void (*)(void))ecdsa_digest_verify_init }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, (void (*)(void))ecdsa_digest_signverify_update }, { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, diff --git a/providers/implementations/signature/eddsa.c b/providers/implementations/signature/eddsa.c index c8e6c7cd3c..dbec8e6040 100644 --- a/providers/implementations/signature/eddsa.c +++ b/providers/implementations/signature/eddsa.c @@ -16,10 +16,11 @@ #include #include "internal/nelem.h" #include "internal/sizes.h" -#include "prov/providercommonerr.h" +#include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/providercommonerr.h" #include "prov/provider_ctx.h" +#include "prov/der_ecx.h" #include "crypto/ecx.h" static OSSL_FUNC_signature_newctx_fn eddsa_newctx; @@ -30,22 +31,33 @@ static OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify; static OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify; static OSSL_FUNC_signature_freectx_fn eddsa_freectx; static OSSL_FUNC_signature_dupctx_fn eddsa_dupctx; +static OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params; +static OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params; typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; ECX_KEY *key; + + /* The Algorithm Identifier of the signature algorithm */ + unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; + unsigned char *aid; + size_t aid_len; } PROV_EDDSA_CTX; static void *eddsa_newctx(void *provctx, const char *propq_unused) { - PROV_EDDSA_CTX *peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); + PROV_EDDSA_CTX *peddsactx; + + if (!ossl_prov_is_running()) + return NULL; + peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); if (peddsactx == NULL) { PROVerr(0, ERR_R_MALLOC_FAILURE); return NULL; } - peddsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + peddsactx->libctx = PROV_LIBCTX_OF(provctx); return peddsactx; } @@ -55,6 +67,11 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, { PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; ECX_KEY *edkey = (ECX_KEY *)vedkey; + WPACKET pkt; + int ret; + + if (!ossl_prov_is_running()) + return 0; if (mdname != NULL && mdname[0] != '\0') { PROVerr(0, PROV_R_INVALID_DIGEST); @@ -66,6 +83,33 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, return 0; } + /* + * TODO(3.0) Should we care about DER writing errors? + * All it really means is that for some reason, there's no + * AlgorithmIdentifier to be had, but the operation itself is + * still valid, just as long as it's not used to construct + * anything that needs an AlgorithmIdentifier. + */ + peddsactx->aid_len = 0; + ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf)); + switch (edkey->type) { + case ECX_KEY_TYPE_ED25519: + ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey); + break; + case ECX_KEY_TYPE_ED448: + ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey); + break; + default: + /* Should never happen */ + PROVerr(0, ERR_R_INTERNAL_ERROR); + return 0; + } + if (ret && WPACKET_finish(&pkt)) { + WPACKET_get_total_written(&pkt, &peddsactx->aid_len); + peddsactx->aid = WPACKET_get_curr(&pkt); + } + WPACKET_cleanup(&pkt); + peddsactx->key = edkey; return 1; @@ -78,6 +122,9 @@ int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; + if (!ossl_prov_is_running()) + return 0; + if (sigret == NULL) { *siglen = ED25519_SIGSIZE; return 1; @@ -103,6 +150,9 @@ int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; + if (!ossl_prov_is_running()) + return 0; + if (sigret == NULL) { *siglen = ED448_SIGSIZE; return 1; @@ -113,7 +163,7 @@ int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, } if (ED448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey, - edkey->privkey, NULL, 0) == 0) { + edkey->privkey, NULL, 0, edkey->propq) == 0) { PROVerr(0, PROV_R_FAILED_TO_SIGN); return 0; } @@ -128,11 +178,11 @@ int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig, PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; - if (siglen != ED25519_SIGSIZE) + if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE) return 0; return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, peddsactx->libctx, - NULL); + edkey->propq); } int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, @@ -142,11 +192,11 @@ int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; const ECX_KEY *edkey = peddsactx->key; - if (siglen != ED448_SIGSIZE) + if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE) return 0; return ED448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey, - NULL, 0); + NULL, 0, edkey->propq); } static void eddsa_freectx(void *vpeddsactx) @@ -163,6 +213,9 @@ static void *eddsa_dupctx(void *vpeddsactx) PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx; PROV_EDDSA_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; @@ -182,7 +235,33 @@ static void *eddsa_dupctx(void *vpeddsactx) return NULL; } -const OSSL_DISPATCH ed25519_signature_functions[] = { +static int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + OSSL_PARAM *p; + + if (peddsactx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); + if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid, + peddsactx->aid_len)) + return 0; + + return 1; +} + +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *provctx) +{ + return known_gettable_ctx_params; +} + +const OSSL_DISPATCH ossl_ed25519_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))eddsa_digest_signverify_init }, @@ -194,10 +273,13 @@ const OSSL_DISPATCH ed25519_signature_functions[] = { (void (*)(void))ed25519_digest_verify }, { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, + { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params }, + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, + (void (*)(void))eddsa_gettable_ctx_params }, { 0, NULL } }; -const OSSL_DISPATCH ed448_signature_functions[] = { +const OSSL_DISPATCH ossl_ed448_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, (void (*)(void))eddsa_digest_signverify_init }, @@ -209,5 +291,8 @@ const OSSL_DISPATCH ed448_signature_functions[] = { (void (*)(void))ed448_digest_verify }, { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, + { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params }, + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, + (void (*)(void))eddsa_gettable_ctx_params }, { 0, NULL } }; diff --git a/providers/implementations/signature/mac_legacy.c b/providers/implementations/signature/mac_legacy.c new file mode 100644 index 0000000000..12a78b7ea4 --- /dev/null +++ b/providers/implementations/signature/mac_legacy.c @@ -0,0 +1,248 @@ +/* + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* We need to use some engine deprecated APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + +#include +#include +#include +#include +#include +#include +#include "prov/implementations.h" +#include "prov/provider_ctx.h" +#include "prov/macsignature.h" +#include "prov/providercommon.h" + +static OSSL_FUNC_signature_newctx_fn mac_hmac_newctx; +static OSSL_FUNC_signature_newctx_fn mac_siphash_newctx; +static OSSL_FUNC_signature_newctx_fn mac_poly1305_newctx; +static OSSL_FUNC_signature_newctx_fn mac_cmac_newctx; +static OSSL_FUNC_signature_digest_sign_init_fn mac_digest_sign_init; +static OSSL_FUNC_signature_digest_sign_update_fn mac_digest_sign_update; +static OSSL_FUNC_signature_digest_sign_final_fn mac_digest_sign_final; +static OSSL_FUNC_signature_freectx_fn mac_freectx; +static OSSL_FUNC_signature_dupctx_fn mac_dupctx; +static OSSL_FUNC_signature_set_ctx_params_fn mac_set_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn mac_hmac_settable_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn mac_siphash_settable_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn mac_poly1305_settable_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn mac_cmac_settable_ctx_params; + +typedef struct { + OSSL_LIB_CTX *libctx; + char *propq; + MAC_KEY *key; + EVP_MAC_CTX *macctx; +} PROV_MAC_CTX; + +static void *mac_newctx(void *provctx, const char *propq, const char *macname) +{ + PROV_MAC_CTX *pmacctx; + EVP_MAC *mac = NULL; + + if (!ossl_prov_is_running()) + return NULL; + + pmacctx = OPENSSL_zalloc(sizeof(PROV_MAC_CTX)); + if (pmacctx == NULL) + return NULL; + + pmacctx->libctx = PROV_LIBCTX_OF(provctx); + if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto err; + } + + mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq); + if (mac == NULL) + goto err; + + pmacctx->macctx = EVP_MAC_CTX_new(mac); + if (pmacctx->macctx == NULL) + goto err; + + EVP_MAC_free(mac); + + return pmacctx; + + err: + OPENSSL_free(pmacctx); + EVP_MAC_free(mac); + return NULL; +} + +#define MAC_NEWCTX(funcname, macname) \ + static void *mac_##funcname##_newctx(void *provctx, const char *propq) \ + { \ + return mac_newctx(provctx, propq, macname); \ + } + +MAC_NEWCTX(hmac, "HMAC") +MAC_NEWCTX(siphash, "SIPHASH") +MAC_NEWCTX(poly1305, "POLY1305") +MAC_NEWCTX(cmac, "CMAC") + +static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey) +{ + PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; + const char *ciphername = NULL, *engine = NULL; + + if (!ossl_prov_is_running() + || pmacctx == NULL + || vkey == NULL + || !mac_key_up_ref(vkey)) + return 0; + + mac_key_free(pmacctx->key); + pmacctx->key = vkey; + + if (pmacctx->key->cipher.cipher != NULL) + ciphername = (char *)EVP_CIPHER_name(pmacctx->key->cipher.cipher); +#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE) + if (pmacctx->key->cipher.engine != NULL) + engine = (char *)ENGINE_get_id(pmacctx->key->cipher.engine); +#endif + + if (!ossl_prov_set_macctx(pmacctx->macctx, NULL, + (char *)ciphername, + (char *)mdname, + (char *)engine, + pmacctx->key->properties, + pmacctx->key->priv_key, + pmacctx->key->priv_key_len)) + return 0; + + if (!EVP_MAC_init(pmacctx->macctx)) + return 0; + + return 1; +} + +int mac_digest_sign_update(void *vpmacctx, const unsigned char *data, + size_t datalen) +{ + PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; + + if (pmacctx == NULL || pmacctx->macctx == NULL) + return 0; + + return EVP_MAC_update(pmacctx->macctx, data, datalen); +} + +int mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen, + size_t macsize) +{ + PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx; + + if (!ossl_prov_is_running() || pmacctx == NULL || pmacctx->macctx == NULL) + return 0; + + return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize); +} + +static void mac_freectx(void *vpmacctx) +{ + PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx; + + OPENSSL_free(ctx->propq); + EVP_MAC_CTX_free(ctx->macctx); + mac_key_free(ctx->key); + OPENSSL_free(ctx); +} + +static void *mac_dupctx(void *vpmacctx) +{ + PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx; + PROV_MAC_CTX *dstctx; + + if (!ossl_prov_is_running()) + return NULL; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + dstctx->key = NULL; + dstctx->macctx = NULL; + + if (srcctx->key != NULL && !mac_key_up_ref(srcctx->key)) + goto err; + dstctx->key = srcctx->key; + + if (srcctx->macctx != NULL) { + dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx); + if (dstctx->macctx == NULL) + goto err; + } + + return dstctx; + err: + mac_freectx(dstctx); + return NULL; +} + +static int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[]) +{ + PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx; + + return EVP_MAC_CTX_set_params(ctx->macctx, params); +} + +static const OSSL_PARAM *mac_settable_ctx_params(void *provctx, + const char *macname) +{ + EVP_MAC *mac = EVP_MAC_fetch(PROV_LIBCTX_OF(provctx), macname, + NULL); + const OSSL_PARAM *params; + + if (mac == NULL) + return NULL; + + params = EVP_MAC_settable_ctx_params(mac); + EVP_MAC_free(mac); + + return params; +} + +#define MAC_SETTABLE_CTX_PARAMS(funcname, macname) \ + static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *provctx) \ + { \ + return mac_settable_ctx_params(provctx, macname); \ + } + +MAC_SETTABLE_CTX_PARAMS(hmac, "HMAC") +MAC_SETTABLE_CTX_PARAMS(siphash, "SIPHASH") +MAC_SETTABLE_CTX_PARAMS(poly1305, "POLY1305") +MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC") + +#define MAC_SIGNATURE_FUNCTIONS(funcname) \ + const OSSL_DISPATCH ossl_mac_legacy_##funcname##_signature_functions[] = { \ + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ + (void (*)(void))mac_digest_sign_init }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, \ + (void (*)(void))mac_digest_sign_update }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, \ + (void (*)(void))mac_digest_sign_final }, \ + { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx }, \ + { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx }, \ + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ + (void (*)(void))mac_set_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ + (void (*)(void))mac_##funcname##_settable_ctx_params }, \ + { 0, NULL } \ + }; + +MAC_SIGNATURE_FUNCTIONS(hmac) +MAC_SIGNATURE_FUNCTIONS(siphash) +MAC_SIGNATURE_FUNCTIONS(poly1305) +MAC_SIGNATURE_FUNCTIONS(cmac) diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c index 42654f929a..b463f03d7f 100644 --- a/providers/implementations/signature/rsa.c +++ b/providers/implementations/signature/rsa.c @@ -25,10 +25,14 @@ #include "internal/nelem.h" #include "internal/sizes.h" #include "crypto/rsa.h" +#include "prov/providercommon.h" #include "prov/providercommonerr.h" #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/der_rsa.h" +#include "prov/securitycheck.h" + +#define RSA_DEFAULT_DIGEST_NAME OSSL_DIGEST_NAME_SHA1 static OSSL_FUNC_signature_newctx_fn rsa_newctx; static OSSL_FUNC_signature_sign_init_fn rsa_sign_init; @@ -70,7 +74,7 @@ static OSSL_ITEM padding_item[] = { */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; char *propq; RSA *rsa; int operation; @@ -83,7 +87,7 @@ typedef struct { */ unsigned int flag_allow_md : 1; - /* The Algorithm Identifier of the combined signature agorithm */ + /* The Algorithm Identifier of the combined signature algorithm */ unsigned char aid_buf[128]; unsigned char *aid; size_t aid_len; @@ -116,49 +120,6 @@ static size_t rsa_get_md_size(const PROV_RSA_CTX *prsactx) return 0; } -static int rsa_get_md_nid(const EVP_MD *md) -{ - /* - * Because the RSA library deals with NIDs, we need to translate. - * We do so using EVP_MD_is_a(), and therefore need a name to NID - * map. - */ - static const OSSL_ITEM name_to_nid[] = { - { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, - { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, - { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, - { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, - { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, - { NID_sha512_224, OSSL_DIGEST_NAME_SHA2_512_224 }, - { NID_sha512_256, OSSL_DIGEST_NAME_SHA2_512_256 }, - { NID_md5, OSSL_DIGEST_NAME_MD5 }, - { NID_md5_sha1, OSSL_DIGEST_NAME_MD5_SHA1 }, - { NID_md2, OSSL_DIGEST_NAME_MD2 }, - { NID_md4, OSSL_DIGEST_NAME_MD4 }, - { NID_mdc2, OSSL_DIGEST_NAME_MDC2 }, - { NID_ripemd160, OSSL_DIGEST_NAME_RIPEMD160 }, - { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, - { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, - { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, - { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, - }; - size_t i; - int mdnid = NID_undef; - - if (md == NULL) - goto end; - - for (i = 0; i < OSSL_NELEM(name_to_nid); i++) { - if (EVP_MD_is_a(md, name_to_nid[i].ptr)) { - mdnid = (int)name_to_nid[i].id; - break; - } - } - - end: - return mdnid; -} - static int rsa_check_padding(int mdnid, int padding) { if (padding == RSA_NO_PADDING) { @@ -176,16 +137,16 @@ static int rsa_check_padding(int mdnid, int padding) return 1; } -static int rsa_check_parameters(EVP_MD *md, PROV_RSA_CTX *prsactx) +static int rsa_check_parameters(PROV_RSA_CTX *prsactx) { if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) { int max_saltlen; /* See if minimum salt length exceeds maximum possible */ - max_saltlen = RSA_size(prsactx->rsa) - EVP_MD_size(md); + max_saltlen = RSA_size(prsactx->rsa) - EVP_MD_size(prsactx->md); if ((RSA_bits(prsactx->rsa) & 0x7) == 1) max_saltlen--; - if (prsactx->min_saltlen > max_saltlen) { + if (prsactx->min_saltlen < 0 || prsactx->min_saltlen > max_saltlen) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH); return 0; } @@ -198,6 +159,9 @@ static void *rsa_newctx(void *provctx, const char *propq) PROV_RSA_CTX *prsactx = NULL; char *propq_copy = NULL; + if (!ossl_prov_is_running()) + return NULL; + if ((prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX))) == NULL || (propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL)) { @@ -206,7 +170,7 @@ static void *rsa_newctx(void *provctx, const char *propq) return NULL; } - prsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + prsactx->libctx = PROV_LIBCTX_OF(provctx); prsactx->flag_allow_md = 1; prsactx->propq = propq_copy; return prsactx; @@ -222,15 +186,15 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, mdprops = ctx->propq; if (mdname != NULL) { - EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); - int md_nid = rsa_get_md_nid(md); WPACKET pkt; + EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); + int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN); + int md_nid = digest_rsa_sign_get_md_nid(md, sha1_allowed); size_t mdname_len = strlen(mdname); if (md == NULL || md_nid == NID_undef || !rsa_check_padding(md_nid, ctx->pad_mode) - || !rsa_check_parameters(md, ctx) || mdname_len >= sizeof(ctx->mdname)) { if (md == NULL) ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, @@ -257,8 +221,9 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, */ ctx->aid_len = 0; if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) - && DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1, ctx->rsa, - md_nid) + && ossl_DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1, + ctx->rsa, + md_nid) && WPACKET_finish(&pkt)) { WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = WPACKET_get_curr(&pkt); @@ -278,6 +243,7 @@ static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, const char *mdprops) { size_t len; + EVP_MD *md = NULL; if (mdprops == NULL) mdprops = ctx->propq; @@ -285,11 +251,19 @@ static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, if (ctx->mgf1_mdname[0] != '\0') EVP_MD_free(ctx->mgf1_md); - if ((ctx->mgf1_md = EVP_MD_fetch(ctx->libctx, mdname, mdprops)) == NULL) { + if ((md = EVP_MD_fetch(ctx->libctx, mdname, mdprops)) == NULL) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s could not be fetched", mdname); return 0; } + /* The default for mgf1 is SHA1 - so allow SHA1 */ + if (digest_rsa_sign_get_md_nid(md, 1) == NID_undef) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, + "digest=%s", mdname); + EVP_MD_free(md); + return 0; + } + ctx->mgf1_md = md; len = OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); if (len >= sizeof(ctx->mgf1_mdname)) { ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, @@ -300,10 +274,13 @@ static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, return 1; } -static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) +static int rsa_signverify_init(void *vprsactx, void *vrsa, int operation) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + if (!ossl_prov_is_running()) + return 0; + if (prsactx == NULL || vrsa == NULL || !RSA_up_ref(vrsa)) return 0; @@ -311,6 +288,11 @@ static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) prsactx->rsa = vrsa; prsactx->operation = operation; + if (!ossl_rsa_check_key(vrsa, operation == EVP_PKEY_OP_SIGN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + /* Maximum for sign, auto for verify */ prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; prsactx->min_saltlen = -1; @@ -324,17 +306,17 @@ static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) { const RSA_PSS_PARAMS_30 *pss = - rsa_get0_pss_params_30(prsactx->rsa); + ossl_rsa_get0_pss_params_30(prsactx->rsa); - if (!rsa_pss_params_30_is_unrestricted(pss)) { - int md_nid = rsa_pss_params_30_hashalg(pss); - int mgf1md_nid = rsa_pss_params_30_maskgenhashalg(pss); - int min_saltlen = rsa_pss_params_30_saltlen(pss); + if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) { + int md_nid = ossl_rsa_pss_params_30_hashalg(pss); + int mgf1md_nid = ossl_rsa_pss_params_30_maskgenhashalg(pss); + int min_saltlen = ossl_rsa_pss_params_30_saltlen(pss); const char *mdname, *mgf1mdname; size_t len; - mdname = rsa_oaeppss_nid2name(md_nid); - mgf1mdname = rsa_oaeppss_nid2name(mgf1md_nid); + mdname = ossl_rsa_oaeppss_nid2name(md_nid); + mgf1mdname = ossl_rsa_oaeppss_nid2name(mgf1md_nid); prsactx->min_saltlen = min_saltlen; if (mdname == NULL) { @@ -365,7 +347,8 @@ static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) prsactx->saltlen = min_saltlen; return rsa_setup_md(prsactx, mdname, prsactx->propq) - && rsa_setup_mgf1_md(prsactx, mgf1mdname, prsactx->propq); + && rsa_setup_mgf1_md(prsactx, mgf1mdname, prsactx->propq) + && rsa_check_parameters(prsactx); } } @@ -404,7 +387,9 @@ static void free_tbuf(PROV_RSA_CTX *ctx) static int rsa_sign_init(void *vprsactx, void *vrsa) { - return rsa_signature_init(vprsactx, vrsa, EVP_PKEY_OP_SIGN); + if (!ossl_prov_is_running()) + return 0; + return rsa_signverify_init(vprsactx, vrsa, EVP_PKEY_OP_SIGN); } static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, @@ -415,6 +400,9 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, size_t rsasize = RSA_size(prsactx->rsa); size_t mdsize = rsa_get_md_size(prsactx); + if (!ossl_prov_is_running()) + return 0; + if (sig == NULL) { *siglen = rsasize; return 1; @@ -552,7 +540,9 @@ static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, static int rsa_verify_recover_init(void *vprsactx, void *vrsa) { - return rsa_signature_init(vprsactx, vrsa, EVP_PKEY_OP_VERIFYRECOVER); + if (!ossl_prov_is_running()) + return 0; + return rsa_signverify_init(vprsactx, vrsa, EVP_PKEY_OP_VERIFYRECOVER); } static int rsa_verify_recover(void *vprsactx, @@ -565,6 +555,9 @@ static int rsa_verify_recover(void *vprsactx, PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; int ret; + if (!ossl_prov_is_running()) + return 0; + if (rout == NULL) { *routlen = RSA_size(prsactx->rsa); return 1; @@ -638,7 +631,9 @@ static int rsa_verify_recover(void *vprsactx, static int rsa_verify_init(void *vprsactx, void *vrsa) { - return rsa_signature_init(vprsactx, vrsa, EVP_PKEY_OP_VERIFY); + if (!ossl_prov_is_running()) + return 0; + return rsa_signverify_init(vprsactx, vrsa, EVP_PKEY_OP_VERIFY); } static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, @@ -647,6 +642,8 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; size_t rslen; + if (!ossl_prov_is_running()) + return 0; if (prsactx->md != NULL) { switch (prsactx->pad_mode) { case RSA_PKCS1_PADDING: @@ -725,8 +722,12 @@ static int rsa_digest_signverify_init(void *vprsactx, const char *mdname, { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - prsactx->flag_allow_md = 0; - if (!rsa_signature_init(vprsactx, vrsa, operation) + if (!ossl_prov_is_running()) + return 0; + + if (prsactx != NULL) + prsactx->flag_allow_md = 0; + if (!rsa_signverify_init(vprsactx, vrsa, operation) || !rsa_setup_md(prsactx, mdname, NULL)) /* TODO RL */ return 0; @@ -764,6 +765,8 @@ static int rsa_digest_signverify_update(void *vprsactx, static int rsa_digest_sign_init(void *vprsactx, const char *mdname, void *vrsa) { + if (!ossl_prov_is_running()) + return 0; return rsa_digest_signverify_init(vprsactx, mdname, vrsa, EVP_PKEY_OP_SIGN); } @@ -775,19 +778,19 @@ static int rsa_digest_sign_final(void *vprsactx, unsigned char *sig, unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; + if (!ossl_prov_is_running() || prsactx == NULL) + return 0; prsactx->flag_allow_md = 1; - if (prsactx == NULL || prsactx->mdctx == NULL) + if (prsactx->mdctx == NULL) return 0; - /* * If sig is NULL then we're just finding out the sig size. Other fields * are ignored. Defer to rsa_sign. */ if (sig != NULL) { /* - * TODO(3.0): There is the possibility that some externally provided - * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - - * but that problem is much larger than just in RSA. + * The digests used here are all known (see rsa_get_md_nid()), so they + * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. */ if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) return 0; @@ -799,6 +802,8 @@ static int rsa_digest_sign_final(void *vprsactx, unsigned char *sig, static int rsa_digest_verify_init(void *vprsactx, const char *mdname, void *vrsa) { + if (!ossl_prov_is_running()) + return 0; return rsa_digest_signverify_init(vprsactx, mdname, vrsa, EVP_PKEY_OP_VERIFY); } @@ -810,14 +815,18 @@ int rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int dlen = 0; + if (!ossl_prov_is_running()) + return 0; + + if (prsactx == NULL) + return 0; prsactx->flag_allow_md = 1; - if (prsactx == NULL || prsactx->mdctx == NULL) + if (prsactx->mdctx == NULL) return 0; /* - * TODO(3.0): There is the possibility that some externally provided - * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - - * but that problem is much larger than just in RSA. + * The digests used here are all known (see rsa_get_md_nid()), so they + * should not exceed the internal buffer size of EVP_MAX_MD_SIZE. */ if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) return 0; @@ -832,14 +841,14 @@ static void rsa_freectx(void *vprsactx) if (prsactx == NULL) return; - RSA_free(prsactx->rsa); EVP_MD_CTX_free(prsactx->mdctx); EVP_MD_free(prsactx->md); EVP_MD_free(prsactx->mgf1_md); OPENSSL_free(prsactx->propq); free_tbuf(prsactx); + RSA_free(prsactx->rsa); - OPENSSL_clear_free(prsactx, sizeof(prsactx)); + OPENSSL_clear_free(prsactx, sizeof(*prsactx)); } static void *rsa_dupctx(void *vprsactx) @@ -847,6 +856,9 @@ static void *rsa_dupctx(void *vprsactx) PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; PROV_RSA_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) { ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); @@ -983,7 +995,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_gettable_ctx_params(void) +static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vctx) { return known_gettable_ctx_params; } @@ -1074,7 +1086,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) goto bad_pad; } if (prsactx->md == NULL - && !rsa_setup_md(prsactx, OSSL_DIGEST_NAME_SHA1, NULL)) { + && !rsa_setup_md(prsactx, RSA_DEFAULT_DIGEST_NAME, NULL)) { return 0; } break; @@ -1151,7 +1163,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) } if (rsa_pss_restricted(prsactx)) { - switch (prsactx->saltlen) { + switch (saltlen) { case RSA_PSS_SALTLEN_AUTO: if (prsactx->operation == EVP_PKEY_OP_VERIFY) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PSS_SALTLEN); @@ -1168,7 +1180,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) EVP_MD_size(prsactx->md)); return 0; } - /* FALLTHRU */ + break; default: if (saltlen >= 0 && saltlen < prsactx->min_saltlen) { ERR_raise_data(ERR_LIB_PROV, @@ -1233,7 +1245,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_settable_ctx_params(void) +static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *provctx) { /* * TODO(3.0): Should this function return a different set of settable ctx @@ -1284,7 +1296,7 @@ static const OSSL_PARAM *rsa_settable_ctx_md_params(void *vprsactx) return EVP_MD_settable_ctx_params(prsactx->md); } -const OSSL_DISPATCH rsa_signature_functions[] = { +const OSSL_DISPATCH ossl_rsa_signature_functions[] = { { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx }, { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))rsa_sign_init }, { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))rsa_sign }, diff --git a/providers/implementations/signature/sm2sig.c b/providers/implementations/signature/sm2sig.c new file mode 100644 index 0000000000..6bd27d9d38 --- /dev/null +++ b/providers/implementations/signature/sm2sig.c @@ -0,0 +1,534 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * ECDSA low level APIs are deprecated for public use, but still ok for + * internal use - SM2 implemetation uses ECDSA_size() function. + */ +#include "internal/deprecated.h" + +#include /* memcpy */ +#include +#include +#include +#include +#include +#include +#include +#include "internal/nelem.h" +#include "internal/sizes.h" +#include "internal/cryptlib.h" +#include "prov/providercommonerr.h" +#include "prov/implementations.h" +#include "prov/provider_ctx.h" +#include "crypto/ec.h" +#include "crypto/sm2.h" +#include "prov/der_sm2.h" + +static OSSL_FUNC_signature_newctx_fn sm2sig_newctx; +static OSSL_FUNC_signature_sign_init_fn sm2sig_signature_init; +static OSSL_FUNC_signature_verify_init_fn sm2sig_signature_init; +static OSSL_FUNC_signature_sign_fn sm2sig_sign; +static OSSL_FUNC_signature_verify_fn sm2sig_verify; +static OSSL_FUNC_signature_digest_sign_init_fn sm2sig_digest_signverify_init; +static OSSL_FUNC_signature_digest_sign_update_fn sm2sig_digest_signverify_update; +static OSSL_FUNC_signature_digest_sign_final_fn sm2sig_digest_sign_final; +static OSSL_FUNC_signature_digest_verify_init_fn sm2sig_digest_signverify_init; +static OSSL_FUNC_signature_digest_verify_update_fn sm2sig_digest_signverify_update; +static OSSL_FUNC_signature_digest_verify_final_fn sm2sig_digest_verify_final; +static OSSL_FUNC_signature_freectx_fn sm2sig_freectx; +static OSSL_FUNC_signature_dupctx_fn sm2sig_dupctx; +static OSSL_FUNC_signature_get_ctx_params_fn sm2sig_get_ctx_params; +static OSSL_FUNC_signature_gettable_ctx_params_fn sm2sig_gettable_ctx_params; +static OSSL_FUNC_signature_set_ctx_params_fn sm2sig_set_ctx_params; +static OSSL_FUNC_signature_settable_ctx_params_fn sm2sig_settable_ctx_params; +static OSSL_FUNC_signature_get_ctx_md_params_fn sm2sig_get_ctx_md_params; +static OSSL_FUNC_signature_gettable_ctx_md_params_fn sm2sig_gettable_ctx_md_params; +static OSSL_FUNC_signature_set_ctx_md_params_fn sm2sig_set_ctx_md_params; +static OSSL_FUNC_signature_settable_ctx_md_params_fn sm2sig_settable_ctx_md_params; + +/* + * What's passed as an actual key is defined by the KEYMGMT interface. + * We happen to know that our KEYMGMT simply passes EC structures, so + * we use that here too. + */ +typedef struct { + OSSL_LIB_CTX *libctx; + char *propq; + EC_KEY *ec; + + /* + * Flag to determine if the hash function can be changed (1) or not (0) + * Because it's dangerous to change during a DigestSign or DigestVerify + * operation, this flag is cleared by their Init function, and set again + * by their Final function. + */ + unsigned int flag_allow_md : 1; + /* + * Flag to termine if the 'z' digest needs to be computed and fed to the + * hash function. + * This flag should be set on initialization and the compuation should + * be performed only once, on first update. + */ + unsigned int flag_compute_z_digest : 1; + + char mdname[OSSL_MAX_NAME_SIZE]; + + /* The Algorithm Identifier of the combined signature algorithm */ + unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; + unsigned char *aid; + size_t aid_len; + + /* main digest */ + EVP_MD *md; + EVP_MD_CTX *mdctx; + size_t mdsize; + + /* SM2 ID used for calculating the Z value */ + unsigned char *id; + size_t id_len; +} PROV_SM2_CTX; + +static void *sm2sig_newctx(void *provctx, const char *propq) +{ + PROV_SM2_CTX *ctx = OPENSSL_zalloc(sizeof(PROV_SM2_CTX)); + + if (ctx == NULL) + return NULL; + + ctx->libctx = PROV_LIBCTX_OF(provctx); + if (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL) { + OPENSSL_free(ctx); + ctx = NULL; + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + } + /* don't allow to change MD, and in fact there is no such need */ + ctx->flag_allow_md = 0; + return ctx; +} + +static int sm2sig_signature_init(void *vpsm2ctx, void *ec) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx == NULL || ec == NULL || !EC_KEY_up_ref(ec)) + return 0; + EC_KEY_free(psm2ctx->ec); + psm2ctx->ec = ec; + return 1; +} + +static int sm2sig_sign(void *vpsm2ctx, unsigned char *sig, size_t *siglen, + size_t sigsize, const unsigned char *tbs, size_t tbslen) +{ + PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; + int ret; + unsigned int sltmp; + /* SM2 uses ECDSA_size as well */ + size_t ecsize = ECDSA_size(ctx->ec); + + if (sig == NULL) { + *siglen = ecsize; + return 1; + } + + if (sigsize < (size_t)ecsize) + return 0; + + if (ctx->mdsize != 0 && tbslen != ctx->mdsize) + return 0; + + ret = sm2_internal_sign(tbs, tbslen, sig, &sltmp, ctx->ec); + if (ret <= 0) + return 0; + + *siglen = sltmp; + return 1; +} + +static int sm2sig_verify(void *vpsm2ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (ctx->mdsize != 0 && tbslen != ctx->mdsize) + return 0; + + return sm2_internal_verify(tbs, tbslen, sig, siglen, ctx->ec); +} + +static void free_md(PROV_SM2_CTX *ctx) +{ + EVP_MD_CTX_free(ctx->mdctx); + EVP_MD_free(ctx->md); + ctx->mdctx = NULL; + ctx->md = NULL; + ctx->mdsize = 0; +} + +static int sm2sig_digest_signverify_init(void *vpsm2ctx, const char *mdname, + void *ec) +{ + PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; + int md_nid = NID_sm3; + WPACKET pkt; + int ret = 0; + + free_md(ctx); + + if (!sm2sig_signature_init(vpsm2ctx, ec)) + return ret; + + ctx->md = EVP_MD_fetch(ctx->libctx, mdname, ctx->propq); + ctx->mdsize = EVP_MD_size(ctx->md); + ctx->mdctx = EVP_MD_CTX_new(); + if (ctx->mdctx == NULL) + goto error; + + /* + * TODO(3.0) Should we care about DER writing errors? + * All it really means is that for some reason, there's no + * AlgorithmIdentifier to be had, but the operation itself is + * still valid, just as long as it's not used to construct + * anything that needs an AlgorithmIdentifier. + */ + ctx->aid_len = 0; + if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) + && DER_w_algorithmIdentifier_SM2_with_MD(&pkt, -1, ctx->ec, md_nid) + && WPACKET_finish(&pkt)) { + WPACKET_get_total_written(&pkt, &ctx->aid_len); + ctx->aid = WPACKET_get_curr(&pkt); + } + WPACKET_cleanup(&pkt); + + if (!EVP_DigestInit_ex(ctx->mdctx, ctx->md, NULL)) + goto error; + + ctx->flag_compute_z_digest = 1; + + ret = 1; + + error: + if (!ret) + free_md(ctx); + return ret; +} + +static int sm2sig_compute_z_digest(PROV_SM2_CTX *ctx) +{ + uint8_t *z = NULL; + int ret = 1; + + if (ctx->flag_compute_z_digest) { + /* Only do this once */ + ctx->flag_compute_z_digest = 0; + + if ((z = OPENSSL_zalloc(ctx->mdsize)) == NULL + /* get hashed prefix 'z' of tbs message */ + || !sm2_compute_z_digest(z, ctx->md, ctx->id, ctx->id_len, ctx->ec) + || !EVP_DigestUpdate(ctx->mdctx, z, ctx->mdsize)) + ret = 0; + OPENSSL_free(z); + } + + return ret; +} + +int sm2sig_digest_signverify_update(void *vpsm2ctx, const unsigned char *data, + size_t datalen) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx == NULL || psm2ctx->mdctx == NULL) + return 0; + + return sm2sig_compute_z_digest(psm2ctx) + && EVP_DigestUpdate(psm2ctx->mdctx, data, datalen); +} + +int sm2sig_digest_sign_final(void *vpsm2ctx, unsigned char *sig, size_t *siglen, + size_t sigsize) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int dlen = 0; + + if (psm2ctx == NULL || psm2ctx->mdctx == NULL) + return 0; + + /* + * If sig is NULL then we're just finding out the sig size. Other fields + * are ignored. Defer to sm2sig_sign. + */ + if (sig != NULL) { + if (!(sm2sig_compute_z_digest(psm2ctx) + && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen))) + return 0; + } + + return sm2sig_sign(vpsm2ctx, sig, siglen, sigsize, digest, (size_t)dlen); +} + + +int sm2sig_digest_verify_final(void *vpsm2ctx, const unsigned char *sig, + size_t siglen) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int dlen = 0; + + if (psm2ctx == NULL || psm2ctx->mdctx == NULL) + return 0; + + /* SM2 always use SM3 so it's not possible to exceed the limit */ + if (!(sm2sig_compute_z_digest(psm2ctx) + && EVP_DigestFinal_ex(psm2ctx->mdctx, digest, &dlen))) + return 0; + + return sm2sig_verify(vpsm2ctx, sig, siglen, digest, (size_t)dlen); +} + +static void sm2sig_freectx(void *vpsm2ctx) +{ + PROV_SM2_CTX *ctx = (PROV_SM2_CTX *)vpsm2ctx; + + free_md(ctx); + EC_KEY_free(ctx->ec); + OPENSSL_free(ctx->id); + OPENSSL_free(ctx); +} + +static void *sm2sig_dupctx(void *vpsm2ctx) +{ + PROV_SM2_CTX *srcctx = (PROV_SM2_CTX *)vpsm2ctx; + PROV_SM2_CTX *dstctx; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + dstctx->ec = NULL; + dstctx->md = NULL; + dstctx->mdctx = NULL; + + if (srcctx->ec != NULL && !EC_KEY_up_ref(srcctx->ec)) + goto err; + dstctx->ec = srcctx->ec; + + if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) + goto err; + dstctx->md = srcctx->md; + + if (srcctx->mdctx != NULL) { + dstctx->mdctx = EVP_MD_CTX_new(); + if (dstctx->mdctx == NULL + || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) + goto err; + } + + if (srcctx->id != NULL) { + dstctx->id = OPENSSL_malloc(srcctx->id_len); + if (dstctx->id == NULL) + goto err; + dstctx->id_len = srcctx->id_len; + memcpy(dstctx->id, srcctx->id, srcctx->id_len); + } + + return dstctx; + err: + sm2sig_freectx(dstctx); + return NULL; +} + +static int sm2sig_get_ctx_params(void *vpsm2ctx, OSSL_PARAM *params) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + OSSL_PARAM *p; + + if (psm2ctx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); + if (p != NULL + && !OSSL_PARAM_set_octet_string(p, psm2ctx->aid, psm2ctx->aid_len)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); + if (p != NULL && !OSSL_PARAM_set_size_t(p, psm2ctx->mdsize)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, psm2ctx->md == NULL + ? psm2ctx->mdname + : EVP_MD_name(psm2ctx->md))) + return 0; + + return 1; +} + +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), + OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *sm2sig_gettable_ctx_params(ossl_unused void *provctx) +{ + return known_gettable_ctx_params; +} + +static int sm2sig_set_ctx_params(void *vpsm2ctx, const OSSL_PARAM params[]) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + const OSSL_PARAM *p; + char *mdname; + + if (psm2ctx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DIST_ID); + if (p != NULL) { + void *tmp_id = NULL; + size_t tmp_idlen; + + /* + * If the 'z' digest has already been computed, the ID is set too late + */ + if (!psm2ctx->flag_compute_z_digest) + return 0; + + if (!OSSL_PARAM_get_octet_string(p, &tmp_id, 0, &tmp_idlen)) + return 0; + OPENSSL_free(psm2ctx->id); + psm2ctx->id = tmp_id; + psm2ctx->id_len = tmp_idlen; + } + + if (psm2ctx->md != NULL) { + /* + * You cannot set the digest name/size when doing a DigestSign or + * DigestVerify. + */ + return 1; + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE); + if (p != NULL && !OSSL_PARAM_get_size_t(p, &psm2ctx->mdsize)) + return 0; + + /* + * We never actually use the mdname, but we do support getting it later. + * This can be useful for applications that want to know the MD that they + * previously set. + */ + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); + mdname = psm2ctx->mdname; + if (p != NULL + && !OSSL_PARAM_get_utf8_string(p, &mdname, sizeof(psm2ctx->mdname))) + return 0; + + return 1; +} + +static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_size_t(OSSL_SIGNATURE_PARAM_DIGEST_SIZE, NULL), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DIST_ID, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *sm2sig_settable_ctx_params(ossl_unused void *provctx) +{ + /* + * TODO(3.0): Should this function return a different set of settable ctx + * params if the ctx is being used for a DigestSign/DigestVerify? In that + * case it is not allowed to set the digest size/digest name because the + * digest is explicitly set as part of the init. + */ + return known_settable_ctx_params; +} + +static int sm2sig_get_ctx_md_params(void *vpsm2ctx, OSSL_PARAM *params) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx->mdctx == NULL) + return 0; + + return EVP_MD_CTX_get_params(psm2ctx->mdctx, params); +} + +static const OSSL_PARAM *sm2sig_gettable_ctx_md_params(void *vpsm2ctx) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx->md == NULL) + return 0; + + return EVP_MD_gettable_ctx_params(psm2ctx->md); +} + +static int sm2sig_set_ctx_md_params(void *vpsm2ctx, const OSSL_PARAM params[]) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx->mdctx == NULL) + return 0; + + return EVP_MD_CTX_set_params(psm2ctx->mdctx, params); +} + +static const OSSL_PARAM *sm2sig_settable_ctx_md_params(void *vpsm2ctx) +{ + PROV_SM2_CTX *psm2ctx = (PROV_SM2_CTX *)vpsm2ctx; + + if (psm2ctx->md == NULL) + return 0; + + return EVP_MD_settable_ctx_params(psm2ctx->md); +} + +const OSSL_DISPATCH sm2_signature_functions[] = { + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))sm2sig_newctx }, + { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))sm2sig_signature_init }, + { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))sm2sig_sign }, + { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))sm2sig_signature_init }, + { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))sm2sig_verify }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, + (void (*)(void))sm2sig_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, + (void (*)(void))sm2sig_digest_signverify_update }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, + (void (*)(void))sm2sig_digest_sign_final }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, + (void (*)(void))sm2sig_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, + (void (*)(void))sm2sig_digest_signverify_update }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, + (void (*)(void))sm2sig_digest_verify_final }, + { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))sm2sig_freectx }, + { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))sm2sig_dupctx }, + { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))sm2sig_get_ctx_params }, + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, + (void (*)(void))sm2sig_gettable_ctx_params }, + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))sm2sig_set_ctx_params }, + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, + (void (*)(void))sm2sig_settable_ctx_params }, + { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, + (void (*)(void))sm2sig_get_ctx_md_params }, + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, + (void (*)(void))sm2sig_gettable_ctx_md_params }, + { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, + (void (*)(void))sm2sig_set_ctx_md_params }, + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, + (void (*)(void))sm2sig_settable_ctx_md_params }, + { 0, NULL } +}; diff --git a/providers/implementations/storemgmt/build.info b/providers/implementations/storemgmt/build.info new file mode 100644 index 0000000000..89939cce54 --- /dev/null +++ b/providers/implementations/storemgmt/build.info @@ -0,0 +1,6 @@ +# We make separate GOAL variables for each algorithm, to make it easy to +# switch each to the Legacy provider when needed. + +$STORE_GOAL=../../libimplementations.a + +SOURCE[$STORE_GOAL]=file_store.c file_store_der2obj.c diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c new file mode 100644 index 0000000000..e41e29ed35 --- /dev/null +++ b/providers/implementations/storemgmt/file_store.c @@ -0,0 +1,921 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" /* To get strncasecmp() on Windows */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* The OSSL_STORE_INFO type numbers */ +#include "internal/o_dir.h" +#include "internal/pem.h" /* For PVK and "blob" PEM headers */ +#include "crypto/decoder.h" +#include "prov/implementations.h" +#include "prov/bio.h" +#include "prov/provider_ctx.h" +#include "prov/providercommonerr.h" +#include "file_store_local.h" + +DEFINE_STACK_OF(OSSL_STORE_INFO) + +#ifdef _WIN32 +# define stat _stat +#endif + +#ifndef S_ISDIR +# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) +#endif + +static OSSL_FUNC_store_open_fn file_open; +static OSSL_FUNC_store_attach_fn file_attach; +static OSSL_FUNC_store_settable_ctx_params_fn file_settable_ctx_params; +static OSSL_FUNC_store_set_ctx_params_fn file_set_ctx_params; +static OSSL_FUNC_store_load_fn file_load; +static OSSL_FUNC_store_eof_fn file_eof; +static OSSL_FUNC_store_close_fn file_close; + +/* + * This implementation makes full use of OSSL_DECODER, and then some. + * It uses its own internal decoder implementation that reads DER and + * passes that on to the data callback; this decoder is created with + * internal OpenSSL functions, thereby bypassing the need for a surrounding + * provider. This is ok, since this is a local decoder, not meant for + * public consumption. It also uses the libcrypto internal decoder + * setup function ossl_decoder_ctx_setup_for_EVP_PKEY(), to allow the + * last resort decoder to be added first (and thereby be executed last). + * Finally, it sets up its own construct and cleanup functions. + * + * Essentially, that makes this implementation a kind of glorified decoder. + */ + +struct file_ctx_st { + void *provctx; + char *uri; /* The URI we currently try to load */ + enum { + IS_FILE = 0, /* Read file and pass results */ + IS_DIR /* Pass directory entry names */ + } type; + + /* Flag bits */ + unsigned int flag_attached:1; + unsigned int flag_buffered:1; + + union { + /* Used with |IS_FILE| */ + struct { + BIO *file; + + OSSL_DECODER_CTX *decoderctx; + char *input_type; + char *propq; /* The properties we got as a parameter */ + } file; + + /* Used with |IS_DIR| */ + struct { + OPENSSL_DIR_CTX *ctx; + int end_reached; + + /* + * When a search expression is given, these are filled in. + * |search_name| contains the file basename to look for. + * The string is exactly 8 characters long. + */ + char search_name[9]; + + /* + * The directory reading utility we have combines opening with + * reading the first name. To make sure we can detect the end + * at the right time, we read early and cache the name. + */ + const char *last_entry; + int last_errno; + } dir; + } _; + + /* Expected object type. May be unspecified */ + int expected_type; +}; + +static void free_file_ctx(struct file_ctx_st *ctx) +{ + if (ctx == NULL) + return; + + OPENSSL_free(ctx->uri); + if (ctx->type != IS_DIR) { + OSSL_DECODER_CTX_free(ctx->_.file.decoderctx); + OPENSSL_free(ctx->_.file.propq); + OPENSSL_free(ctx->_.file.input_type); + } + OPENSSL_free(ctx); +} + +static struct file_ctx_st *new_file_ctx(int type, const char *uri, + void *provctx) +{ + struct file_ctx_st *ctx = NULL; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL + && (uri == NULL || (ctx->uri = OPENSSL_strdup(uri)) != NULL)) { + ctx->type = type; + ctx->provctx = provctx; + return ctx; + } + free_file_ctx(ctx); + return NULL; +} + +static OSSL_DECODER_CONSTRUCT file_load_construct; +static OSSL_DECODER_CLEANUP file_load_cleanup; + +/*- + * Opening / attaching streams and directories + * ------------------------------------------- + */ + +/* + * Function to service both file_open() and file_attach() + * + * + */ +static struct file_ctx_st *file_open_stream(BIO *source, const char *uri, + const char *input_type, + void *provctx) +{ + struct file_ctx_st *ctx; + + if ((ctx = new_file_ctx(IS_FILE, uri, provctx)) == NULL + || (input_type != NULL + && (ctx->_.file.input_type = + OPENSSL_strdup(input_type)) == NULL)) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto err; + } + + ctx->_.file.file = source; + + return ctx; + err: + free_file_ctx(ctx); + return NULL; +} + +static void *file_open_dir(const char *path, const char *uri, void *provctx) +{ + struct file_ctx_st *ctx; + + if ((ctx = new_file_ctx(IS_DIR, uri, provctx)) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto err; + } + + ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, path); + ctx->_.dir.last_errno = errno; + if (ctx->_.dir.last_entry == NULL) { + if (ctx->_.dir.last_errno != 0) { + ERR_raise_data(ERR_LIB_SYS, ctx->_.dir.last_errno, + "Calling OPENSSL_DIR_read(\"%s\")", path); + goto err; + } + ctx->_.dir.end_reached = 1; + } + return ctx; + err: + file_close(ctx); + return NULL; +} + +static void *file_open(void *provctx, const char *uri) +{ + struct file_ctx_st *ctx = NULL; + struct stat st; + struct { + const char *path; + unsigned int check_absolute:1; + } path_data[2]; + size_t path_data_n = 0, i; + const char *path; + BIO *bio; + + ERR_set_mark(); + + /* + * First step, just take the URI as is. + */ + path_data[path_data_n].check_absolute = 0; + path_data[path_data_n++].path = uri; + + /* + * Second step, if the URI appears to start with the 'file' scheme, + * extract the path and make that the second path to check. + * There's a special case if the URI also contains an authority, then + * the full URI shouldn't be used as a path anywhere. + */ + if (strncasecmp(uri, "file:", 5) == 0) { + const char *p = &uri[5]; + + if (strncmp(&uri[5], "//", 2) == 0) { + path_data_n--; /* Invalidate using the full URI */ + if (strncasecmp(&uri[7], "localhost/", 10) == 0) { + p = &uri[16]; + } else if (uri[7] == '/') { + p = &uri[7]; + } else { + ERR_clear_last_mark(); + ERR_raise(ERR_LIB_PROV, PROV_R_URI_AUTHORITY_UNSUPPORTED); + return NULL; + } + } + + path_data[path_data_n].check_absolute = 1; +#ifdef _WIN32 + /* Windows file: URIs with a drive letter start with a / */ + if (p[0] == '/' && p[2] == ':' && p[3] == '/') { + char c = tolower(p[1]); + + if (c >= 'a' && c <= 'z') { + p++; + /* We know it's absolute, so no need to check */ + path_data[path_data_n].check_absolute = 0; + } + } +#endif + path_data[path_data_n++].path = p; + } + + + for (i = 0, path = NULL; path == NULL && i < path_data_n; i++) { + /* + * If the scheme "file" was an explicit part of the URI, the path must + * be absolute. So says RFC 8089 + */ + if (path_data[i].check_absolute && path_data[i].path[0] != '/') { + ERR_clear_last_mark(); + ERR_raise_data(ERR_LIB_PROV, PROV_R_PATH_MUST_BE_ABSOLUTE, + "Given path=%s", path_data[i].path); + return NULL; + } + + if (stat(path_data[i].path, &st) < 0) { + ERR_raise_data(ERR_LIB_SYS, errno, + "calling stat(%s)", + path_data[i].path); + } else { + path = path_data[i].path; + } + } + if (path == NULL) { + ERR_clear_last_mark(); + return NULL; + } + + /* Successfully found a working path, clear possible collected errors */ + ERR_pop_to_mark(); + + if (S_ISDIR(st.st_mode)) + ctx = file_open_dir(path, uri, provctx); + else if ((bio = BIO_new_file(path, "rb")) == NULL + || (ctx = file_open_stream(bio, uri, NULL, provctx)) == NULL) + BIO_free_all(bio); + + return ctx; +} + +/* + * Attached input streams must be treated very very carefully to avoid + * nasty surprises. + * + * This implementation tries to support input streams that can't be reset, + * such as standard input. However, OSSL_DECODER assumes resettable streams, + * and because the PEM decoder may read quite a bit of the input file to skip + * past any non-PEM text that precedes the PEM block, we may need to detect + * if the input stream is a PEM file early. + * + * If the input stream supports BIO_tell(), we assume that it also supports + * BIO_seek(), making it a resettable stream and therefore safe to fully + * unleash OSSL_DECODER. + * + * If the input stream doesn't support BIO_tell(), we must assume that we + * have a non-resettable stream, and must tread carefully. We do so by + * trying to detect if the input is PEM, MSBLOB or PVK, and if not, we + * assume that it's DER. + * + * To detect if an input stream is PEM, MSBLOB or PVK, we use the buffer BIO + * filter, which allows us a 4KiB resettable read-ahead. We *hope* that 4KiB + * will be enough to find the start of the PEM block. + * + * It should be possible to use this same technique to detect other file + * types as well. + * + * An alternative technique would be to have an endlessly caching BIO filter. + * That would take away the need for all the detection here, and simply leave + * it for OSSL_DECODER to find out on its own while supporting its demand for + * resettable input streams. + * That's a possible future development. + */ + +# define INPUT_TYPE_ANY NULL +# define INPUT_TYPE_DER "DER" +# define INPUT_TYPE_PEM "PEM" +# define INPUT_TYPE_MSBLOB "MSBLOB" +# define INPUT_TYPE_PVK "PVK" + +void *file_attach(void *provctx, OSSL_CORE_BIO *cin) +{ + BIO *new_bio = bio_new_from_core_bio(provctx, cin); + BIO *new_bio_tmp = NULL; + BIO *buff = NULL; + char peekbuf[4096] = { 0, }; + int loc; + const char *input_type = NULL; + unsigned int flag_attached = 1; + unsigned int flag_buffered = 0; + struct file_ctx_st *ctx = NULL; + + if (new_bio == NULL) + return 0; + + /* Try to get the current position */ + loc = BIO_tell(new_bio); + + if ((buff = BIO_new(BIO_f_buffer())) == NULL + || (new_bio_tmp = BIO_push(buff, new_bio)) == NULL) + goto err; + + /* Assumption, if we can't detect PEM */ + input_type = INPUT_TYPE_DER; + flag_buffered = 1; + new_bio = new_bio_tmp; + + if (BIO_buffer_peek(new_bio, peekbuf, sizeof(peekbuf) - 1) > 0) { +#ifndef OPENSSL_NO_DSA + const unsigned char *p = NULL; + unsigned int magic = 0, bitlen = 0; + int isdss = 0, ispub = -1; +# ifndef OPENSSL_NO_RC4 + unsigned int saltlen = 0, keylen = 0; +# endif +#endif + + peekbuf[sizeof(peekbuf) - 1] = '\0'; + if (strstr(peekbuf, "-----BEGIN ") != NULL) + input_type = INPUT_TYPE_PEM; +#ifndef OPENSSL_NO_DSA + else if (p = (unsigned char *)peekbuf, + ossl_do_blob_header(&p, sizeof(peekbuf), &magic, &bitlen, + &isdss, &ispub)) + input_type = INPUT_TYPE_MSBLOB; +# ifndef OPENSSL_NO_RC4 + else if (p = (unsigned char *)peekbuf, + ossl_do_PVK_header(&p, sizeof(peekbuf), 0, &saltlen, &keylen)) + input_type = INPUT_TYPE_PVK; +# endif +#endif + } + + /* + * After peeking, we know that the underlying source BIO has moved ahead + * from its earlier position and that if it supports BIO_tell(), that + * should be a number that differs from |loc|. Otherwise, we will get + * the same value, which may one of: + * + * - zero (the source BIO doesn't support BIO_tell() / BIO_seek() / + * BIO_reset()) + * - -1 (the underlying operating system / C library routines do not + * support BIO_tell() / BIO_seek() / BIO_reset()) + * + * If it turns out that the source BIO does support BIO_tell(), we pop + * the buffer BIO filter and mark this input as |INPUT_TYPE_ANY|, which + * fully unleashes OSSL_DECODER to do its thing. + */ + if (BIO_tell(new_bio) != loc) { + /* In this case, anything goes */ + input_type = INPUT_TYPE_ANY; + + /* Restore the source BIO like it was when entering this function */ + new_bio = BIO_pop(buff); + BIO_free(buff); + (void)BIO_seek(new_bio, loc); + + flag_buffered = 0; + } + + if ((ctx = file_open_stream(new_bio, NULL, input_type, provctx)) == NULL) + goto err; + + ctx->flag_attached = flag_attached; + ctx->flag_buffered = flag_buffered; + + return ctx; + err: + if (flag_buffered) { + new_bio = BIO_pop(buff); + BIO_free(buff); + } + BIO_free(new_bio); /* Removes the provider BIO filter */ + return NULL; +} + +/*- + * Setting parameters + * ------------------ + */ + +static const OSSL_PARAM *file_settable_ctx_params(void *provctx) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_int(OSSL_STORE_PARAM_EXPECT, NULL), + OSSL_PARAM_octet_string(OSSL_STORE_PARAM_SUBJECT, NULL, 0), + OSSL_PARAM_END + }; + return known_settable_ctx_params; +} + +static int file_set_ctx_params(void *loaderctx, const OSSL_PARAM params[]) +{ + struct file_ctx_st *ctx = loaderctx; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_PROPERTIES); + if (p != NULL) { + OPENSSL_free(ctx->_.file.propq); + ctx->_.file.propq = NULL; + if (!OSSL_PARAM_get_utf8_string(p, &ctx->_.file.propq, 0)) + return 0; + } + p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_EXPECT); + if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->expected_type)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); + if (p != NULL) { + const unsigned char *der = NULL; + size_t der_len = 0; + X509_NAME *x509_name; + unsigned long hash; + + if (ctx->type != IS_DIR) { + ERR_raise(ERR_LIB_PROV, + PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES); + return 0; + } + + if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&der, &der_len) + || (x509_name = d2i_X509_NAME(NULL, &der, der_len)) == NULL) + return 0; + hash = X509_NAME_hash(x509_name); + BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name), + "%08lx", hash); + X509_NAME_free(x509_name); + } + return 1; +} + +/*- + * Loading an object from a stream + * ------------------------------- + */ + +struct file_load_data_st { + OSSL_CALLBACK *object_cb; + void *object_cbarg; +}; + +static int file_load_construct(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, void *construct_data) +{ + struct file_load_data_st *data = construct_data; + + /* + * At some point, we may find it justifiable to recognise PKCS#12 and + * handle it specially here, making |file_load()| return pass its + * contents one piece at ta time, like |e_loader_attic.c| does. + * + * However, that currently means parsing them out, which converts the + * DER encoded PKCS#12 into a bunch of EVP_PKEYs and X509s, just to + * have to re-encode them into DER to create an object abstraction for + * each of them. + * It's much simpler (less churn) to pass on the object abstraction we + * get to the load_result callback and leave it to that one to do the + * work. If that's libcrypto code, we know that it has much better + * possibilities to handle the EVP_PKEYs and X509s without the extra + * churn. + */ + + return data->object_cb(params, data->object_cbarg); +} + +void file_load_cleanup(void *construct_data) +{ + /* Nothing to do */ +} + +static int file_setup_decoders(struct file_ctx_st *ctx) +{ + EVP_PKEY *dummy; /* for OSSL_DECODER_CTX_new_by_EVP_PKEY() */ + OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); + OSSL_DECODER *to_obj = NULL; /* Last resort decoder */ + OSSL_DECODER_INSTANCE *to_obj_inst = NULL; + OSSL_DECODER_CLEANUP *old_cleanup = NULL; + void *old_construct_data = NULL; + int ok = 0; + + /* Setup for this session, so only if not already done */ + if (ctx->_.file.decoderctx == NULL) { + if ((ctx->_.file.decoderctx = OSSL_DECODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Make sure the input type is set */ + if (!OSSL_DECODER_CTX_set_input_type(ctx->_.file.decoderctx, + ctx->_.file.input_type)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + /* + * Create the internal last resort decoder implementation together + * with a "decoder instance". + * The decoder doesn't need any identification or to be attached to + * any provider, since it's only used locally. + */ + to_obj = ossl_decoder_from_dispatch(0, &ossl_der_to_obj_algorithm, + NULL); + if (to_obj == NULL) + goto err; + to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx); + if (to_obj_inst == NULL) + goto err; + + if (!ossl_decoder_ctx_add_decoder_inst(ctx->_.file.decoderctx, + to_obj_inst)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + /* + * OSSL_DECODER_INSTANCE shouldn't be freed from this point on. + * That's going to happen whenever the OSSL_DECODER_CTX is freed. + */ + to_obj_inst = NULL; + + /* + * Add on the usual decoder context for keys, with a dummy object. + * Since we're setting up our own constructor, we don't need to care + * more than that... + */ + if (!ossl_decoder_ctx_setup_for_EVP_PKEY(ctx->_.file.decoderctx, + &dummy, NULL, + libctx, ctx->_.file.propq) + || !OSSL_DECODER_CTX_add_extra(ctx->_.file.decoderctx, + libctx, ctx->_.file.propq)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + + /* + * Then we throw away the installed finalizer data, and install our + * own instead. + */ + old_cleanup = OSSL_DECODER_CTX_get_cleanup(ctx->_.file.decoderctx); + old_construct_data = + OSSL_DECODER_CTX_get_construct_data(ctx->_.file.decoderctx); + if (old_cleanup != NULL) + old_cleanup(old_construct_data); + + /* + * Set the hooks. + */ + if (!OSSL_DECODER_CTX_set_construct(ctx->_.file.decoderctx, + file_load_construct) + || !OSSL_DECODER_CTX_set_cleanup(ctx->_.file.decoderctx, + file_load_cleanup)) { + ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); + goto err; + } + } + + ok = 1; + err: + OSSL_DECODER_free(to_obj); + return ok; +} + +static int file_load_file(struct file_ctx_st *ctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct file_load_data_st data; + + /* Setup the decoders (one time shot per session */ + + if (!file_setup_decoders(ctx)) + return 0; + + /* Setup for this object */ + + data.object_cb = object_cb; + data.object_cbarg = object_cbarg; + OSSL_DECODER_CTX_set_construct_data(ctx->_.file.decoderctx, &data); + OSSL_DECODER_CTX_set_passphrase_cb(ctx->_.file.decoderctx, pw_cb, pw_cbarg); + + /* Launch */ + + return OSSL_DECODER_from_bio(ctx->_.file.decoderctx, ctx->_.file.file); +} + +/*- + * Loading a name object from a directory + * -------------------------------------- + */ + +static int ends_with_dirsep(const char *uri) +{ + if (*uri != '\0') + uri += strlen(uri) - 1; +#if defined(__VMS) + if (*uri == ']' || *uri == '>' || *uri == ':') + return 1; +#elif defined(_WIN32) + if (*uri == '\\') + return 1; +#endif + return *uri == '/'; +} + +static char *file_name_to_uri(struct file_ctx_st *ctx, const char *name) +{ + char *data = NULL; + + assert(name != NULL); + { + const char *pathsep = ends_with_dirsep(ctx->uri) ? "" : "/"; + long calculated_length = strlen(ctx->uri) + strlen(pathsep) + + strlen(name) + 1 /* \0 */; + + data = OPENSSL_zalloc(calculated_length); + if (data == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_strlcat(data, ctx->uri, calculated_length); + OPENSSL_strlcat(data, pathsep, calculated_length); + OPENSSL_strlcat(data, name, calculated_length); + } + return data; +} + +static int file_name_check(struct file_ctx_st *ctx, const char *name) +{ + const char *p = NULL; + + /* If there are no search criteria, all names are accepted */ + if (ctx->_.dir.search_name[0] == '\0') + return 1; + + /* If the expected type isn't supported, no name is accepted */ + if (ctx->expected_type != 0 + && ctx->expected_type != OSSL_STORE_INFO_CERT + && ctx->expected_type != OSSL_STORE_INFO_CRL) + return 0; + + /* + * First, check the basename + */ + if (strncasecmp(name, ctx->_.dir.search_name, + sizeof(ctx->_.dir.search_name) - 1) != 0 + || name[sizeof(ctx->_.dir.search_name) - 1] != '.') + return 0; + p = &name[sizeof(ctx->_.dir.search_name)]; + + /* + * Then, if the expected type is a CRL, check that the extension starts + * with 'r' + */ + if (*p == 'r') { + p++; + if (ctx->expected_type != 0 + && ctx->expected_type != OSSL_STORE_INFO_CRL) + return 0; + } else if (ctx->expected_type == OSSL_STORE_INFO_CRL) { + return 0; + } + + /* + * Last, check that the rest of the extension is a decimal number, at + * least one digit long. + */ + if (!isdigit(*p)) + return 0; + while (isdigit(*p)) + p++; + +#ifdef __VMS + /* + * One extra step here, check for a possible generation number. + */ + if (*p == ';') + for (p++; *p != '\0'; p++) + if (!ossl_isdigit(*p)) + break; +#endif + + /* + * If we've reached the end of the string at this point, we've successfully + * found a fitting file name. + */ + return *p == '\0'; +} + +static int file_load_dir_entry(struct file_ctx_st *ctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + /* Prepare as much as possible in advance */ + static const int object_type = OSSL_OBJECT_NAME; + OSSL_PARAM object[] = { + OSSL_PARAM_int(OSSL_OBJECT_PARAM_TYPE, (int *)&object_type), + OSSL_PARAM_utf8_string(OSSL_OBJECT_PARAM_DATA, NULL, 0), + OSSL_PARAM_END + }; + char *newname = NULL; + int ok; + + /* Loop until we get an error or until we have a suitable name */ + do { + if (ctx->_.dir.last_entry == NULL) { + if (!ctx->_.dir.end_reached) { + assert(ctx->_.dir.last_errno != 0); + ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno); + } + /* file_eof() will tell if EOF was reached */ + return 0; + } + + /* flag acceptable names */ + if (ctx->_.dir.last_entry[0] != '.' + && file_name_check(ctx, ctx->_.dir.last_entry)) { + + /* If we can't allocate the new name, we fail */ + if ((newname = + file_name_to_uri(ctx, ctx->_.dir.last_entry)) == NULL) + return 0; + } + + /* + * On the first call (with a NULL context), OPENSSL_DIR_read() + * cares about the second argument. On the following calls, it + * only cares that it isn't NULL. Therefore, we can safely give + * it our URI here. + */ + ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, ctx->uri); + ctx->_.dir.last_errno = errno; + if (ctx->_.dir.last_entry == NULL && ctx->_.dir.last_errno == 0) + ctx->_.dir.end_reached = 1; + } while (newname == NULL); + + object[1].data = newname; + object[1].data_size = strlen(newname); + ok = object_cb(object, object_cbarg); + OPENSSL_free(newname); + return ok; +} + +/*- + * Loading, local dispatcher + * ------------------------- + */ + +static int file_load(void *loaderctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct file_ctx_st *ctx = loaderctx; + + switch (ctx->type) { + case IS_FILE: + return file_load_file(ctx, object_cb, object_cbarg, pw_cb, pw_cbarg); + case IS_DIR: + return + file_load_dir_entry(ctx, object_cb, object_cbarg, pw_cb, pw_cbarg); + default: + break; + } + + /* ctx->type has an unexpected value */ + assert(0); + return 0; +} + +/*- + * Eof detection and closing + * ------------------------- + */ + +static int file_eof(void *loaderctx) +{ + struct file_ctx_st *ctx = loaderctx; + + switch (ctx->type) { + case IS_DIR: + return ctx->_.dir.end_reached; + case IS_FILE: + /* + * BIO_pending() checks any filter BIO. + * BIO_eof() checks the source BIO. + */ + return !BIO_pending(ctx->_.file.file) + && BIO_eof(ctx->_.file.file); + } + + /* ctx->type has an unexpected value */ + assert(0); + return 1; +} + +static int file_close_dir(struct file_ctx_st *ctx) +{ + if (ctx->_.dir.ctx != NULL) + OPENSSL_DIR_end(&ctx->_.dir.ctx); + free_file_ctx(ctx); + return 1; +} + +static int file_close_stream(struct file_ctx_st *ctx) +{ + if (ctx->flag_buffered) { + /* + * file_attach() pushed a BIO_f_buffer() on top of the regular BIO. + * Drop it. + */ + BIO *buff = ctx->_.file.file; + + /* Detach buff */ + ctx->_.file.file = BIO_pop(ctx->_.file.file); + + BIO_free(buff); + } + + /* + * If it was attached, we only free the top, as that's the provider BIO + * filter. Otherwise, it was entirely allocated by this implementation, + * and can safely be completely freed. + */ + if (ctx->flag_attached) + BIO_free(ctx->_.file.file); + else + BIO_free_all(ctx->_.file.file); + + /* To avoid double free */ + ctx->_.file.file = NULL; + + free_file_ctx(ctx); + return 1; +} + +static int file_close(void *loaderctx) +{ + struct file_ctx_st *ctx = loaderctx; + + switch (ctx->type) { + case IS_DIR: + return file_close_dir(ctx); + case IS_FILE: + return file_close_stream(ctx); + } + + /* ctx->type has an unexpected value */ + assert(0); + return 1; +} + +const OSSL_DISPATCH ossl_file_store_functions[] = { + { OSSL_FUNC_STORE_OPEN, (void (*)(void))file_open }, + { OSSL_FUNC_STORE_ATTACH, (void (*)(void))file_attach }, + { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, + (void (*)(void))file_settable_ctx_params }, + { OSSL_FUNC_STORE_SET_CTX_PARAMS, (void (*)(void))file_set_ctx_params }, + { OSSL_FUNC_STORE_LOAD, (void (*)(void))file_load }, + { OSSL_FUNC_STORE_EOF, (void (*)(void))file_eof }, + { OSSL_FUNC_STORE_CLOSE, (void (*)(void))file_close }, + { 0, NULL }, +}; diff --git a/providers/implementations/storemgmt/file_store_der2obj.c b/providers/implementations/storemgmt/file_store_der2obj.c new file mode 100644 index 0000000000..8c9168b125 --- /dev/null +++ b/providers/implementations/storemgmt/file_store_der2obj.c @@ -0,0 +1,134 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * This is a decoder that's completely internal to the 'file:' store + * implementation. Only code in file_store.c know about this one. Because + * of this close relationship, we can cut certain corners, such as making + * assumptions about the "provider context", which is currently simply the + * provider context that the file_store.c code operates within. + * + * All this does is to read DER from the input if it can, and passes it on + * to the data callback as an object abstraction, leaving it to the callback + * to figure out what it actually is. + * + * This MUST be made the last decoder in a chain, leaving it to other more + * specialized decoders to recognise and process their stuff first. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/asn1.h" +#include "prov/bio.h" +#include "file_store_local.h" + +/* + * newctx and freectx are not strictly necessary. However, the method creator, + * ossl_decoder_from_dispatch(), demands that they exist, so we make sure to + * oblige. + */ + +static OSSL_FUNC_decoder_newctx_fn der2obj_newctx; +static OSSL_FUNC_decoder_freectx_fn der2obj_freectx; + +static void *der2obj_newctx(void *provctx) +{ + return provctx; +} + +static void der2obj_freectx(void *vctx) +{ +} + +static OSSL_FUNC_decoder_gettable_params_fn der2obj_gettable_params; +static OSSL_FUNC_decoder_get_params_fn der2obj_get_params; +static OSSL_FUNC_decoder_decode_fn der2obj_decode; + +static const OSSL_PARAM *der2obj_gettable_params(void *provctx) +{ + static const OSSL_PARAM gettables[] = { + { OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 }, + OSSL_PARAM_END, + }; + + return gettables; +} + +static int der2obj_get_params(OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE); + if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER")) + return 0; + + return 1; +} + +static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + /* + * We're called from file_store.c, so we know that OSSL_CORE_BIO is a + * BIO in this case. + */ + BIO *in = (BIO *)cin; + BUF_MEM *mem = NULL; + int err, ok; + + ERR_set_mark(); + ok = (asn1_d2i_read_bio(in, &mem) >= 0); + /* + * Prune low-level ASN.1 parse errors from error queue, assuming that + * this is called by decoder_process() in a loop trying several formats. + */ + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_ASN1 + && (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG + || ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR)) + ERR_pop_to_mark(); + else + ERR_clear_last_mark(); + if (ok) { + OSSL_PARAM params[3]; + int object_type = OSSL_OBJECT_UNKNOWN; + + params[0] = + OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); + params[1] = + OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, + mem->data, mem->length); + params[2] = OSSL_PARAM_construct_end(); + + ok = data_cb(params, data_cbarg); + OPENSSL_free(mem->data); + OPENSSL_free(mem); + } + return ok; +} + +static const OSSL_DISPATCH der_to_obj_decoder_functions[] = { + { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))der2obj_newctx }, + { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))der2obj_freectx }, + { OSSL_FUNC_DECODER_GETTABLE_PARAMS, + (void (*)(void))der2obj_gettable_params }, + { OSSL_FUNC_DECODER_GET_PARAMS, (void (*)(void))der2obj_get_params }, + { OSSL_FUNC_DECODER_DECODE, (void (*)(void))der2obj_decode }, + { 0, NULL } +}; + +const OSSL_ALGORITHM ossl_der_to_obj_algorithm = + { "obj", NULL, der_to_obj_decoder_functions }; diff --git a/providers/implementations/storemgmt/file_store_local.h b/providers/implementations/storemgmt/file_store_local.h new file mode 100644 index 0000000000..b25dacc18b --- /dev/null +++ b/providers/implementations/storemgmt/file_store_local.h @@ -0,0 +1,11 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +extern const OSSL_ALGORITHM ossl_der_to_obj_algorithm; + diff --git a/providers/legacyprov.c b/providers/legacyprov.c index adf7c82374..f4e0bc9278 100644 --- a/providers/legacyprov.c +++ b/providers/legacyprov.c @@ -15,6 +15,7 @@ #include #include "prov/provider_ctx.h" #include "prov/implementations.h" +#include "prov/providercommon.h" /* * Forward declarations to ensure that interface functions are correctly @@ -40,6 +41,7 @@ static const OSSL_PARAM legacy_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END }; @@ -61,83 +63,85 @@ static int legacy_get_params(void *provctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR)) return 0; - + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); + if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) + return 0; return 1; } static const OSSL_ALGORITHM legacy_digests[] = { #ifndef OPENSSL_NO_MD2 - ALG("MD2", md2_functions), + ALG("MD2", ossl_md2_functions), #endif #ifndef OPENSSL_NO_MD4 - ALG("MD4", md4_functions), + ALG("MD4", ossl_md4_functions), #endif #ifndef OPENSSL_NO_MDC2 - ALG("MDC2", mdc2_functions), + ALG("MDC2", ossl_mdc2_functions), #endif /* OPENSSL_NO_MDC2 */ #ifndef OPENSSL_NO_WHIRLPOOL - ALG("WHIRLPOOL", wp_functions), + ALG("WHIRLPOOL", ossl_wp_functions), #endif /* OPENSSL_NO_WHIRLPOOL */ #ifndef OPENSSL_NO_RMD160 - ALG("RIPEMD-160:RIPEMD160:RIPEMD:RMD160", ripemd160_functions), + ALG("RIPEMD-160:RIPEMD160:RIPEMD:RMD160", ossl_ripemd160_functions), #endif /* OPENSSL_NO_RMD160 */ { NULL, NULL, NULL } }; static const OSSL_ALGORITHM legacy_ciphers[] = { #ifndef OPENSSL_NO_CAST - ALG("CAST5-ECB", cast5128ecb_functions), - ALG("CAST5-CBC:CAST-CBC:CAST", cast5128cbc_functions), - ALG("CAST5-OFB", cast5128ofb64_functions), - ALG("CAST5-CFB", cast5128cfb64_functions), + ALG("CAST5-ECB", ossl_cast5128ecb_functions), + ALG("CAST5-CBC:CAST-CBC:CAST", ossl_cast5128cbc_functions), + ALG("CAST5-OFB", ossl_cast5128ofb64_functions), + ALG("CAST5-CFB", ossl_cast5128cfb64_functions), #endif /* OPENSSL_NO_CAST */ #ifndef OPENSSL_NO_BF - ALG("BF-ECB", blowfish128ecb_functions), - ALG("BF-CBC:BF:BLOWFISH", blowfish128cbc_functions), - ALG("BF-OFB", blowfish64ofb64_functions), - ALG("BF-CFB", blowfish64cfb64_functions), + ALG("BF-ECB", ossl_blowfish128ecb_functions), + ALG("BF-CBC:BF:BLOWFISH", ossl_blowfish128cbc_functions), + ALG("BF-OFB", ossl_blowfish64ofb64_functions), + ALG("BF-CFB", ossl_blowfish64cfb64_functions), #endif /* OPENSSL_NO_BF */ #ifndef OPENSSL_NO_IDEA - ALG("IDEA-ECB", idea128ecb_functions), - ALG("IDEA-CBC:IDEA", idea128cbc_functions), - ALG("IDEA-OFB:IDEA-OFB64", idea128ofb64_functions), - ALG("IDEA-CFB:IDEA-CFB64", idea128cfb64_functions), + ALG("IDEA-ECB", ossl_idea128ecb_functions), + ALG("IDEA-CBC:IDEA", ossl_idea128cbc_functions), + ALG("IDEA-OFB:IDEA-OFB64", ossl_idea128ofb64_functions), + ALG("IDEA-CFB:IDEA-CFB64", ossl_idea128cfb64_functions), #endif /* OPENSSL_NO_IDEA */ #ifndef OPENSSL_NO_SEED - ALG("SEED-ECB", seed128ecb_functions), - ALG("SEED-CBC:SEED", seed128cbc_functions), - ALG("SEED-OFB:SEED-OFB128", seed128ofb128_functions), - ALG("SEED-CFB:SEED-CFB128", seed128cfb128_functions), + ALG("SEED-ECB", ossl_seed128ecb_functions), + ALG("SEED-CBC:SEED", ossl_seed128cbc_functions), + ALG("SEED-OFB:SEED-OFB128", ossl_seed128ofb128_functions), + ALG("SEED-CFB:SEED-CFB128", ossl_seed128cfb128_functions), #endif /* OPENSSL_NO_SEED */ #ifndef OPENSSL_NO_RC2 - ALG("RC2-ECB", rc2128ecb_functions), - ALG("RC2-CBC", rc2128cbc_functions), - ALG("RC2-40-CBC", rc240cbc_functions), - ALG("RC2-64-CBC", rc264cbc_functions), - ALG("RC2-CFB", rc2128cfb128_functions), - ALG("RC2-OFB", rc2128ofb128_functions), + ALG("RC2-ECB", ossl_rc2128ecb_functions), + ALG("RC2-CBC:RC2:RC2-128", ossl_rc2128cbc_functions), + ALG("RC2-40-CBC:RC2-40", ossl_rc240cbc_functions), + ALG("RC2-64-CBC:RC2-64", ossl_rc264cbc_functions), + ALG("RC2-CFB", ossl_rc2128cfb128_functions), + ALG("RC2-OFB", ossl_rc2128ofb128_functions), #endif /* OPENSSL_NO_RC2 */ #ifndef OPENSSL_NO_RC4 - ALG("RC4", rc4128_functions), - ALG("RC4-40", rc440_functions), + ALG("RC4", ossl_rc4128_functions), + ALG("RC4-40", ossl_rc440_functions), # ifndef OPENSSL_NO_MD5 - ALG("RC4-HMAC-MD5", rc4_hmac_md5_functions), + ALG("RC4-HMAC-MD5", ossl_rc4_hmac_ossl_md5_functions), # endif /* OPENSSL_NO_MD5 */ #endif /* OPENSSL_NO_RC4 */ #ifndef OPENSSL_NO_RC5 - ALG("RC5-ECB", rc5128ecb_functions), - ALG("RC5-CBC", rc5128cbc_functions), - ALG("RC5-OFB", rc5128ofb64_functions), - ALG("RC5-CFB", rc5128cfb64_functions), + ALG("RC5-ECB", ossl_rc5128ecb_functions), + ALG("RC5-CBC:RC5", ossl_rc5128cbc_functions), + ALG("RC5-OFB", ossl_rc5128ofb64_functions), + ALG("RC5-CFB", ossl_rc5128cfb64_functions), #endif /* OPENSSL_NO_RC5 */ #ifndef OPENSSL_NO_DES - ALG("DESX-CBC:DESX", tdes_desx_cbc_functions), - ALG("DES-ECB", des_ecb_functions), - ALG("DES-CBC:DES", des_cbc_functions), - ALG("DES-OFB", des_ofb64_functions), - ALG("DES-CFB", des_cfb64_functions), - ALG("DES-CFB1", des_cfb1_functions), - ALG("DES-CFB8", des_cfb8_functions), + ALG("DESX-CBC:DESX", ossl_tdes_desx_cbc_functions), + ALG("DES-ECB", ossl_des_ecb_functions), + ALG("DES-CBC:DES", ossl_des_cbc_functions), + ALG("DES-OFB", ossl_des_ofb64_functions), + ALG("DES-CFB", ossl_des_cfb64_functions), + ALG("DES-CFB1", ossl_des_cfb1_functions), + ALG("DES-CFB8", ossl_des_cfb8_functions), #endif /* OPENSSL_NO_DES */ { NULL, NULL, NULL } }; @@ -157,8 +161,8 @@ static const OSSL_ALGORITHM *legacy_query(void *provctx, int operation_id, static void legacy_teardown(void *provctx) { - OPENSSL_CTX_free(PROV_LIBRARY_CONTEXT_OF(provctx)); - PROV_CTX_free(provctx); + OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx)); + ossl_prov_ctx_free(provctx); } /* Functions we provide to the core */ @@ -175,8 +179,8 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH **out, void **provctx) { - OSSL_FUNC_core_get_library_context_fn *c_get_libctx = NULL; - OPENSSL_CTX *libctx = NULL; + OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; + OSSL_LIB_CTX *libctx = NULL; for (; in->function_id != 0; in++) { switch (in->function_id) { @@ -186,8 +190,8 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, case OSSL_FUNC_CORE_GET_PARAMS: c_get_params = OSSL_FUNC_core_get_params(in); break; - case OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT: - c_get_libctx = OSSL_FUNC_core_get_library_context(in); + case OSSL_FUNC_CORE_GET_LIBCTX: + c_get_libctx = OSSL_FUNC_core_get_libctx(in); break; /* Just ignore anything we don't understand */ default: @@ -198,15 +202,15 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, if (c_get_libctx == NULL) return 0; - if ((*provctx = PROV_CTX_new()) == NULL - || (libctx = OPENSSL_CTX_new()) == NULL) { - OPENSSL_CTX_free(libctx); + if ((*provctx = ossl_prov_ctx_new()) == NULL + || (libctx = OSSL_LIB_CTX_new()) == NULL) { + OSSL_LIB_CTX_free(libctx); legacy_teardown(*provctx); *provctx = NULL; return 0; } - PROV_CTX_set0_library_context(*provctx, libctx); - PROV_CTX_set0_handle(*provctx, handle); + ossl_prov_ctx_set0_libctx(*provctx, libctx); + ossl_prov_ctx_set0_handle(*provctx, handle); *out = legacy_dispatch_table; diff --git a/providers/nullprov.c b/providers/nullprov.c index bdad5f15e6..537c90b78f 100644 --- a/providers/nullprov.c +++ b/providers/nullprov.c @@ -14,6 +14,7 @@ #include #include #include "prov/implementations.h" +#include "prov/providercommon.h" OSSL_provider_init_fn ossl_null_provider_init; @@ -22,6 +23,7 @@ static const OSSL_ITEM null_param_types[] = { { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_NAME }, { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_VERSION }, { OSSL_PARAM_UTF8_PTR, OSSL_PROV_PARAM_BUILDINFO }, + { OSSL_PARAM_INTEGER, OSSL_PROV_PARAM_STATUS }, { 0, NULL } }; @@ -30,7 +32,7 @@ static const OSSL_ITEM *null_gettable_params(const OSSL_PROVIDER *prov) return null_param_types; } -static int null_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) +static int null_get_params(const OSSL_PROVIDER *provctx, OSSL_PARAM params[]) { OSSL_PARAM *p; @@ -43,7 +45,9 @@ static int null_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO); if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_FULL_VERSION_STR)) return 0; - + p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); + if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) + return 0; return 1; } diff --git a/providers/prov_running.c b/providers/prov_running.c new file mode 100644 index 0000000000..379fd5d25c --- /dev/null +++ b/providers/prov_running.c @@ -0,0 +1,22 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "prov/providercommon.h" + +/* By default, our providers don't have an error state */ +void ossl_set_error_state(const char *type) +{ +} + +/* By default, our providers are always in a happy state */ +int ossl_prov_is_running(void) +{ + return 1; +} diff --git a/providers/serializers.inc b/providers/serializers.inc deleted file mode 100644 index 3143ebbec5..0000000000 --- a/providers/serializers.inc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef SER -# error Macro SER undefined -#endif - - SER("RSA", "yes", "text", "private", rsa_priv_text_serializer_functions), - SER("RSA", "yes", "text", "public", rsa_pub_text_serializer_functions), - SER("RSA", "yes", "der", "private", rsa_priv_der_serializer_functions), - SER("RSA", "yes", "der", "public", rsa_pub_der_serializer_functions), - SER("RSA", "yes", "pem", "private", rsa_priv_pem_serializer_functions), - SER("RSA", "yes", "pem", "public", rsa_pub_pem_serializer_functions), - SER("RSA-PSS", "yes", "text", "private", - rsa_priv_text_serializer_functions), - SER("RSA-PSS", "yes", "text", "public", rsa_pub_text_serializer_functions), - SER("RSA-PSS", "yes", "der", "private", rsa_priv_der_serializer_functions), - SER("RSA-PSS", "yes", "der", "public", rsa_pub_der_serializer_functions), - SER("RSA-PSS", "yes", "pem", "private", rsa_priv_pem_serializer_functions), - SER("RSA-PSS", "yes", "pem", "public", rsa_pub_pem_serializer_functions), - -#ifndef OPENSSL_NO_DH - SER("DH", "yes", "text", "private", dh_priv_text_serializer_functions), - SER("DH", "yes", "text", "public", dh_pub_text_serializer_functions), - SER("DH", "yes", "text", "parameters", dh_param_text_serializer_functions), - SER("DH", "yes", "der", "private", dh_priv_der_serializer_functions), - SER("DH", "yes", "der", "public", dh_pub_der_serializer_functions), - SER("DH", "yes", "der", "parameters", dh_param_der_serializer_functions), - SER("DH", "yes", "pem", "private", dh_priv_pem_serializer_functions), - SER("DH", "yes", "pem", "public", dh_pub_pem_serializer_functions), - SER("DH", "yes", "pem", "parameters", dh_param_pem_serializer_functions), -#endif - -#ifndef OPENSSL_NO_DSA - SER("DSA", "yes", "text", "private", dsa_priv_text_serializer_functions), - SER("DSA", "yes", "text", "public", dsa_pub_text_serializer_functions), - SER("DSA", "yes", "text", "parameters", - dsa_param_text_serializer_functions), - SER("DSA", "yes", "der", "private", dsa_priv_der_serializer_functions), - SER("DSA", "yes", "der", "public", dsa_pub_der_serializer_functions), - SER("DSA", "yes", "der", "parameters", dsa_param_der_serializer_functions), - SER("DSA", "yes", "pem", "private", dsa_priv_pem_serializer_functions), - SER("DSA", "yes", "pem", "public", dsa_pub_pem_serializer_functions), - SER("DSA", "yes", "pem", "parameters", dsa_param_pem_serializer_functions), -#endif - -#ifndef OPENSSL_NO_EC - SER("X25519", "yes", "text", "private", - x25519_priv_print_serializer_functions), - SER("X25519", "yes", "text", "public", - x25519_pub_print_serializer_functions), - SER("X25519", "yes", "der", "private", - x25519_priv_der_serializer_functions), - SER("X25519", "yes", "der", "public", x25519_pub_der_serializer_functions), - SER("X25519", "yes", "pem", "private", - x25519_priv_pem_serializer_functions), - SER("X25519", "yes", "pem", "public", x25519_pub_pem_serializer_functions), - - SER("X448", "no", "text", "private", x448_priv_print_serializer_functions), - SER("X448", "no", "text", "public", x448_pub_print_serializer_functions), - SER("X448", "no", "der", "private", x448_priv_der_serializer_functions), - SER("X448", "no", "der", "public", x448_pub_der_serializer_functions), - SER("X448", "no", "pem", "private", x448_priv_pem_serializer_functions), - SER("X448", "no", "pem", "public", x448_pub_pem_serializer_functions), - - SER("ED25519", "yes", "text", "private", - ed25519_priv_print_serializer_functions), - SER("ED25519", "yes", "text", "public", - ed25519_pub_print_serializer_functions), - SER("ED25519", "yes", "der", "private", - ed25519_priv_der_serializer_functions), - SER("ED25519", "yes", "der", "public", - ed25519_pub_der_serializer_functions), - SER("ED25519", "yes", "pem", "private", - ed25519_priv_pem_serializer_functions), - SER("ED25519", "yes", "pem", "public", - ed25519_pub_pem_serializer_functions), - - SER("ED448", "no", "text", "private", - ed448_priv_print_serializer_functions), - SER("ED448", "no", "text", "public", ed448_pub_print_serializer_functions), - SER("ED448", "no", "der", "private", ed448_priv_der_serializer_functions), - SER("ED448", "no", "der", "public", ed448_pub_der_serializer_functions), - SER("ED448", "no", "pem", "private", ed448_priv_pem_serializer_functions), - SER("ED448", "no", "pem", "public", ed448_pub_pem_serializer_functions), - - SER("EC", "yes", "text", "private", ec_priv_text_serializer_functions), - SER("EC", "yes", "text", "public", ec_pub_text_serializer_functions), - SER("EC", "yes", "text", "parameters", ec_param_text_serializer_functions), - SER("EC", "yes", "der", "private", ec_priv_der_serializer_functions), - SER("EC", "yes", "der", "public", ec_pub_der_serializer_functions), - SER("EC", "yes", "der", "parameters", ec_param_der_serializer_functions), - SER("EC", "yes", "pem", "private", ec_priv_pem_serializer_functions), - SER("EC", "yes", "pem", "public", ec_pub_pem_serializer_functions), - SER("EC", "yes", "pem", "parameters", ec_param_pem_serializer_functions), -#endif diff --git a/providers/stores.inc b/providers/stores.inc new file mode 100644 index 0000000000..4c1ec8f287 --- /dev/null +++ b/providers/stores.inc @@ -0,0 +1,14 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef STORE +# error Macro STORE undefined +#endif + +STORE("file", "yes", ossl_file_store_functions) diff --git a/ssl/build.info b/ssl/build.info index fd187ac7e5..fd9a16784e 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -10,6 +10,11 @@ IF[{- !$disabled{asm} -}] ENDIF ENDIF +$KTLSSRC= +IF[{- !$disabled{ktls} -}] + $KTLSSRC=ktls.c +ENDIF + #TODO: For now we just include the libcrypto packet.c in libssl as well. We # could either continue to do it like this, or export all the WPACKET # symbols so that libssl can use them like any other. Probably would do @@ -18,7 +23,7 @@ SOURCE[../libssl]=\ pqueue.c ../crypto/packet.c \ statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c record/rec_layer_s3.c \ statem/statem_lib.c statem/extensions.c statem/extensions_srvr.c \ - statem/extensions_clnt.c statem/extensions_cust.c s3_cbc.c s3_msg.c \ + statem/extensions_clnt.c statem/extensions_cust.c s3_msg.c \ methods.c t1_lib.c t1_enc.c tls13_enc.c \ d1_lib.c record/rec_layer_d1.c d1_msg.c \ statem/statem_dtls.c d1_srtp.c \ @@ -27,7 +32,12 @@ SOURCE[../libssl]=\ ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \ bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \ record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ - statem/statem.c record/ssl3_record_tls13.c record/tls_pad.c + statem/statem.c record/ssl3_record_tls13.c record/tls_pad.c \ + $KTLSSRC +IF[{- !$disabled{'deprecated-3.0'} -}] + SOURCE[../libssl]=s3_cbc.c +ENDIF DEFINE[../libssl]=$AESDEF SOURCE[../providers/libcommon.a]=record/tls_pad.c +SOURCE[../providers/libimplementations.a]=s3_cbc.c diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c index 66c1b54eeb..87fb4a243d 100644 --- a/ssl/d1_srtp.c +++ b/ssl/d1_srtp.c @@ -19,8 +19,6 @@ #ifndef OPENSSL_NO_SRTP -DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) - static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { { "SRTP_AES128_CM_SHA1_80", diff --git a/ssl/ktls.c b/ssl/ktls.c new file mode 100644 index 0000000000..e6c0963259 --- /dev/null +++ b/ssl/ktls.c @@ -0,0 +1,222 @@ +/* + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "ssl_local.h" +#include "internal/ktls.h" + +#if defined(__FreeBSD__) +# include + +/*- + * Check if a given cipher is supported by the KTLS interface. + * The kernel might still fail the setsockopt() if no suitable + * provider is found, but this checks if the socket option + * supports the cipher suite used at all. + */ +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + + switch (s->version) { + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + case TLS1_3_VERSION: + break; + default: + return 0; + } + + switch (s->s3.tmp.new_cipher->algorithm_enc) { + case SSL_AES128GCM: + case SSL_AES256GCM: + return 1; + case SSL_AES128: + case SSL_AES256: + if (s->ext.use_etm) + return 0; + switch (s->s3.tmp.new_cipher->algorithm_mac) { + case SSL_SHA1: + case SSL_SHA256: + case SSL_SHA384: + return 1; + default: + return 0; + } + default: + return 0; + } +} + +/* Function to configure kernel TLS structure */ +int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, + void *rl_sequence, ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key, unsigned char *mac_key, + size_t mac_secret_size) +{ + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (s->s3.tmp.new_cipher->algorithm_enc) { + case SSL_AES128GCM: + case SSL_AES256GCM: + crypto_info->cipher_algorithm = CRYPTO_AES_NIST_GCM_16; + if (s->version == TLS1_3_VERSION) + crypto_info->iv_len = EVP_CIPHER_CTX_iv_length(dd); + else + crypto_info->iv_len = EVP_GCM_TLS_FIXED_IV_LEN; + break; + case SSL_AES128: + case SSL_AES256: + switch (s->s3.tmp.new_cipher->algorithm_mac) { + case SSL_SHA1: + crypto_info->auth_algorithm = CRYPTO_SHA1_HMAC; + break; + case SSL_SHA256: + crypto_info->auth_algorithm = CRYPTO_SHA2_256_HMAC; + break; + case SSL_SHA384: + crypto_info->auth_algorithm = CRYPTO_SHA2_384_HMAC; + break; + default: + return 0; + } + crypto_info->cipher_algorithm = CRYPTO_AES_CBC; + crypto_info->iv_len = EVP_CIPHER_iv_length(c); + crypto_info->auth_key = mac_key; + crypto_info->auth_key_len = mac_secret_size; + break; + default: + return 0; + } + crypto_info->cipher_key = key; + crypto_info->cipher_key_len = EVP_CIPHER_key_length(c); + crypto_info->iv = iv; + crypto_info->tls_vmajor = (s->version >> 8) & 0x000000ff; + crypto_info->tls_vminor = (s->version & 0x000000ff); +# ifdef TCP_RXTLS_ENABLE + memcpy(crypto_info->rec_seq, rl_sequence, sizeof(crypto_info->rec_seq)); + if (rec_seq != NULL) + *rec_seq = crypto_info->rec_seq; +# else + if (rec_seq != NULL) + *rec_seq = NULL; +# endif + return 1; +}; + +#endif /* __FreeBSD__ */ + +#if defined(OPENSSL_SYS_LINUX) + +/* Function to check supported ciphers in Linux */ +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + switch (s->version) { + case TLS1_2_VERSION: + case TLS1_3_VERSION: + break; + default: + return 0; + } + + /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */ + switch (EVP_CIPHER_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) + return 0; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: +# endif + return 1; + default: + return 0; + } +} + +/* Function to configure kernel TLS structure */ +int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, + void *rl_sequence, ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key, unsigned char *mac_key, + size_t mac_secret_size) +{ + unsigned char geniv[12]; + unsigned char *iiv = iv; + + if (s->version == TLS1_2_VERSION && + EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { + if (!EVP_CIPHER_CTX_get_iv_state(dd, geniv, + EVP_GCM_TLS_FIXED_IV_LEN + + EVP_GCM_TLS_EXPLICIT_IV_LEN)) + return 0; + iiv = geniv; + } + + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (EVP_CIPHER_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: + crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; + crypto_info->gcm128.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); + memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_128_IV_SIZE); + memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c)); + memcpy(crypto_info->gcm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm128.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: + crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; + crypto_info->gcm256.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); + memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_256_IV_SIZE); + memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); + memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c)); + memcpy(crypto_info->gcm256.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm256.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; + crypto_info->ccm128.info.version = s->version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); + memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_CCM_128_IV_SIZE); + memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c)); + memcpy(crypto_info->ccm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->ccm128.rec_seq; + return 1; +# endif + default: + return 0; + } + +} + +#endif /* OPENSSL_SYS_LINUX */ diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 1d9e803570..19483ef8c3 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1107,14 +1107,14 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, if (s->msg_callback) { recordstart = WPACKET_get_curr(thispkt) - len - SSL3_RT_HEADER_LENGTH; - s->msg_callback(1, 0, SSL3_RT_HEADER, recordstart, + s->msg_callback(1, thiswr->rec_version, SSL3_RT_HEADER, recordstart, SSL3_RT_HEADER_LENGTH, s, s->msg_callback_arg); if (SSL_TREAT_AS_TLS13(s) && s->enc_write_ctx != NULL) { unsigned char ctype = type; - s->msg_callback(1, s->version, SSL3_RT_INNER_CONTENT_TYPE, + s->msg_callback(1, thiswr->rec_version, SSL3_RT_INNER_CONTENT_TYPE, &ctype, 1, s, s->msg_callback_arg); } } diff --git a/ssl/record/record_local.h b/ssl/record/record_local.h index 9047c23fd5..0a929c696a 100644 --- a/ssl/record/record_local.h +++ b/ssl/record/record_local.h @@ -113,7 +113,7 @@ __owur int ssl3_cbc_remove_padding_and_mac(size_t *reclen, unsigned char **mac, int *alloced, size_t block_size, size_t mac_size, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); __owur int tls1_cbc_remove_padding_and_mac(size_t *reclen, size_t origreclen, unsigned char *recdata, @@ -121,7 +121,7 @@ __owur int tls1_cbc_remove_padding_and_mac(size_t *reclen, int *alloced, size_t block_size, size_t mac_size, int aead, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); __owur int dtls1_get_record(SSL *s); int early_data_count_ok(SSL *s, size_t length, size_t overhead, int send); diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 80990e8296..046d6f2054 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -213,7 +213,7 @@ int ssl3_get_record(SSL *s) num_recs == 0 ? 1 : 0, &n); if (rret <= 0) { #ifndef OPENSSL_NO_KTLS - if (!BIO_get_ktls_recv(s->rbio)) + if (!BIO_get_ktls_recv(s->rbio) || rret == 0) return rret; /* error or non-blocking */ switch (errno) { case EBADMSG: @@ -287,14 +287,14 @@ int ssl3_get_record(SSL *s) } } else { /* SSLv3+ style record */ - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); /* Pull apart the header into the SSL3_RECORD */ if (!PACKET_get_1(&pkt, &type) || !PACKET_get_net_2(&pkt, &version) || !PACKET_get_net_2_len(&pkt, &thisrr->length)) { + if (s->msg_callback) + s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); return -1; @@ -302,6 +302,10 @@ int ssl3_get_record(SSL *s) thisrr->type = type; thisrr->rec_version = version; + if (s->msg_callback) + s->msg_callback(0, version, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); + /* * Lets check version. In TLSv1.3 we only check this field * when encryption is occurring (see later check). For the @@ -1303,6 +1307,25 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending, return 1; } +/* + * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. + */ +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + return 1; + default: + return 0; + } +} + int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) { unsigned char *mac_sec, *seq; @@ -1331,6 +1354,9 @@ int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) if (!sending && EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && ssl3_cbc_record_digest_supported(hash)) { +#ifdef OPENSSL_NO_DEPRECATED_3_0 + return 0; +#else /* * This is a CBC-encrypted record. We must avoid leaking any * timing-side channel information about how many blocks of data we @@ -1358,12 +1384,13 @@ int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) header[j++] = (unsigned char)(rec->length & 0xff); /* Final param == is SSLv3 */ - if (ssl3_cbc_digest_record(ssl, hash, + if (ssl3_cbc_digest_record(EVP_MD_CTX_md(hash), md, &md_size, header, rec->input, - rec->length + md_size, rec->orig_len, + rec->length, rec->orig_len, mac_sec, md_size, 1) <= 0) return 0; +#endif } else { unsigned int md_size_u; /* Chop the digest off the end :-) */ @@ -1461,31 +1488,25 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) header[12] = (unsigned char)(rec->length & 0xff); if (!sending && !SSL_READ_ETM(ssl) && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(mac_ctx)) { - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - /* Final param == not SSLv3 */ - if (ssl3_cbc_digest_record(ssl, mac_ctx, - md, &md_size, - header, rec->input, - rec->length + md_size, rec->orig_len, - ssl->s3.read_mac_secret, - ssl->s3.read_mac_secret_size, 0) <= 0) { - EVP_MD_CTX_free(hmac); - return 0; - } - } else { - /* TODO(size_t): Convert these calls */ - if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 - || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 - || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { - EVP_MD_CTX_free(hmac); + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(mac_ctx)) { + OSSL_PARAM tls_hmac_params[2], *p = tls_hmac_params; + + *p++ = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE, + &rec->orig_len); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_set_params(EVP_MD_CTX_pkey_ctx(mac_ctx), + tls_hmac_params)) return 0; - } + } + + /* TODO(size_t): Convert these calls */ + if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 + || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 + || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { + EVP_MD_CTX_free(hmac); + return 0; } EVP_MD_CTX_free(hmac); diff --git a/ssl/record/tls_pad.c b/ssl/record/tls_pad.c index 9f698483f1..8383ce8d1c 100644 --- a/ssl/record/tls_pad.c +++ b/ssl/record/tls_pad.c @@ -29,7 +29,7 @@ static int ssl3_cbc_copy_mac(size_t *reclen, size_t block_size, size_t mac_size, size_t good, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); int ssl3_cbc_remove_padding_and_mac(size_t *reclen, size_t origreclen, @@ -37,7 +37,7 @@ int ssl3_cbc_remove_padding_and_mac(size_t *reclen, unsigned char **mac, int *alloced, size_t block_size, size_t mac_size, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); int tls1_cbc_remove_padding_and_mac(size_t *reclen, size_t origreclen, @@ -46,7 +46,7 @@ int tls1_cbc_remove_padding_and_mac(size_t *reclen, int *alloced, size_t block_size, size_t mac_size, int aead, - OPENSSL_CTX *libctx); + OSSL_LIB_CTX *libctx); /*- * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC @@ -71,7 +71,7 @@ int ssl3_cbc_remove_padding_and_mac(size_t *reclen, unsigned char **mac, int *alloced, size_t block_size, size_t mac_size, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { size_t padding_length; size_t good; @@ -117,7 +117,7 @@ int tls1_cbc_remove_padding_and_mac(size_t *reclen, int *alloced, size_t block_size, size_t mac_size, int aead, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { size_t good = -1; size_t padding_length, to_check, i; @@ -204,7 +204,7 @@ static int ssl3_cbc_copy_mac(size_t *reclen, size_t block_size, size_t mac_size, size_t good, - OPENSSL_CTX *libctx) + OSSL_LIB_CTX *libctx) { #if defined(CBC_MAC_ROTATE_IN_PLACE) unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index ec1f3cf83b..26f12654e4 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c @@ -7,6 +7,16 @@ * https://www.openssl.org/source/license.html */ +/* + * This file has no dependencies on the rest of libssl because it is shared + * with the providers. It contains functions for low level MAC calculations. + * Responsibility for this lies with the HMAC implementation in the + * providers. However there are legacy code paths in libssl which also need to + * do this. In time those legacy code paths can be removed and this file can be + * moved out of libssl. + */ + + /* * MD5 and SHA-1 low level APIs are deprecated for public use, but still ok for * internal use. @@ -14,12 +24,44 @@ #include "internal/deprecated.h" #include "internal/constant_time.h" -#include "ssl_local.h" #include "internal/cryptlib.h" +#include #include #include +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD *md, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + size_t mac_secret_length, char is_sslv3); + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + /* * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's * length field. (SHA-384/512 have 128-bit length.) @@ -90,25 +132,6 @@ static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) #undef LARGEST_DIGEST_CTX #define LARGEST_DIGEST_CTX SHA512_CTX -/* - * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function - * which ssl3_cbc_digest_record supports. - */ -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) -{ - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - case NID_sha1: - case NID_sha224: - case NID_sha256: - case NID_sha384: - case NID_sha512: - return 1; - default: - return 0; - } -} - /*- * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS * record. @@ -119,25 +142,21 @@ char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) * md_out_size: if non-NULL, the number of output bytes is written here. * header: the 13-byte, TLS record header. * data: the record data itself, less any preceding explicit IV. - * data_plus_mac_size: the secret, reported length of the data and MAC - * once the padding has been removed. + * data_size: the secret, reported length of the data once the MAC and padding + * has been removed. * data_plus_mac_plus_padding_size: the public length of the whole - * record, including padding. + * record, including MAC and padding. * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. * - * On entry: by virtue of having been through one of the remove_padding - * functions, above, we know that data_plus_mac_size is large enough to contain - * a padding byte and MAC. (If the padding was invalid, it might contain the - * padding too. ) + * On entry: we know that data is data_plus_mac_plus_padding_size in length * Returns 1 on success or 0 on error */ -int ssl3_cbc_digest_record(SSL *s, - const EVP_MD_CTX *ctx, +int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char *md_out, size_t *md_out_size, const unsigned char header[13], const unsigned char *data, - size_t data_plus_mac_size, + size_t data_size, size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, size_t mac_secret_length, char is_sslv3) @@ -168,7 +187,6 @@ int ssl3_cbc_digest_record(SSL *s, size_t md_length_size = 8; char length_is_big_endian = 1; int ret = 0; - const EVP_MD *md = NULL; /* * This is a, hopefully redundant, check that allows us to forget about @@ -177,8 +195,7 @@ int ssl3_cbc_digest_record(SSL *s, if (!ossl_assert(data_plus_mac_plus_padding_size < 1024 * 1024)) return 0; - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: + if (EVP_MD_is_a(md, "MD5")) { if (MD5_Init((MD5_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_md5_final_raw; @@ -187,32 +204,28 @@ int ssl3_cbc_digest_record(SSL *s, md_size = 16; sslv3_pad_length = 48; length_is_big_endian = 0; - break; - case NID_sha1: + } else if (EVP_MD_is_a(md, "SHA1")) { if (SHA1_Init((SHA_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha1_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA1_Transform; md_size = 20; - break; - case NID_sha224: + } else if (EVP_MD_is_a(md, "SHA2-224")) { if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha256_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; md_size = 224 / 8; - break; - case NID_sha256: + } else if (EVP_MD_is_a(md, "SHA2-256")) { if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha256_final_raw; md_transform = (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; md_size = 32; - break; - case NID_sha384: + } else if (EVP_MD_is_a(md, "SHA2-384")) { if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha512_final_raw; @@ -221,8 +234,7 @@ int ssl3_cbc_digest_record(SSL *s, md_size = 384 / 8; md_block_size = 128; md_length_size = 16; - break; - case NID_sha512: + } else if (EVP_MD_is_a(md, "SHA2-512")) { if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0) return 0; md_final_raw = tls1_sha512_final_raw; @@ -231,8 +243,7 @@ int ssl3_cbc_digest_record(SSL *s, md_size = 64; md_block_size = 128; md_length_size = 16; - break; - default: + } else { /* * ssl3_cbc_record_digest_supported should have been called first to * check that the hash function is supported. @@ -303,7 +314,7 @@ int ssl3_cbc_digest_record(SSL *s, /* * mac_end_offset is the index just past the end of the data to be MACed. */ - mac_end_offset = data_plus_mac_size + header_length - md_size; + mac_end_offset = data_size + header_length; /* * c is the index of the 0x80 byte in the final hash block that contains * application data. @@ -463,10 +474,7 @@ int ssl3_cbc_digest_record(SSL *s, md_ctx = EVP_MD_CTX_new(); if (md_ctx == NULL) goto err; - md = ssl_evp_md_fetch(s->ctx->libctx, EVP_MD_type(EVP_MD_CTX_md(ctx)), - s->ctx->propq); - if (md == NULL) - goto err; + if (EVP_DigestInit_ex(md_ctx, md, NULL /* engine */ ) <= 0) goto err; if (is_sslv3) { @@ -494,6 +502,5 @@ int ssl3_cbc_digest_record(SSL *s, ret = 1; err: EVP_MD_CTX_free(md_ctx); - ssl_evp_md_free(md); return ret; } diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 36b7c7616e..bd90e059b5 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -22,7 +22,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX *s1; unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; unsigned char c = 'A'; - unsigned int i, j, k; + unsigned int i, k; int ret = 0; #ifdef CHARSET_EBCDIC @@ -47,8 +47,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) goto err; } - for (j = 0; j < k; j++) - buf[j] = c; + memset(buf, c, k); c++; if (!EVP_DigestInit_ex(s1, sha1, NULL) || !EVP_DigestUpdate(s1, buf, k) @@ -409,7 +408,12 @@ int ssl3_digest_cached_records(SSL *s, int keep) } md = ssl_handshake_md(s); - if (md == NULL || !EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL) + if (md == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, + SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); + return 0; + } + if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL) || !EVP_DigestUpdate(s->s3.handshake_dgst, hdata, hdatalen)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 8f5aaaf942..1fd424a52e 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -20,10 +20,6 @@ #include #include "internal/cryptlib.h" -DEFINE_STACK_OF(X509_NAME) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF_CONST(SSL_CIPHER) - #define TLS13_NUM_CIPHERS OSSL_NELEM(tls13_ciphers) #define SSL3_NUM_CIPHERS OSSL_NELEM(ssl3_ciphers) #define SSL3_NUM_SCSVS OSSL_NELEM(ssl3_scsvs) @@ -4136,8 +4132,7 @@ const SSL_CIPHER *ssl3_get_cipher_by_std_name(const char *stdname) if (tbl->stdname == NULL) continue; if (strcmp(stdname, tbl->stdname) == 0) { - c = tbl; - break; + return tbl; } } } @@ -4837,6 +4832,32 @@ EVP_PKEY *ssl_generate_param_group(SSL *s, uint16_t id) return pkey; } +/* Generate secrets from pms */ +int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen) +{ + int rv = 0; + + /* SSLfatal() called as appropriate in the below functions */ + if (SSL_IS_TLS13(s)) { + /* + * If we are resuming then we already generated the early secret + * when we created the ClientHello, so don't recreate it. + */ + if (!s->hit) + rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, + 0, + (unsigned char *)&s->early_secret); + else + rv = 1; + + rv = rv && tls13_generate_handshake_secret(s, pms, pmslen); + } else { + rv = ssl_generate_master_secret(s, pms, pmslen, 0); + } + + return rv; +} + /* Derive secrets for ECDH/DH */ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) { @@ -4881,22 +4902,7 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) if (gensecret) { /* SSLfatal() called as appropriate in the below functions */ - if (SSL_IS_TLS13(s)) { - /* - * If we are resuming then we already generated the early secret - * when we created the ClientHello, so don't recreate it. - */ - if (!s->hit) - rv = tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, - 0, - (unsigned char *)&s->early_secret); - else - rv = 1; - - rv = rv && tls13_generate_handshake_secret(s, pms, pmslen); - } else { - rv = ssl_generate_master_secret(s, pms, pmslen, 0); - } + rv = ssl_gensecret(s, pms, pmslen); } else { /* Save premaster secret */ s->s3.tmp.pms = pms; @@ -4911,6 +4917,125 @@ int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) return rv; } +/* Decapsulate secrets for KEM */ +int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, + const unsigned char *ct, size_t ctlen, + int gensecret) +{ + int rv = 0; + unsigned char *pms = NULL; + size_t pmslen = 0; + EVP_PKEY_CTX *pctx; + + if (privkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, privkey, s->ctx->propq); + + if (EVP_PKEY_decapsulate_init(pctx) <= 0 + || EVP_PKEY_decapsulate(pctx, NULL, &pmslen, ct, ctlen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + pms = OPENSSL_malloc(pmslen); + if (pms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decapsulate(pctx, pms, &pmslen, ct, ctlen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_DECAPSULATE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (gensecret) { + /* SSLfatal() called as appropriate in the below functions */ + rv = ssl_gensecret(s, pms, pmslen); + } else { + /* Save premaster secret */ + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; + pms = NULL; + rv = 1; + } + + err: + OPENSSL_clear_free(pms, pmslen); + EVP_PKEY_CTX_free(pctx); + return rv; +} + +int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, + unsigned char **ctp, size_t *ctlenp, + int gensecret) +{ + int rv = 0; + unsigned char *pms = NULL, *ct = NULL; + size_t pmslen = 0, ctlen = 0; + EVP_PKEY_CTX *pctx; + + if (pubkey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ENCAPSULATE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pubkey, s->ctx->propq); + + if (EVP_PKEY_encapsulate_init(pctx) <= 0 + || EVP_PKEY_encapsulate(pctx, NULL, &ctlen, NULL, &pmslen) <= 0 + || pmslen == 0 || ctlen == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ENCAPSULATE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + pms = OPENSSL_malloc(pmslen); + ct = OPENSSL_malloc(ctlen); + if (pms == NULL || ct == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ENCAPSULATE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encapsulate(pctx, ct, &ctlen, pms, &pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ENCAPSULATE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (gensecret) { + /* SSLfatal() called as appropriate in the below functions */ + rv = ssl_gensecret(s, pms, pmslen); + } else { + /* Save premaster secret */ + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; + pms = NULL; + rv = 1; + } + + if (rv > 0) { + /* Pass ownership of ct to caller */ + *ctp = ct; + *ctlenp = ctlen; + ct = NULL; + } + + err: + OPENSSL_clear_free(pms, pmslen); + OPENSSL_free(ct); + EVP_PKEY_CTX_free(pctx); + return rv; +} + #ifndef OPENSSL_NO_DH EVP_PKEY *ssl_dh_to_pkey(DH *dh) { diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index e6262bfaeb..c1e26bd3b4 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -25,9 +25,6 @@ #include "ssl_cert_table.h" #include "internal/thread_once.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_NAME) - static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex); @@ -383,7 +380,7 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) else verify_store = s->ctx->cert_store; - ctx = X509_STORE_CTX_new_with_libctx(s->ctx->libctx, s->ctx->propq); + ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, s->ctx->propq); if (ctx == NULL) { SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE); return 0; @@ -608,23 +605,23 @@ static unsigned long xname_hash(const X509_NAME *a) return X509_NAME_hash((X509_NAME *)a); } -STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file, - OPENSSL_CTX *libctx, - const char *propq) +STACK_OF(X509_NAME) *SSL_load_client_CA_file_ex(const char *file, + OSSL_LIB_CTX *libctx, + const char *propq) { BIO *in = BIO_new(BIO_s_file()); X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL; LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp); - OPENSSL_CTX *prev_libctx = NULL; + OSSL_LIB_CTX *prev_libctx = NULL; if ((name_hash == NULL) || (in == NULL)) { SSLerr(0, ERR_R_MALLOC_FAILURE); goto err; } - x = X509_new_with_libctx(libctx, propq); + x = X509_new_ex(libctx, propq); if (x == NULL) { SSLerr(0, ERR_R_MALLOC_FAILURE); goto err; @@ -633,7 +630,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file, goto err; /* Internally lh_X509_NAME_retrieve() needs the libctx to retrieve SHA1 */ - prev_libctx = OPENSSL_CTX_set0_default(libctx); + prev_libctx = OSSL_LIB_CTX_set0_default(libctx); for (;;) { if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) break; @@ -668,7 +665,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file, ret = NULL; done: /* restore the old libctx */ - OPENSSL_CTX_set0_default(prev_libctx); + OSSL_LIB_CTX_set0_default(prev_libctx); BIO_free(in); X509_free(x); lh_X509_NAME_free(name_hash); @@ -679,7 +676,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file_with_libctx(const char *file, STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { - return SSL_load_client_CA_file_with_libctx(file, NULL, NULL); + return SSL_load_client_CA_file_ex(file, NULL, NULL); } int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, @@ -884,7 +881,7 @@ int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags) untrusted = cpk->chain; } - xs_ctx = X509_STORE_CTX_new_with_libctx(real_ctx->libctx, ctx->propq); + xs_ctx = X509_STORE_CTX_new_ex(real_ctx->libctx, ctx->propq); if (xs_ctx == NULL) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_MALLOC_FAILURE); goto err; diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 64d773acbd..b8d22a72ce 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -25,9 +25,6 @@ #include "internal/thread_once.h" #include "internal/cryptlib.h" -DEFINE_STACK_OF(SSL_COMP) -DEFINE_STACK_OF_CONST(SSL_CIPHER) - /* NB: make sure indices in these tables match values above */ typedef struct { @@ -1382,7 +1379,7 @@ static int update_cipher_list(STACK_OF(SSL_CIPHER) **cipher_list, while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0 && sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls == TLS1_3_VERSION) - sk_SSL_CIPHER_delete(tmp_cipher_list, 0); + (void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0); /* Insert the new TLSv1.3 ciphersuites */ for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 56590da207..8151213938 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -14,8 +14,6 @@ #include #include "internal/nelem.h" -DEFINE_STACK_OF(X509_NAME) - /* * structure holding name tables. This is used for permitted elements in lists * such as TLSv1. @@ -471,7 +469,7 @@ static int do_store(SSL_CONF_CTX *cctx, CERT *cert; X509_STORE **st; SSL_CTX *ctx; - OPENSSL_CTX *libctx = NULL; + OSSL_LIB_CTX *libctx = NULL; const char *propq = NULL; if (cctx->ctx != NULL) { @@ -494,13 +492,12 @@ static int do_store(SSL_CONF_CTX *cctx, return 0; } - if (CAfile != NULL && !X509_STORE_load_file_with_libctx(*st, CAfile, - libctx, propq)) + if (CAfile != NULL && !X509_STORE_load_file_ex(*st, CAfile, libctx, propq)) return 0; if (CApath != NULL && !X509_STORE_load_path(*st, CApath)) return 0; - if (CAstore != NULL && !X509_STORE_load_store_with_libctx(*st, CAstore, - libctx, propq)) + if (CAstore != NULL && !X509_STORE_load_store_ex(*st, CAstore, libctx, + propq)) return 0; return 1; } diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index f84b3f94d8..9f47a924f0 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -300,6 +300,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS), "no shared signature algorithms"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM), + "no suitable digest algorithm"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_KEY_SHARE), "no suitable key share"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM), diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 3f621d5677..219d30ff24 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -29,14 +28,6 @@ #include "internal/refcount.h" #include "internal/ktls.h" -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_NAME) -DEFINE_STACK_OF_CONST(SSL_CIPHER) -DEFINE_STACK_OF(X509_EXTENSION) -DEFINE_STACK_OF(OCSP_RESPID) -DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) -DEFINE_STACK_OF(SCT) - static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t, SSL_MAC_BUF *mac, size_t macsize) { @@ -557,6 +548,19 @@ static int ssl_check_allowed_versions(int min_version, int max_version) return 1; } +#if defined(__TANDEM) && defined(OPENSSL_VPROC) +/* + * Define a VPROC function for HP NonStop build ssl library. + * This is used by platform version identification tools. + * Do not inline this procedure or make it static. + */ +# define OPENSSL_VPROC_STRING_(x) x##_SSL +# define OPENSSL_VPROC_STRING(x) OPENSSL_VPROC_STRING_(x) +# define OPENSSL_VPROC_FUNC OPENSSL_VPROC_STRING(OPENSSL_VPROC) +void OPENSSL_VPROC_FUNC(void) {} +#endif + + static void clear_ciphers(SSL *s) { /* clear the current cipher */ @@ -643,6 +647,7 @@ int SSL_clear(SSL *s) return 1; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 /** Used to change an SSL_CTXs default SSL method type */ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) { @@ -665,6 +670,7 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) } return 1; } +#endif SSL *SSL_new(SSL_CTX *ctx) { @@ -980,7 +986,7 @@ int SSL_add1_host(SSL *s, const char *hostname) old_ip = X509_VERIFY_PARAM_get1_ip_asc(s->param); if (old_ip) { - free(old_ip); + OPENSSL_free(old_ip); /* There can be only one IP address */ return 0; } @@ -2836,7 +2842,7 @@ const char *SSL_get_servername(const SSL *s, const int type) * - Otherwise it returns NULL * * During/after the handshake (TLSv1.2 or below resumption occurred): - * - If the session from the orignal handshake had a servername accepted + * - If the session from the original handshake had a servername accepted * by the server then it will return that servername. * - Otherwise it returns the servername set via * SSL_set_tlsext_host_name() (or NULL if it was not called). @@ -3053,7 +3059,8 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *context, size_t contextlen, int use_context) { - if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) + if (s->session == NULL + || (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER)) return -1; return s->method->ssl3_enc->export_keying_material(s, out, olen, label, @@ -3116,8 +3123,8 @@ static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) * via ssl.h. */ -SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, - const SSL_METHOD *meth) +SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, + const SSL_METHOD *meth) { SSL_CTX *ret = NULL; @@ -3171,7 +3178,7 @@ SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, if (ret->cert_store == NULL) goto err; #ifndef OPENSSL_NO_CT - ret->ctlog_store = CTLOG_STORE_new_with_libctx(libctx, propq); + ret->ctlog_store = CTLOG_STORE_new_ex(libctx, propq); if (ret->ctlog_store == NULL) goto err; #endif @@ -3324,7 +3331,7 @@ SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq, SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) { - return SSL_CTX_new_with_libctx(NULL, NULL, meth); + return SSL_CTX_new_ex(NULL, NULL, meth); } int SSL_CTX_up_ref(SSL_CTX *ctx) @@ -4283,8 +4290,8 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { - return X509_STORE_set_default_paths_with_libctx(ctx->cert_store, - ctx->libctx, ctx->propq); + return X509_STORE_set_default_paths_ex(ctx->cert_store, ctx->libctx, + ctx->propq); } int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx) @@ -4316,8 +4323,8 @@ int SSL_CTX_set_default_verify_file(SSL_CTX *ctx) /* We ignore errors, in case the directory doesn't exist */ ERR_set_mark(); - X509_LOOKUP_load_file_with_libctx(lookup, NULL, X509_FILETYPE_DEFAULT, - ctx->libctx, ctx->propq); + X509_LOOKUP_load_file_ex(lookup, NULL, X509_FILETYPE_DEFAULT, ctx->libctx, + ctx->propq); ERR_pop_to_mark(); @@ -4335,7 +4342,7 @@ int SSL_CTX_set_default_verify_store(SSL_CTX *ctx) /* We ignore errors, in case the directory doesn't exist */ ERR_set_mark(); - X509_LOOKUP_add_store_with_libctx(lookup, NULL, ctx->libctx, ctx->propq); + X509_LOOKUP_add_store_ex(lookup, NULL, ctx->libctx, ctx->propq); ERR_pop_to_mark(); @@ -4344,8 +4351,8 @@ int SSL_CTX_set_default_verify_store(SSL_CTX *ctx) int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile) { - return X509_STORE_load_file_with_libctx(ctx->cert_store, CAfile, - ctx->libctx, ctx->propq); + return X509_STORE_load_file_ex(ctx->cert_store, CAfile, ctx->libctx, + ctx->propq); } int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) @@ -4355,8 +4362,8 @@ int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath) int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore) { - return X509_STORE_load_store_with_libctx(ctx->cert_store, CAstore, - ctx->libctx, ctx->propq); + return X509_STORE_load_store_ex(ctx->cert_store, CAstore, ctx->libctx, + ctx->propq); } int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, @@ -5187,7 +5194,7 @@ int ssl_validate_ct(SSL *s) } } - ctx = CT_POLICY_EVAL_CTX_new_with_libctx(s->ctx->libctx, s->ctx->propq); + ctx = CT_POLICY_EVAL_CTX_new_ex(s->ctx->libctx, s->ctx->propq); if (ctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_VALIDATE_CT, ERR_R_MALLOC_FAILURE); @@ -5886,7 +5893,7 @@ void SSL_set_allow_early_data_cb(SSL *s, s->allow_early_data_cb_data = arg; } -const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx, +const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx, int nid, const char *properties) { @@ -5941,7 +5948,7 @@ void ssl_evp_cipher_free(const EVP_CIPHER *cipher) } } -const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx, +const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx, int nid, const char *properties) { diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 250098600f..b83cf1e1ca 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -35,6 +35,7 @@ # include "internal/refcount.h" # include "internal/tsan_assist.h" # include "internal/bio.h" +# include "internal/ktls.h" # ifdef OPENSSL_BUILD_SHLIBSSL # undef OPENSSL_EXTERN @@ -523,7 +524,7 @@ struct ssl_method_st { * Matches the length of PSK_MAX_PSK_LEN. We keep it the same value for * consistency, even in the event of OPENSSL_NO_PSK being defined. */ -# define TLS13_MAX_RESUMPTION_PSK_LENGTH 256 +# define TLS13_MAX_RESUMPTION_PSK_LENGTH 512 /*- * Lets make this into an ASN.1 type structure as follows @@ -817,6 +818,7 @@ typedef struct tls_group_info_st { int maxtls; /* Maximum TLS version (or 0 for undefined) */ int mindtls; /* Minimum DTLS version, -1 unsupported */ int maxdtls; /* Maximum DTLS version (or 0 for undefined) */ + char is_kem; /* Mode for this Group: 0 is KEX, 1 is KEM */ } TLS_GROUP_INFO; /* flags values */ @@ -830,7 +832,7 @@ typedef struct tls_group_info_st { # define TLS_GROUP_FFDHE_FOR_TLS1_3 (TLS_GROUP_FFDHE|TLS_GROUP_ONLY_FOR_TLS1_3) struct ssl_ctx_st { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; const SSL_METHOD *method; STACK_OF(SSL_CIPHER) *cipher_list; @@ -2452,8 +2454,15 @@ __owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, __owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen, int free_pms); __owur EVP_PKEY *ssl_generate_pkey(SSL *s, EVP_PKEY *pm); +__owur int ssl_gensecret(SSL *s, unsigned char *pms, size_t pmslen); __owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int genmaster); +__owur int ssl_decapsulate(SSL *s, EVP_PKEY *privkey, + const unsigned char *ct, size_t ctlen, + int gensecret); +__owur int ssl_encapsulate(SSL *s, EVP_PKEY *pubkey, + unsigned char **ctp, size_t *ctlenp, + int gensecret); __owur EVP_PKEY *ssl_dh_to_pkey(DH *dh); __owur unsigned int ssl_get_max_send_fragment(const SSL *ssl); __owur unsigned int ssl_get_split_send_fragment(const SSL *ssl); @@ -2747,15 +2756,25 @@ __owur int ssl_log_secret(SSL *ssl, const char *label, #define EARLY_EXPORTER_SECRET_LABEL "EARLY_EXPORTER_SECRET" #define EXPORTER_SECRET_LABEL "EXPORTER_SECRET" +# ifndef OPENSSL_NO_KTLS +/* ktls.c */ +int ktls_check_supported_cipher(const SSL *s, const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd); +int ktls_configure_crypto(const SSL *s, const EVP_CIPHER *c, EVP_CIPHER_CTX *dd, + void *rl_sequence, ktls_crypto_info_t *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key, unsigned char *mac_key, + size_t mac_secret_size); +# endif + /* s3_cbc.c */ __owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -__owur int ssl3_cbc_digest_record(SSL *s, - const EVP_MD_CTX *ctx, +__owur int ssl3_cbc_digest_record(const EVP_MD *md, unsigned char *md_out, size_t *md_out_size, const unsigned char header[13], const unsigned char *data, - size_t data_plus_mac_size, + size_t data_size, size_t data_plus_mac_plus_padding_size, const unsigned char *mac_secret, size_t mac_secret_length, char is_sslv3); @@ -2793,12 +2812,12 @@ void ssl_comp_free_compression_methods_int(void); /* ssl_mcnf.c */ void ssl_ctx_system_config(SSL_CTX *ctx); -const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx, +const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx, int nid, const char *properties); int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher); void ssl_evp_cipher_free(const EVP_CIPHER *cipher); -const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx, +const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx, int nid, const char *properties); int ssl_evp_md_up_ref(const EVP_MD *md); diff --git a/ssl/ssl_mcnf.c b/ssl/ssl_mcnf.c index 10c2f412e0..82003ba69e 100644 --- a/ssl/ssl_mcnf.c +++ b/ssl/ssl_mcnf.c @@ -28,8 +28,8 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) unsigned int flags; const SSL_METHOD *meth; const SSL_CONF_CMD *cmds; - OPENSSL_CTX *prev_libctx = NULL; - OPENSSL_CTX *libctx = NULL; + OSSL_LIB_CTX *prev_libctx = NULL; + OSSL_LIB_CTX *libctx = NULL; if (s == NULL && ctx == NULL) { SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER); @@ -66,7 +66,7 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) if (meth->ssl_connect != ssl_undefined_function) flags |= SSL_CONF_FLAG_CLIENT; SSL_CONF_CTX_set_flags(cctx, flags); - prev_libctx = OPENSSL_CTX_set0_default(libctx); + prev_libctx = OSSL_LIB_CTX_set0_default(libctx); for (i = 0; i < cmd_count; i++) { char *cmdstr, *arg; @@ -84,7 +84,7 @@ static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name, int system) } rv = SSL_CONF_CTX_finish(cctx); err: - OPENSSL_CTX_set0_default(prev_libctx); + OSSL_LIB_CTX_set0_default(prev_libctx); SSL_CONF_CTX_free(cctx); return rv <= 0 ? 0 : 1; } diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 144dd2c374..51604b8a87 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -17,8 +17,6 @@ #include #include -DEFINE_STACK_OF(X509) - static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); @@ -66,7 +64,7 @@ int SSL_use_certificate_file(SSL *ssl, const char *file, int type) SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } - x = X509_new_with_libctx(ssl->ctx->libctx, ssl->ctx->propq); + x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq); if (x == NULL) { SSLerr(0, ERR_R_MALLOC_FAILURE); goto end; @@ -100,7 +98,7 @@ int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) X509 *x; int ret; - x = X509_new_with_libctx(ssl->ctx->libctx, ssl->ctx->propq); + x = X509_new_ex(ssl->ctx->libctx, ssl->ctx->propq); if (x == NULL) { SSLerr(0, ERR_R_MALLOC_FAILURE); return 0; @@ -168,15 +166,6 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) EVP_PKEY_copy_parameters(pktmp, pkey); ERR_clear_error(); -#ifndef OPENSSL_NO_RSA - /* - * Don't check the public/private key, this is mostly for smart - * cards. - */ - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA - && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ; - else -#endif if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { X509_free(c->pkeys[i].x509); c->pkeys[i].x509 = NULL; @@ -367,16 +356,6 @@ static int ssl_set_cert(CERT *c, X509 *x) EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); ERR_clear_error(); -#ifndef OPENSSL_NO_RSA - /* - * Don't check the public/private key, this is mostly for smart - * cards. - */ - if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA - && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) & - RSA_METHOD_FLAG_NO_CHECK) ; - else -#endif /* OPENSSL_NO_RSA */ if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { /* * don't fail for a cert/key mismatch, just free current private @@ -419,7 +398,7 @@ int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); goto end; } - x = X509_new_with_libctx(ctx->libctx, ctx->propq); + x = X509_new_ex(ctx->libctx, ctx->propq); if (x == NULL) { SSLerr(0, ERR_R_MALLOC_FAILURE); goto end; @@ -449,7 +428,7 @@ int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d) X509 *x; int ret; - x = X509_new_with_libctx(ctx->libctx, ctx->propq); + x = X509_new_ex(ctx->libctx, ctx->propq); if (x == NULL) { SSLerr(0, ERR_R_MALLOC_FAILURE); return 0; @@ -655,7 +634,7 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) goto end; } - x = X509_new_with_libctx(real_ctx->libctx, real_ctx->propq); + x = X509_new_ex(real_ctx->libctx, real_ctx->propq); if (x == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE); goto end; @@ -694,7 +673,7 @@ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) } while (1) { - ca = X509_new_with_libctx(real_ctx->libctx, real_ctx->propq); + ca = X509_new_ex(real_ctx->libctx, real_ctx->propq); if (ca == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE); goto end; @@ -1136,13 +1115,6 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr EVP_PKEY_copy_parameters(pubkey, privatekey); } /* else both have parameters */ - /* Copied from ssl_set_cert/pkey */ -#ifndef OPENSSL_NO_RSA - if ((EVP_PKEY_id(privatekey) == EVP_PKEY_RSA) && - ((RSA_flags(EVP_PKEY_get0_RSA(privatekey)) & RSA_METHOD_FLAG_NO_CHECK))) - /* no-op */ ; - else -#endif /* check that key <-> cert match */ if (EVP_PKEY_eq(pubkey, privatekey) != 1) { SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 63624e9e80..4c4fc80023 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -19,8 +19,6 @@ #include "ssl_local.h" #include "statem/statem_local.h" -DEFINE_STACK_OF(X509) - static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); @@ -112,7 +110,7 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) { SSL_SESSION *dest; - dest = OPENSSL_malloc(sizeof(*src)); + dest = OPENSSL_malloc(sizeof(*dest)); if (dest == NULL) { goto err; } diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 9086348618..65c6de1373 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -14,8 +14,6 @@ #include "statem_local.h" #include "internal/cryptlib.h" -DEFINE_STACK_OF(X509_NAME) - static int final_renegotiate(SSL *s, unsigned int context, int sent); static int init_server_name(SSL *s, unsigned int context); static int final_server_name(SSL *s, unsigned int context, int sent); @@ -1598,8 +1596,9 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, goto err; } - mackey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finishedkey, - hashsize); + mackey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, finishedkey, + hashsize); if (mackey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR); @@ -1610,8 +1609,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, binderout = tmpbinder; bindersize = hashsize; - if (EVP_DigestSignInit_ex(mctx, NULL, EVP_MD_name(md), s->ctx->propq, - mackey, s->ctx->libctx) <= 0 + if (EVP_DigestSignInit_ex(mctx, NULL, EVP_MD_name(md), s->ctx->libctx, + s->ctx->propq, mackey) <= 0 || EVP_DigestSignUpdate(mctx, hash, hashsize) <= 0 || EVP_DigestSignFinal(mctx, binderout, &bindersize) <= 0 || bindersize != hashsize) { diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index abff069ec9..15cd622ed5 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -12,10 +12,6 @@ #include "internal/cryptlib.h" #include "statem_local.h" -DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) -DEFINE_STACK_OF_CONST(SSL_CIPHER) -DEFINE_STACK_OF(OCSP_RESPID) - EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1834,6 +1830,7 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, unsigned int group_id; PACKET encoded_pt; EVP_PKEY *ckey = s->s3.tmp.pkey, *skey = NULL; + const TLS_GROUP_INFO *ginf = NULL; /* Sanity check */ if (ckey == NULL || s->s3.peer_tmp != NULL) { @@ -1897,6 +1894,12 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } + if ((ginf = tls1_group_id_lookup(s->ctx, group_id)) == NULL) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, + SSL_R_BAD_KEY_SHARE); + return 0; + } + if (!PACKET_as_length_prefixed_2(pkt, &encoded_pt) || PACKET_remaining(&encoded_pt) == 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, @@ -1904,27 +1907,39 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - skey = EVP_PKEY_new(); - if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_COPY_PARAMETERS_FAILED); - return 0; - } + if (!ginf->is_kem) { + /* Regular KEX */ + skey = EVP_PKEY_new(); + if (skey == NULL || EVP_PKEY_copy_parameters(skey, ckey) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, + SSL_R_COPY_PARAMETERS_FAILED); + return 0; + } - if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), - PACKET_remaining(&encoded_pt))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - SSL_R_BAD_ECPOINT); - EVP_PKEY_free(skey); - return 0; - } + if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt))) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, + SSL_R_BAD_ECPOINT); + EVP_PKEY_free(skey); + return 0; + } - if (ssl_derive(s, ckey, skey, 1) == 0) { - /* SSLfatal() already called */ - EVP_PKEY_free(skey); - return 0; + if (ssl_derive(s, ckey, skey, 1) == 0) { + /* SSLfatal() already called */ + EVP_PKEY_free(skey); + return 0; + } + s->s3.peer_tmp = skey; + } else { + /* KEM Mode */ + const unsigned char *ct = PACKET_data(&encoded_pt); + size_t ctlen = PACKET_remaining(&encoded_pt); + + if (ssl_decapsulate(s, ckey, ct, ctlen, 1) == 0) { + /* SSLfatal() already called */ + return 0; + } } - s->s3.peer_tmp = skey; #endif return 1; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 27ddef9aaf..eb24d0a19e 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -12,10 +12,6 @@ #include "statem_local.h" #include "internal/cryptlib.h" -DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE) -DEFINE_STACK_OF(OCSP_RESPID) -DEFINE_STACK_OF(X509_EXTENSION) - #define COOKIE_STATE_FORMAT_VERSION 0 /* @@ -771,10 +767,10 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, /* Verify the HMAC of the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext - .cookie_hmac_key)); + pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, + s->session_ctx->ext.cookie_hmac_key, + sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { EVP_MD_CTX_free(hctx); EVP_PKEY_free(pkey); @@ -784,8 +780,8 @@ int tls_parse_ctos_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, } hmaclen = SHA256_DIGEST_LENGTH; - if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->propq, pkey, - s->ctx->libctx) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, + s->ctx->propq, pkey) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, data, rawlen - SHA256_DIGEST_LENGTH) <= 0 || hmaclen != SHA256_DIGEST_LENGTH) { @@ -1700,6 +1696,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, unsigned char *encodedPoint; size_t encoded_pt_len = 0; EVP_PKEY *ckey = s->s3.peer_tmp, *skey = NULL; + const TLS_GROUP_INFO *ginf = NULL; if (s->hello_retry_request == SSL_HRR_PENDING) { if (ckey != NULL) { @@ -1737,37 +1734,92 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - skey = ssl_generate_pkey(s, ckey); - if (skey == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_MALLOC_FAILURE); + if ((ginf = tls1_group_id_lookup(s->ctx, s->s3.group_id)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - /* Generate encoding of server key */ - encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); - if (encoded_pt_len == 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_EC_LIB); - EVP_PKEY_free(skey); - return EXT_RETURN_FAIL; - } + if (!ginf->is_kem) { + /* Regular KEX */ + skey = ssl_generate_pkey(s, ckey); + if (skey == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_MALLOC_FAILURE); + return EXT_RETURN_FAIL; + } - if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) - || !WPACKET_close(pkt)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(skey); + /* Generate encoding of server key */ + encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); + if (encoded_pt_len == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_EC_LIB); + EVP_PKEY_free(skey); + return EXT_RETURN_FAIL; + } + + if (!WPACKET_sub_memcpy_u16(pkt, encodedPoint, encoded_pt_len) + || !WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(skey); + OPENSSL_free(encodedPoint); + return EXT_RETURN_FAIL; + } OPENSSL_free(encodedPoint); - return EXT_RETURN_FAIL; - } - OPENSSL_free(encodedPoint); - /* This causes the crypto state to be updated based on the derived keys */ - s->s3.tmp.pkey = skey; - if (ssl_derive(s, skey, ckey, 1) == 0) { - /* SSLfatal() already called */ - return EXT_RETURN_FAIL; + /* + * This causes the crypto state to be updated based on the derived keys + */ + s->s3.tmp.pkey = skey; + if (ssl_derive(s, skey, ckey, 1) == 0) { + /* SSLfatal() already called */ + return EXT_RETURN_FAIL; + } + } else { + /* KEM mode */ + unsigned char *ct = NULL; + size_t ctlen = 0; + + /* + * This does not update the crypto state. + * + * The generated pms is stored in `s->s3.tmp.pms` to be later used via + * ssl_gensecret(). + */ + if (ssl_encapsulate(s, ckey, &ct, &ctlen, 0) == 0) { + /* SSLfatal() already called */ + return EXT_RETURN_FAIL; + } + + if (ctlen == 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_INTERNAL_ERROR); + OPENSSL_free(ct); + return EXT_RETURN_FAIL; + } + + if (!WPACKET_sub_memcpy_u16(pkt, ct, ctlen) + || !WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, + ERR_R_INTERNAL_ERROR); + OPENSSL_free(ct); + return EXT_RETURN_FAIL; + } + OPENSSL_free(ct); + + /* + * This causes the crypto state to be updated based on the generated pms + */ + if (ssl_gensecret(s, s->s3.tmp.pms, s->s3.tmp.pmslen) == 0) { + /* SSLfatal() already called */ + return EXT_RETURN_FAIL; + } } return EXT_RETURN_SENT; #else @@ -1863,18 +1915,18 @@ EXT_RETURN tls_construct_stoc_cookie(SSL *s, WPACKET *pkt, unsigned int context, /* HMAC the cookie */ hctx = EVP_MD_CTX_create(); - pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, - s->session_ctx->ext.cookie_hmac_key, - sizeof(s->session_ctx->ext - .cookie_hmac_key)); + pkey = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, + s->session_ctx->ext.cookie_hmac_key, + sizeof(s->session_ctx->ext.cookie_hmac_key)); if (hctx == NULL || pkey == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->propq, pkey, - s->ctx->libctx) <= 0 + if (EVP_DigestSignInit_ex(hctx, NULL, "SHA2-256", s->ctx->libctx, + s->ctx->propq, pkey) <= 0 || EVP_DigestSign(hctx, hmac, &hmaclen, cookie, totcookielen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_COOKIE, diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 4cd85ef609..cb5130c713 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -28,10 +28,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(SSL_COMP) -DEFINE_STACK_OF_CONST(SSL_CIPHER) - static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); @@ -1858,7 +1854,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) } certstart = certbytes; - x = X509_new_with_libctx(s->ctx->libctx, s->ctx->propq); + x = X509_new_ex(s->ctx->libctx, s->ctx->propq); if (x == NULL) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); @@ -2356,7 +2352,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); + SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); goto err; } if (SSL_USE_SIGALGS(s)) @@ -2379,7 +2375,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (EVP_DigestVerifyInit_ex(md_ctx, &pctx, md == NULL ? NULL : EVP_MD_name(md), - s->ctx->propq, pkey, s->ctx->libctx) <= 0) { + s->ctx->libctx, s->ctx->propq, pkey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); goto err; @@ -3068,9 +3064,9 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) { #ifndef OPENSSL_NO_DH DH *dh_clnt = NULL; - const BIGNUM *pub_key; EVP_PKEY *ckey = NULL, *skey = NULL; unsigned char *keybytes = NULL; + int prime_len; skey = s->s3.peer_tmp; if (skey == NULL) { @@ -3100,15 +3096,19 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) } /* send off the data */ - DH_get0_key(dh_clnt, &pub_key, NULL); - if (!WPACKET_sub_allocate_bytes_u16(pkt, BN_num_bytes(pub_key), - &keybytes)) { + prime_len = BN_num_bytes(DH_get0_p(dh_clnt)); + /* + * For interoperability with some versions of the Microsoft TLS + * stack, we need to zero pad the DHE pub key to the same length + * as the prime, so use the length of the prime here. + */ + if (!WPACKET_sub_allocate_bytes_u16(pkt, prime_len, &keybytes) + || BN_bn2binpad(DH_get0_pub_key(dh_clnt), keybytes, prime_len) < 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR); goto err; } - BN_bn2bin(pub_key, keybytes); EVP_PKEY_free(ckey); return 1; diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index 564829c808..8f7ec0c695 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1051,12 +1051,16 @@ int dtls1_buffer_message(SSL *s, int is_ccs) if (!ossl_assert(s->d1->w_msg_hdr.msg_len + ((s->version == DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH) - == (unsigned int)s->init_num)) + == (unsigned int)s->init_num)) { + dtls1_hm_fragment_free(frag); return 0; + } } else { if (!ossl_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) { + dtls1_hm_fragment_free(frag); return 0; + } } frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index d8aab20e92..ef4067a749 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -21,10 +21,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_NAME) -DEFINE_STACK_OF_CONST(SSL_CIPHER) - /* * Map error codes to TLS/SSL alart types. */ @@ -94,6 +90,8 @@ int tls_close_construct_packet(SSL *s, WPACKET *pkt, int htype) int tls_setup_handshake(SSL *s) { + int ver_min, ver_max, ok; + if (!ssl3_init_finished_mac(s)) { /* SSLfatal() already called */ return 0; @@ -102,20 +100,61 @@ int tls_setup_handshake(SSL *s) /* Reset any extension flags */ memset(s->ext.extflags, 0, sizeof(s->ext.extflags)); + if (ssl_get_min_max_version(s, &ver_min, &ver_max, NULL) != 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_SETUP_HANDSHAKE, + ERR_R_INTERNAL_ERROR); + return 0; + } + + /* Sanity check that we have MD5-SHA1 if we need it */ + if (s->ctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { + int md5sha1_needed = 0; + + /* We don't have MD5-SHA1 - do we need it? */ + if (SSL_IS_DTLS(s)) { + if (DTLS_VERSION_LE(ver_max, DTLS1_VERSION)) + md5sha1_needed = 1; + } else { + if (ver_max <= TLS1_1_VERSION) + md5sha1_needed = 1; + } + if (md5sha1_needed) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_SETUP_HANDSHAKE, + SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); + ERR_add_error_data(1, "The max supported SSL/TLS version needs the" + " MD5-SHA1 digest but it is not available" + " in the loaded providers. Use (D)TLSv1.2 or" + " above, or load different providers"); + return 0; + } + + ok = 1; + /* Don't allow TLSv1.1 or below to be negotiated */ + if (SSL_IS_DTLS(s)) { + if (DTLS_VERSION_LT(ver_min, DTLS1_2_VERSION)) + ok = SSL_set_min_proto_version(s, DTLS1_2_VERSION); + } else { + if (ver_min < TLS1_2_VERSION) + ok = SSL_set_min_proto_version(s, TLS1_2_VERSION); + } + if (!ok) { + /* Shouldn't happen */ + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_SETUP_HANDSHAKE, + ERR_R_INTERNAL_ERROR); + return 0; + } + } + + ok = 0; if (s->server) { STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s); - int i, ver_min, ver_max, ok = 0; + int i; /* * Sanity check that the maximum version we accept has ciphers * enabled. For clients we do this check during construction of the * ClientHello. */ - if (ssl_get_min_max_version(s, &ver_min, &ver_max, NULL) != 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_SETUP_HANDSHAKE, - ERR_R_INTERNAL_ERROR); - return 0; - } for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); @@ -277,9 +316,8 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt) goto err; } - if (EVP_DigestSignInit_ex(mctx, &pctx, - md == NULL ? NULL : EVP_MD_name(md), - s->ctx->propq, pkey, s->ctx->libctx) <= 0) { + if (EVP_DigestSignInit_ex(mctx, &pctx, md == NULL ? NULL : EVP_MD_name(md), + s->ctx->libctx, s->ctx->propq, pkey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY, ERR_R_EVP_LIB); goto err; @@ -474,7 +512,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt) if (EVP_DigestVerifyInit_ex(mctx, &pctx, md == NULL ? NULL : EVP_MD_name(md), - s->ctx->propq, pkey, s->ctx->libctx) <= 0) { + s->ctx->libctx, s->ctx->propq, pkey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB); goto err; @@ -962,8 +1000,8 @@ static int ssl_add_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk) chain_store = s->ctx->cert_store; if (chain_store != NULL) { - X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_with_libctx(s->ctx->libctx, - s->ctx->propq); + X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new_ex(s->ctx->libctx, + s->ctx->propq); if (xs_ctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_ADD_CERT_CHAIN, @@ -1367,6 +1405,7 @@ int tls_get_message_body(SSL *s, size_t *len) static const X509ERR2ALERT x509table[] = { {X509_V_ERR_APPLICATION_VERIFICATION, SSL_AD_HANDSHAKE_FAILURE}, {X509_V_ERR_CA_KEY_TOO_SMALL, SSL_AD_BAD_CERTIFICATE}, + {X509_V_ERR_EC_KEY_EXPLICIT_PARAMS, SSL_AD_BAD_CERTIFICATE}, {X509_V_ERR_CA_MD_TOO_WEAK, SSL_AD_BAD_CERTIFICATE}, {X509_V_ERR_CERT_CHAIN_TOO_LONG, SSL_AD_UNKNOWN_CA}, {X509_V_ERR_CERT_HAS_EXPIRED, SSL_AD_CERTIFICATE_EXPIRED}, diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index b329e89379..2da037a248 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -26,10 +26,6 @@ #include #include -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(SSL_COMP) -DEFINE_STACK_OF_CONST(SSL_CIPHER) - #define TICKET_NONCE_SIZE 8 typedef struct { @@ -2809,7 +2805,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) if (EVP_DigestSignInit_ex(md_ctx, &pctx, md == NULL ? NULL : EVP_MD_name(md), - s->ctx->propq, pkey, s->ctx->libctx) <= 0) { + s->ctx->libctx, s->ctx->propq, pkey) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); @@ -3676,7 +3672,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt) } certstart = certbytes; - x = X509_new_with_libctx(s->ctx->libctx, s->ctx->propq); + x = X509_new_ex(s->ctx->libctx, s->ctx->propq); if (x == NULL) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 11eea82fff..91c3904723 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -175,6 +175,18 @@ int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx, return 1; } + +static int tls_iv_length_within_key_block(const EVP_CIPHER *c) +{ + /* If GCM/CCM mode only part of IV comes from PRF */ + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) + return EVP_GCM_TLS_FIXED_IV_LEN; + else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) + return EVP_CCM_TLS_FIXED_IV_LEN; + else + return EVP_CIPHER_iv_length(c); +} + int tls1_change_cipher_state(SSL *s, int which) { unsigned char *p, *mac_secret; @@ -192,16 +204,12 @@ int tls1_change_cipher_state(SSL *s, int which) size_t n, i, j, k, cl; int reuse_dd = 0; #ifndef OPENSSL_NO_KTLS -# ifdef __FreeBSD__ - struct tls_enable crypto_info; -# else - struct tls_crypto_info_all crypto_info; + ktls_crypto_info_t crypto_info; unsigned char *rec_seq; void *rl_sequence; -# ifndef OPENSSL_NO_KTLS_RX +# ifndef OPENSSL_NO_KTLS_RX int count_unprocessed; int bit; -# endif # endif BIO *bio; #endif @@ -341,14 +349,7 @@ int tls1_change_cipher_state(SSL *s, int which) /* TODO(size_t): convert me */ cl = EVP_CIPHER_key_length(c); j = cl; - /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ - /* If GCM/CCM mode only part of IV comes from PRF */ - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - k = EVP_GCM_TLS_FIXED_IV_LEN; - else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) - k = EVP_CCM_TLS_FIXED_IV_LEN; - else - k = EVP_CIPHER_iv_length(c); + k = tls_iv_length_within_key_block(c); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms = &(p[0]); @@ -376,13 +377,22 @@ int tls1_change_cipher_state(SSL *s, int which) memcpy(mac_secret, ms, i); if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { - /* TODO(size_t): Convert this function */ - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, - (int)*mac_secret_size); + if (mac_type == EVP_PKEY_HMAC) { + mac_key = EVP_PKEY_new_raw_private_key_ex(s->ctx->libctx, "HMAC", + s->ctx->propq, mac_secret, + *mac_secret_size); + } else { + /* + * If its not HMAC then the only other types of MAC we support are + * the GOST MACs, so we need to use the old style way of creating + * a MAC key. + */ + mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, + (int)*mac_secret_size); + } if (mac_key == NULL - || EVP_DigestSignInit_ex(mac_ctx, NULL, - EVP_MD_name(m), s->ctx->propq, - mac_key, s->ctx->libctx) <= 0) { + || EVP_DigestSignInit_ex(mac_ctx, NULL, EVP_MD_name(m), + s->ctx->libctx, s->ctx->propq, mac_key) <= 0) { EVP_PKEY_free(mac_key); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); @@ -453,53 +463,9 @@ int tls1_change_cipher_state(SSL *s, int which) if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) goto skip_ktls; -# ifdef __FreeBSD__ - memset(&crypto_info, 0, sizeof(crypto_info)); - switch (s->s3.tmp.new_cipher->algorithm_enc) { - case SSL_AES128GCM: - case SSL_AES256GCM: - crypto_info.cipher_algorithm = CRYPTO_AES_NIST_GCM_16; - crypto_info.iv_len = EVP_GCM_TLS_FIXED_IV_LEN; - break; - case SSL_AES128: - case SSL_AES256: - if (s->ext.use_etm) - goto skip_ktls; - switch (s->s3.tmp.new_cipher->algorithm_mac) { - case SSL_SHA1: - crypto_info.auth_algorithm = CRYPTO_SHA1_HMAC; - break; - case SSL_SHA256: - crypto_info.auth_algorithm = CRYPTO_SHA2_256_HMAC; - break; - case SSL_SHA384: - crypto_info.auth_algorithm = CRYPTO_SHA2_384_HMAC; - break; - default: - goto skip_ktls; - } - crypto_info.cipher_algorithm = CRYPTO_AES_CBC; - crypto_info.iv_len = EVP_CIPHER_iv_length(c); - crypto_info.auth_key = ms; - crypto_info.auth_key_len = *mac_secret_size; - break; - default: - goto skip_ktls; - } - crypto_info.cipher_key = key; - crypto_info.cipher_key_len = EVP_CIPHER_key_length(c); - crypto_info.iv = iv; - crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff; - crypto_info.tls_vminor = (s->version & 0x000000ff); -# else /* !defined(__FreeBSD__) */ /* check that cipher is supported */ - if (!ktls_check_supported_cipher(c, dd)) - goto skip_ktls; - - /* check version */ - if (s->version != TLS1_2_VERSION) + if (!ktls_check_supported_cipher(s, c, dd)) goto skip_ktls; -# endif if (which & SSL3_CC_WRITE) bio = s->wbio; @@ -526,18 +492,17 @@ int tls1_change_cipher_state(SSL *s, int which) goto err; } -# ifndef __FreeBSD__ if (which & SSL3_CC_WRITE) rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); else rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); - if (!ktls_configure_crypto(c, s->version, dd, rl_sequence, &crypto_info, - &rec_seq, iv, key)) + if (!ktls_configure_crypto(s, c, dd, rl_sequence, &crypto_info, &rec_seq, + iv, key, ms, *mac_secret_size)) goto skip_ktls; if (which & SSL3_CC_READ) { -# ifndef OPENSSL_NO_KTLS_RX +# ifndef OPENSSL_NO_KTLS_RX count_unprocessed = count_unprocessed_records(s); if (count_unprocessed < 0) goto skip_ktls; @@ -551,11 +516,10 @@ int tls1_change_cipher_state(SSL *s, int which) } count_unprocessed--; } -# else +# else goto skip_ktls; -# endif +# endif } -# endif /* !__FreeBSD__ */ /* ktls works with user provided buffers directly */ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { @@ -606,7 +570,7 @@ int tls1_setup_key_block(SSL *s) s->s3.tmp.new_hash = hash; s->s3.tmp.new_mac_pkey_type = mac_type; s->s3.tmp.new_mac_secret_size = mac_secret_size; - num = EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c); + num = mac_secret_size + EVP_CIPHER_key_length(c) + tls_iv_length_within_key_block(c); num *= 2; ssl3_cleanup_key_block(s); @@ -621,6 +585,7 @@ int tls1_setup_key_block(SSL *s) s->s3.tmp.key_block = p; OSSL_TRACE_BEGIN(TLS) { + BIO_printf(trc_out, "key block length: %ld\n", num); BIO_printf(trc_out, "client random\n"); BIO_dump_indent(trc_out, s->s3.client_random, SSL3_RANDOM_SIZE, 4); BIO_printf(trc_out, "server random\n"); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index bf955bf3ec..8005f4ee32 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -28,10 +28,6 @@ #include "ssl_local.h" #include -DEFINE_STACK_OF_CONST(SSL_CIPHER) -DEFINE_STACK_OF(X509) -DEFINE_STACK_OF(X509_NAME) - static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey); static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu); @@ -253,6 +249,7 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) TLS_GROUP_INFO *ginf = NULL; EVP_KEYMGMT *keymgmt; unsigned int gid; + unsigned int is_kem = 0; int ret = 0; if (ctx->group_list_max_len == ctx->group_list_len) { @@ -325,6 +322,13 @@ static int add_provider_groups(const OSSL_PARAM params[], void *data) goto err; } + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM); + if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) { + SSLerr(0, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->is_kem = 1 & is_kem; + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS); if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) { SSLerr(0, ERR_R_PASSED_INVALID_ARGUMENT); @@ -3389,7 +3393,7 @@ SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx) return ret; } #endif - mac = EVP_MAC_fetch(ctx->libctx, "HMAC", NULL); + mac = EVP_MAC_fetch(ctx->libctx, "HMAC", ctx->propq); if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL) goto err; EVP_MAC_free(mac); diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index ba385f6ea2..829a6e9be1 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -516,10 +516,8 @@ int tls13_change_cipher_state(SSL *s, int which) const EVP_MD *md = NULL; const EVP_CIPHER *cipher = NULL; #if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) -# ifndef __FreeBSD__ - struct tls_crypto_info_all crypto_info; + ktls_crypto_info_t crypto_info; BIO *bio; -# endif #endif if (which & SSL3_CC_READ) { @@ -784,7 +782,6 @@ int tls13_change_cipher_state(SSL *s, int which) s->statem.enc_write_state = ENC_WRITE_STATE_VALID; #ifndef OPENSSL_NO_KTLS # if defined(OPENSSL_KTLS_TLS13) -# ifndef __FreeBSD__ if (!(which & SSL3_CC_WRITE) || !(which & SSL3_CC_APPLICATION) || ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX))) goto skip_ktls; @@ -798,7 +795,7 @@ int tls13_change_cipher_state(SSL *s, int which) goto skip_ktls; /* check that cipher is supported */ - if (!ktls_check_supported_cipher(cipher, ciph_ctx)) + if (!ktls_check_supported_cipher(s, cipher, ciph_ctx)) goto skip_ktls; bio = s->wbio; @@ -814,15 +811,14 @@ int tls13_change_cipher_state(SSL *s, int which) goto skip_ktls; /* configure kernel crypto structure */ - if (!ktls_configure_crypto(cipher, s->version, ciph_ctx, + if (!ktls_configure_crypto(s, cipher, ciph_ctx, RECORD_LAYER_get_write_sequence(&s->rlayer), - &crypto_info, NULL, iv, key)) + &crypto_info, NULL, iv, key, NULL, 0)) goto skip_ktls; /* ktls works with user provided buffers directly */ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) ssl3_release_write_buffer(s); -# endif skip_ktls: # endif #endif