diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000..0aa1995664591 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", + "include" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000..f211624cdf61c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,31 @@ +{ + "configurations": [ + { + "name": "C/C++: gcc-9 build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}/${fileBasenameNoExtension}", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ], + "preLaunchTask": "C/C++: gcc-9 build active file", + "miDebuggerPath": "/usr/bin/gdb" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000..d94e517de7b01 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,16 @@ +{ + "files.associations": { + "*.in": "c", + "x509_acert.h": "c", + "*.inc": "c", + "typeinfo": "c", + "x509v3.h": "c", + "x509_local.h": "c", + "array": "c", + "string": "c", + "string_view": "c", + "pkcs12.h": "c", + "nelem.h": "c", + "ssl_local.h": "c" + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000000..c6f780dbd9da7 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,29 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc-9 build active file", + "command": "/usr/bin/gcc-9", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}", + "-L${fileDirname}", + "-lcrypto", + "-lssl", + "-Iinclude" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": "build", + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/acert.der b/acert.der new file mode 100644 index 0000000000000..c5fd29ab914de Binary files /dev/null and b/acert.der differ diff --git a/acert.pem b/acert.pem new file mode 100644 index 0000000000000..4ae75c33ea8de --- /dev/null +++ b/acert.pem @@ -0,0 +1,19 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIDCjCB8wIBATAcoRqkGDAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbaAcMBqkGDAW +MRQwEgYDVQQDDAtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAIUIfeqckR0blhi +qXxjCfD1iCzm0z4wIhgPMjAyMzA0MTgyMzU2NDlaGA8yMDI0MDQxNzIzNTY0OVow +aTAWBgNVBCoxDwwNVVRGODpKb25hdGhhbjAUBgNVBAQxDQwLVVRGODpXaWxidXIw +GgYDVQQHMRMMEVVURjg6SmFja3NvbnZpbGxlMBAGA1UECDEJDAdVVEY4OkZMMAsG +A1UEBjEEEwJVUzANBgkqhkiG9w0BAQsFAAOCAgEAcrhnHFqrMjpHAbMvqkGyYKbx +cytD2Ih5ag5nj+TNBZYQPA6qzTOAs4DFbRFX8VWvVDTYI6+xD2iB4xnlKPd55d+P +dnBGHaOprwGKGJitYUdz/j9NKs308gCMfXMBmDT7WaABmqy3wljI70XX1kW1mD/8 +fmtT8WCeXejkuPXjQ7jVN0SM25JSAh8pOwBnY8QPNBxIpNMspOBmjUYIFT3O2AZ4 +YF+Eeh1ZRIWfaIhWuWL79bLSCuyFYRo+1H5sO+UhuQ5X3hHN9m6wPEbWf4Sv9Rni +Yl5aZBwjJiDWfOotH1rHV39G2nBE2epLXVADdjCORcSsu45zwTtT/dvvStlcHLKg +VL4tdDo6RS6Ek9Q1BO8sL6Hvku4v9AMj5AqjaBCPDaXMyeZT+qfRsfEBmJ9sEP/M +myWqw1YXA6+uekz08WvIlJfLN8+0gPPKM8Y6GA2eHD/mDWnpHnQoxseqL2iXQv7B ++fUgPYM2kqjgjHHaU35bf7W4R199KtKkHonWQFudvRlpudkOUaJOfWrarQTWwB+v +ifBWM1NX9d0HkkbFeJKEP/TnMXM/IiynMG9h1VPFeSWaaYLdLPqntxDctC779HU6 +RTluvNcgVmgCEI2C1VLZPGMpWjeyRQ+8HWUqI7AjZTibrvDBIn4MnhqdBE6U3v2W +dAvn/XDvXxFvLvZCj0E= +-----END ATTRIBUTE CERTIFICATE----- diff --git a/acert2.pem b/acert2.pem new file mode 100644 index 0000000000000..4069788e245ee --- /dev/null +++ b/acert2.pem @@ -0,0 +1,19 @@ +-----BEGIN ATTRIBUTE CERTIFICATE----- +MIIDIzCCAQsCAQEwNKAyMBqkGDAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbQIUWr/i +wNOOpTyBFzhXwVolFRlafNigHDAapBgwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20w +DQYJKoZIhvcNAQELBQACFGMX9ix+t36jUBDLqXulnn6+CjBkMCIYDzIwMjMwNTE4 +MTIxODU5WhgPMjAyMzA3MTcxMjE4NTlaMGkwFgYDVQQqMQ8MDVVURjg6Sm9uYXRo +YW4wFAYDVQQEMQ0MC1VURjg6V2lsYnVyMBoGA1UEBzETDBFVVEY4OkphY2tzb252 +aWxsZTAQBgNVBAgxCQwHVVRGODpGTDALBgNVBAYxBBMCVVMwDQYJKoZIhvcNAQEL +BQADggIBAAhhEHyeIQqJEjVnym995B0mCtN2Xe1LZ/dhEDVihV0SKhEM7+IkVgmn +KIIxzzFdILUFArpDrSasSzdKxhPgdFh1pSaOjEfjDw5OLFafvv+Exk7AB8xNZUKZ +YEOZ6mIk+2MyOmkt19/FDw+0RvmN8su/Kg6RGy19+e7ctuKzjN6CCq2GaOiydSSd +wBI6aXaXN+B1uSl5FcMiybYUCZ6AH5A0bDMykz3Ow4q98s5iwEEqtchSRP9Atjgz +cKwp7AxqWiafAu0aXSx7Pb+aEkvGT6pokb0yAYjqLg+IaDMQ8DyJde9bheA70zCX +rZut3vafEdQWJLdNCodNIpyHJ/uicson8Vx3zWPEtJ1uIIq7gb6K+DCdwetqW7gH +/VmI+zLcDWk029974QPijiKPCO6pI+jJAsvbN6aAid5sIxNeOguVxzd9pLgv4aKX +qfEqWHMIHh4M41+W4na2nL6IjsWB6nyznPcIs69i7k2wx8Jr0JustCP17xLlNx4W +6BhJjhPHKEuCWDQZ/anF752IG3FB30GWfSGx17S8+v0WfWAMcoyqMorx9d/HC8M1 +j+uFc29vfOdxXDEi9Lv/zvn6cc7uazQ2K2NttOvHjIjzvaN7PovqWKSjmh7CjNM8 +T/9/brhtZgZJfyPl5yftliEbSCLLVq2X2J9B30He1JaIJT8UhwwD +-----END ATTRIBUTE CERTIFICATE----- diff --git a/apps/acert.c b/apps/acert.c new file mode 100644 index 0000000000000..9adecbbbdf354 --- /dev/null +++ b/apps/acert.c @@ -0,0 +1,769 @@ +/* + * Copyright 2021 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 +#ifdef OPENSSL_SYS_WINDOWS +# define timegm _mkgmtime +#else +# ifndef _DEFAULT_SOURCE +# define _DEFAULT_SOURCE /* for timegm() from time.h */ +# endif +#endif + +#include +#include +#include +#include +#include +#include "apps.h" +#include "progs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ATTRIBUTES "attributes" +#define V3_EXTENSIONS "extensions" +#define UTF8_IN "utf8" + +#define DEFAULT_KEY_LENGTH 2048 +#define MIN_KEY_LENGTH 512 +#define DEFAULT_DAYS 1 /* default cert validity period in days */ + +static int make_ACERT(X509_ACERT *acert, X509 *holder, + X509 *issuer, int holder_name, int holder_basecertid); +static int set_acert_validity(X509_ACERT *acert, char *notBefore, + char *notAfter, int days); +static int add_config_attributes(CONF *conf, X509_ACERT *acert, + unsigned long chtype); + +static const char *section = "acert"; +static CONF *acert_conf = NULL; +static CONF *addext_conf = NULL; + +typedef enum OPTION_choice { + OPT_COMMON, + OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, + OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT, + OPT_SIGOPT, OPT_VERIFY, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, + OPT_NAMEOPT, OPT_HOLDER, OPT_CERTOPT, OPT_TEXT, + OPT_HOLDER_BASECERTID, OPT_HOLDER_NAME, + OPT_AA, OPT_AAKEY, OPT_PASSIN, + OPT_DAYS, OPT_SET_SERIAL, OPT_STARTDATE, OPT_ENDDATE, + OPT_ADDEXT, OPT_ACERTEXTS, + OPT_SECTION, + OPT_PROV_ENUM, OPT_MD, + OPT_ASSERTED_BEFORE, OPT_TARGET_CERT +} OPTION_CHOICE; + +const OPTIONS acert_options[] = { + OPT_SECTION("General"), + {"help", OPT_HELP, '-', "Display this summary"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif + {"in", OPT_IN, '<', "attribute certificate input file"}, + {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"}, + {"verify", OPT_VERIFY, '-', "Verify signature on the attribue certificate"}, + + OPT_SECTION("Certificate"), + {"new", OPT_NEW, '-', "New Attribute Certificate"}, + {"config", OPT_CONFIG, '<', "Attribute certificate template file"}, + {"section", OPT_SECTION, 's', "Config section to use (default \"acert\")"}, + {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, + {"nameopt", OPT_NAMEOPT, 's', "Certificate holder/issuer name printing options"}, + {"certopt", OPT_CERTOPT, 's', "Various certificate text printing options"}, + {"text", OPT_TEXT, '-', "Text form of request"}, + {"AA", OPT_AA, '<', "Attribtue authority (issuer) certificate to use"}, + {"AAkey", OPT_AAKEY, 's', + "Attribute authority Issuer private key to use; default is -AA arg"}, + {"keyform", OPT_KEYFORM, 'f', "File format of AAkey"}, + {"passin", OPT_PASSIN, 's', "Private key and cert file pass-phrase source"}, + {"holder", OPT_HOLDER, '<', "Attribute holder certificate"}, + {"use-holder-basecertid", OPT_HOLDER_BASECERTID, '-', + "Specify holder certificate using base certifiate id (default)"}, + {"use-holder-name", OPT_HOLDER_NAME, '-', + "Specify holder certificate using certificate subject name"}, + {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYYYMMDDHHMMSSZ"}, + {"enddate", OPT_ENDDATE, 's', + "YYYYMMDDHHMMSSZ cert notAfter (overrides -days)"}, + {"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', + "Additional cert extension key=value pair (may be given more than once)"}, + {"acertexts", OPT_ACERTEXTS, 's', + "Attribute certificate extension section (override value in config file)"}, + {"asserted-before", OPT_ASSERTED_BEFORE, '-', + "Fail verification if the attribute certificate contains the singleUse extension."}, + {"target-cert", OPT_TARGET_CERT, '<', + "The target certificate path to check against the targetingInformation extension"}, + + OPT_SECTION("Signing"), + {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, + {"", OPT_MD, '-', "Any supported digest, used for signing and printing"}, + + OPT_SECTION("Output"), + {"out", OPT_OUT, '>', "Output file"}, + {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"}, + {"verbose", OPT_VERBOSE, '-', "Verbose output"}, + {"noout", OPT_NOOUT, '-', "Do not output attribute certificate"}, + + OPT_PROV_OPTIONS, + {NULL} +}; + +/* + * An LHASH of strings, where each string is an extension name. + */ +static unsigned long ext_name_hash(const OPENSSL_STRING *a) +{ + return OPENSSL_LH_strhash((const char *)a); +} + +static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b) +{ + return strcmp((const char *)a, (const char *)b); +} + +static void exts_cleanup(OPENSSL_STRING *x) +{ + OPENSSL_free((char *)x); +} + +/* + * Is the |kv| key already duplicated? This is remarkably tricky to get right. + * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error. + */ +static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv) +{ + char *p; + size_t off; + + /* Check syntax. */ + /* Skip leading whitespace, make a copy. */ + while (*kv && isspace(*kv)) + if (*++kv == '\0') + return 1; + if ((p = strchr(kv, '=')) == NULL) + return 1; + off = p - kv; + if ((kv = OPENSSL_strdup(kv)) == NULL) + return -1; + + /* Skip trailing space before the equal sign. */ + for (p = kv + off; p > kv; --p) + if (!isspace(p[-1])) + break; + if (p == kv) { + OPENSSL_free(kv); + return 1; + } + *p = '\0'; + + /* Finally have a clean "key"; see if it's there [by attempt to add it]. */ + p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING *)kv); + if (p != NULL) { + OPENSSL_free(p); + return 1; + } else if (lh_OPENSSL_STRING_error(addexts)) { + OPENSSL_free(kv); + return -1; + } + + return 0; +} + +int acert_main(int argc, char **argv) +{ + ASN1_INTEGER *serial = NULL; + BIO *out = NULL; + ENGINE *e = NULL; + EVP_PKEY *AAkey = NULL; + EVP_PKEY_CTX *genctx = NULL; + STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL; + LHASH_OF(OPENSSL_STRING) *addexts = NULL; + X509 *AAcert = NULL, *holder = NULL, *target_x509 = NULL; + TARGET_CERT *target_cert = NULL; + OSSL_ISSUER_SERIAL *target_iss_ser = NULL; + GENERAL_NAME *target_cert_name = NULL; + TARGET *target = NULL; + X509_ACERT *acert = NULL; + BIO *addext_bio = NULL; + const char *infile = NULL, *AAfile = NULL, *AAkeyfile = NULL; + const char *holderfile = NULL, *targetfile = NULL; + int hldr_basecertid = 0, hldr_entity = 0; + char *outfile = NULL, *digest = NULL; + char *keyalgstr = NULL, *p, *prog; + char *passin = NULL, *passinarg = NULL; + char *acert_exts = NULL; + X509_NAME *fsubj = NULL, *target_subj = NULL; + char *template = default_config_file; + OPTION_CHOICE o; + int days = DEFAULT_DAYS; + int ret = 1, i = 0, newacert = 0, verbose = 0, asserted_before = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_UNDEF; + int verify = 0, noout = 0, text = 0; + unsigned long chtype = MBSTRING_ASC, certflag = 0; + char *startdate = NULL, *enddate = NULL; + + opt_set_unknown_name("digest"); + prog = opt_init(argc, argv, acert_options); + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(acert_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) + goto opthelp; + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) + goto opthelp; + break; + case OPT_ENGINE: + e = setup_engine(opt_arg(), 0); + break; + case OPT_NEW: + newacert = 1; + break; + case OPT_CONFIG: + template = opt_arg(); + break; + case OPT_SECTION: + section = opt_arg(); + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_PROV_CASES: + if (!opt_provider(o)) + goto end; + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_SIGOPT: + if (!sigopts) + sigopts = sk_OPENSSL_STRING_new_null(); + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) + goto opthelp; + break; + case OPT_VERIFY: + verify = 1; + break; + case OPT_NOOUT: + noout = 1; + break; + case OPT_VERBOSE: + verbose = 1; + break; + case OPT_UTF8: + chtype = MBSTRING_UTF8; + break; + case OPT_NAMEOPT: + if (!set_nameopt(opt_arg())) + goto opthelp; + break; + case OPT_CERTOPT: + if (!set_cert_ex(&certflag, opt_arg())) + goto opthelp; + break; + case OPT_TEXT: + text = 1; + break; + case OPT_HOLDER: + holderfile = opt_arg(); + break; + case OPT_HOLDER_BASECERTID: + hldr_basecertid = 1; + break; + case OPT_HOLDER_NAME: + hldr_entity = 1; + break; + case OPT_AA: + AAfile = opt_arg(); + break; + case OPT_AAKEY: + AAkeyfile = opt_arg(); + break; + case OPT_STARTDATE: + startdate = opt_arg(); + break; + case OPT_ENDDATE: + enddate = opt_arg(); + break; + case OPT_ASSERTED_BEFORE: + asserted_before = 1; + break; + case OPT_TARGET_CERT: + targetfile = opt_arg(); + break; + case OPT_DAYS: + days = atoi(opt_arg()); + if (days < -1) { + BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n", + prog); + goto end; + } + break; + case OPT_SET_SERIAL: + if (serial != NULL) { + BIO_printf(bio_err, "Serial number supplied twice\n"); + goto opthelp; + } + serial = s2i_ASN1_INTEGER(NULL, opt_arg()); + if (serial == NULL) + goto opthelp; + break; + case OPT_ADDEXT: + p = opt_arg(); + if (addexts == NULL) { + addexts = lh_OPENSSL_STRING_new(ext_name_hash, ext_name_cmp); + addext_bio = BIO_new(BIO_s_mem()); + if (addexts == NULL || addext_bio == NULL) + goto end; + } + i = duplicated(addexts, p); + if (i == 1) { + BIO_printf(bio_err, "Duplicate extension: %s\n", p); + goto opthelp; + } + if (i < 0 || BIO_printf(addext_bio, "%s\n", p) < 0) + goto end; + break; + case OPT_ACERTEXTS: + acert_exts = opt_arg(); + break; + case OPT_MD: + digest = opt_unknown(); + break; + } + } + + /* No extra arguments. */ + argc = opt_num_rest(); + if (argc != 0) + goto opthelp; + + if (!app_passwd(passinarg, NULL, &passin, NULL)) { + BIO_printf(bio_err, "Error getting passwords\n"); + goto end; + } + + if ((acert_conf = app_load_config_verbose(template, verbose)) == NULL) + goto end; + if (addext_bio != NULL) { + if (verbose) + BIO_printf(bio_err, + "Using additional configuration from -addext options\n"); + if ((addext_conf = app_load_config_bio(addext_bio, NULL)) == NULL) + goto end; + } + if (template != default_config_file && !app_load_modules(acert_conf)) + goto end; + + if (acert_conf != NULL) { + p = NCONF_get_string(acert_conf, NULL, "oid_file"); + if (p == NULL) + ERR_clear_error(); + if (p != NULL) { + BIO *oid_bio; + + oid_bio = BIO_new_file(p, "r"); + if (oid_bio == NULL) { + if (verbose) { + BIO_printf(bio_err, + "Problems opening '%s' for extra OIDs\n", p); + ERR_print_errors(bio_err); + } + } else { + OBJ_create_objects(oid_bio); + BIO_free(oid_bio); + } + } + } + if (!add_oid_section(acert_conf)) + goto end; + + if (digest == NULL) { + p = NCONF_get_string(acert_conf, section, "default_md"); + if (p == NULL) + ERR_clear_error(); + else + digest = p; + } + + if (addext_conf != NULL) { + /* Check syntax of command line extensions */ + X509V3_CTX ctx; + + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, addext_conf); + if (!X509V3_EXT_ACERT_add_nconf(addext_conf, &ctx, "default", NULL)) { + BIO_printf(bio_err, "Error checking extensions defined using -addext\n"); + goto end; + } + } + + if (chtype != MBSTRING_UTF8) { + p = NCONF_get_string(acert_conf, section, UTF8_IN); + if (p == NULL) + ERR_clear_error(); + else if (strcmp(p, "yes") == 0) + chtype = MBSTRING_UTF8; + } + + if (acert_exts == NULL) { + acert_exts = NCONF_get_string(acert_conf, section, V3_EXTENSIONS); + if (acert_exts == NULL) + ERR_clear_error(); + } + if (acert_exts != NULL) { + /* Check syntax of file */ + X509V3_CTX ctx; + + X509V3_set_ctx_test(&ctx); + X509V3_set_nconf(&ctx, acert_conf); + if (!X509V3_EXT_ACERT_add_nconf(acert_conf, &ctx, acert_exts, NULL)) { + BIO_printf(bio_err, + "Error checking request extension section %s\n", + acert_exts); + goto end; + } + } + + if (!newacert) { + BIO *in; + in = bio_open_default(infile, 'r', informat); + if (informat == FORMAT_ASN1) + acert = d2i_X509_ACERT_bio(in, NULL); + else if (informat == FORMAT_PEM) + acert = PEM_read_bio_X509_ACERT(in, NULL, NULL, NULL); + else + print_format_error(informat, OPT_FMT_PEMDER); + + BIO_free(in); + if (acert == NULL) + goto end; + } else { + if (AAkeyfile == NULL) + AAkeyfile = AAfile; + if (AAkeyfile != NULL) { + if (AAfile == NULL) { + BIO_printf(bio_err, + "Ignoring -AAkey option since -AA is not given\n"); + } else { + if ((AAkey = load_key(AAkeyfile, FORMAT_UNDEF, 0, passin, e, + "issuer private key")) == NULL) + goto end; + } + } + } + + if (AAfile != NULL) { + if ((AAcert = load_cert_pass(AAfile, FORMAT_UNDEF, 1, passin, + "issuer certificate")) == NULL) + goto end; + if (AAkey && !X509_check_private_key(AAcert, AAkey)) { + BIO_printf(bio_err, + "Issuer certificate and key do not match\n"); + goto end; + } + } + + if (holderfile) { + if ((holder = load_cert_pass(holderfile, FORMAT_UNDEF, 1, passin, + "holder certificate")) == NULL) + goto end; + } + + if (newacert) { + X509V3_CTX ext_ctx; + + if (holder == NULL) { + BIO_printf(bio_err, + "Must specify 'holder' to create new certificate\n"); + goto end; + } + + if (AAcert == NULL) { + BIO_printf(bio_err, + "Must specify 'AA' to create new certificate\n"); + goto end; + } + + /* TODO: _ex variant not implented yet */ + acert = X509_ACERT_new(); + if (acert == NULL) { + goto end; + } + + if ((hldr_entity == 0) && (hldr_basecertid == 0)) + hldr_basecertid = 1; + + if (!make_ACERT(acert, holder, AAcert, hldr_entity, hldr_basecertid)) { + BIO_printf(bio_err, "Error making attribute certificate\n"); + goto end; + } + + if (serial != NULL) { + if (!X509_ACERT_set1_serialNumber(acert, serial)) + goto end; + } else { + if (!rand_serial(NULL, X509_ACERT_get0_serialNumber(acert))) + goto end; + } + + if (!set_acert_validity(acert, startdate, enddate, days)) { + BIO_printf(bio_err, "Invalid validity period start(%s) or end(%s)\n", + startdate, enddate); + goto end; + } + + /* Set up V3 context struct */ + X509V3_set_ctx(&ext_ctx, AAcert, + NULL, NULL, NULL, X509V3_CTX_REPLACE); + + if (acert_exts != NULL + && !X509V3_EXT_ACERT_add_nconf(acert_conf, &ext_ctx, + acert_exts, acert)) { + BIO_printf(bio_err, "Error adding extensions from section %s\n", + acert_exts); + goto end; + } + + if (addext_conf != NULL + && !X509V3_EXT_ACERT_add_nconf(addext_conf, &ext_ctx, "default", + acert)) { + BIO_printf(bio_err, "Error adding extensions defined via -addext\n"); + goto end; + } + + if (!add_config_attributes(acert_conf, acert, chtype)) + goto end; + + if (!do_X509_ACERT_sign(acert, AAkey, digest, sigopts)) + goto end; + } + + if (verify) { + if (targetfile) { + if ((target_x509 = load_cert_pass(targetfile, FORMAT_UNDEF, 1, passin, + "target certificate")) == NULL) + goto end; + target_iss_ser = OSSL_ISSUER_SERIAL_new(); + if (OSSL_ISSUER_SERIAL_set1_issuer(target_iss_ser, X509_get_issuer_name(target_x509)) == 0) + goto end; + if (OSSL_ISSUER_SERIAL_set1_serial(target_iss_ser, X509_get_serialNumber(target_x509)) == 0) + goto end; + + target_cert_name = GENERAL_NAME_new(); + target_subj = X509_NAME_dup(X509_get_subject_name(target_x509)); + if (target_subj == NULL) + goto end; + GENERAL_NAME_set0_value(target_cert_name, GEN_DIRNAME, target_subj); + target_cert = TARGET_CERT_new(); + target_cert->targetCertificate = target_iss_ser; + target_cert->targetName = target_cert_name; + target = TARGET_new(); + target->type = TGT_TARGET_CERT; + target->choice.targetCert = target_cert; + } + ret = X509_attr_cert_verify_ex(acert, AAcert, holder, target, asserted_before); + if (ret != X509_V_OK) { + BIO_printf(bio_err, "Attribute certificate is invalid.\n"); + goto end; + } else { + BIO_printf(bio_err, "Attribute certificate is valid.\n"); + } + } + + if (noout && !text) { + ret = 0; + goto end; + } + + out = bio_open_default(outfile, 'w', outformat); + if (out == NULL) + goto end; + + if (text) { + ret = X509_ACERT_print_ex(out, acert, get_nameopt(), certflag); + if (ret == 0) { + BIO_printf(bio_err, "Error printing attribute certificate\n"); + } + } + + if (!noout) { + if (outformat == FORMAT_ASN1) + i = i2d_X509_ACERT_bio(out, acert); + else + i = PEM_write_bio_X509_ACERT(out, acert); + if (!i) { + BIO_printf(bio_err, "Unable to write attribute certificate\n"); + goto end; + } + } + ret = 0; + end: + if (ret) { + ERR_print_errors(bio_err); + } + NCONF_free(acert_conf); + NCONF_free(addext_conf); + BIO_free(addext_bio); + BIO_free_all(out); + EVP_PKEY_CTX_free(genctx); + sk_OPENSSL_STRING_free(pkeyopts); + sk_OPENSSL_STRING_free(sigopts); + lh_OPENSSL_STRING_doall(addexts, exts_cleanup); + lh_OPENSSL_STRING_free(addexts); + OPENSSL_free(keyalgstr); + X509_ACERT_free(acert); + X509_NAME_free(fsubj); + X509_free(holder); + X509_free(AAcert); + EVP_PKEY_free(AAkey); + ASN1_INTEGER_free(serial); + release_engine(e); + return ret; +} + +static int add_config_attributes(CONF *conf, X509_ACERT *acert, + unsigned long chtype) +{ + char *attr_sect; + attr_sect = NCONF_get_string(conf, section, ATTRIBUTES); + if (attr_sect == NULL) { + ERR_clear_error(); + return 1; + } + + if (!X509_ACERT_add_attr_nconf(conf, attr_sect, chtype, acert)) { + BIO_printf(bio_err, + "Unable to add attributes from section '%s'\n", attr_sect); + return 0; + } + return 1; +} + +static int make_ACERT(X509_ACERT *acert, X509 *holder, + X509 *issuer, int holder_name, int holder_basecertid) +{ + int ret = 0; + OSSL_ISSUER_SERIAL *isss = NULL; + GENERAL_NAMES *names = NULL; + GENERAL_NAME *name = NULL; + X509_NAME *holder_subj = NULL; + + if (!X509_ACERT_set_version(acert, X509_ACERT_VERSION_2)) + goto err; + + if (holder_basecertid == 1) { + isss = OSSL_ISSUER_SERIAL_new(); + if (OSSL_ISSUER_SERIAL_set1_issuer(isss, X509_get_issuer_name(holder)) == 0) + goto err; + + if (OSSL_ISSUER_SERIAL_set1_serial(isss, X509_get_serialNumber(holder)) == 0) + goto err; + + X509_ACERT_set0_holder_baseCertId(acert, isss); + } + + if (holder_name == 1) { + holder_subj = X509_NAME_dup(X509_get_subject_name(holder)); + if (holder_subj == NULL) + goto err; + + names = sk_GENERAL_NAME_new_null(); + if (names == NULL) + goto err; + + name = GENERAL_NAME_new(); + if (name == NULL) + goto err; + + if (sk_GENERAL_NAME_push(names, name) <= 0) + goto err; + + GENERAL_NAME_set0_value(name, GEN_DIRNAME, holder_subj); + X509_ACERT_set0_holder_entityName(acert, names); + } + + if (X509_ACERT_set1_issuerName(acert, X509_get_subject_name(issuer)) == 0) + goto err; + + return 1; + err: + OSSL_ISSUER_SERIAL_free(isss); + GENERAL_NAME_free(name); + GENERAL_NAMES_free(names); + X509_NAME_free(holder_subj); + return ret; +} + +static int set_acert_validity(X509_ACERT *acert, char *notBefore, + char *notAfter, int days) +{ + int ret = 0; + ASN1_GENERALIZEDTIME *tmp_time; + + tmp_time = ASN1_GENERALIZEDTIME_new(); + if (tmp_time == NULL) + return 0; + + if (notBefore) { + if (!ASN1_GENERALIZEDTIME_set_string(tmp_time, notBefore)) + goto err; + } else { + time_t now = time(NULL); + if (!ASN1_GENERALIZEDTIME_set(tmp_time, now)) + goto err; + } + X509_ACERT_set1_notBefore(acert, tmp_time); + + if (notAfter) { + if (!ASN1_GENERALIZEDTIME_set_string(tmp_time, notAfter)) + goto err; + } else { + struct tm tm; + time_t start_tm; + ASN1_TIME_to_tm(tmp_time, &tm); + start_tm = timegm(&tm); + if (!X509_time_adj_ex(tmp_time, days, 0, &start_tm)) + goto err; + } + X509_ACERT_set1_notAfter(acert, tmp_time); + + ret = 1; +err: + ASN1_GENERALIZEDTIME_free(tmp_time); + return ret; +} \ No newline at end of file diff --git a/apps/build.info b/apps/build.info index 020d129f8cacc..49878a154b936 100644 --- a/apps/build.info +++ b/apps/build.info @@ -12,7 +12,7 @@ ENDIF # Source for the 'openssl' program $OPENSSLSRC=\ openssl.c \ - asn1parse.c ca.c ciphers.c crl.c crl2pkcs7.c dgst.c \ + acert.c asn1parse.c ca.c ciphers.c crl.c crl2pkcs7.c dgst.c \ enc.c errstr.c \ genpkey.c kdf.c mac.c nseq.c passwd.c pkcs7.c \ pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \ diff --git a/apps/include/apps.h b/apps/include/apps.h index b48937a8c2aac..1c1ddce42e3cf 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -348,4 +348,7 @@ void app_providers_cleanup(void); EVP_PKEY *app_keygen(EVP_PKEY_CTX *ctx, const char *alg, int bits, int verbose); EVP_PKEY *app_paramgen(EVP_PKEY_CTX *ctx, const char *alg); +int do_X509_ACERT_sign(X509_ACERT *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts); + #endif diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 4a749b0df3479..2ab2690585696 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -3428,3 +3428,16 @@ int opt_legacy_okay(void) return 0; return 1; } + +/* Sign the attribute certificate info */ +int do_X509_ACERT_sign(X509_ACERT *x, EVP_PKEY *pkey, const char *md, + STACK_OF(OPENSSL_STRING) *sigopts) +{ + int rv = 0; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + + if (do_sign_init(mctx, pkey, md, sigopts) > 0) + rv = (X509_ACERT_sign_ctx(x, mctx) > 0); + EVP_MD_CTX_free(mctx); + return rv; +} diff --git a/build.info b/build.info index 5a8421623b976..70bde8a47fc18 100644 --- a/build.info +++ b/build.info @@ -39,6 +39,7 @@ DEPEND[]=include/openssl/asn1.h \ include/openssl/ui.h \ include/openssl/x509.h \ include/openssl/x509v3.h \ + include/openssl/x509_acert.h \ include/openssl/x509_vfy.h \ include/crypto/bn_conf.h include/crypto/dso_conf.h @@ -69,6 +70,7 @@ GENERATE[include/openssl/ssl.h]=include/openssl/ssl.h.in GENERATE[include/openssl/ui.h]=include/openssl/ui.h.in GENERATE[include/openssl/x509.h]=include/openssl/x509.h.in GENERATE[include/openssl/x509v3.h]=include/openssl/x509v3.h.in +GENERATE[include/openssl/x509_acert.h]=include/openssl/x509_acert.h.in GENERATE[include/openssl/x509_vfy.h]=include/openssl/x509_vfy.h.in GENERATE[include/crypto/bn_conf.h]=include/crypto/bn_conf.h.in GENERATE[include/crypto/dso_conf.h]=include/crypto/dso_conf.h.in diff --git a/cert-file.pem b/cert-file.pem new file mode 100644 index 0000000000000..2ead433303ab4 --- /dev/null +++ b/cert-file.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFDTCCAvWgAwIBAgIUWr/iwNOOpTyBFzhXwVolFRlafNgwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjMwMzI0MTg1NDA3WhcNMzMw +MzIxMTg1NDA3WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAL0O9ywvmyEKR2RPr5UWM22V7ugvsHrMTndHN48O +oClONTqSFLWp4BB558yfMHGRXi9b4Q5qIHF9OQY4udnimjmq/IRCH24QHHSgbd8P +oFS8ZXyHdJBFclp83VjPWtltd5rBTpSx7TYhEXrjHGLT76ewCrrUT2C1IlNJBmGD +8nU0M0QAGjP/fewAiRbcLSsKRugIpIIuIIA0OwTg2Jhrzt8elkrrZDML6hxHtCA2 +F4WBJwEbYWYJ5u6+MUp+b04UhA5mEBJbjYr123El3Y2MTawfyuMuojqrnZIvPN1M +dibQ6rjFsMjeYMqSTj9Dur2cLll0VwwGmwTfNEIkCclT4an+r5+MKj7iZ+iVykl9 +GsW4uLGeMzRFcVMJZnGrOoLJElAX9I2Wv4FksBtdVQ2WLL17DI5Vf2Cfp8Vf9bN6 +6InKJIR9MF6MGep7fgIA237nvpGn+EQjQmwuvn+RMomJLAFSgli1cHYsoyRuyJtw +VnJqNGH9l9v6cauUz+NK7qN3hwdwAxrzeq6hgqVofvgD4e+ZqX326+qW+l4lqnW+ +dH66wvItfaIb2LUJpYxdi90wAkNJMzk220SPjQmPXZH4Xe+wYX+bfMCvCGxNt1xP +d8GT2qkImrTPQu0fnwg1/HpExFbnNboIRsQ+WGr+oIvJMfTBogy8Ex/KEY9cPuGy +rYjtAgMBAAGjUzBRMB0GA1UdDgQWBBSXlHNfpenxrgoi4VtoW0wfow0QizAfBgNV +HSMEGDAWgBSXlHNfpenxrgoi4VtoW0wfow0QizAPBgNVHRMBAf8EBTADAQH/MA0G +CSqGSIb3DQEBCwUAA4ICAQBa+SvNbu/s5Q7yG3OfnH9Ja9Qyi7mMZJYgE8FGxa1j +n/S5rzcrkIu02xRjM53Af3o9D7MIeEyVjPHYpKwKTpES92md2ZaUeiyfP9UP/5NW +9kJGBwFjIHL6rlKJucwsrlFzn+qSnrKGfANEqvv5GG+iJx+4SREUZgzBn5JZM8Wy +5rxpab+Pd1LObbVb5+kw6/95X/fHddONdz3vFYy9d0jQun0X7nFtqn8NMvO8MkjM +TqQr+SW5c2oYEDEooWrT+8eDwEGMBLZoGIXntGwfz977MNS4G7WsbQXlvy6xZyqG +kibH4J678NYhlVUwAL1BvlhSm+S3YaOo6imvdxIYPpy+uKYhH5IectZdWbyYI69o +qXRK9N/lmMuTlAnTmK8SkAeRHb0QfuUOIcY2bbMhGkzqH/DZemno5fidezliMAp8 +xBVjd0nvgPkLofteaGGhQmiBd1Eew5uhF5MuGyro+b9hR6Glcyy2csuFvZlX9tWW +FJKW6awhJyyhNAsfeYs4iGcYpgeSnv3Y1XT2q43okq56tC27ztnGwy+gAywIm8ug +0BQzA3e6+sxUA30cYlq/2zazcIu/K0DZxQJHdBmQtHWukL7l/udKHDI/pe7OHfJR +5v19zCuaXNY9PcPd+aNAlRn/hxt17uhi39sSuBYacqIilLQ/GByvlWiOxqNQJ1BS +Kg== +-----END CERTIFICATE----- diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index 0ef83307722b2..03d59485d2d90 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -804,3 +804,16 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) { return ossl_obj_obj2nid(a, 1); } + +int print_oid (BIO *out, ASN1_OBJECT *oid) { + const char *ln; + char objbuf[80]; + + if (OBJ_obj2txt(objbuf, sizeof(objbuf), oid, 1) <= 0) { + return 0; + } + ln = OBJ_nid2ln(OBJ_obj2nid(oid)); + return (ln != NULL) + ? BIO_printf(out, "%s (%s)", objbuf, ln) + : BIO_printf(out, "%s", objbuf); +} diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 3f90b7765f846..b866453f67df6 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by crypto/objects/obj_dat.pl * - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 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 @@ -10,7 +10,7 @@ */ /* Serialized OID's */ -static const unsigned char so[8364] = { +static const unsigned char so[8717] = { 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 */ @@ -1153,9 +1153,89 @@ static const unsigned char so[8364] = { 0x60,0x86,0x48,0x01,0x86,0xF9,0x66,0xAD,0xCA,0x7B,0x01,0x01, /* [ 8332] OBJ_oracle_jdk_trustedkeyusage */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x32, /* [ 8344] OBJ_id_ct_signedTAL */ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x0A, /* [ 8355] OBJ_sm4_xts */ + 0x55,0x1D,0x26, /* [ 8363] OBJ_authority_attribute_identifier */ + 0x55,0x1D,0x27, /* [ 8366] OBJ_role_spec_cert_identifier */ + 0x55,0x1D,0x29, /* [ 8369] OBJ_basic_att_constraints */ + 0x55,0x1D,0x2A, /* [ 8372] OBJ_delegated_name_constraints */ + 0x55,0x1D,0x2B, /* [ 8375] OBJ_time_specification */ + 0x55,0x1D,0x30, /* [ 8378] OBJ_attribute_descriptor */ + 0x55,0x1D,0x31, /* [ 8381] OBJ_user_notice */ + 0x55,0x1D,0x32, /* [ 8384] OBJ_soa_identifier */ + 0x55,0x1D,0x34, /* [ 8387] OBJ_acceptable_cert_policies */ + 0x55,0x1D,0x39, /* [ 8390] OBJ_acceptable_privilege_policies */ + 0x55,0x1D,0x3D, /* [ 8393] OBJ_indirect_issuer */ + 0x55,0x1D,0x3E, /* [ 8396] OBJ_no_assertion */ + 0x55,0x1D,0x3F, /* [ 8399] OBJ_id_aa_issuing_distribution_point */ + 0x55,0x1D,0x40, /* [ 8402] OBJ_issued_on_behalf_of */ + 0x55,0x1D,0x41, /* [ 8405] OBJ_single_use */ + 0x55,0x1D,0x42, /* [ 8408] OBJ_group_ac */ + 0x55,0x1D,0x43, /* [ 8411] OBJ_allowed_attribute_assignments */ + 0x55,0x1D,0x44, /* [ 8414] OBJ_attribute_mappings */ + 0x55,0x1D,0x45, /* [ 8417] OBJ_holder_name_constraints */ + 0x55,0x1D,0x46, /* [ 8420] OBJ_authorization_validation */ + 0x55,0x1D,0x47, /* [ 8423] OBJ_prot_restrict */ + 0x55,0x1D,0x48, /* [ 8426] OBJ_subject_alt_public_key_info */ + 0x55,0x1D,0x49, /* [ 8429] OBJ_alt_signature_algorithm */ + 0x55,0x1D,0x4A, /* [ 8432] OBJ_alt_signature_value */ + 0x55,0x1D,0x4B, /* [ 8435] OBJ_associated_information */ + 0x67,0x81,0x05, /* [ 8438] OBJ_tcg */ + 0x67,0x81,0x05,0x01, /* [ 8441] OBJ_tcg_tcpaSpecVersion */ + 0x67,0x81,0x05,0x02, /* [ 8445] OBJ_tcg_attribute */ + 0x67,0x81,0x05,0x03, /* [ 8449] OBJ_tcg_protocol */ + 0x67,0x81,0x05,0x04, /* [ 8453] OBJ_tcg_algorithm */ + 0x67,0x81,0x05,0x05, /* [ 8457] OBJ_tcg_platformClass */ + 0x67,0x81,0x05,0x06, /* [ 8461] OBJ_tcg_ce */ + 0x67,0x81,0x05,0x08, /* [ 8465] OBJ_tcg_kp */ + 0x67,0x81,0x05,0x11, /* [ 8469] OBJ_tcg_address */ + 0x67,0x81,0x05,0x12, /* [ 8473] OBJ_tcg_registry */ + 0x67,0x81,0x05,0x05,0x01, /* [ 8477] OBJ_tcg_common */ + 0x67,0x81,0x05,0x05,0x01,0x01, /* [ 8482] OBJ_tcg_at_platformManufacturerStr */ + 0x67,0x81,0x05,0x05,0x01,0x02, /* [ 8488] OBJ_tcg_at_platformManufacturerId */ + 0x67,0x81,0x05,0x05,0x01,0x03, /* [ 8494] OBJ_tcg_at_platformConfigUri */ + 0x67,0x81,0x05,0x05,0x01,0x04, /* [ 8500] OBJ_tcg_at_platformModel */ + 0x67,0x81,0x05,0x05,0x01,0x05, /* [ 8506] OBJ_tcg_at_platformVersion */ + 0x67,0x81,0x05,0x05,0x01,0x06, /* [ 8512] OBJ_tcg_at_platformSerial */ + 0x67,0x81,0x05,0x05,0x01,0x07, /* [ 8518] OBJ_tcg_at_platformConfiguration */ + 0x67,0x81,0x05,0x02,0x01, /* [ 8524] OBJ_tcg_at_tpmManufacturer */ + 0x67,0x81,0x05,0x02,0x02, /* [ 8529] OBJ_tcg_at_tpmModel */ + 0x67,0x81,0x05,0x02,0x03, /* [ 8534] OBJ_tcg_at_tpmVersion */ + 0x67,0x81,0x05,0x02,0x0A, /* [ 8539] OBJ_tcg_at_securityQualities */ + 0x67,0x81,0x05,0x02,0x0B, /* [ 8544] OBJ_tcg_at_tpmProtectionProfile */ + 0x67,0x81,0x05,0x02,0x0C, /* [ 8549] OBJ_tcg_at_tpmSecurityTarget */ + 0x67,0x81,0x05,0x02,0x0D, /* [ 8554] OBJ_tcg_at_tbbProtectionProfile */ + 0x67,0x81,0x05,0x02,0x0E, /* [ 8559] OBJ_tcg_at_tbbSecurityTarget */ + 0x67,0x81,0x05,0x02,0x0F, /* [ 8564] OBJ_tcg_at_tpmIdLabel */ + 0x67,0x81,0x05,0x02,0x10, /* [ 8569] OBJ_tcg_at_tpmSpecification */ + 0x67,0x81,0x05,0x02,0x11, /* [ 8574] OBJ_tcg_at_tcgPlatformSpecification */ + 0x67,0x81,0x05,0x02,0x12, /* [ 8579] OBJ_tcg_at_tpmSecurityAssertions */ + 0x67,0x81,0x05,0x02,0x13, /* [ 8584] OBJ_tcg_at_tbbSecurityAssertions */ + 0x67,0x81,0x05,0x02,0x17, /* [ 8589] OBJ_tcg_at_tcgCredentialSpecification */ + 0x67,0x81,0x05,0x02,0x19, /* [ 8594] OBJ_tcg_at_tcgCredentialType */ + 0x67,0x81,0x05,0x05,0x01,0x07,0x01, /* [ 8599] OBJ_tcg_at_platformConfiguration_v1 */ + 0x67,0x81,0x05,0x05,0x01,0x07,0x02, /* [ 8606] OBJ_tcg_at_platformConfiguration_v2 */ + 0x67,0x81,0x05,0x04,0x01, /* [ 8613] OBJ_tcg_algorithm_null */ + 0x67,0x81,0x05,0x08,0x01, /* [ 8618] OBJ_tcg_kp_EKCertificate */ + 0x67,0x81,0x05,0x08,0x02, /* [ 8623] OBJ_tcg_kp_PlatformAttributeCertificate */ + 0x67,0x81,0x05,0x08,0x03, /* [ 8628] OBJ_tcg_kp_AIKCertificate */ + 0x67,0x81,0x05,0x08,0x04, /* [ 8633] OBJ_tcg_kp_PlatformKeyCertificate */ + 0x67,0x81,0x05,0x08,0x05, /* [ 8638] OBJ_tcg_kp_DeltaPlatformAttributeCertificate */ + 0x67,0x81,0x05,0x06,0x02, /* [ 8643] OBJ_tcg_ce_relevantCredentials */ + 0x67,0x81,0x05,0x06,0x03, /* [ 8648] OBJ_tcg_ce_relevantManifests */ + 0x67,0x81,0x05,0x06,0x04, /* [ 8653] OBJ_tcg_ce_virtualPlatformAttestationService */ + 0x67,0x81,0x05,0x06,0x05, /* [ 8658] OBJ_tcg_ce_migrationControllerAttestationService */ + 0x67,0x81,0x05,0x06,0x06, /* [ 8663] OBJ_tcg_ce_migrationControllerRegistrationService */ + 0x67,0x81,0x05,0x06,0x07, /* [ 8668] OBJ_tcg_ce_virtualPlatformBackupService */ + 0x67,0x81,0x05,0x03,0x01, /* [ 8673] OBJ_tcg_prt_tpmIdProtocol */ + 0x67,0x81,0x05,0x11,0x01, /* [ 8678] OBJ_tcg_address_ethernetmac */ + 0x67,0x81,0x05,0x11,0x02, /* [ 8683] OBJ_tcg_address_wlanmac */ + 0x67,0x81,0x05,0x11,0x03, /* [ 8688] OBJ_tcg_address_bluetoothmac */ + 0x67,0x81,0x05,0x12,0x03, /* [ 8693] OBJ_tcg_registry_componentClass */ + 0x67,0x81,0x05,0x12,0x03,0x01, /* [ 8698] OBJ_tcg_registry_componentClass_tcg */ + 0x67,0x81,0x05,0x12,0x03,0x02, /* [ 8704] OBJ_tcg_registry_componentClass_ietf */ + 0x67,0x81,0x05,0x12,0x03,0x03, /* [ 8710] OBJ_tcg_registry_componentClass_dmtf */ }; -#define NUM_NID 1291 +#define NUM_NID 1371 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -1444,7 +1524,7 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, &so[2075]}, {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, &so[2083]}, {"qcStatements", "qcStatements", NID_qcStatements, 8, &so[2091]}, - {"ac-auditEntity", "ac-auditEntity", NID_ac_auditEntity, 8, &so[2099]}, + {"ac-auditEntity", "Audit Identity", NID_ac_auditEntity, 8, &so[2099]}, {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &so[2107]}, {"aaControls", "aaControls", NID_aaControls, 8, &so[2115]}, {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, &so[2123]}, @@ -2448,9 +2528,89 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"brotli", "Brotli compression", NID_brotli}, {"zstd", "Zstandard compression", NID_zstd}, {"SM4-XTS", "sm4-xts", NID_sm4_xts, 8, &so[8355]}, + {"authorityAttributeIdentifier", "X509v3 Authority Attribute Identifier", NID_authority_attribute_identifier, 3, &so[8363]}, + {"roleSpecCertIdentifier", "X509v3 Role Specification Certificate Identifier", NID_role_spec_cert_identifier, 3, &so[8366]}, + {"basicAttConstraints", "X509v3 Basic Attribute Certificate Constraints", NID_basic_att_constraints, 3, &so[8369]}, + {"delegatedNameConstraints", "X509v3 Delegated Name Constraints", NID_delegated_name_constraints, 3, &so[8372]}, + {"timeSpecification", "X509v3 Time Specification", NID_time_specification, 3, &so[8375]}, + {"attributeDescriptor", "X509v3 Attribute Descriptor", NID_attribute_descriptor, 3, &so[8378]}, + {"userNotice", "X509v3 User Notice", NID_user_notice, 3, &so[8381]}, + {"sOAIdentifier", "X509v3 Source of Authority Identifier", NID_soa_identifier, 3, &so[8384]}, + {"acceptableCertPolicies", "X509v3 Acceptable Certification Policies", NID_acceptable_cert_policies, 3, &so[8387]}, + {"acceptablePrivPolicies", "X509v3 Acceptable Privilege Policies", NID_acceptable_privilege_policies, 3, &so[8390]}, + {"indirectIssuer", "X509v3 Indirect Issuer", NID_indirect_issuer, 3, &so[8393]}, + {"noAssertion", "X509v3 No Assertion", NID_no_assertion, 3, &so[8396]}, + {"aAissuingDistributionPoint", "X509v3 Attribute Authority Issuing Distribution Point", NID_id_aa_issuing_distribution_point, 3, &so[8399]}, + {"issuedOnBehalfOf", "X509v3 Issued On Behalf Of", NID_issued_on_behalf_of, 3, &so[8402]}, + {"singleUse", "X509v3 Single Use", NID_single_use, 3, &so[8405]}, + {"groupAC", "X509v3 Group Attribute Certificate", NID_group_ac, 3, &so[8408]}, + {"allowedAttributeAssignments", "X509v3 Allowed Attribute Assignments", NID_allowed_attribute_assignments, 3, &so[8411]}, + {"attributeMappings", "X509v3 Attribute Mappings", NID_attribute_mappings, 3, &so[8414]}, + {"holderNameConstraints", "X509v3 Holder Name Constraints", NID_holder_name_constraints, 3, &so[8417]}, + {"authorizationValidation", "X509v3 Authorization Validation", NID_authorization_validation, 3, &so[8420]}, + {"protRestrict", "X509v3 Protocol Restriction", NID_prot_restrict, 3, &so[8423]}, + {"subjectAltPublicKeyInfo", "X509v3 Subject Alternative Public Key Info", NID_subject_alt_public_key_info, 3, &so[8426]}, + {"altSignatureAlgorithm", "X509v3 Alternative Signature Algorithm", NID_alt_signature_algorithm, 3, &so[8429]}, + {"altSignatureValue", "X509v3 Alternative Signature Value", NID_alt_signature_value, 3, &so[8432]}, + {"associatedInformation", "X509v3 Associated Information", NID_associated_information, 3, &so[8435]}, + {"tcg", "Trusted Computing Group", NID_tcg, 3, &so[8438]}, + {"tcg-tcpaSpecVersion", "tcg-tcpaSpecVersion", NID_tcg_tcpaSpecVersion, 4, &so[8441]}, + {"tcg-attribute", "Trusted Computing Group Attributes", NID_tcg_attribute, 4, &so[8445]}, + {"tcg-protocol", "Trusted Computing Group Protocols", NID_tcg_protocol, 4, &so[8449]}, + {"tcg-algorithm", "Trusted Computing Group Algorithms", NID_tcg_algorithm, 4, &so[8453]}, + {"tcg-platformClass", "Trusted Computing Group Platform Classes", NID_tcg_platformClass, 4, &so[8457]}, + {"tcg-ce", "Trusted Computing Group Certificate Extensions", NID_tcg_ce, 4, &so[8461]}, + {"tcg-kp", "Trusted Computing Group Key Purposes", NID_tcg_kp, 4, &so[8465]}, + {"tcg-address", "Trusted Computing Group Address Formats", NID_tcg_address, 4, &so[8469]}, + {"tcg-registry", "Trusted Computing Group Registry", NID_tcg_registry, 4, &so[8473]}, + {"tcg-common", "TCG Common", NID_tcg_common, 5, &so[8477]}, + {"tcg-at-platformManufacturerStr", "TCG Platform Manufacturer String", NID_tcg_at_platformManufacturerStr, 6, &so[8482]}, + {"tcg-at-platformManufacturerId", "TCG Platform Manufacturer ID", NID_tcg_at_platformManufacturerId, 6, &so[8488]}, + {"tcg-at-platformConfigUri", "TCG Platform Configuration URI", NID_tcg_at_platformConfigUri, 6, &so[8494]}, + {"tcg-at-platformModel", "TCG Platform Model", NID_tcg_at_platformModel, 6, &so[8500]}, + {"tcg-at-platformVersion", "TCG Platform Version", NID_tcg_at_platformVersion, 6, &so[8506]}, + {"tcg-at-platformSerial", "TCG Platform Serial Number", NID_tcg_at_platformSerial, 6, &so[8512]}, + {"tcg-at-platformConfiguration", "TCG Platform Configuration", NID_tcg_at_platformConfiguration, 6, &so[8518]}, + {"tcg-at-tpmManufacturer", "TPM Manufacturer", NID_tcg_at_tpmManufacturer, 5, &so[8524]}, + {"tcg-at-tpmModel", "TPM Model", NID_tcg_at_tpmModel, 5, &so[8529]}, + {"tcg-at-tpmVersion", "TPM Version", NID_tcg_at_tpmVersion, 5, &so[8534]}, + {"tcg-at-securityQualities", "Security Qualities", NID_tcg_at_securityQualities, 5, &so[8539]}, + {"tcg-at-tpmProtectionProfile", "TPM Protection Profile", NID_tcg_at_tpmProtectionProfile, 5, &so[8544]}, + {"tcg-at-tpmSecurityTarget", "TPM Security Target", NID_tcg_at_tpmSecurityTarget, 5, &so[8549]}, + {"tcg-at-tbbProtectionProfile", "TBB Protection Profile", NID_tcg_at_tbbProtectionProfile, 5, &so[8554]}, + {"tcg-at-tbbSecurityTarget", "TBB Security Target", NID_tcg_at_tbbSecurityTarget, 5, &so[8559]}, + {"tcg-at-tpmIdLabel", "TPM ID Label", NID_tcg_at_tpmIdLabel, 5, &so[8564]}, + {"tcg-at-tpmSpecification", "TPM Specification", NID_tcg_at_tpmSpecification, 5, &so[8569]}, + {"tcg-at-tcgPlatformSpecification", "TPM Platform Specification", NID_tcg_at_tcgPlatformSpecification, 5, &so[8574]}, + {"tcg-at-tpmSecurityAssertions", "TPM Security Assertions", NID_tcg_at_tpmSecurityAssertions, 5, &so[8579]}, + {"tcg-at-tbbSecurityAssertions", "TBB Security Assertions", NID_tcg_at_tbbSecurityAssertions, 5, &so[8584]}, + {"tcg-at-tcgCredentialSpecification", "TCG Credential Specification", NID_tcg_at_tcgCredentialSpecification, 5, &so[8589]}, + {"tcg-at-tcgCredentialType", "TCG Credential Type", NID_tcg_at_tcgCredentialType, 5, &so[8594]}, + {"tcg-at-platformConfiguration-v1", "Platform Configuration Version 1", NID_tcg_at_platformConfiguration_v1, 7, &so[8599]}, + {"tcg-at-platformConfiguration-v2", "Platform Configuration Version 2", NID_tcg_at_platformConfiguration_v2, 7, &so[8606]}, + {"tcg-algorithm-null", "TCG NULL Algorithm", NID_tcg_algorithm_null, 5, &so[8613]}, + {"tcg-kp-EKCertificate", "Endorsement Key Certificate", NID_tcg_kp_EKCertificate, 5, &so[8618]}, + {"tcg-kp-PlatformAttributeCertificate", "Platform Attribute Certificate", NID_tcg_kp_PlatformAttributeCertificate, 5, &so[8623]}, + {"tcg-kp-AIKCertificate", "Attestation Identity Key Certificate", NID_tcg_kp_AIKCertificate, 5, &so[8628]}, + {"tcg-kp-PlatformKeyCertificate", "Platform Key Certificate", NID_tcg_kp_PlatformKeyCertificate, 5, &so[8633]}, + {"tcg-kp-DeltaPlatformAttributeCertificate", "Delta Platform Attribute Certificate", NID_tcg_kp_DeltaPlatformAttributeCertificate, 5, &so[8638]}, + {"tcg-ce-relevantCredentials", "Relevant Credentials", NID_tcg_ce_relevantCredentials, 5, &so[8643]}, + {"tcg-ce-relevantManifests", "Relevant Manifests", NID_tcg_ce_relevantManifests, 5, &so[8648]}, + {"tcg-ce-virtualPlatformAttestationService", "Virtual Platform Attestation Service", NID_tcg_ce_virtualPlatformAttestationService, 5, &so[8653]}, + {"tcg-ce-migrationControllerAttestationService", "Migration Controller Attestation Service", NID_tcg_ce_migrationControllerAttestationService, 5, &so[8658]}, + {"tcg-ce-migrationControllerRegistrationService", "Migration Controller Registration Service", NID_tcg_ce_migrationControllerRegistrationService, 5, &so[8663]}, + {"tcg-ce-virtualPlatformBackupService", "Virtual Platform Backup Service", NID_tcg_ce_virtualPlatformBackupService, 5, &so[8668]}, + {"tcg-prt-tpmIdProtocol", "TCG TPM Protocol", NID_tcg_prt_tpmIdProtocol, 5, &so[8673]}, + {"tcg-address-ethernetmac", "Ethernet MAC Address", NID_tcg_address_ethernetmac, 5, &so[8678]}, + {"tcg-address-wlanmac", "WLAN MAC Address", NID_tcg_address_wlanmac, 5, &so[8683]}, + {"tcg-address-bluetoothmac", "Bluetooth MAC Address", NID_tcg_address_bluetoothmac, 5, &so[8688]}, + {"tcg-registry-componentClass", "TCG Component Class", NID_tcg_registry_componentClass, 5, &so[8693]}, + {"tcg-registry-componentClass-tcg", "Trusted Computed Group Registry", NID_tcg_registry_componentClass_tcg, 6, &so[8698]}, + {"tcg-registry-componentClass-ietf", "Internet Engineering Task Force Registry", NID_tcg_registry_componentClass_ietf, 6, &so[8704]}, + {"tcg-registry-componentClass-dmtf", "Distributed Management Task Force Registry", NID_tcg_registry_componentClass_dmtf, 6, &so[8710]}, }; -#define NUM_SN 1282 +#define NUM_SN 1362 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2760,25 +2920,37 @@ static const unsigned int sn_objs[NUM_SN] = { 1206, /* "X963KDF" */ 185, /* "X9cm" */ 125, /* "ZLIB" */ + 1303, /* "aAissuingDistributionPoint" */ 478, /* "aRecord" */ 289, /* "aaControls" */ 287, /* "ac-auditEntity" */ 397, /* "ac-proxying" */ 288, /* "ac-targeting" */ + 1299, /* "acceptableCertPolicies" */ + 1300, /* "acceptablePrivPolicies" */ 368, /* "acceptableResponses" */ 446, /* "account" */ 363, /* "ad_timestamping" */ 376, /* "algorithm" */ + 1307, /* "allowedAttributeAssignments" */ + 1313, /* "altSignatureAlgorithm" */ + 1314, /* "altSignatureValue" */ 405, /* "ansi-X9-62" */ 910, /* "anyExtendedKeyUsage" */ 746, /* "anyPolicy" */ 370, /* "archiveCutoff" */ 484, /* "associatedDomain" */ + 1315, /* "associatedInformation" */ 485, /* "associatedName" */ + 1296, /* "attributeDescriptor" */ + 1308, /* "attributeMappings" */ 501, /* "audio" */ + 1291, /* "authorityAttributeIdentifier" */ 177, /* "authorityInfoAccess" */ 90, /* "authorityKeyIdentifier" */ 882, /* "authorityRevocationList" */ + 1310, /* "authorizationValidation" */ + 1293, /* "basicAttConstraints" */ 87, /* "basicConstraints" */ 365, /* "basicOCSPResponse" */ 285, /* "biometricInfo" */ @@ -2870,6 +3042,7 @@ static const unsigned int sn_objs[NUM_SN] = { 495, /* "dSAQuality" */ 434, /* "data" */ 390, /* "dcobject" */ + 1294, /* "delegatedNameConstraints" */ 140, /* "deltaCRL" */ 891, /* "deltaRevocationList" */ 107, /* "description" */ @@ -2957,6 +3130,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1010, /* "gost89-ecb" */ 812, /* "gost94" */ 850, /* "gost94cc" */ + 1306, /* "groupAC" */ 1156, /* "hmacWithDstu34311" */ 797, /* "hmacWithMD5" */ 163, /* "hmacWithSHA1" */ @@ -2971,6 +3145,7 @@ static const unsigned int sn_objs[NUM_SN] = { 430, /* "holdInstructionCode" */ 431, /* "holdInstructionNone" */ 433, /* "holdInstructionReject" */ + 1309, /* "holderNameConstraints" */ 486, /* "homePostalAddress" */ 473, /* "homeTelephoneNumber" */ 466, /* "host" */ @@ -3315,6 +3490,7 @@ static const unsigned int sn_objs[NUM_SN] = { 676, /* "identified-organization" */ 1170, /* "ieee" */ 1171, /* "ieee-siswg" */ + 1301, /* "indirectIssuer" */ 461, /* "info" */ 748, /* "inhibitAnyPolicy" */ 101, /* "initials" */ @@ -3327,6 +3503,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1022, /* "ipsecIKE" */ 295, /* "ipsecTunnel" */ 296, /* "ipsecUser" */ + 1304, /* "issuedOnBehalfOf" */ 86, /* "issuerAltName" */ 1008, /* "issuerSignTool" */ 770, /* "issuingDistributionPoint" */ @@ -3391,6 +3568,7 @@ static const unsigned int sn_objs[NUM_SN] = { 481, /* "nSRecord" */ 173, /* "name" */ 666, /* "nameConstraints" */ + 1302, /* "noAssertion" */ 369, /* "noCheck" */ 403, /* "noRevAvail" */ 72, /* "nsBaseUrl" */ @@ -3464,6 +3642,7 @@ static const unsigned int sn_objs[NUM_SN] = { 415, /* "prime256v1" */ 385, /* "private" */ 84, /* "privateKeyUsagePeriod" */ + 1311, /* "protRestrict" */ 886, /* "protocolInformation" */ 663, /* "proxyCertInfo" */ 510, /* "pseudonym" */ @@ -3474,6 +3653,7 @@ static const unsigned int sn_objs[NUM_SN] = { 870, /* "registeredAddress" */ 400, /* "role" */ 877, /* "roleOccupant" */ + 1292, /* "roleSpecCertIdentifier" */ 448, /* "room" */ 463, /* "roomNumber" */ 1243, /* "rpkiManifest" */ @@ -3482,6 +3662,7 @@ static const unsigned int sn_objs[NUM_SN] = { 644, /* "rsaOAEPEncryptionSET" */ 377, /* "rsaSignature" */ 1, /* "rsadsi" */ + 1298, /* "sOAIdentifier" */ 482, /* "sOARecord" */ 155, /* "safeContentsBag" */ 291, /* "sbgp-autonomousSysNum" */ @@ -3671,10 +3852,12 @@ static const unsigned int sn_objs[NUM_SN] = { 52, /* "signingTime" */ 454, /* "simpleSecurityObject" */ 496, /* "singleLevelQuality" */ + 1305, /* "singleUse" */ 1142, /* "sm-scheme" */ 387, /* "snmpv2" */ 660, /* "street" */ 85, /* "subjectAltName" */ + 1312, /* "subjectAltPublicKeyInfo" */ 769, /* "subjectDirectoryAttributes" */ 398, /* "subjectInfoAccess" */ 82, /* "subjectKeyIdentifier" */ @@ -3684,11 +3867,67 @@ static const unsigned int sn_objs[NUM_SN] = { 890, /* "supportedAlgorithms" */ 874, /* "supportedApplicationContext" */ 402, /* "targetInformation" */ + 1316, /* "tcg" */ + 1324, /* "tcg-address" */ + 1366, /* "tcg-address-bluetoothmac" */ + 1364, /* "tcg-address-ethernetmac" */ + 1365, /* "tcg-address-wlanmac" */ + 1320, /* "tcg-algorithm" */ + 1351, /* "tcg-algorithm-null" */ + 1329, /* "tcg-at-platformConfigUri" */ + 1333, /* "tcg-at-platformConfiguration" */ + 1349, /* "tcg-at-platformConfiguration-v1" */ + 1350, /* "tcg-at-platformConfiguration-v2" */ + 1328, /* "tcg-at-platformManufacturerId" */ + 1327, /* "tcg-at-platformManufacturerStr" */ + 1330, /* "tcg-at-platformModel" */ + 1332, /* "tcg-at-platformSerial" */ + 1331, /* "tcg-at-platformVersion" */ + 1337, /* "tcg-at-securityQualities" */ + 1340, /* "tcg-at-tbbProtectionProfile" */ + 1346, /* "tcg-at-tbbSecurityAssertions" */ + 1341, /* "tcg-at-tbbSecurityTarget" */ + 1347, /* "tcg-at-tcgCredentialSpecification" */ + 1348, /* "tcg-at-tcgCredentialType" */ + 1344, /* "tcg-at-tcgPlatformSpecification" */ + 1342, /* "tcg-at-tpmIdLabel" */ + 1334, /* "tcg-at-tpmManufacturer" */ + 1335, /* "tcg-at-tpmModel" */ + 1338, /* "tcg-at-tpmProtectionProfile" */ + 1345, /* "tcg-at-tpmSecurityAssertions" */ + 1339, /* "tcg-at-tpmSecurityTarget" */ + 1343, /* "tcg-at-tpmSpecification" */ + 1336, /* "tcg-at-tpmVersion" */ + 1318, /* "tcg-attribute" */ + 1322, /* "tcg-ce" */ + 1360, /* "tcg-ce-migrationControllerAttestationService" */ + 1361, /* "tcg-ce-migrationControllerRegistrationService" */ + 1357, /* "tcg-ce-relevantCredentials" */ + 1358, /* "tcg-ce-relevantManifests" */ + 1359, /* "tcg-ce-virtualPlatformAttestationService" */ + 1362, /* "tcg-ce-virtualPlatformBackupService" */ + 1326, /* "tcg-common" */ + 1323, /* "tcg-kp" */ + 1354, /* "tcg-kp-AIKCertificate" */ + 1356, /* "tcg-kp-DeltaPlatformAttributeCertificate" */ + 1352, /* "tcg-kp-EKCertificate" */ + 1353, /* "tcg-kp-PlatformAttributeCertificate" */ + 1355, /* "tcg-kp-PlatformKeyCertificate" */ + 1321, /* "tcg-platformClass" */ + 1319, /* "tcg-protocol" */ + 1363, /* "tcg-prt-tpmIdProtocol" */ + 1325, /* "tcg-registry" */ + 1367, /* "tcg-registry-componentClass" */ + 1370, /* "tcg-registry-componentClass-dmtf" */ + 1369, /* "tcg-registry-componentClass-ietf" */ + 1368, /* "tcg-registry-componentClass-tcg" */ + 1317, /* "tcg-tcpaSpecVersion" */ 864, /* "telephoneNumber" */ 866, /* "teletexTerminalIdentifier" */ 865, /* "telexNumber" */ 459, /* "textEncodedORAddress" */ 293, /* "textNotice" */ + 1295, /* "timeSpecification" */ 133, /* "timeStamping" */ 106, /* "title" */ 1020, /* "tlsfeature" */ @@ -3712,6 +3951,7 @@ static const unsigned int sn_objs[NUM_SN] = { 49, /* "unstructuredName" */ 880, /* "userCertificate" */ 465, /* "userClass" */ + 1297, /* "userNotice" */ 879, /* "userPassword" */ 373, /* "valid" */ 678, /* "wap" */ @@ -3736,17 +3976,20 @@ static const unsigned int sn_objs[NUM_SN] = { 1289, /* "zstd" */ }; -#define NUM_LN 1282 +#define NUM_LN 1362 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ 368, /* "Acceptable OCSP Responses" */ 910, /* "Any Extended Key Usage" */ 664, /* "Any language" */ + 1354, /* "Attestation Identity Key Certificate" */ + 287, /* "Audit Identity" */ 177, /* "Authority Information Access" */ 1220, /* "BGPsec Router" */ 365, /* "Basic OCSP Response" */ 285, /* "Biometric Info" */ + 1366, /* "Bluetooth MAC Address" */ 1221, /* "Brand Indicator for Message Identification" */ 1288, /* "Brotli compression" */ 179, /* "CA Issuers" */ @@ -3786,13 +4029,17 @@ static const unsigned int ln_objs[NUM_LN] = { 1167, /* "DSTU curve 7" */ 1168, /* "DSTU curve 8" */ 1169, /* "DSTU curve 9" */ + 1356, /* "Delta Platform Attribute Certificate" */ 783, /* "Diffie-Hellman based MAC" */ 382, /* "Directory" */ + 1370, /* "Distributed Management Task Force Registry" */ 392, /* "Domain" */ 132, /* "E-mail Protection" */ 1087, /* "ED25519" */ 1088, /* "ED448" */ + 1352, /* "Endorsement Key Certificate" */ 389, /* "Enterprises" */ + 1364, /* "Ethernet MAC Address" */ 384, /* "Experimental" */ 372, /* "Extended OCSP Status" */ 172, /* "Extension Request" */ @@ -3848,6 +4095,7 @@ static const unsigned int ln_objs[NUM_LN] = { 667, /* "Independent" */ 665, /* "Inherit all" */ 647, /* "International Organizations" */ + 1369, /* "Internet Engineering Task Force Registry" */ 142, /* "Invalidity Date" */ 504, /* "MIME MHS" */ 388, /* "Mail" */ @@ -3862,6 +4110,8 @@ static const unsigned int ln_objs[NUM_LN] = { 648, /* "Microsoft Smartcard Login" */ 136, /* "Microsoft Trust List Signing" */ 649, /* "Microsoft User Principal Name" */ + 1360, /* "Migration Controller Attestation Service" */ + 1361, /* "Migration Controller Registration Service" */ 1211, /* "NAIRealm" */ 393, /* "NULL" */ 404, /* "NULL" */ @@ -3894,6 +4144,10 @@ static const unsigned int ln_objs[NUM_LN] = { 1032, /* "PKINIT Client Auth" */ 127, /* "PKIX" */ 858, /* "Permanent Identifier" */ + 1353, /* "Platform Attribute Certificate" */ + 1349, /* "Platform Configuration Version 1" */ + 1350, /* "Platform Configuration Version 2" */ + 1355, /* "Platform Key Certificate" */ 164, /* "Policy Qualifier CPS" */ 165, /* "Policy Qualifier User Notice" */ 385, /* "Private" */ @@ -3907,6 +4161,8 @@ static const unsigned int ln_objs[NUM_LN] = { 1117, /* "RSA-SHA3-256" */ 1118, /* "RSA-SHA3-384" */ 1119, /* "RSA-SHA3-512" */ + 1357, /* "Relevant Credentials" */ + 1358, /* "Relevant Manifests" */ 188, /* "S/MIME" */ 167, /* "S/MIME Capabilities" */ 1204, /* "SM2-with-SM3" */ @@ -3917,6 +4173,7 @@ static const unsigned int ln_objs[NUM_LN] = { 1026, /* "SSH Server" */ 512, /* "Secure Electronic Transactions" */ 386, /* "Security" */ + 1337, /* "Security Qualities" */ 394, /* "Selected Attribute Types" */ 1029, /* "Send Owner" */ 1030, /* "Send Proxied Owner" */ @@ -3929,39 +4186,102 @@ static const unsigned int ln_objs[NUM_LN] = { 1208, /* "Smtp UTF8 Mailbox" */ 143, /* "Strong Extranet ID" */ 398, /* "Subject Information Access" */ + 1340, /* "TBB Protection Profile" */ + 1346, /* "TBB Security Assertions" */ + 1341, /* "TBB Security Target" */ + 1326, /* "TCG Common" */ + 1367, /* "TCG Component Class" */ + 1347, /* "TCG Credential Specification" */ + 1348, /* "TCG Credential Type" */ + 1351, /* "TCG NULL Algorithm" */ + 1333, /* "TCG Platform Configuration" */ + 1329, /* "TCG Platform Configuration URI" */ + 1328, /* "TCG Platform Manufacturer ID" */ + 1327, /* "TCG Platform Manufacturer String" */ + 1330, /* "TCG Platform Model" */ + 1332, /* "TCG Platform Serial Number" */ + 1331, /* "TCG Platform Version" */ + 1363, /* "TCG TPM Protocol" */ 1020, /* "TLS Feature" */ 130, /* "TLS Web Client Authentication" */ 129, /* "TLS Web Server Authentication" */ + 1342, /* "TPM ID Label" */ + 1334, /* "TPM Manufacturer" */ + 1335, /* "TPM Model" */ + 1344, /* "TPM Platform Specification" */ + 1338, /* "TPM Protection Profile" */ + 1345, /* "TPM Security Assertions" */ + 1339, /* "TPM Security Target" */ + 1343, /* "TPM Specification" */ + 1336, /* "TPM Version" */ 133, /* "Time Stamping" */ 375, /* "Trust Root" */ + 1368, /* "Trusted Computed Group Registry" */ + 1316, /* "Trusted Computing Group" */ + 1324, /* "Trusted Computing Group Address Formats" */ + 1320, /* "Trusted Computing Group Algorithms" */ + 1318, /* "Trusted Computing Group Attributes" */ + 1322, /* "Trusted Computing Group Certificate Extensions" */ + 1323, /* "Trusted Computing Group Key Purposes" */ + 1321, /* "Trusted Computing Group Platform Classes" */ + 1319, /* "Trusted Computing Group Protocols" */ + 1325, /* "Trusted Computing Group Registry" */ 1283, /* "Trusted key usage (Oracle)" */ + 1359, /* "Virtual Platform Attestation Service" */ + 1362, /* "Virtual Platform Backup Service" */ + 1365, /* "WLAN MAC Address" */ 1034, /* "X25519" */ 1035, /* "X448" */ 12, /* "X509" */ 402, /* "X509v3 AC Targeting" */ + 1299, /* "X509v3 Acceptable Certification Policies" */ + 1300, /* "X509v3 Acceptable Privilege Policies" */ + 1307, /* "X509v3 Allowed Attribute Assignments" */ + 1313, /* "X509v3 Alternative Signature Algorithm" */ + 1314, /* "X509v3 Alternative Signature Value" */ 746, /* "X509v3 Any Policy" */ + 1315, /* "X509v3 Associated Information" */ + 1303, /* "X509v3 Attribute Authority Issuing Distribution Point" */ + 1296, /* "X509v3 Attribute Descriptor" */ + 1308, /* "X509v3 Attribute Mappings" */ + 1291, /* "X509v3 Authority Attribute Identifier" */ 90, /* "X509v3 Authority Key Identifier" */ + 1310, /* "X509v3 Authorization Validation" */ + 1293, /* "X509v3 Basic Attribute Certificate Constraints" */ 87, /* "X509v3 Basic Constraints" */ 103, /* "X509v3 CRL Distribution Points" */ 88, /* "X509v3 CRL Number" */ 141, /* "X509v3 CRL Reason Code" */ 771, /* "X509v3 Certificate Issuer" */ 89, /* "X509v3 Certificate Policies" */ + 1294, /* "X509v3 Delegated Name Constraints" */ 140, /* "X509v3 Delta CRL Indicator" */ 126, /* "X509v3 Extended Key Usage" */ 857, /* "X509v3 Freshest CRL" */ + 1306, /* "X509v3 Group Attribute Certificate" */ + 1309, /* "X509v3 Holder Name Constraints" */ + 1301, /* "X509v3 Indirect Issuer" */ 748, /* "X509v3 Inhibit Any Policy" */ + 1304, /* "X509v3 Issued On Behalf Of" */ 86, /* "X509v3 Issuer Alternative Name" */ 770, /* "X509v3 Issuing Distribution Point" */ 83, /* "X509v3 Key Usage" */ 666, /* "X509v3 Name Constraints" */ + 1302, /* "X509v3 No Assertion" */ 403, /* "X509v3 No Revocation Available" */ 401, /* "X509v3 Policy Constraints" */ 747, /* "X509v3 Policy Mappings" */ 84, /* "X509v3 Private Key Usage Period" */ + 1311, /* "X509v3 Protocol Restriction" */ + 1292, /* "X509v3 Role Specification Certificate Identifier" */ + 1305, /* "X509v3 Single Use" */ + 1298, /* "X509v3 Source of Authority Identifier" */ 85, /* "X509v3 Subject Alternative Name" */ + 1312, /* "X509v3 Subject Alternative Public Key Info" */ 769, /* "X509v3 Subject Directory Attributes" */ 82, /* "X509v3 Subject Key Identifier" */ + 1295, /* "X509v3 Time Specification" */ + 1297, /* "X509v3 User Notice" */ 920, /* "X9.42 DH" */ 184, /* "X9.57" */ 185, /* "X9.57 CM ?" */ @@ -3969,7 +4289,6 @@ static const unsigned int ln_objs[NUM_LN] = { 1289, /* "Zstandard compression" */ 478, /* "aRecord" */ 289, /* "aaControls" */ - 287, /* "ac-auditEntity" */ 397, /* "ac-proxying" */ 288, /* "ac-targeting" */ 446, /* "account" */ @@ -4979,6 +5298,7 @@ static const unsigned int ln_objs[NUM_LN] = { 890, /* "supportedAlgorithms" */ 874, /* "supportedApplicationContext" */ 100, /* "surname" */ + 1317, /* "tcg-tcpaSpecVersion" */ 864, /* "telephoneNumber" */ 866, /* "teletexTerminalIdentifier" */ 865, /* "telexNumber" */ @@ -5022,7 +5342,7 @@ static const unsigned int ln_objs[NUM_LN] = { 125, /* "zlib compression" */ }; -#define NUM_OBJ 1148 +#define NUM_OBJ 1228 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -5135,10 +5455,35 @@ static const unsigned int obj_objs[NUM_OBJ] = { 90, /* OBJ_authority_key_identifier 2 5 29 35 */ 401, /* OBJ_policy_constraints 2 5 29 36 */ 126, /* OBJ_ext_key_usage 2 5 29 37 */ + 1291, /* OBJ_authority_attribute_identifier 2 5 29 38 */ + 1292, /* OBJ_role_spec_cert_identifier 2 5 29 39 */ + 1293, /* OBJ_basic_att_constraints 2 5 29 41 */ + 1294, /* OBJ_delegated_name_constraints 2 5 29 42 */ + 1295, /* OBJ_time_specification 2 5 29 43 */ 857, /* OBJ_freshest_crl 2 5 29 46 */ + 1296, /* OBJ_attribute_descriptor 2 5 29 48 */ + 1297, /* OBJ_user_notice 2 5 29 49 */ + 1298, /* OBJ_soa_identifier 2 5 29 50 */ + 1299, /* OBJ_acceptable_cert_policies 2 5 29 52 */ 748, /* OBJ_inhibit_any_policy 2 5 29 54 */ 402, /* OBJ_target_information 2 5 29 55 */ 403, /* OBJ_no_rev_avail 2 5 29 56 */ + 1300, /* OBJ_acceptable_privilege_policies 2 5 29 57 */ + 1301, /* OBJ_indirect_issuer 2 5 29 61 */ + 1302, /* OBJ_no_assertion 2 5 29 62 */ + 1303, /* OBJ_id_aa_issuing_distribution_point 2 5 29 63 */ + 1304, /* OBJ_issued_on_behalf_of 2 5 29 64 */ + 1305, /* OBJ_single_use 2 5 29 65 */ + 1306, /* OBJ_group_ac 2 5 29 66 */ + 1307, /* OBJ_allowed_attribute_assignments 2 5 29 67 */ + 1308, /* OBJ_attribute_mappings 2 5 29 68 */ + 1309, /* OBJ_holder_name_constraints 2 5 29 69 */ + 1310, /* OBJ_authorization_validation 2 5 29 70 */ + 1311, /* OBJ_prot_restrict 2 5 29 71 */ + 1312, /* OBJ_subject_alt_public_key_info 2 5 29 72 */ + 1313, /* OBJ_alt_signature_algorithm 2 5 29 73 */ + 1314, /* OBJ_alt_signature_value 2 5 29 74 */ + 1315, /* OBJ_associated_information 2 5 29 75 */ 513, /* OBJ_set_ctype 2 23 42 0 */ 514, /* OBJ_set_msgExt 2 23 42 1 */ 515, /* OBJ_set_attr 2 23 42 3 */ @@ -5146,6 +5491,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { 517, /* OBJ_set_certExt 2 23 42 7 */ 518, /* OBJ_set_brand 2 23 42 8 */ 679, /* OBJ_wap_wsg 2 23 43 1 */ + 1316, /* OBJ_tcg 2 23 133 */ 1266, /* OBJ_electronic_signature_standard 0 4 0 1733 */ 382, /* OBJ_Directory 1 3 6 1 1 */ 383, /* OBJ_Management 1 3 6 1 2 */ @@ -5272,6 +5618,15 @@ static const unsigned int obj_objs[NUM_OBJ] = { 637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ 638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ 639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ + 1317, /* OBJ_tcg_tcpaSpecVersion 2 23 133 1 */ + 1318, /* OBJ_tcg_attribute 2 23 133 2 */ + 1319, /* OBJ_tcg_protocol 2 23 133 3 */ + 1320, /* OBJ_tcg_algorithm 2 23 133 4 */ + 1321, /* OBJ_tcg_platformClass 2 23 133 5 */ + 1322, /* OBJ_tcg_ce 2 23 133 6 */ + 1323, /* OBJ_tcg_kp 2 23 133 8 */ + 1324, /* OBJ_tcg_address 2 23 133 17 */ + 1325, /* OBJ_tcg_registry 2 23 133 18 */ 1273, /* OBJ_cades 0 4 0 19122 */ 1267, /* OBJ_ess_attributes 0 4 0 1733 2 */ 1195, /* OBJ_gmac 1 0 9797 3 4 */ @@ -5357,6 +5712,39 @@ static const unsigned int obj_objs[NUM_OBJ] = { 743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ 744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ 745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ + 1334, /* OBJ_tcg_at_tpmManufacturer 2 23 133 2 1 */ + 1335, /* OBJ_tcg_at_tpmModel 2 23 133 2 2 */ + 1336, /* OBJ_tcg_at_tpmVersion 2 23 133 2 3 */ + 1337, /* OBJ_tcg_at_securityQualities 2 23 133 2 10 */ + 1338, /* OBJ_tcg_at_tpmProtectionProfile 2 23 133 2 11 */ + 1339, /* OBJ_tcg_at_tpmSecurityTarget 2 23 133 2 12 */ + 1340, /* OBJ_tcg_at_tbbProtectionProfile 2 23 133 2 13 */ + 1341, /* OBJ_tcg_at_tbbSecurityTarget 2 23 133 2 14 */ + 1342, /* OBJ_tcg_at_tpmIdLabel 2 23 133 2 15 */ + 1343, /* OBJ_tcg_at_tpmSpecification 2 23 133 2 16 */ + 1344, /* OBJ_tcg_at_tcgPlatformSpecification 2 23 133 2 17 */ + 1345, /* OBJ_tcg_at_tpmSecurityAssertions 2 23 133 2 18 */ + 1346, /* OBJ_tcg_at_tbbSecurityAssertions 2 23 133 2 19 */ + 1347, /* OBJ_tcg_at_tcgCredentialSpecification 2 23 133 2 23 */ + 1348, /* OBJ_tcg_at_tcgCredentialType 2 23 133 2 25 */ + 1363, /* OBJ_tcg_prt_tpmIdProtocol 2 23 133 3 1 */ + 1351, /* OBJ_tcg_algorithm_null 2 23 133 4 1 */ + 1326, /* OBJ_tcg_common 2 23 133 5 1 */ + 1357, /* OBJ_tcg_ce_relevantCredentials 2 23 133 6 2 */ + 1358, /* OBJ_tcg_ce_relevantManifests 2 23 133 6 3 */ + 1359, /* OBJ_tcg_ce_virtualPlatformAttestationService 2 23 133 6 4 */ + 1360, /* OBJ_tcg_ce_migrationControllerAttestationService 2 23 133 6 5 */ + 1361, /* OBJ_tcg_ce_migrationControllerRegistrationService 2 23 133 6 6 */ + 1362, /* OBJ_tcg_ce_virtualPlatformBackupService 2 23 133 6 7 */ + 1352, /* OBJ_tcg_kp_EKCertificate 2 23 133 8 1 */ + 1353, /* OBJ_tcg_kp_PlatformAttributeCertificate 2 23 133 8 2 */ + 1354, /* OBJ_tcg_kp_AIKCertificate 2 23 133 8 3 */ + 1355, /* OBJ_tcg_kp_PlatformKeyCertificate 2 23 133 8 4 */ + 1356, /* OBJ_tcg_kp_DeltaPlatformAttributeCertificate 2 23 133 8 5 */ + 1364, /* OBJ_tcg_address_ethernetmac 2 23 133 17 1 */ + 1365, /* OBJ_tcg_address_wlanmac 2 23 133 17 2 */ + 1366, /* OBJ_tcg_address_bluetoothmac 2 23 133 17 3 */ + 1367, /* OBJ_tcg_registry_componentClass 2 23 133 18 3 */ 1274, /* OBJ_cades_attributes 0 4 0 19122 1 */ 1268, /* OBJ_id_aa_ets_mimeType 0 4 0 1733 2 1 */ 1269, /* OBJ_id_aa_ets_longTermValidation 0 4 0 1733 2 2 */ @@ -5405,6 +5793,16 @@ static const unsigned int obj_objs[NUM_OBJ] = { 633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ 634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ 635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ + 1327, /* OBJ_tcg_at_platformManufacturerStr 2 23 133 5 1 1 */ + 1328, /* OBJ_tcg_at_platformManufacturerId 2 23 133 5 1 2 */ + 1329, /* OBJ_tcg_at_platformConfigUri 2 23 133 5 1 3 */ + 1330, /* OBJ_tcg_at_platformModel 2 23 133 5 1 4 */ + 1331, /* OBJ_tcg_at_platformVersion 2 23 133 5 1 5 */ + 1332, /* OBJ_tcg_at_platformSerial 2 23 133 5 1 6 */ + 1333, /* OBJ_tcg_at_platformConfiguration 2 23 133 5 1 7 */ + 1368, /* OBJ_tcg_registry_componentClass_tcg 2 23 133 18 3 1 */ + 1369, /* OBJ_tcg_registry_componentClass_ietf 2 23 133 18 3 2 */ + 1370, /* OBJ_tcg_registry_componentClass_dmtf 2 23 133 18 3 3 */ 1275, /* OBJ_id_aa_ets_signerAttrV2 0 4 0 19122 1 1 */ 1276, /* OBJ_id_aa_ets_sigPolicyStore 0 4 0 19122 1 3 */ 1277, /* OBJ_id_aa_ATSHashIndex_v2 0 4 0 19122 1 4 */ @@ -5487,6 +5885,8 @@ static const unsigned int obj_objs[NUM_OBJ] = { 508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ 57, /* OBJ_netscape 2 16 840 1 113730 */ 1282, /* OBJ_oracle 2 16 840 1 113894 */ + 1349, /* OBJ_tcg_at_platformConfiguration_v1 2 23 133 5 1 7 1 */ + 1350, /* OBJ_tcg_at_platformConfiguration_v2 2 23 133 5 1 7 2 */ 754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ 766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ 757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index f0fe5c64e5202..673e255f1480b 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1288,3 +1288,83 @@ brainpoolP512r1tls13 1287 brotli 1288 zstd 1289 sm4_xts 1290 +authority_attribute_identifier 1291 +role_spec_cert_identifier 1292 +basic_att_constraints 1293 +delegated_name_constraints 1294 +time_specification 1295 +attribute_descriptor 1296 +user_notice 1297 +soa_identifier 1298 +acceptable_cert_policies 1299 +acceptable_privilege_policies 1300 +indirect_issuer 1301 +no_assertion 1302 +id_aa_issuing_distribution_point 1303 +issued_on_behalf_of 1304 +single_use 1305 +group_ac 1306 +allowed_attribute_assignments 1307 +attribute_mappings 1308 +holder_name_constraints 1309 +authorization_validation 1310 +prot_restrict 1311 +subject_alt_public_key_info 1312 +alt_signature_algorithm 1313 +alt_signature_value 1314 +associated_information 1315 +tcg 1316 +tcg_tcpaSpecVersion 1317 +tcg_attribute 1318 +tcg_protocol 1319 +tcg_algorithm 1320 +tcg_platformClass 1321 +tcg_ce 1322 +tcg_kp 1323 +tcg_address 1324 +tcg_registry 1325 +tcg_common 1326 +tcg_at_platformManufacturerStr 1327 +tcg_at_platformManufacturerId 1328 +tcg_at_platformConfigUri 1329 +tcg_at_platformModel 1330 +tcg_at_platformVersion 1331 +tcg_at_platformSerial 1332 +tcg_at_platformConfiguration 1333 +tcg_at_tpmManufacturer 1334 +tcg_at_tpmModel 1335 +tcg_at_tpmVersion 1336 +tcg_at_securityQualities 1337 +tcg_at_tpmProtectionProfile 1338 +tcg_at_tpmSecurityTarget 1339 +tcg_at_tbbProtectionProfile 1340 +tcg_at_tbbSecurityTarget 1341 +tcg_at_tpmIdLabel 1342 +tcg_at_tpmSpecification 1343 +tcg_at_tcgPlatformSpecification 1344 +tcg_at_tpmSecurityAssertions 1345 +tcg_at_tbbSecurityAssertions 1346 +tcg_at_tcgCredentialSpecification 1347 +tcg_at_tcgCredentialType 1348 +tcg_at_platformConfiguration_v1 1349 +tcg_at_platformConfiguration_v2 1350 +tcg_algorithm_null 1351 +tcg_kp_EKCertificate 1352 +tcg_kp_PlatformAttributeCertificate 1353 +tcg_kp_AIKCertificate 1354 +tcg_kp_PlatformKeyCertificate 1355 +tcg_kp_DeltaPlatformAttributeCertificate 1356 +tcg_ce_relevantCredentials 1357 +tcg_ce_relevantManifests 1358 +tcg_ce_virtualPlatformAttestationService 1359 +tcg_ce_migrationControllerAttestationService 1360 +tcg_ce_migrationControllerRegistrationService 1361 +tcg_ce_virtualPlatformBackupService 1362 +tcg_prt_tpmIdProtocol 1363 +tcg_address_ethernetmac 1364 +tcg_address_wlanmac 1365 +tcg_address_bluetoothmac 1366 +tcg_registry_componentClass 1367 +tcg_registry_componentClass_tcg 1368 +tcg_registry_componentClass_ietf 1369 +tcg_registry_componentClass_dmtf 1370 diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h index c08b5fc2aba07..fff70400757e5 100644 --- a/crypto/objects/obj_xref.h +++ b/crypto/objects/obj_xref.h @@ -2,7 +2,7 @@ * WARNING: do not edit! * Generated by objxref.pl * - * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2023 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/objects/objects.txt b/crypto/objects/objects.txt index ed4746f4620e2..1d53174c056cf 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -512,7 +512,7 @@ id-pkix-mod 100 : id-mod-cmp2021-02 id-pe 1 : authorityInfoAccess : Authority Information Access id-pe 2 : biometricInfo : Biometric Info id-pe 3 : qcStatements -id-pe 4 : ac-auditEntity +id-pe 4 : ac-auditEntity : Audit Identity id-pe 5 : ac-targeting id-pe 6 : aaControls id-pe 7 : sbgp-ipAddrBlock @@ -873,14 +873,64 @@ id-ce 35 : authorityKeyIdentifier : X509v3 Authority Key Identifier id-ce 36 : policyConstraints : X509v3 Policy Constraints !Cname ext-key-usage id-ce 37 : extendedKeyUsage : X509v3 Extended Key Usage +!Cname authority-attribute-identifier +id-ce 38 : authorityAttributeIdentifier : X509v3 Authority Attribute Identifier +!Cname role-spec-cert-identifier +id-ce 39 : roleSpecCertIdentifier : X509v3 Role Specification Certificate Identifier +!Cname basic-att-constraints +id-ce 41 : basicAttConstraints : X509v3 Basic Attribute Certificate Constraints +!Cname delegated-name-constraints +id-ce 42 : delegatedNameConstraints : X509v3 Delegated Name Constraints +!Cname time-specification +id-ce 43 : timeSpecification : X509v3 Time Specification !Cname freshest-crl id-ce 46 : freshestCRL : X509v3 Freshest CRL +!Cname attribute-descriptor +id-ce 48 : attributeDescriptor : X509v3 Attribute Descriptor +!Cname user-notice +id-ce 49 : userNotice : X509v3 User Notice +!Cname soa-identifier +id-ce 50 : sOAIdentifier : X509v3 Source of Authority Identifier +!Cname acceptable-cert-policies +id-ce 52 : acceptableCertPolicies : X509v3 Acceptable Certification Policies !Cname inhibit-any-policy id-ce 54 : inhibitAnyPolicy : X509v3 Inhibit Any Policy !Cname target-information id-ce 55 : targetInformation : X509v3 AC Targeting !Cname no-rev-avail id-ce 56 : noRevAvail : X509v3 No Revocation Available +!Cname acceptable-privilege-policies +id-ce 57 : acceptablePrivPolicies : X509v3 Acceptable Privilege Policies +!Cname indirect-issuer +id-ce 61 : indirectIssuer : X509v3 Indirect Issuer +!Cname no-assertion +id-ce 62 : noAssertion : X509v3 No Assertion +!Cname id-aa-issuing-distribution-point +id-ce 63 : aAissuingDistributionPoint : X509v3 Attribute Authority Issuing Distribution Point +!Cname issued-on-behalf-of +id-ce 64 : issuedOnBehalfOf : X509v3 Issued On Behalf Of +!Cname single-use +id-ce 65 : singleUse : X509v3 Single Use +!Cname group-ac +id-ce 66 : groupAC : X509v3 Group Attribute Certificate +!Cname allowed-attribute-assignments +id-ce 67 : allowedAttributeAssignments : X509v3 Allowed Attribute Assignments +!Cname attribute-mappings +id-ce 68 : attributeMappings : X509v3 Attribute Mappings +!Cname holder-name-constraints +id-ce 69 : holderNameConstraints : X509v3 Holder Name Constraints +!Cname authorization-validation +id-ce 70 : authorizationValidation : X509v3 Authorization Validation +!Cname prot-restrict +id-ce 71 : protRestrict : X509v3 Protocol Restriction +!Cname subject-alt-public-key-info +id-ce 72 : subjectAltPublicKeyInfo : X509v3 Subject Alternative Public Key Info +!Cname alt-signature-algorithm +id-ce 73 : altSignatureAlgorithm : X509v3 Alternative Signature Algorithm +!Cname alt-signature-value +id-ce 74 : altSignatureValue : X509v3 Alternative Signature Value +!Cname associated-information +id-ce 75 : associatedInformation : X509v3 Associated Information # From RFC5280 ext-key-usage 0 : anyExtendedKeyUsage : Any Extended Key Usage @@ -1807,3 +1857,70 @@ oracle 746875 1 1 : oracle-jdk-trustedkeyusage : Trusted key usage (Oracle) # NID for compression : brotli : Brotli compression : zstd : Zstandard compression + +2 23 133 : tcg : Trusted Computing Group + +tcg 1 : tcg-tcpaSpecVersion +tcg 2 : tcg-attribute : Trusted Computing Group Attributes +tcg 3 : tcg-protocol : Trusted Computing Group Protocols +tcg 4 : tcg-algorithm : Trusted Computing Group Algorithms +tcg 5 : tcg-platformClass : Trusted Computing Group Platform Classes +tcg 6 : tcg-ce : Trusted Computing Group Certificate Extensions +tcg 8 : tcg-kp : Trusted Computing Group Key Purposes +tcg 17 : tcg-address : Trusted Computing Group Address Formats +tcg 18 : tcg-registry : Trusted Computing Group Registry + +tcg-platformClass 1 : tcg-common : TCG Common +tcg-common 1 : tcg-at-platformManufacturerStr : TCG Platform Manufacturer String +tcg-common 2 : tcg-at-platformManufacturerId : TCG Platform Manufacturer ID +tcg-common 3 : tcg-at-platformConfigUri : TCG Platform Configuration URI +tcg-common 4 : tcg-at-platformModel : TCG Platform Model +tcg-common 5 : tcg-at-platformVersion : TCG Platform Version +tcg-common 6 : tcg-at-platformSerial : TCG Platform Serial Number +tcg-common 7 : tcg-at-platformConfiguration : TCG Platform Configuration + +tcg-attribute 1 : tcg-at-tpmManufacturer : TPM Manufacturer +tcg-attribute 2 : tcg-at-tpmModel : TPM Model +tcg-attribute 3 : tcg-at-tpmVersion : TPM Version +tcg-attribute 10 : tcg-at-securityQualities : Security Qualities +tcg-attribute 11 : tcg-at-tpmProtectionProfile : TPM Protection Profile +tcg-attribute 12 : tcg-at-tpmSecurityTarget : TPM Security Target +tcg-attribute 13 : tcg-at-tbbProtectionProfile : TBB Protection Profile +tcg-attribute 14 : tcg-at-tbbSecurityTarget : TBB Security Target +tcg-attribute 15 : tcg-at-tpmIdLabel : TPM ID Label +tcg-attribute 16 : tcg-at-tpmSpecification : TPM Specification +tcg-attribute 17 : tcg-at-tcgPlatformSpecification : TPM Platform Specification +tcg-attribute 18 : tcg-at-tpmSecurityAssertions : TPM Security Assertions +tcg-attribute 19 : tcg-at-tbbSecurityAssertions : TBB Security Assertions +tcg-attribute 23 : tcg-at-tcgCredentialSpecification : TCG Credential Specification +tcg-attribute 25 : tcg-at-tcgCredentialType : TCG Credential Type + +tcg-at-platformConfiguration 1 : tcg-at-platformConfiguration-v1 : Platform Configuration Version 1 +tcg-at-platformConfiguration 2 : tcg-at-platformConfiguration-v2 : Platform Configuration Version 2 + +tcg-algorithm 1 : tcg-algorithm-null : TCG NULL Algorithm + +tcg-kp 1 : tcg-kp-EKCertificate : Endorsement Key Certificate +tcg-kp 2 : tcg-kp-PlatformAttributeCertificate : Platform Attribute Certificate +tcg-kp 3 : tcg-kp-AIKCertificate : Attestation Identity Key Certificate +tcg-kp 4 : tcg-kp-PlatformKeyCertificate : Platform Key Certificate +tcg-kp 5 : tcg-kp-DeltaPlatformAttributeCertificate : Delta Platform Attribute Certificate + +tcg-ce 2 : tcg-ce-relevantCredentials : Relevant Credentials +tcg-ce 3 : tcg-ce-relevantManifests : Relevant Manifests +tcg-ce 4 : tcg-ce-virtualPlatformAttestationService : Virtual Platform Attestation Service +tcg-ce 5 : tcg-ce-migrationControllerAttestationService : Migration Controller Attestation Service +tcg-ce 6 : tcg-ce-migrationControllerRegistrationService : Migration Controller Registration Service +tcg-ce 7 : tcg-ce-virtualPlatformBackupService : Virtual Platform Backup Service + +tcg-protocol 1 : tcg-prt-tpmIdProtocol : TCG TPM Protocol + +tcg-address 1 : tcg-address-ethernetmac : Ethernet MAC Address +tcg-address 2 : tcg-address-wlanmac : WLAN MAC Address +tcg-address 3 : tcg-address-bluetoothmac : Bluetooth MAC Address + +tcg-registry 3 : tcg-registry-componentClass : TCG Component Class + +tcg-registry-componentClass 1 : tcg-registry-componentClass-tcg : Trusted Computed Group Registry +tcg-registry-componentClass 2 : tcg-registry-componentClass-ietf : Internet Engineering Task Force Registry +tcg-registry-componentClass 3 : tcg-registry-componentClass-dmtf : Distributed Management Task Force Registry \ No newline at end of file diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c index 222af64397b4d..37ba78f270e1c 100644 --- a/crypto/pem/pem_all.c +++ b/crypto/pem/pem_all.c @@ -40,6 +40,7 @@ IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) IMPLEMENT_PEM_rw(X509_PUBKEY, X509_PUBKEY, PEM_STRING_PUBLIC, X509_PUBKEY) IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) +IMPLEMENT_PEM_rw(X509_ACERT, X509_ACERT, PEM_STRING_ACERT, X509_ACERT) IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) diff --git a/crypto/x509/acert_vfy.c b/crypto/x509/acert_vfy.c new file mode 100644 index 0000000000000..b9b37e2c8acc5 --- /dev/null +++ b/crypto/x509/acert_vfy.c @@ -0,0 +1,321 @@ +/* + * Copyright 1995-2023 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/ctype.h" +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/dane.h" +#include "crypto/x509.h" +#include "x509_local.h" +#include "crypto/x509_acert.h" +#include "openssl/x509_acert.h" + +int TARGET_CERT_cmp (TARGET_CERT* a, TARGET_CERT* b); +int ossl_x509_check_targeting (TARGET *asserted, TARGETING_INFORMATION *tinfo); + +/*- + * Check attribute certificate validity times. + * Make second argument NULL to evaluate against the current time. + */ +int ossl_x509_check_acert_time(X509_ACERT *acert, time_t* as_of) +{ + int i; + + i = X509_cmp_time(X509_ACERT_get0_notBefore(acert), as_of); + if (i == 0) + return X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + if (i > 0) + return X509_V_ERR_CERT_NOT_YET_VALID; + + i = X509_cmp_time(X509_ACERT_get0_notAfter(acert), as_of); + if (i == 0) + return X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + if (i < 0) + return X509_V_ERR_CERT_HAS_EXPIRED; + + return X509_V_OK; +} + +/* Returns 0 if they are equal, != 0 otherwise. certDigestInfo is not checked. */ +int TARGET_CERT_cmp (TARGET_CERT* a, TARGET_CERT* b) { + int a_name_num, b_name_num, i, j; + GENERAL_NAMES *a_names, *b_names; + GENERAL_NAME *a_name, *b_name; + if (!ASN1_INTEGER_cmp(&a->targetCertificate->serial, + &b->targetCertificate->serial)) { + return 1; + } + a_names = a->targetCertificate->issuer; + b_names = b->targetCertificate->issuer; + a_name_num = sk_GENERAL_NAME_num(a_names); + b_name_num = sk_GENERAL_NAME_num(b_names); + for (i = 0; i < a_name_num; i++) { + for (j = 0; j < b_name_num; j++) { + a_name = sk_GENERAL_NAME_value(a_names, i); + b_name = sk_GENERAL_NAME_value(b_names, j); + if (!GENERAL_NAME_cmp(a_name, b_name)) { + return 0; + } + } + } + return 2; +} + +int ossl_x509_check_targeting (TARGET *asserted, TARGETING_INFORMATION *tinfo) { + int i, j, targets_num, target_num; + TARGETS* tgts; + TARGET* tgt; + GENERAL_NAME *gn, *asserted_gn; + TARGET_CERT *tc, *asserted_tc; + targets_num = sk_TARGETS_num(tinfo); + for (i = 0; i < targets_num; i++) { + tgts = sk_TARGETS_value(tinfo, i); + target_num = sk_TARGET_num(tgts); + for (j = 0; j < target_num; j++) { + tgt = sk_TARGET_value(tgts, j); + if (tgt->type != asserted->type) { + continue; + } + switch (tgt->type) { + case (TGT_TARGET_NAME): { + gn = tgt->choice.targetName; + asserted_gn = asserted->choice.targetName; + if (!GENERAL_NAME_cmp(gn, asserted_gn)) { + return 1; + } + break; + } + case (TGT_TARGET_GROUP): { + // TODO: Define a group lookup callback? + // gn = tgt->choice.targetGroup; + /* Currently unrecognized. */ + break; + } + case (TGT_TARGET_CERT): { + tc = tgt->choice.targetCert; + asserted_tc = asserted->choice.targetCert; + if (TARGET_CERT_cmp(asserted_tc, tc)) { + continue; + } + /* The targetName field of TargetCert is not explained. My + assumption is that, if it is present in the certificate, it + further constrains the asserted targetName to an exact + match, and without it, any targetName is acceptable as long + as the target's IssuerSerial matches. */ + if (tc->targetName != NULL) { + if (asserted_tc->targetName != NULL) { + continue; + } + if (!GENERAL_NAME_cmp(tc->targetName, + asserted_tc->targetName)) { + return 1; + } + } + break; + } + } + } + } + return 0; +} + +int ossl_x509_check_acert_exts(X509_ACERT *acert, TARGET *tgt, + int asserted_before) +{ + int i, critical, nid; + X509_EXTENSION *current_ext; + ASN1_OBJECT *oid; + TARGETING_INFORMATION *tinfo; + int n = X509_acert_get_ext_count(acert); + + for (i = 0; i < n; i++) { + current_ext = X509_acert_get_ext(acert, i); + if (current_ext == NULL) + break; + oid = X509_EXTENSION_get_object(current_ext); + nid = OBJ_obj2nid(oid); + switch (nid) { + case NID_no_assertion: + return X509_V_ERR_NO_ASSERTION; + case NID_single_use: { + if (asserted_before) + return X509_V_ERR_SINGLE_USE; + break; + } + case NID_target_information: { + if (tgt != NULL) { + tinfo = X509V3_EXT_d2i(current_ext); + if (!ossl_x509_check_targeting(tgt, tinfo)) + return X509_V_ERR_INVALID_TARGET; + } + break; + } + default: { + /* You have to use this function, because X509_EXTENSION defaults the + critical field to -1 which evaluates truthy! */ + critical = X509_EXTENSION_get_critical(current_ext); + if (critical) { + return X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + } + } + } + } + return X509_V_OK; +} + +/* This DOES NOT verify the issuer or holder certificates. Those must be +verified separately. */ +int X509_attr_cert_verify_ex(X509_ACERT *acert, X509 *issuer, X509 *holder, + TARGET *tgt, int asserted_before) { + int rc, holder_verified; + EVP_PKEY *pkey; + AUTHORITY_KEYID *akid; + OSSL_ISSUER_SERIAL *basecertid; + GENERAL_NAMES *holder_ent; + + if (X509_ALGOR_cmp(&acert->sig_alg, &acert->acinfo->signature) != 0) + return X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH; + + if (holder != NULL) { + /* + * Check that holder cert matches attribute cert holder field. + * This can be done withi *either* the baseCertificateId or the + * entityName. RFC 5755 recommends that only one option is used + * for a given AC, but in case both are present, baseCertificateId + * takes precedence. + */ + if ((basecertid = X509_ACERT_get0_holder_baseCertId(acert)) != NULL) { + if (X509_NAME_cmp(OSSL_ISSUER_SERIAL_get0_issuer(basecertid), + X509_get_issuer_name(holder)) != 0 + || ASN1_STRING_cmp(OSSL_ISSUER_SERIAL_get0_serial(basecertid), + X509_get0_serialNumber(holder)) != 0) { + return X509_V_ERR_ISSUER_HOLDER_MISMATCH; + } + holder_verified = 1; + } + + if (holder_verified == 0 + && (holder_ent = X509_ACERT_get0_holder_entityName(acert)) != NULL + && sk_GENERAL_NAME_num(holder_ent) >= 1) { + GENERAL_NAMES *holderAltNames; + GENERAL_NAME *entName = sk_GENERAL_NAME_value(holder_ent, 0); + int i; + + if (entName->type == GEN_DIRNAME + && X509_NAME_cmp(entName->d.directoryName, X509_get_subject_name(holder)) == 0) + holder_verified = 1; + + if (holder_verified == 0 + && (holderAltNames = X509_get_ext_d2i(holder, NID_subject_alt_name, + NULL, NULL)) != NULL) { + for (i = 0; i < sk_GENERAL_NAME_num(holderAltNames); i++) { + GENERAL_NAME *name = sk_GENERAL_NAME_value(holderAltNames, i); + + if (GENERAL_NAME_cmp(name, entName) == 0) { + holder_verified = 1; + break; + } + } + } + } + + if (holder_verified == 0) { + return X509_V_ERR_ISSUER_HOLDER_MISMATCH; + } + } + + akid = X509V3_get_d2i(acert->acinfo->extensions, NID_authority_key_identifier, NULL, NULL); + if (akid != NULL) { + rc = X509_check_akid(issuer, akid); + if (rc != X509_V_OK) + return rc; + } + if ((pkey = X509_get0_pubkey(issuer)) == NULL) + return X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + rc = X509_ACERT_verify(acert, pkey); + if (rc != 1) + return X509_V_ERR_CERT_SIGNATURE_FAILURE; + + rc = ossl_x509_check_acert_time(acert, NULL); + if (rc != X509_V_OK) + return rc; + + /* + * Check that the issuer satisfies the AC issuer profile in + * RFC 5755 Section 4.5. This will also cache the attached + * X509v3 extensions, which must be done before calling + * X509_check_akid() and X509_check_ca() to get valid results. + */ + if ((X509_get_key_usage(issuer) & X509v3_KU_DIGITAL_SIGNATURE) == 0) { + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } + + rc = ossl_x509_check_acert_exts(acert, tgt, asserted_before); + if (rc != X509_V_OK) + return rc; + + return X509_V_OK; +} + +int X509_attr_cert_verify(X509_ACERT *acert, X509 *issuer) +{ + return X509_attr_cert_verify_ex(acert, issuer, NULL, NULL, 0); +} + +/*- + * Inform the verify callback of an error, CRL-specific variant. Here, the + * error depth and certificate are already set, we just specify the error + * number. + * + * Returns 0 to abort verification with an error, non-zero to continue. + */ +static int verify_cb_crl(X509_STORE_CTX *ctx, int err) +{ + ctx->error = err; + return ctx->verify_cb(0, ctx); +} + +int acert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509_ACERT *x) +{ + X509_REVOKED *rev; + + /* + * The rules changed for this... previously if a CRL contained unhandled + * critical extensions it could still be used to indicate a certificate + * was revoked. This has since been changed since critical extensions can + * change the meaning of CRL entries. + */ + if ((ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) == 0 + && (crl->flags & EXFLAG_CRITICAL) != 0 && + !verify_cb_crl(ctx, X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION)) + return 0; + /* + * Look for serial number of certificate in CRL. If found, make sure + * reason is not removeFromCRL. + */ + if (X509_CRL_get0_by_serial(crl, &rev, &x->acinfo->serialNumber)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + if (!verify_cb_crl(ctx, X509_V_ERR_CERT_REVOKED)) + return 0; + } + + return 1; +} diff --git a/crypto/x509/build.info b/crypto/x509/build.info index 8820f983bb3d0..4d4d0380a222b 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -14,7 +14,13 @@ SOURCE[../../libcrypto]=\ v3_info.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c \ v3_pcia.c v3_pci.c v3_ist.c \ pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ - v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c + v3_asid.c v3_addr.c v3_tlsf.c v3_admis.c \ + x509_acert.c t_acert.c x509aset.c x_ietfatt.c \ + v3_no_rev_avail.c v3_soa_id.c v3_no_ass.c v3_group_ac.c \ + v3_single_use.c v3_ac_tgt.c v3_audit_id.c v3_bacons.c v3_sda.c \ + v3_usernotice.c x_unotice.c x_iserial.c v3_authattid.c v3_iobo.c \ + v3_aaa.c v3_attrmap.c v3_ind_iss.c v3_attrdesc.c v3_rolespec.c \ + v3_timespec.c platcert.c acert_vfy.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=x509type.c diff --git a/crypto/x509/ext_dat.h b/crypto/x509/ext_dat.h index a0a7f88ccd8ad..f57c11fedffa2 100644 --- a/crypto/x509/ext_dat.h +++ b/crypto/x509/ext_dat.h @@ -25,3 +25,27 @@ extern const X509V3_EXT_METHOD ossl_v3_tls_feature; extern const X509V3_EXT_METHOD ossl_v3_ext_admission; extern const X509V3_EXT_METHOD ossl_v3_utf8_list[1]; extern const X509V3_EXT_METHOD ossl_v3_issuer_sign_tool; +extern const X509V3_EXT_METHOD ossl_v3_group_ac; +extern const X509V3_EXT_METHOD ossl_v3_soa_identifier; +extern const X509V3_EXT_METHOD ossl_v3_no_assertion; +extern const X509V3_EXT_METHOD ossl_v3_no_rev_avail; +extern const X509V3_EXT_METHOD ossl_v3_single_use; +extern const X509V3_EXT_METHOD ossl_v3_targeting_information; +extern const X509V3_EXT_METHOD ossl_v3_audit_identity; +extern const X509V3_EXT_METHOD ossl_v3_bacons; +extern const X509V3_EXT_METHOD ossl_v3_delegated_name_constraints; +extern const X509V3_EXT_METHOD ossl_v3_subj_dir_attrs; +extern const X509V3_EXT_METHOD ossl_v3_associated_info; +extern const X509V3_EXT_METHOD ossl_v3_user_notice; +extern const X509V3_EXT_METHOD ossl_v3_acc_cert_policies; +extern const X509V3_EXT_METHOD ossl_v3_acc_priv_policies; +extern const X509V3_EXT_METHOD ossl_v3_authority_attribute_identifier; +extern const X509V3_EXT_METHOD ossl_v3_issued_on_behalf_of; +extern const X509V3_EXT_METHOD ossl_v3_allowed_attribute_assignments; +extern const X509V3_EXT_METHOD ossl_v3_attribute_mappings; +extern const X509V3_EXT_METHOD ossl_v3_holder_name_constraints; +extern const X509V3_EXT_METHOD ossl_v3_indirect_issuer; +extern const X509V3_EXT_METHOD ossl_v3_attribute_descriptor; +extern const X509V3_EXT_METHOD ossl_v3_aa_issuing_dist_point; +extern const X509V3_EXT_METHOD ossl_v3_role_spec_cert_identifier; +extern const X509V3_EXT_METHOD ossl_v3_time_specification; diff --git a/crypto/x509/platcert.c b/crypto/x509/platcert.c new file mode 100644 index 0000000000000..7c2d4bb52586e --- /dev/null +++ b/crypto/x509/platcert.c @@ -0,0 +1,670 @@ +/* + * Copyright 2022 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 "x509_local.h" +#include +#include +#include + +ASN1_SEQUENCE(URI_REFERENCE) = { + ASN1_SIMPLE(URI_REFERENCE, uniformResourceIdentifier, ASN1_IA5STRING), + ASN1_OPT(URI_REFERENCE, hashAlgorithm, X509_ALGOR), + ASN1_OPT(URI_REFERENCE, hashValue, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(URI_REFERENCE) + +IMPLEMENT_ASN1_FUNCTIONS(URI_REFERENCE) + +ASN1_SEQUENCE(COMMON_CRITERIA_MEASURES) = { + ASN1_SIMPLE(COMMON_CRITERIA_MEASURES, version, ASN1_IA5STRING), + ASN1_SIMPLE(COMMON_CRITERIA_MEASURES, assurancelevel, ASN1_ENUMERATED), + ASN1_SIMPLE(COMMON_CRITERIA_MEASURES, evaluationStatus, ASN1_ENUMERATED), + ASN1_OPT(COMMON_CRITERIA_MEASURES, plus, ASN1_FBOOLEAN), + ASN1_IMP_OPT(COMMON_CRITERIA_MEASURES, strengthOfFunction, ASN1_ENUMERATED, 0), + ASN1_IMP_OPT(COMMON_CRITERIA_MEASURES, profileOid, ASN1_OBJECT, 1), + ASN1_IMP_OPT(COMMON_CRITERIA_MEASURES, profileUri, URI_REFERENCE, 2), + ASN1_IMP_OPT(COMMON_CRITERIA_MEASURES, targetOid, ASN1_OBJECT, 3), + ASN1_IMP_OPT(COMMON_CRITERIA_MEASURES, targetUri, URI_REFERENCE, 4), +} ASN1_SEQUENCE_END(COMMON_CRITERIA_MEASURES) + +IMPLEMENT_ASN1_FUNCTIONS(COMMON_CRITERIA_MEASURES) + +ASN1_SEQUENCE(FIPS_LEVEL) = { + ASN1_SIMPLE(FIPS_LEVEL, version, ASN1_IA5STRING), + ASN1_SIMPLE(FIPS_LEVEL, level, ASN1_ENUMERATED), + ASN1_OPT(FIPS_LEVEL, plus, ASN1_FBOOLEAN) +} ASN1_SEQUENCE_END(FIPS_LEVEL) + +IMPLEMENT_ASN1_FUNCTIONS(FIPS_LEVEL) + +ASN1_SEQUENCE(TBB_SECURITY_ASSERTIONS) = { + ASN1_OPT(TBB_SECURITY_ASSERTIONS, version, ASN1_INTEGER), + ASN1_IMP_OPT(TBB_SECURITY_ASSERTIONS, ccInfo, COMMON_CRITERIA_MEASURES, 0), + ASN1_IMP_OPT(TBB_SECURITY_ASSERTIONS, fipsLevel, FIPS_LEVEL, 1), + ASN1_IMP_OPT(TBB_SECURITY_ASSERTIONS, rtmType, ASN1_ENUMERATED, 2), + ASN1_OPT(TBB_SECURITY_ASSERTIONS, iso9000Certified, ASN1_FBOOLEAN), + ASN1_OPT(TBB_SECURITY_ASSERTIONS, iso9000Uri, ASN1_IA5STRING), +} ASN1_SEQUENCE_END(TBB_SECURITY_ASSERTIONS) + +IMPLEMENT_ASN1_FUNCTIONS(TBB_SECURITY_ASSERTIONS) + +ASN1_SEQUENCE(MANUFACTURER_ID) = { + ASN1_SIMPLE(MANUFACTURER_ID, manufacturerIdentifier, ASN1_OBJECT) +} ASN1_SEQUENCE_END(MANUFACTURER_ID) + +IMPLEMENT_ASN1_FUNCTIONS(MANUFACTURER_ID) + +ASN1_SEQUENCE(TCG_SPEC_VERSION) = { + ASN1_SIMPLE(TCG_SPEC_VERSION, majorVersion, ASN1_INTEGER), + ASN1_SIMPLE(TCG_SPEC_VERSION, minorVersion, ASN1_INTEGER), + ASN1_SIMPLE(TCG_SPEC_VERSION, revision, ASN1_INTEGER) +} ASN1_SEQUENCE_END(TCG_SPEC_VERSION) + +IMPLEMENT_ASN1_FUNCTIONS(TCG_SPEC_VERSION) + +ASN1_SEQUENCE(TCG_PLATFORM_SPEC) = { + ASN1_SIMPLE(TCG_PLATFORM_SPEC, version, TCG_SPEC_VERSION), + ASN1_SIMPLE(TCG_PLATFORM_SPEC, platformClass, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(TCG_PLATFORM_SPEC) + +IMPLEMENT_ASN1_FUNCTIONS(TCG_PLATFORM_SPEC) + +ASN1_SEQUENCE(TCG_CRED_TYPE) = { + ASN1_SIMPLE(TCG_CRED_TYPE, certificateType, ASN1_OBJECT) +} ASN1_SEQUENCE_END(TCG_CRED_TYPE) + +IMPLEMENT_ASN1_FUNCTIONS(TCG_CRED_TYPE) + +ASN1_SEQUENCE(COMPONENT_ADDRESS) = { + ASN1_SIMPLE(COMPONENT_ADDRESS, addressType, ASN1_OBJECT), + ASN1_SIMPLE(COMPONENT_ADDRESS, addressValue, ASN1_UTF8STRING) +} ASN1_SEQUENCE_END(COMPONENT_ADDRESS) + +IMPLEMENT_ASN1_FUNCTIONS(COMPONENT_ADDRESS) + +ASN1_SEQUENCE(PLATFORM_PROPERTY) = { + ASN1_SIMPLE(PLATFORM_PROPERTY, propertyName, ASN1_UTF8STRING), + ASN1_SIMPLE(PLATFORM_PROPERTY, propertyValue, ASN1_UTF8STRING), + ASN1_IMP_OPT(PLATFORM_PROPERTY, status, ASN1_ENUMERATED, 0) +} ASN1_SEQUENCE_END(PLATFORM_PROPERTY) + +IMPLEMENT_ASN1_FUNCTIONS(PLATFORM_PROPERTY) + +ASN1_SEQUENCE(ATTRIBUTE_CERTIFICATE_IDENTIFIER) = { + ASN1_SIMPLE(ATTRIBUTE_CERTIFICATE_IDENTIFIER, hashAlgorithm, X509_ALGOR), + ASN1_SIMPLE(ATTRIBUTE_CERTIFICATE_IDENTIFIER, hashOverSignatureValue, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(ATTRIBUTE_CERTIFICATE_IDENTIFIER) + +ASN1_SEQUENCE(CERTIFICATE_IDENTIFIER) = { + ASN1_IMP_OPT(CERTIFICATE_IDENTIFIER, attributeCertIdentifier, ATTRIBUTE_CERTIFICATE_IDENTIFIER, 0), + ASN1_IMP_OPT(CERTIFICATE_IDENTIFIER, genericCertIdentifier, OSSL_ISSUER_SERIAL, 1) +} ASN1_SEQUENCE_END(CERTIFICATE_IDENTIFIER) + +ASN1_SEQUENCE(COMPONENT_CLASS) = { + ASN1_SIMPLE(COMPONENT_CLASS, componentClassRegistry, ASN1_OBJECT), + ASN1_SIMPLE(COMPONENT_CLASS, componentClassValue, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(COMPONENT_CLASS) + +IMPLEMENT_ASN1_FUNCTIONS(COMPONENT_CLASS) + +ASN1_SEQUENCE(COMPONENT_IDENTIFIER) = { + ASN1_SIMPLE(COMPONENT_IDENTIFIER, componentClass, COMPONENT_CLASS), + ASN1_SIMPLE(COMPONENT_IDENTIFIER, componentManufacturer, ASN1_UTF8STRING), + ASN1_SIMPLE(COMPONENT_IDENTIFIER, componentModel, ASN1_UTF8STRING), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, componentSerial, ASN1_UTF8STRING, 0), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, componentRevision, ASN1_UTF8STRING, 1), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, componentManufacturerId, ASN1_OBJECT, 2), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, fieldReplaceable, ASN1_BOOLEAN, 3), + ASN1_IMP_SEQUENCE_OF_OPT(COMPONENT_IDENTIFIER, componentAddresses, COMPONENT_ADDRESS, 4), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, componentPlatformCert, CERTIFICATE_IDENTIFIER, 5), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, componentPlatformCertUri, URI_REFERENCE, 6), + ASN1_IMP_OPT(COMPONENT_IDENTIFIER, status, ASN1_ENUMERATED, 7) +} ASN1_SEQUENCE_END(COMPONENT_IDENTIFIER) + +IMPLEMENT_ASN1_FUNCTIONS(COMPONENT_IDENTIFIER) + +ASN1_SEQUENCE(PLATFORM_CONFIG) = { + ASN1_IMP_SEQUENCE_OF_OPT(PLATFORM_CONFIG, componentIdentifiers, COMPONENT_IDENTIFIER, 0), + ASN1_IMP_OPT(PLATFORM_CONFIG, componentIdentifiersUri, URI_REFERENCE, 1), + ASN1_IMP_SEQUENCE_OF_OPT(PLATFORM_CONFIG, platformProperties, PLATFORM_PROPERTY, 2), + ASN1_IMP_OPT(PLATFORM_CONFIG, platformPropertiesUri, URI_REFERENCE, 3) +} ASN1_SEQUENCE_END(PLATFORM_CONFIG) + +IMPLEMENT_ASN1_FUNCTIONS(PLATFORM_CONFIG) + +int URI_REFERENCE_print (BIO *out, URI_REFERENCE *value, int indent) { + int rc; + + rc = BIO_printf(out, "%*sURI: %.*s\n", indent, "", + value->uniformResourceIdentifier->length, + value->uniformResourceIdentifier->data); + if (rc <= 0) return rc; + if (value->hashAlgorithm != NULL) { + rc = BIO_printf(out, "%*sHash Algorithm:\n%*s", indent, "", indent + 4, ""); + if (rc <= 0) return rc; + rc = TS_X509_ALGOR_print_bio(out, value->hashAlgorithm); + if (rc <= 0) return rc; + } + if (value->hashValue != NULL) { + rc = BIO_printf(out, "%*sHash Value: ", indent, ""); + if (rc <= 0) return rc; + rc = print_hex(out, value->hashValue->data, value->hashValue->length); + if (rc <= 0) return rc; + } + return rc; +} + +static ENUMERATED_NAMES measurement_root_types[] = { + {MEASUREMENT_ROOT_TYPE_STATIC, "Static (0)", "static"}, + {MEASUREMENT_ROOT_TYPE_DYNAMIC, "Dynamic (1)", "dynamic"}, + {MEASUREMENT_ROOT_TYPE_NONHOST, "Non-Host (2)", "nonHost"}, + {MEASUREMENT_ROOT_TYPE_HYBRID, "Hybrid (3)", "hybrid"}, + {MEASUREMENT_ROOT_TYPE_PHYSICAL, "Physical (4)", "physical"}, + {MEASUREMENT_ROOT_TYPE_VIRTUAL, "Virtual (5)", "virtual"}, + {-1, NULL, NULL}, +}; + +static ENUMERATED_NAMES evaluation_assurance_levels[] = { + {EVALUATION_ASSURANCE_LEVEL_1, "Level 1", "level1"}, + {EVALUATION_ASSURANCE_LEVEL_2, "Level 2", "level2"}, + {EVALUATION_ASSURANCE_LEVEL_3, "Level 3", "level3"}, + {EVALUATION_ASSURANCE_LEVEL_4, "Level 4", "level4"}, + {EVALUATION_ASSURANCE_LEVEL_5, "Level 5", "level5"}, + {EVALUATION_ASSURANCE_LEVEL_6, "Level 6", "level6"}, + {EVALUATION_ASSURANCE_LEVEL_7, "Level 7", "level7"}, + {-1, NULL, NULL}, +}; + +static ENUMERATED_NAMES evaluation_statuses[] = { + {EVALUATION_STATUS_DESIGNED_TO_MEET, "Designed To Meet (0)", "designedToMeet"}, + {EVALUATION_STATUS_EVAL_IN_PROGRESS, "Evaluation In Progress (1)", "evaluationInProgress"}, + {EVALUATION_STATUS_EVAL_COMPLETED, "Evaluation Completed (2)", "evaluationCompleted"}, + {-1, NULL, NULL}, +}; + +static ENUMERATED_NAMES strengths_of_function[] = { + {STRENGTH_OF_FUNCTION_BASIC, "Basic (0)", "basic"}, + {STRENGTH_OF_FUNCTION_MEDIUM, "Medium (1)", "medium"}, + {STRENGTH_OF_FUNCTION_HIGH, "High (2)", "high"}, + {-1, NULL, NULL}, +}; + +static ENUMERATED_NAMES security_levels[] = { + {SECURITY_LEVEL_1, "Level 1", "level1"}, + {SECURITY_LEVEL_2, "Level 2", "level2"}, + {SECURITY_LEVEL_3, "Level 3", "level3"}, + {SECURITY_LEVEL_4, "Level 4", "level4"}, + {-1, NULL, NULL}, +}; + +static ENUMERATED_NAMES attribute_statuses[] = { + {ATTRIBUTE_STATUS_ADDED, "Added (0)", "added"}, + {ATTRIBUTE_STATUS_MODIFIED, "Modified (1)", "modified"}, + {ATTRIBUTE_STATUS_REMOVED, "Removed (2)", "removed"}, + {-1, NULL, NULL}, +}; + +int COMPONENT_CLASS_print (BIO *out, COMPONENT_CLASS *value, int indent) { + int rc; + + rc = BIO_printf(out, "%*sComponent Class Registry: ", indent, ""); + if (rc <= 0) return rc; + rc = print_oid(out, value->componentClassRegistry); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sComponent Class Registry: ", indent, ""); + if (rc <= 0) return rc; + rc = print_hex(out, value->componentClassValue->data, value->componentClassValue->length); + if (rc <= 0) return rc; + return BIO_puts(out, "\n"); +} + +int COMMON_CRITERIA_MEASURES_print (BIO *out, + COMMON_CRITERIA_MEASURES *value, + int indent) { + int rc; + int64_t int_val; + + rc = BIO_printf(out, "%*sVersion: %.*s\n", indent, "", + value->version->length, + value->version->data); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sAssurance Level: ", indent, ""); + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->assurancelevel) + || int_val <= 0 + || int_val > INT_MAX) + return -1; + if (int_val > 7) { + rc = BIO_printf(out, "%ld\n", int_val); + } else { + rc = BIO_printf(out, "%s\n", evaluation_assurance_levels[int_val - 1].lname); + } + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->evaluationStatus) + || int_val < 0 + || int_val > INT_MAX) + return -1; + if (int_val > 2) { + rc = BIO_printf(out, "%*sEvaluation Status: %ld\n", indent, "", int_val); + } else { + rc = BIO_printf(out, "%*sEvaluation Status: %s\n", indent, "", evaluation_statuses[int_val].lname); + } + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sPlus: ", indent, ""); + if (rc <= 0) return rc; + if (value->plus) { + rc = BIO_puts(out, "TRUE\n"); + } else { + rc = BIO_puts(out, "FALSE\n"); + } + if (rc <= 0) return rc; + if (value->strengthOfFunction != NULL) { + rc = BIO_printf(out, "%*sStrength Of Function: ", indent, ""); + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->strengthOfFunction) + || int_val < 0 + || int_val > INT_MAX) + return -1; + if (int_val > 2) { + rc = BIO_printf(out, "%ld\n", int_val); + } else { + rc = BIO_printf(out, "%s\n", strengths_of_function[int_val].lname); + } + if (rc <= 0) return rc; + } + if (value->profileOid != NULL) { + rc = BIO_printf(out, "%*sProfile OID: ", indent, ""); + if (rc <= 0) return rc; + rc = print_oid(out, value->profileOid); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->profileUri != NULL) { + rc = BIO_printf(out, "%*sProfile URI:\n", indent, ""); + if (rc <= 0) return rc; + rc = URI_REFERENCE_print(out, value->profileUri, indent + 4); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->targetOid != NULL) { + rc = BIO_printf(out, "%*sTarget OID: ", indent, ""); + if (rc <= 0) return rc; + rc = print_oid(out, value->targetOid); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->targetUri != NULL) { + rc = BIO_printf(out, "%*sTarget URI:\n", indent, ""); + if (rc <= 0) return rc; + rc = URI_REFERENCE_print(out, value->targetUri, indent + 4); + if (rc <= 0) return rc; + } + return rc; +} + +int FIPS_LEVEL_print (BIO *out, FIPS_LEVEL *value, int indent) { + int rc; + int64_t int_val; + + rc = BIO_printf(out, "%*sVersion: %.*s\n", indent, "", + value->version->length, + value->version->data); + if (rc <= 0) return rc; + if (value->level != NULL) { + rc = BIO_printf(out, "%*sLevel: ", indent, ""); + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->level) + || int_val <= 0 + || int_val > INT_MAX) + return -1; + if (int_val > 4) { + rc = BIO_printf(out, "%ld\n", int_val); + } else { + rc = BIO_printf(out, "%s\n", security_levels[int_val - 1].lname); + } + if (rc <= 0) return rc; + } + if (value->plus) { + rc = BIO_printf(out, "%*sPlus: TRUE\n", indent, ""); + } else { + rc = BIO_printf(out, "%*sPlus: FALSE\n", indent, ""); + } + return rc; +} + +int TBB_SECURITY_ASSERTIONS_print (BIO *out, TBB_SECURITY_ASSERTIONS *value, int indent) { + int rc = 1; /* All fields are OPTIONAL, so we start off at 1 in case all are omitted. */ + int64_t int_val; + + if (value->version != NULL) { + if (!ASN1_INTEGER_get_int64(&int_val, value->version) + || int_val < 0 + || int_val > INT_MAX) + return -1; + rc = BIO_printf(out, "%*sVersion: %ld\n", indent, "", int_val); + } else { + rc = BIO_printf(out, "%*sVersion: 1\n", indent, ""); + } + if (rc <= 0) return rc; + if (value->ccInfo != NULL) { + rc = BIO_printf(out, "%*sCommon Criteria Measures:\n", indent, ""); + if (rc <= 0) return rc; + rc = COMMON_CRITERIA_MEASURES_print(out, value->ccInfo, indent + 4); + if (rc <= 0) return rc; + } + if (value->fipsLevel != NULL) { + rc = BIO_printf(out, "%*sFIPS Level:\n", indent, ""); + if (rc <= 0) return rc; + rc = FIPS_LEVEL_print(out, value->fipsLevel, indent + 4); + if (rc <= 0) return rc; + } + if (value->rtmType != NULL) { + rc = BIO_printf(out, "%*sRoot Measurement Type: ", indent, ""); + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->rtmType) + || int_val < 0 + || int_val > INT_MAX) + return -1; + if (int_val > 5) { + rc = BIO_printf(out, "%ld\n", int_val); + } else { + rc = BIO_printf(out, "%s\n", measurement_root_types[int_val].lname); + } + if (rc <= 0) return rc; + } + if (value->iso9000Certified) { + rc = BIO_printf(out, "%*sPlus: TRUE\n", indent, ""); + } else { + rc = BIO_printf(out, "%*sPlus: FALSE\n", indent, ""); + } + if (rc <= 0) return rc; + if (value->iso9000Uri) { + rc = BIO_printf(out, "%*sISO 9001 URI: %.*s", + indent, + "", + value->iso9000Uri->length, + value->iso9000Uri->data); + } + return rc; +} + +int MANUFACTURER_ID_print (BIO *out, MANUFACTURER_ID *value, int indent) { + int rc; + + rc = BIO_printf(out, "%*sManufacturer Identifier: ", indent, ""); + if (rc <= 0) return rc; + return print_oid(out, value->manufacturerIdentifier); +} + +int TCG_SPEC_VERSION_print (BIO *out, TCG_SPEC_VERSION *value) { + int64_t major, minor, rev; + + if (!ASN1_INTEGER_get_int64(&major, value->majorVersion) + || major < 0 + || major > INT_MAX) + return -1; + if (!ASN1_INTEGER_get_int64(&minor, value->minorVersion) + || minor < 0 + || minor > INT_MAX) + return -1; + if (!ASN1_INTEGER_get_int64(&rev, value->revision) + || rev < 0 + || rev > INT_MAX) + return -1; + return BIO_printf(out, "%ld.%ld.%ld", major, minor, rev); +} + +int TCG_PLATFORM_SPEC_print (BIO *out, TCG_PLATFORM_SPEC *value) { + int rc; + + rc = TCG_SPEC_VERSION_print(out, value->version); + if (rc <= 0) return rc; + rc = BIO_puts(out, " : "); + if (rc <= 0) return rc; + return print_hex(out, value->platformClass->data, value->platformClass->length); +} + +int TCG_CRED_TYPE_print (BIO *out, TCG_CRED_TYPE *value, int indent) { + int rc; + rc = BIO_printf(out, "%*sCredential Type: ", indent, ""); + if (rc <= 0) return rc; + return print_oid(out, value->certificateType); +} + +int COMPONENT_ADDRESS_print (BIO *out, COMPONENT_ADDRESS *value, int indent) { + int rc; + + rc = BIO_printf(out, "%*sAddress Type: ", indent, ""); + if (rc <= 0) return rc; + rc = print_oid(out, value->addressType); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sAddress Value: %.*s", indent, "", value->addressValue->length, value->addressValue->data); + if (rc <= 0) return rc; + return BIO_puts(out, "\n"); +} + +int PLATFORM_PROPERTY_print (BIO *out, PLATFORM_PROPERTY *value, int indent) { + int rc; + int64_t int_val; + + rc = BIO_printf(out, "%*sProperty Name: %.*s\n", indent, "", value->propertyName->length, value->propertyName->data); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sProperty Value: %.*s\n", indent, "", value->propertyValue->length, value->propertyValue->data); + if (rc <= 0) return rc; + if (value->status != NULL) { + rc = BIO_printf(out, "%*sStatus: ", indent, ""); + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->status) + || int_val < 0 + || int_val > INT_MAX) + return -1; + if (int_val > 2) { + rc = BIO_printf(out, "%ld\n", int_val); + } else { + rc = BIO_printf(out, "%s\n", attribute_statuses[int_val].lname); + } + if (rc <= 0) return rc; + } + return 1; +} + +int ATTRIBUTE_CERTIFICATE_IDENTIFIER_print (BIO *out, ATTRIBUTE_CERTIFICATE_IDENTIFIER *value, int indent) { + int rc; + + rc = BIO_printf(out, "%*sHash Algorithm:\n%*s", indent, "", indent + 4, ""); + if (rc <= 0) return rc; + rc = TS_X509_ALGOR_print_bio(out, value->hashAlgorithm); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sHash Over Signature Value: ", indent, ""); + if (rc <= 0) return rc; + rc = print_hex(out, value->hashOverSignatureValue->data, value->hashOverSignatureValue->length); + if (rc <= 0) return rc; + return BIO_puts(out, "\n"); +} + +int CERTIFICATE_IDENTIFIER_print (BIO *out, CERTIFICATE_IDENTIFIER *value, int indent) { + int rc; + OSSL_ISSUER_SERIAL *iss; + + if (value->attributeCertIdentifier != NULL) { + rc = BIO_printf(out, "%*sAttribute Certificate Identifier:\n", indent, ""); + if (rc <= 0) return rc; + rc = ATTRIBUTE_CERTIFICATE_IDENTIFIER_print(out, value->attributeCertIdentifier, indent + 4); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->genericCertIdentifier != NULL) { + rc = BIO_printf(out, "%*sGeneric Certificate Identifier:\n", indent, ""); + if (rc <= 0) return rc; + iss = value->genericCertIdentifier; + if (iss->issuer != NULL) { + rc = BIO_printf(out, "%*sIssuer Names:\n", indent + 4, ""); + if (rc <= 0) return rc; + rc = ossl_print_gens(out, iss->issuer, indent + 4); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + rc = BIO_printf(out, "%*sIssuer Serial: 0x", indent + 4, ""); + if (rc <= 0) return rc; + if (i2a_ASN1_INTEGER(out, &iss->serial) <= 0) + return 0; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + if (iss->issuerUID != NULL) { + BIO_printf(out, "%*sIssuer UID: ", indent + 4, ""); + if (i2a_ASN1_STRING(out, iss->issuerUID, V_ASN1_BIT_STRING) <= 0) + return 0; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + } + return 1; +} + +int COMPONENT_IDENTIFIER_print (BIO *out, COMPONENT_IDENTIFIER *value, int indent) { + int rc, i; + int64_t int_val; + COMPONENT_ADDRESS *caddr; + + rc = BIO_printf(out, "%*sComponent Class:\n", indent, ""); + if (rc <= 0) return rc; + rc = COMPONENT_CLASS_print(out, value->componentClass, indent + 4); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sComponent Manufacturer: %.*s\n", indent, "", + value->componentManufacturer->length, + value->componentManufacturer->data); + if (rc <= 0) return rc; + rc = BIO_printf(out, "%*sComponent Model: %.*s\n", indent, "", + value->componentModel->length, + value->componentModel->data); + if (rc <= 0) return rc; + if (value->componentSerial != NULL) { + rc = BIO_printf(out, "%*sComponent Serial: %.*s\n", indent, "", + value->componentSerial->length, + value->componentSerial->data); + if (rc <= 0) return rc; + } + if (value->componentRevision != NULL) { + rc = BIO_printf(out, "%*sComponent Revision: %.*s\n", indent, "", + value->componentRevision->length, + value->componentRevision->data); + if (rc <= 0) return rc; + } + if (value->componentManufacturerId != NULL) { + rc = BIO_printf(out, "%*sComponent Manufacturer ID: ", indent, ""); + if (rc <= 0) return rc; + rc = print_oid(out, value->componentManufacturerId); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->fieldReplaceable) { + rc = BIO_printf(out, "%*sField Replaceable: TRUE\n", indent, ""); + } else { + rc = BIO_printf(out, "%*sField Replaceable: TRUE\n", indent, ""); + } + if (rc <= 0) return rc; + if (value->componentAddresses != NULL) { + rc = BIO_printf(out, "%*sComponent Addresses:\n", indent, ""); + for (i = 0; i < sk_COMPONENT_ADDRESS_num(value->componentAddresses); i++) { + rc = BIO_printf(out, "%*sComponent Address:\n", indent + 4, ""); + if (rc <= 0) return rc; + caddr = sk_COMPONENT_ADDRESS_value(value->componentAddresses, i); + rc = COMPONENT_ADDRESS_print(out, caddr, indent + 8); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + } + if (value->componentPlatformCert != NULL) { + rc = BIO_printf(out, "%*sComponent Platform Certificate:\n", indent, ""); + if (rc <= 0) return rc; + rc = CERTIFICATE_IDENTIFIER_print(out, value->componentPlatformCert, indent + 4); + if (rc <= 0) return rc; + } + if (value->componentPlatformCertUri != NULL) { + rc = BIO_printf(out, "%*sComponent Platform Certificate URI:\n", indent, ""); + if (rc <= 0) return rc; + rc = URI_REFERENCE_print(out, value->componentPlatformCertUri, indent + 4); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->status != NULL) { + rc = BIO_printf(out, "%*sStatus: ", indent, ""); + if (rc <= 0) return rc; + if (!ASN1_ENUMERATED_get_int64(&int_val, value->status) + || int_val < 0 + || int_val > INT_MAX) + return -1; + if (int_val > 2) { + rc = BIO_printf(out, "%ld\n", int_val); + } else { + rc = BIO_printf(out, "%s\n", attribute_statuses[int_val].lname); + } + if (rc <= 0) return rc; + } + return 1; +} + +int PLATFORM_CONFIG_print (BIO *out, PLATFORM_CONFIG *value, int indent) { + int rc = 1, i; /* All fields are OPTIONAL, so we start off rc at 1 in case all are omitted. */ + COMPONENT_IDENTIFIER *cid; + PLATFORM_PROPERTY *p; + + if (value->componentIdentifiers) { + rc = BIO_printf(out, "%*sComponent Identifiers:\n", indent, ""); + for (i = 0; i < sk_COMPONENT_IDENTIFIER_num(value->componentIdentifiers); i++) { + rc = BIO_printf(out, "%*sComponent Identifier:\n", indent + 4, ""); + if (rc <= 0) return rc; + cid = sk_COMPONENT_IDENTIFIER_value(value->componentIdentifiers, i); + rc = COMPONENT_IDENTIFIER_print(out, cid, indent + 8); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + } + if (value->componentIdentifiersUri) { + rc = BIO_printf(out, "%*sComponent Identifier URI:\n", indent, ""); + if (rc <= 0) return rc; + rc = URI_REFERENCE_print(out, value->componentIdentifiersUri, indent + 4); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + if (value->platformProperties) { + rc = BIO_printf(out, "%*sProperties:\n", indent, ""); + for (i = 0; i < sk_PLATFORM_PROPERTY_num(value->platformProperties); i++) { + rc = BIO_printf(out, "%*sProperty:\n", indent + 4, ""); + if (rc <= 0) return rc; + p = sk_PLATFORM_PROPERTY_value(value->platformProperties, i); + rc = PLATFORM_PROPERTY_print(out, p, indent + 8); + if (rc <= 0) return rc; + } + } + if (value->platformPropertiesUri) { + rc = BIO_printf(out, "%*sPlatform Properties URI:\n", indent, ""); + if (rc <= 0) return rc; + rc = URI_REFERENCE_print(out, value->platformPropertiesUri, indent + 4); + if (rc <= 0) return rc; + rc = BIO_puts(out, "\n"); + if (rc <= 0) return rc; + } + return 1; +} diff --git a/crypto/x509/standard_exts.h b/crypto/x509/standard_exts.h index 27a99a4b13ed7..c3c70caa23eb1 100644 --- a/crypto/x509/standard_exts.h +++ b/crypto/x509/standard_exts.h @@ -39,6 +39,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { #endif &ossl_v3_sxnet, &ossl_v3_info, + &ossl_v3_audit_identity, // 287 #ifndef OPENSSL_NO_RFC3779 &ossl_v3_addr, &ossl_v3_asid, @@ -53,6 +54,8 @@ static const X509V3_EXT_METHOD *standard_exts[] = { #endif &ossl_v3_sinfo, &ossl_v3_policy_constraints, + &ossl_v3_targeting_information, // 402 + &ossl_v3_no_rev_avail, // 403 #ifndef OPENSSL_NO_OCSP &ossl_v3_crl_hold, #endif @@ -60,6 +63,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &ossl_v3_name_constraints, &ossl_v3_policy_mappings, &ossl_v3_inhibit_anyp, + &ossl_v3_subj_dir_attrs, // 769 &ossl_v3_idp, &ossl_v3_alt[2], &ossl_v3_freshest_crl, @@ -71,7 +75,27 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &ossl_v3_utf8_list[0], &ossl_v3_issuer_sign_tool, &ossl_v3_tls_feature, - &ossl_v3_ext_admission + &ossl_v3_ext_admission, + &ossl_v3_authority_attribute_identifier, // 1291 + &ossl_v3_role_spec_cert_identifier, // 1292 + &ossl_v3_bacons, // 1293 + &ossl_v3_delegated_name_constraints, // 1294 + &ossl_v3_time_specification, // 1295 + &ossl_v3_attribute_descriptor, // 1296 + &ossl_v3_user_notice, // 1297 + &ossl_v3_soa_identifier, // 1298 + &ossl_v3_acc_cert_policies, // 1299 + &ossl_v3_acc_priv_policies, // 1300 + &ossl_v3_indirect_issuer, // 1301 + &ossl_v3_no_assertion, // 1302 + &ossl_v3_aa_issuing_dist_point, // 1303 + &ossl_v3_issued_on_behalf_of, // 1304 + &ossl_v3_single_use, // 1305 + &ossl_v3_group_ac, // 1306 + &ossl_v3_allowed_attribute_assignments, // 1307 + &ossl_v3_attribute_mappings, // 1308 + &ossl_v3_holder_name_constraints, // 1309 + &ossl_v3_associated_info, // 1315 }; /* Number of standard extensions */ diff --git a/crypto/x509/t_acert.c b/crypto/x509/t_acert.c new file mode 100644 index 0000000000000..b730d0e0c860b --- /dev/null +++ b/crypto/x509/t_acert.c @@ -0,0 +1,266 @@ +/* + * Copyright 2021 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 +#include +#include +#include + +static int print_attribute(BIO *bp, X509_ATTRIBUTE *a, int indent) +{ + ASN1_TYPE *at; + ASN1_OBJECT *aobj; + int nid, i, j, count = 0; + int ret = 0; + + count = X509_ATTRIBUTE_count(a); + if (count == 0) { + ERR_raise(ERR_LIB_X509, X509_R_INVALID_ATTRIBUTES); + goto err; + } + + aobj = X509_ATTRIBUTE_get0_object(a); + nid = OBJ_obj2nid(aobj); + + if (BIO_printf(bp, "%*s", indent, "") <= 0) + goto err; + + if ((j = i2a_ASN1_OBJECT(bp, aobj)) <= 0) + goto err; + + if (BIO_puts(bp, ":\n") <= 0) + goto err; + + for (i = 0; i < count; i++) { + at = X509_ATTRIBUTE_get0_type(a, i); + print_attribute_value(bp, nid, at, indent + 4); + } + + if (BIO_puts(bp, "\n") <= 0) + goto err; + + ret = 1; +err: + return ret; +} + +int X509_ACERT_print_ex(BIO *bp, X509_ACERT *x, unsigned long nmflags, + unsigned long cflag) +{ + int i; + char mlch = ' '; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + } + + if ((cflag & X509_FLAG_NO_HEADER) == 0) { + if (BIO_printf(bp, "Attribute Certificate:\n") <= 0) + goto err; + if (BIO_write(bp, " Data:\n", 10) <= 0) + goto err; + } + + if ((cflag & X509_FLAG_NO_VERSION) == 0) { + long l; + + l = X509_ACERT_get_version(x); + if (l == X509_ACERT_VERSION_2) { + if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, + (unsigned long)l) <= 0) + goto err; + } else { + if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0) + goto err; + } + } + + if ((cflag & X509_FLAG_NO_SERIAL) == 0) { + ASN1_INTEGER *serial; + char *serial_str; + + serial = X509_ACERT_get0_serialNumber(x); + serial_str = i2s_ASN1_INTEGER(NULL, serial); + if (serial_str == NULL) + goto err; + + if (BIO_printf(bp, "%8sSerial Number: %s\n", "", serial_str) <= 0) { + OPENSSL_free(serial_str); + goto err; + } + OPENSSL_free(serial_str); + } + + if ((cflag & X509_FLAG_NO_SUBJECT) == 0) { + const GENERAL_NAMES *holderEntities; + OSSL_ISSUER_SERIAL *holder_bcid; + X509_NAME *holderIssuer = NULL; + + if (BIO_printf(bp, " Holder:\n") <= 0) + goto err; + + holderEntities = X509_ACERT_get0_holder_entityName(x); + if (holderEntities != NULL) { + GENERAL_NAME *entity = NULL; + /* + * Just display the first name in the sequence. Any others + * are ignored. + */ + if (sk_GENERAL_NAME_num(holderEntities) >= 1) + entity = sk_GENERAL_NAME_value(holderEntities, 0); + + if (entity != NULL) { + if (BIO_printf(bp, " Name:%c", mlch) <= 0) + goto err; + + if (GENERAL_NAME_print(bp, entity) <= 0) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + + if ((holder_bcid = X509_ACERT_get0_holder_baseCertId(x)) != NULL) + holderIssuer = OSSL_ISSUER_SERIAL_get0_issuer(holder_bcid); + + if (holderIssuer != NULL) { + char *serial_s; + ASN1_INTEGER *holder_serial; + ASN1_BIT_STRING *iuid; + holder_serial = OSSL_ISSUER_SERIAL_get0_serial(holder_bcid); + + if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) + goto err; + + if (X509_NAME_print(bp, holderIssuer, 0) <= 0) + goto err; + + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + + if (BIO_printf(bp, " Serial: ") <= 0) + goto err; + + serial_s = i2s_ASN1_INTEGER(NULL, holder_serial); + if (serial_s == NULL) + goto err; + + if (BIO_printf(bp, "%s", serial_s) <= 0) { + OPENSSL_free(serial_s); + goto err; + } + OPENSSL_free(serial_s); + + iuid = OSSL_ISSUER_SERIAL_get0_issuerUID(holder_bcid); + if (iuid != NULL) { + if (BIO_printf(bp, " Issuer UID: ") <= 0) + goto err; + if (!X509_signature_dump(bp, iuid, 24)) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + } + + if ((cflag & X509_FLAG_NO_ISSUER) == 0) { + if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex(bp, X509_ACERT_get0_issuerName(x), 0, nmflags) + < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + + if ((cflag & X509_FLAG_NO_VALIDITY) == 0) { + if (BIO_write(bp, " Validity\n", 17) <= 0) + goto err; + if (BIO_write(bp, " Not Before: ", 24) <= 0) + goto err; + if (ASN1_GENERALIZEDTIME_print(bp, X509_ACERT_get0_notBefore(x)) == 0) + goto err; + if (BIO_write(bp, "\n Not After : ", 25) <= 0) + goto err; + if (ASN1_GENERALIZEDTIME_print(bp, X509_ACERT_get0_notAfter(x)) == 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + + if ((cflag & X509_FLAG_NO_ATTRIBUTES) == 0) { + if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) + goto err; + + if (X509_ACERT_get_attr_count(x) == 0) { + if (BIO_printf(bp, "%12s(none)\n", "") <= 0) + goto err; + } else { + for (i = 0; i < X509_ACERT_get_attr_count(x); i++) { + if (print_attribute(bp, X509_ACERT_get_attr(x, i), 12) == 0) + goto err; + } + } + } + + if ((cflag & X509_FLAG_NO_EXTENSIONS) == 0) { + const STACK_OF(X509_EXTENSION) *exts; + + exts = X509_ACERT_get0_extensions(x); + if (exts != NULL) { + if (BIO_printf(bp, "%8sExtensions:\n", "") <= 0) + goto err; + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + int critical; + ex = sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bp, "%12s", "") <= 0) + goto err; + obj = X509_EXTENSION_get_object(ex); + if (i2a_ASN1_OBJECT(bp, obj) <= 0) + goto err; + critical = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0) + goto err; + if (!X509V3_EXT_print(bp, ex, cflag, 20)) { + if (BIO_printf(bp, "%16s", "") <= 0 + || ASN1_STRING_print(bp, + X509_EXTENSION_get_data(ex)) <= 0) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + } + } + + if ((cflag & X509_FLAG_NO_SIGDUMP) == 0) { + const X509_ALGOR *sig_alg; + const ASN1_BIT_STRING *sig; + + X509_ACERT_get0_signature(x, &sig, &sig_alg); + if (!X509_signature_print(bp, sig_alg, sig)) + goto err; + } + + return 1; + +err: + ERR_raise(ERR_LIB_X509, ERR_R_BUF_LIB); + return 0; +} + +int X509_ACERT_print(BIO *bp, X509_ACERT *x) +{ + return X509_ACERT_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} diff --git a/crypto/x509/v3_aaa.c b/crypto/x509/v3_aaa.c new file mode 100644 index 0000000000000..7060b9c82c1ed --- /dev/null +++ b/crypto/x509/v3_aaa.c @@ -0,0 +1,134 @@ +/* + * Copyright 1999-2021 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 + +IMPLEMENT_ASN1_FUNCTIONS(ALLOWED_ATTRIBUTES_SYNTAX) + +ASN1_CHOICE(ALLOWED_ATTRIBUTES_CHOICE) = { + ASN1_IMP(ALLOWED_ATTRIBUTES_CHOICE, choice.attributeType, ASN1_OBJECT, AAA_ATTRIBUTE_TYPE), + ASN1_IMP(ALLOWED_ATTRIBUTES_CHOICE, choice.attributeTypeandValues, X509_ATTRIBUTE, AAA_ATTRIBUTE_VALUES), +} ASN1_CHOICE_END(ALLOWED_ATTRIBUTES_CHOICE) + +ASN1_SEQUENCE(ALLOWED_ATTRIBUTES_ITEM) = { + ASN1_IMP_SET_OF(ALLOWED_ATTRIBUTES_ITEM, attributes, ALLOWED_ATTRIBUTES_CHOICE, 0), + // This MUST be EXPLICIT, because it contains a CHOICE. + ASN1_EXP(ALLOWED_ATTRIBUTES_ITEM, holderDomain, GENERAL_NAME, 1), +} ASN1_SEQUENCE_END(ALLOWED_ATTRIBUTES_ITEM) + +ASN1_ITEM_TEMPLATE(ALLOWED_ATTRIBUTES_SYNTAX) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ALLOWED_ATTRIBUTES_SYNTAX, ALLOWED_ATTRIBUTES_ITEM) +ASN1_ITEM_TEMPLATE_END(ALLOWED_ATTRIBUTES_SYNTAX) + +static int i2r_ALLOWED_ATTRIBUTES_CHOICE(X509V3_EXT_METHOD *method, + ALLOWED_ATTRIBUTES_CHOICE *a, + BIO *out, int indent) +{ + ASN1_OBJECT *attr_obj; + int attr_nid, j; + X509_ATTRIBUTE *attr; + ASN1_TYPE *av; + + switch (a->type) { + case (AAA_ATTRIBUTE_TYPE): + if (BIO_printf(out, "%*sAttribute Type: ", indent, "") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(out, a->choice.attributeType) <= 0) { + return 0; + } + return BIO_puts(out, "\n"); + case (AAA_ATTRIBUTE_VALUES): + attr = a->choice.attributeTypeandValues; + attr_obj = X509_ATTRIBUTE_get0_object(attr); + attr_nid = OBJ_obj2nid(attr_obj); + if (BIO_printf(out, "%*sAttribute Values: ", indent, "") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(out, attr_obj) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) + { + av = X509_ATTRIBUTE_get0_type(attr, j); + if (print_attribute_value(out, attr_nid, av, indent + 4) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + // BIO_puts(out, "\n"); + break; + default: return 0; + } + return 1; +} + +static int i2r_ALLOWED_ATTRIBUTES_ITEM(X509V3_EXT_METHOD *method, + ALLOWED_ATTRIBUTES_ITEM *aai, + BIO *out, int indent) +{ + int i; + ALLOWED_ATTRIBUTES_CHOICE *a; + for (i = 0; i < sk_ALLOWED_ATTRIBUTES_CHOICE_num(aai->attributes); i++) { + if (BIO_printf(out, "%*sAllowed Attribute Type or Values:\n", indent, "") <= 0) { + return 0; + } + a = sk_ALLOWED_ATTRIBUTES_CHOICE_value(aai->attributes, i); + if (i2r_ALLOWED_ATTRIBUTES_CHOICE(method, a, out, indent + 4) <= 0) { + return 0; + } + } + if (BIO_printf(out, "%*sHolder Domain: ", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, aai->holderDomain) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + return 1; +} + +static int i2r_ALLOWED_ATTRIBUTES_SYNTAX(X509V3_EXT_METHOD *method, + ALLOWED_ATTRIBUTES_SYNTAX *aaa, + BIO *out, int indent) +{ + int i; + ALLOWED_ATTRIBUTES_ITEM *aai; + for (i = 0; i < sk_ALLOWED_ATTRIBUTES_ITEM_num(aaa); i++) { + if (BIO_printf(out, "%*sAllowed Attributes:\n", indent, "") <= 0) { + return 0; + } + aai = sk_ALLOWED_ATTRIBUTES_ITEM_value(aaa, i); + if (i2r_ALLOWED_ATTRIBUTES_ITEM(method, aai, out, indent + 4) <= 0) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_allowed_attribute_assignments = { + NID_allowed_attribute_assignments, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ALLOWED_ATTRIBUTES_SYNTAX), + 0, 0, 0, 0, + 0, 0, + 0, + 0, + (X509V3_EXT_I2R)i2r_ALLOWED_ATTRIBUTES_SYNTAX, + 0, + NULL +}; diff --git a/crypto/x509/v3_ac_tgt.c b/crypto/x509/v3_ac_tgt.c new file mode 100644 index 0000000000000..5cc40e9f42e5b --- /dev/null +++ b/crypto/x509/v3_ac_tgt.c @@ -0,0 +1,244 @@ +/* + * Copyright 1999-2021 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/cryptlib.h" +#include +#include +#include + +static int i2r_TARGET_CERT(X509V3_EXT_METHOD *method, + TARGET_CERT *tc, + BIO *out, int indent); +static int i2r_TARGET(X509V3_EXT_METHOD *method, + TARGET *target, + BIO *out, int indent); +static int i2r_TARGETING_INFORMATION(X509V3_EXT_METHOD *method, + TARGETING_INFORMATION *tinfo, + BIO *out, int indent); + +ASN1_SEQUENCE(OBJECT_DIGEST_INFO) = { + ASN1_SIMPLE(OBJECT_DIGEST_INFO, digestedObjectType, ASN1_ENUMERATED), + ASN1_OPT(OBJECT_DIGEST_INFO, otherObjectTypeID, ASN1_OBJECT), + ASN1_SIMPLE(OBJECT_DIGEST_INFO, digestAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OBJECT_DIGEST_INFO, objectDigest, ASN1_BIT_STRING), +} ASN1_SEQUENCE_END(OBJECT_DIGEST_INFO) + +ASN1_SEQUENCE(TARGET_CERT) = { + ASN1_SIMPLE(TARGET_CERT, targetCertificate, OSSL_ISSUER_SERIAL), + ASN1_OPT(TARGET_CERT, targetName, GENERAL_NAME), + ASN1_OPT(TARGET_CERT, certDigestInfo, OBJECT_DIGEST_INFO), +} ASN1_SEQUENCE_END(TARGET_CERT) + +ASN1_CHOICE(TARGET) = { + ASN1_EXP(TARGET, choice.targetName, GENERAL_NAME, 0), + ASN1_EXP(TARGET, choice.targetGroup, GENERAL_NAME, 1), + ASN1_IMP(TARGET, choice.targetCert, TARGET_CERT, 2), +} ASN1_CHOICE_END(TARGET) + +ASN1_ITEM_TEMPLATE(TARGETS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Targets, TARGET) +ASN1_ITEM_TEMPLATE_END(TARGETS) + +ASN1_ITEM_TEMPLATE(TARGETING_INFORMATION) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TargetingInformation, TARGETS) +ASN1_ITEM_TEMPLATE_END(TARGETING_INFORMATION) + +IMPLEMENT_ASN1_FUNCTIONS(OBJECT_DIGEST_INFO) +IMPLEMENT_ASN1_FUNCTIONS(TARGET_CERT) +IMPLEMENT_ASN1_FUNCTIONS(TARGET) +IMPLEMENT_ASN1_FUNCTIONS(TARGETS) +IMPLEMENT_ASN1_FUNCTIONS(TARGETING_INFORMATION) + +static int i2r_OBJECT_DIGEST_INFO(X509V3_EXT_METHOD *method, + OBJECT_DIGEST_INFO *odi, + BIO *out, int indent) +{ + int64_t dot = 0; + int sig_nid; + X509_ALGOR *digalg; + ASN1_STRING *sig; + + if (odi == NULL) { + ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + digalg = odi->digestAlgorithm; + sig = odi->objectDigest; + if (!ASN1_ENUMERATED_get_int64(&dot, odi->digestedObjectType)) { + return 0; + } + switch (dot) { + case (ODI_TYPE_PUBLIC_KEY): + if (BIO_printf(out, "%*sDigest Type: Public Key\n", indent, "") <= 0) { + return 0; + } + break; + case (ODI_TYPE_PUBLIC_KEY_CERT): + if (BIO_printf(out, "%*sDigest Type: Public Key Certificate\n", indent, "") <= 0) { + return 0; + } + break; + case (ODI_TYPE_OTHER): { + if (BIO_printf(out, "%*sDigest Type: Other\n", indent, "") <= 0) { + return 0; + } + break; + } + } + if (odi->otherObjectTypeID != NULL) { + if (BIO_printf(out, "%*sDigest Type Identifier: ", indent, "") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(out, odi->otherObjectTypeID) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (BIO_printf(out, "%*sSignature Algorithm: ", indent, "") <= 0) + return 0; + if (i2a_ASN1_OBJECT(out, odi->digestAlgorithm->algorithm) <= 0) + return 0; + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + if (BIO_printf(out, "\n%*sSignature Value: ", indent, "") <= 0) + return 0; + sig_nid = OBJ_obj2nid(odi->digestAlgorithm->algorithm); + if (sig_nid != NID_undef) { + int pkey_nid, dig_nid; + const EVP_PKEY_ASN1_METHOD *ameth; + if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { + ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); + if (ameth && ameth->sig_print) + return ameth->sig_print(out, digalg, sig, indent + 4, 0); + } + } + if (BIO_write(out, "\n", 1) <= 0) + return 0; + if (sig) + return X509_signature_dump(out, sig, indent + 4); + return 1; +} + +static int i2r_TARGET_CERT(X509V3_EXT_METHOD *method, + TARGET_CERT *tc, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + if (tc->targetCertificate != NULL) { + if (BIO_puts(out, "Target Certificate:\n") <= 0) { + return 0; + } + if (i2r_ISSUER_SERIAL(method, tc->targetCertificate, out, indent + 2) <= 0) { + return 0; + } + } + if (tc->targetName != NULL) { + // BIO_puts(out, "Target Name: "); + if (BIO_printf(out, "%*sTarget Name: ", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, tc->targetName) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (tc->certDigestInfo != NULL) { + if (BIO_printf(out, "%*sCertificate Digest Info:\n", indent, "") <= 0) { + return 0; + } + if (i2r_OBJECT_DIGEST_INFO(method, tc->certDigestInfo, out, indent + 2) <= 0) { + return 0; + } + } + return BIO_puts(out, "\n"); +} + +static int i2r_TARGET(X509V3_EXT_METHOD *method, + TARGET *target, + BIO *out, int indent) +{ + switch (target->type) { + case (TGT_TARGET_NAME): + if (BIO_printf(out, "%*sTarget Name: ", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, target->choice.targetName) <= 0) { + return 0; + } + return BIO_puts(out, "\n"); + case (TGT_TARGET_GROUP): + if (BIO_printf(out, "%*sTarget Group: ", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, target->choice.targetGroup) <= 0) { + return 0; + } + return BIO_puts(out, "\n"); + case (TGT_TARGET_CERT): + if (BIO_printf(out, "%*sTarget Cert:\n", indent, "") <= 0) { + return 0; + } + return i2r_TARGET_CERT(method, target->choice.targetCert, out, indent + 2); + } + return 1; +} + +static int i2r_TARGETS(X509V3_EXT_METHOD *method, + TARGETS *targets, + BIO *out, int indent) +{ + int i; + TARGET *target; + for (i = 0; i < sk_TARGET_num(targets); i++) { + if (BIO_printf(out, "%*sTarget:\n", indent, "") <= 0) { + return 0; + } + target = sk_TARGET_value(targets, i); + if (i2r_TARGET(method, target, out, indent + 2) <= 0) { + return 0; + } + } + return 1; +} + +static int i2r_TARGETING_INFORMATION(X509V3_EXT_METHOD *method, + TARGETING_INFORMATION *tinfo, + BIO *out, int indent) +{ + int i; + TARGETS *targets; + for (i = 0; i < sk_TARGETS_num(tinfo); i++) { + if (BIO_printf(out, "%*sTargets:\n", indent, "") <= 0) { + return 0; + } + targets = sk_TARGETS_value(tinfo, i); + if (i2r_TARGETS(method, targets, out, indent + 2) <= 0) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_targeting_information = { + NID_target_information, 0, ASN1_ITEM_ref(TARGETING_INFORMATION), + 0, 0, 0, 0, + 0, + 0, + 0, 0, + (X509V3_EXT_I2R)i2r_TARGETING_INFORMATION, + 0, + NULL +}; diff --git a/crypto/x509/v3_attrdesc.c b/crypto/x509/v3_attrdesc.c new file mode 100644 index 0000000000000..f5748fa4a35ba --- /dev/null +++ b/crypto/x509/v3_attrdesc.c @@ -0,0 +1,192 @@ +/* + * Copyright 1999-2021 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 + +ASN1_SEQUENCE(HASH) = { + ASN1_SIMPLE(HASH, algorithmIdentifier, X509_ALGOR), + ASN1_OPT(HASH, hashValue, ASN1_BIT_STRING), +} ASN1_SEQUENCE_END(HASH) + +ASN1_SEQUENCE(INFO_SYNTAX_POINTER) = { + ASN1_SIMPLE(INFO_SYNTAX_POINTER, name, GENERAL_NAMES), + ASN1_OPT(INFO_SYNTAX_POINTER, hash, HASH), +} ASN1_SEQUENCE_END(INFO_SYNTAX_POINTER) + +ASN1_CHOICE(INFO_SYNTAX) = { + ASN1_SIMPLE(INFO_SYNTAX, choice.content, DIRECTORYSTRING), + ASN1_SIMPLE(INFO_SYNTAX, choice.pointer, INFO_SYNTAX_POINTER) +} ASN1_CHOICE_END(INFO_SYNTAX) + +ASN1_SEQUENCE(PRIVILEGE_POLICY_ID) = { + ASN1_SIMPLE(PRIVILEGE_POLICY_ID, privilegePolicy, ASN1_OBJECT), + ASN1_SIMPLE(PRIVILEGE_POLICY_ID, privPolSyntax, INFO_SYNTAX), +} ASN1_SEQUENCE_END(PRIVILEGE_POLICY_ID) + +ASN1_SEQUENCE(ATTRIBUTE_DESCRIPTOR) = { + ASN1_SIMPLE(ATTRIBUTE_DESCRIPTOR, identifier, ASN1_OBJECT), + ASN1_SIMPLE(ATTRIBUTE_DESCRIPTOR, attributeSyntax, ASN1_OCTET_STRING), + ASN1_IMP_OPT(ATTRIBUTE_DESCRIPTOR, name, ASN1_UTF8STRING, 0), + ASN1_IMP_OPT(ATTRIBUTE_DESCRIPTOR, description, ASN1_UTF8STRING, 1), + ASN1_SIMPLE(ATTRIBUTE_DESCRIPTOR, dominationRule, PRIVILEGE_POLICY_ID), +} ASN1_SEQUENCE_END(ATTRIBUTE_DESCRIPTOR) + +IMPLEMENT_ASN1_FUNCTIONS(ATTRIBUTE_DESCRIPTOR) + +static int i2r_HASH(X509V3_EXT_METHOD *method, + HASH *hash, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*sAlgorithm: ", indent, "") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(out, hash->algorithmIdentifier->algorithm) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + if (hash->algorithmIdentifier->parameter) { + if (BIO_printf(out, "%*sParameter: ", indent, "") <= 0) { + return 0; + } + if (print_attribute_value(out, 0, hash->algorithmIdentifier->parameter, indent + 4) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (BIO_printf(out, "%*sHash Value: ", indent, "") <= 0) { + return 0; + } + return print_hex(out, hash->hashValue->data, hash->hashValue->length); +} + +static int i2r_INFO_SYNTAX_POINTER(X509V3_EXT_METHOD *method, + INFO_SYNTAX_POINTER *pointer, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*sNames:\n", indent, "") <= 0) { + return 0; + } + if (ossl_print_gens(out, pointer->name, indent) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + if (pointer->hash != NULL) { + if (BIO_printf(out, "%*sHash:\n", indent, "") <= 0) { + return 0; + } + if (i2r_HASH(method, pointer->hash, out, indent + 4) <= 0) { + return 0; + } + } + return 1; +} + +static int i2r_INFO_SYNTAX(X509V3_EXT_METHOD *method, + INFO_SYNTAX *info, + BIO *out, int indent) +{ + switch (info->type) { + case (INFO_SYNTAX_TYPE_CONTENT): { + if (BIO_printf(out, "%*sContent: ", indent, "") <= 0) { + return 0; + } + if (BIO_printf(out, "%.*s", info->choice.content->length, info->choice.content->data) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + return 1; + } + case (INFO_SYNTAX_TYPE_POINTER): { + if (BIO_printf(out, "%*sPointer:\n", indent, "") <= 0) { + return 0; + } + return i2r_INFO_SYNTAX_POINTER(method, info->choice.pointer, out, indent + 4); + } + default: return 0; + } + return 0; +} + +static int i2r_PRIVILEGE_POLICY_ID(X509V3_EXT_METHOD *method, + PRIVILEGE_POLICY_ID *ppid, + BIO *out, int indent) +{ + char buf[80]; + + /* Intentionally display the numeric OID, rather than the textual name. */ + if (OBJ_obj2txt(buf, sizeof(buf), ppid->privilegePolicy, 1) <= 0) { + return 0; + } + if (BIO_printf(out, "%*sIdentifier: %s\n", indent, "", buf) <= 0) { + return 0; + } + if (BIO_printf(out, "%*sSyntax:\n", indent, "") <= 0) { + return 0; + } + return i2r_INFO_SYNTAX(method, ppid->privPolSyntax, out, indent + 4); +} + +static int i2r_ATTRIBUTE_DESCRIPTOR(X509V3_EXT_METHOD *method, + ATTRIBUTE_DESCRIPTOR *ad, + BIO *out, int indent) +{ + char buf[80]; + + /* Intentionally display the numeric OID, rather than the textual name. */ + if (OBJ_obj2txt(buf, sizeof(buf), ad->identifier, 1) <= 0) { + return 0; + } + if (BIO_printf(out, "%*sIdentifier: %s\n", indent, "", buf) <= 0) { + return 0; + } + if (BIO_printf(out, "%*sSyntax:\n", indent, "") <= 0) { + return 0; + } + if (BIO_printf(out, "%*s%.*s", indent + 4, "", ad->attributeSyntax->length, ad->attributeSyntax->data) <= 0) { + return 0; + } + if (BIO_puts(out, "\n\n") <= 0) { + return 0; + } + if (ad->name != NULL) { + if (BIO_printf(out, "%*sName: %.*s\n", indent, "", ad->name->length, ad->name->data) <= 0) { + return 0; + } + } + if (ad->description != NULL) { + if (BIO_printf(out, "%*sDescription: %.*s\n", indent, "", ad->description->length, ad->description->data) <= 0) { + return 0; + } + } + if (BIO_printf(out, "%*sDomination Rule:\n", indent, "") <= 0) { + return 0; + } + return i2r_PRIVILEGE_POLICY_ID(method, ad->dominationRule, out, indent + 4); +} + +const X509V3_EXT_METHOD ossl_v3_attribute_descriptor = { + NID_attribute_descriptor, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ATTRIBUTE_DESCRIPTOR), + 0, 0, 0, 0, + 0, 0, + 0, + 0, + (X509V3_EXT_I2R)i2r_ATTRIBUTE_DESCRIPTOR, + NULL, + NULL +}; diff --git a/crypto/x509/v3_attrmap.c b/crypto/x509/v3_attrmap.c new file mode 100644 index 0000000000000..815cd10a2c13a --- /dev/null +++ b/crypto/x509/v3_attrmap.c @@ -0,0 +1,120 @@ +/* + * Copyright 1999-2021 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 + +ASN1_SEQUENCE(ATAV) = { + ASN1_SIMPLE(ATAV, type, ASN1_OBJECT), + ASN1_SIMPLE(ATAV, value, ASN1_ANY) +} ASN1_SEQUENCE_END(ATAV) + +ASN1_SEQUENCE(ATTRIBUTE_TYPE_MAPPING) = { + ASN1_IMP(ATTRIBUTE_TYPE_MAPPING, local, ASN1_OBJECT, 0), + ASN1_IMP(ATTRIBUTE_TYPE_MAPPING, remote, ASN1_OBJECT, 1), +} ASN1_SEQUENCE_END(ATTRIBUTE_TYPE_MAPPING) + +ASN1_SEQUENCE(ATTRIBUTE_VALUE_MAPPING) = { + ASN1_IMP(ATTRIBUTE_VALUE_MAPPING, local, ATAV, 0), + ASN1_IMP(ATTRIBUTE_VALUE_MAPPING, remote, ATAV, 1), +} ASN1_SEQUENCE_END(ATTRIBUTE_VALUE_MAPPING) + +ASN1_CHOICE(ATTRIBUTE_MAPPING) = { + ASN1_IMP(ATTRIBUTE_MAPPING, choice.typeMappings, ATTRIBUTE_TYPE_MAPPING, ATTR_MAP_TYPE), + ASN1_IMP(ATTRIBUTE_MAPPING, choice.typeValueMappings, ATTRIBUTE_VALUE_MAPPING, ATTR_MAP_VALUE), +} ASN1_CHOICE_END(ATTRIBUTE_MAPPING) + +ASN1_ITEM_TEMPLATE(ATTRIBUTE_MAPPINGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ATTRIBUTE_MAPPINGS, ATTRIBUTE_MAPPING) +ASN1_ITEM_TEMPLATE_END(ATTRIBUTE_MAPPINGS) + +IMPLEMENT_ASN1_FUNCTIONS(ATTRIBUTE_MAPPINGS) + +static int i2r_ATTRIBUTE_MAPPING(X509V3_EXT_METHOD *method, + ATTRIBUTE_MAPPING *am, + BIO *out, int indent) +{ + ASN1_OBJECT *local_type, *remote_type; + int local_attr_nid, remote_attr_nid; + ASN1_TYPE *local_val, *remote_val; + + switch (am->type) { + case (ATTR_MAP_TYPE): { + if (i2a_ASN1_OBJECT(out, am->choice.typeMappings->local) <= 0) { + return 0; + } + if (BIO_puts(out, " == ") <= 0) { + return 0; + } + return i2a_ASN1_OBJECT(out, am->choice.typeMappings->remote); + } + case (ATTR_MAP_VALUE): { + local_type = am->choice.typeValueMappings->local->type; + remote_type = am->choice.typeValueMappings->remote->type; + local_val = am->choice.typeValueMappings->local->value; + remote_val = am->choice.typeValueMappings->remote->value; + local_attr_nid = OBJ_obj2nid(local_type); + remote_attr_nid = OBJ_obj2nid(remote_type); + if (i2a_ASN1_OBJECT(out, local_type) <= 0) { + return 0; + } + if (BIO_puts(out, ":") <= 0) { + return 0; + } + if (print_attribute_value(out, local_attr_nid, local_val, 0) <= 0) { + return 0; + } + if (BIO_puts(out, " == ") <= 0) { + return 0; + } + if (i2a_ASN1_OBJECT(out, remote_type) <= 0) { + return 0; + } + if (BIO_puts(out, ":") <= 0) { + return 0; + } + return print_attribute_value(out, remote_attr_nid, remote_val, 0); + } + default: return 0; + } + return 1; +} + +static int i2r_ATTRIBUTE_MAPPINGS(X509V3_EXT_METHOD *method, + ATTRIBUTE_MAPPINGS *ams, + BIO *out, int indent) +{ + int i; + ATTRIBUTE_MAPPING *am; + for (i = 0; i < sk_ATTRIBUTE_MAPPING_num(ams); i++) { + am = sk_ATTRIBUTE_MAPPING_value(ams, i); + if (BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + if (i2r_ATTRIBUTE_MAPPING(method, am, out, indent + 4) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_attribute_mappings = { + NID_attribute_mappings, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ATTRIBUTE_MAPPINGS), + 0, 0, 0, 0, + 0, 0, + 0, + 0, + (X509V3_EXT_I2R)i2r_ATTRIBUTE_MAPPINGS, + 0, + NULL +}; diff --git a/crypto/x509/v3_audit_id.c b/crypto/x509/v3_audit_id.c new file mode 100644 index 0000000000000..b74cb18997c96 --- /dev/null +++ b/crypto/x509/v3_audit_id.c @@ -0,0 +1,19 @@ +/* + * Copyright 1999-2021 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 + +const X509V3_EXT_METHOD ossl_v3_audit_identity = { + NID_ac_auditEntity, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, + (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING, + 0, 0, 0, 0, + NULL +}; diff --git a/crypto/x509/v3_authattid.c b/crypto/x509/v3_authattid.c new file mode 100644 index 0000000000000..faa6e6370ecac --- /dev/null +++ b/crypto/x509/v3_authattid.c @@ -0,0 +1,50 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_AUTHORITY_ATTRIBUTE_ID_SYNTAX(X509V3_EXT_METHOD *method, + AUTHORITY_ATTRIBUTE_ID_SYNTAX *aids, + BIO *out, int indent) +{ + int i; + OSSL_ISSUER_SERIAL *aid; + for (i = 0; i < sk_OSSL_ISSUER_SERIAL_num(aids); i++) { + if (BIO_printf(out, "%*sIssuer-Serials:\n", indent, "") <= 0) { + return 0; + } + aid = sk_OSSL_ISSUER_SERIAL_value(aids, i); + if (i2r_ISSUER_SERIAL(method, aid, out, indent + 4) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + }; + } + return 1; +} + +ASN1_ITEM_TEMPLATE(AUTHORITY_ATTRIBUTE_ID_SYNTAX) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, AUTHORITY_ATTRIBUTE_ID_SYNTAX, OSSL_ISSUER_SERIAL) +ASN1_ITEM_TEMPLATE_END(AUTHORITY_ATTRIBUTE_ID_SYNTAX) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_ATTRIBUTE_ID_SYNTAX) + +const X509V3_EXT_METHOD ossl_v3_authority_attribute_identifier = { + NID_authority_attribute_identifier, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_ATTRIBUTE_ID_SYNTAX), + 0, 0, 0, 0, + 0, + 0, + 0, 0, + (X509V3_EXT_I2R)i2r_AUTHORITY_ATTRIBUTE_ID_SYNTAX, + 0, + NULL +}; diff --git a/crypto/x509/v3_bacons.c b/crypto/x509/v3_bacons.c new file mode 100644 index 0000000000000..008cb82c8f3f0 --- /dev/null +++ b/crypto/x509/v3_bacons.c @@ -0,0 +1,82 @@ +/* + * Copyright 1999-2021 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/cryptlib.h" +#include +#include +#include +#include "x509_local.h" + +static STACK_OF(CONF_VALUE) *i2v_BASIC_ATTR_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_ATTR_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist); +static BASIC_ATTR_CONSTRAINTS *v2i_BASIC_ATTR_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD ossl_v3_bacons = { + NID_basic_att_constraints, 0, + ASN1_ITEM_ref(BASIC_ATTR_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_BASIC_ATTR_CONSTRAINTS, + (X509V3_EXT_V2I)v2i_BASIC_ATTR_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(BASIC_ATTR_CONSTRAINTS) = { + ASN1_OPT(BASIC_ATTR_CONSTRAINTS, authority, ASN1_FBOOLEAN), + ASN1_OPT(BASIC_ATTR_CONSTRAINTS, pathlen, ASN1_INTEGER) +} ASN1_SEQUENCE_END(BASIC_ATTR_CONSTRAINTS) + +IMPLEMENT_ASN1_FUNCTIONS(BASIC_ATTR_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_BASIC_ATTR_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_ATTR_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist) +{ + X509V3_add_value_bool("authority", bcons->authority, &extlist); + X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); + return extlist; +} + +static BASIC_ATTR_CONSTRAINTS *v2i_BASIC_ATTR_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + BASIC_ATTR_CONSTRAINTS *bcons = NULL; + CONF_VALUE *val; + int i; + + if ((bcons = BASIC_ATTR_CONSTRAINTS_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (strcmp(val->name, "authority") == 0) { + if (!X509V3_get_value_bool(val, &bcons->authority)) + goto err; + } else if (strcmp(val->name, "pathlen") == 0) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) + goto err; + } else { + ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_add_error_name_value(val); + goto err; + } + } + return bcons; + err: + BASIC_ATTR_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c index c575a43459ead..bcc1da2d41ef1 100644 --- a/crypto/x509/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -16,6 +16,7 @@ #include #include "crypto/x509.h" #include +#include "openssl/x509_acert.h" static int v3_check_critical(const char **value); static int v3_check_generic(const char **value); @@ -600,3 +601,32 @@ int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, NCONF_free(ctmp); return ret; } + +/* + * Add extensions to an ACERT. Just check in case acert == NULL. + * Note that on error new elements may remain added to acert if acert != NULL. + */ +int X509V3_EXT_ACERT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section, + X509_ACERT *acert) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (acert != NULL) + sk = &acert->acinfo->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Same as above but for an X509_ACERT */ + +int X509V3_EXT_ACERT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + const char *section, X509_ACERT *acert) +{ + CONF *ctmp; + int ret; + + if ((ctmp = NCONF_new(NULL)) == NULL) + return 0; + CONF_set_nconf(ctmp, conf); + ret = X509V3_EXT_ACERT_add_nconf(ctmp, ctx, section, acert); + NCONF_free(ctmp); + return ret; +} \ No newline at end of file diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c index ae602ea2cd28a..fb1964dd4815c 100644 --- a/crypto/x509/v3_cpols.c +++ b/crypto/x509/v3_cpols.c @@ -26,7 +26,6 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *value); static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent); -static void print_notice(BIO *out, USERNOTICE *notice, int indent); static POLICYINFO *policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org); static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, @@ -461,42 +460,6 @@ static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, } } -static void print_notice(BIO *out, USERNOTICE *notice, int indent) -{ - int i; - if (notice->noticeref) { - NOTICEREF *ref; - ref = notice->noticeref; - BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", - ref->organization->length, - ref->organization->data); - BIO_printf(out, "%*sNumber%s: ", indent, "", - sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); - for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { - ASN1_INTEGER *num; - char *tmp; - num = sk_ASN1_INTEGER_value(ref->noticenos, i); - if (i) - BIO_puts(out, ", "); - if (num == NULL) - BIO_puts(out, "(null)"); - else { - tmp = i2s_ASN1_INTEGER(NULL, num); - if (tmp == NULL) - return; - BIO_puts(out, tmp); - OPENSSL_free(tmp); - } - } - if (notice->exptext) - BIO_puts(out, "\n"); - } - if (notice->exptext) - BIO_printf(out, "%*sExplicit Text: %.*s", indent, "", - notice->exptext->length, - notice->exptext->data); -} - void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) { const X509_POLICY_DATA *dat = node->data; diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c index 08df3faf86eef..3f03d31338534 100644 --- a/crypto/x509/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -13,9 +13,7 @@ #include #include #include - #include "crypto/x509.h" -#include "ext_dat.h" #include "x509_local.h" static void *v2i_crld(const X509V3_EXT_METHOD *method, @@ -182,7 +180,7 @@ static int print_reasons(BIO *out, const char *rname, { int first = 1; const BIT_STRING_BITNAME *pbn; - BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 4, ""); for (pbn = reason_flags; pbn->lname; pbn++) { if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { if (first) @@ -413,27 +411,16 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, return NULL; } -static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) -{ - int i; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - if (i > 0) - BIO_puts(out, "\n"); - BIO_printf(out, "%*s", indent + 2, ""); - GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); - } - return 1; -} - static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) { if (dpn->type == 0) { BIO_printf(out, "%*sFull Name:\n", indent, ""); - print_gens(out, dpn->name.fullname, indent); + ossl_print_gens(out, dpn->name.fullname, indent); + BIO_puts(out, "\n"); } else { X509_NAME ntmp; ntmp.entries = dpn->name.relativename; - BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); + BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 4, ""); X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); BIO_puts(out, "\n"); } @@ -480,7 +467,7 @@ static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, print_reasons(out, "Reasons", point->reasons, indent); if (point->CRLissuer) { BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); - print_gens(out, point->CRLissuer, indent); + ossl_print_gens(out, point->CRLissuer, indent); } } return 1; @@ -514,3 +501,190 @@ int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, const X509_NAME *iname) dpn->dpname = NULL; return 0; } + +ASN1_SEQUENCE(AA_DIST_POINT) = { + ASN1_EXP_OPT(AA_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(AA_DIST_POINT, reasons, ASN1_BIT_STRING, 1), + ASN1_IMP_OPT(AA_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(AA_DIST_POINT, containsUserAttributeCerts, ASN1_TBOOLEAN, 3), + ASN1_IMP_OPT(AA_DIST_POINT, containsAACerts, ASN1_TBOOLEAN, 4), + ASN1_IMP_OPT(AA_DIST_POINT, containsSOAPublicKeyCerts, ASN1_TBOOLEAN, 5) +} ASN1_SEQUENCE_END(AA_DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(AA_DIST_POINT) + +static int print_boolean (BIO *out, ASN1_BOOLEAN b) { + if (b) { + return BIO_puts(out, "TRUE"); + } else { + return BIO_puts(out, "FALSE"); + } +} + +static AA_DIST_POINT *aaidp_from_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE *cnf; + AA_DIST_POINT *point = AA_DIST_POINT_new(); + + if (point == NULL) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (strcmp(cnf->name, "reasons") == 0) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } else if (strcmp(cnf->name, "indirectCRL") == 0) { + if (!X509V3_get_value_bool(cnf, &point->indirectCRL)) + goto err; + } else if (strcmp(cnf->name, "containsUserAttributeCerts") == 0) { + if (!X509V3_get_value_bool(cnf, &point->containsUserAttributeCerts)) + goto err; + } else if (strcmp(cnf->name, "containsAACerts") == 0) { + if (!X509V3_get_value_bool(cnf, &point->containsAACerts)) + goto err; + } else if (strcmp(cnf->name, "containsSOAPublicKeyCerts") == 0) { + if (!X509V3_get_value_bool(cnf, &point->containsSOAPublicKeyCerts)) + goto err; + } + } + + return point; + + err: + AA_DIST_POINT_free(point); + return NULL; +} + +static void *v2i_aaidp(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + int i = 0; + AA_DIST_POINT *point = NULL; + + cnf = sk_CONF_VALUE_value(nval, i); + if (cnf->value == NULL) { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = aaidp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (point == NULL) { + goto err; + } + } else { + if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) + goto err; + if ((gens = GENERAL_NAMES_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if (!sk_GENERAL_NAME_push(gens, gen)) { + ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); + goto err; + } + gen = NULL; + if ((point = AA_DIST_POINT_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + if ((point->distpoint = DIST_POINT_NAME_new()) == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); + goto err; + } + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + return point; + + err: + if (point != NULL) { + AA_DIST_POINT_free(point); + } + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + return NULL; +} + + +static int i2r_aaidp(const X509V3_EXT_METHOD *method, void *pdp, BIO *out, + int indent) +{ + AA_DIST_POINT *dp = pdp; + if (dp->distpoint) + if (print_distpoint(out, dp->distpoint, indent) <= 0) { + return 0; + } + if (dp->reasons) + if (print_reasons(out, "Reasons", dp->reasons, indent) <= 0) { + return 0; + } + if (dp->indirectCRL) { + if (BIO_printf(out, "%*sIndirect CRL: ", indent, "") <= 0) { + return 0; + } + if (print_boolean(out, dp->indirectCRL) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (dp->containsUserAttributeCerts) { + if (BIO_printf(out, "%*sContains User Attribute Certificates: ", indent, "") <= 0) { + return 0; + } + if (print_boolean(out, dp->containsUserAttributeCerts) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (dp->containsAACerts) { + if (BIO_printf(out, "%*sContains Attribute Authority (AA) Certificates: ", indent, "") <= 0) { + return 0; + } + if (print_boolean(out, dp->containsAACerts) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (dp->containsSOAPublicKeyCerts) { + if (BIO_printf(out, "%*sContains Source Of Authority (SOA) Public Key Certificates: ", indent, "") <= 0) { + return 0; + } + if (print_boolean(out, dp->containsSOAPublicKeyCerts) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_aa_issuing_dist_point = { + NID_id_aa_issuing_distribution_point, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AA_DIST_POINT), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_aaidp, + i2r_aaidp, 0, + NULL +}; \ No newline at end of file diff --git a/crypto/x509/v3_extku.c b/crypto/x509/v3_extku.c index 22c951e251c2a..6053d5e2cb999 100644 --- a/crypto/x509/v3_extku.c +++ b/crypto/x509/v3_extku.c @@ -44,6 +44,30 @@ const X509V3_EXT_METHOD ossl_v3_ocsp_accresp = { NULL }; +/* Acceptable Certificate Policies also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD ossl_v3_acc_cert_policies = { + NID_acceptable_cert_policies, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +/* Acceptable Privilege Policies also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD ossl_v3_acc_priv_policies = { + NID_acceptable_privilege_policies, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) diff --git a/crypto/x509/v3_group_ac.c b/crypto/x509/v3_group_ac.c new file mode 100644 index 0000000000000..549ae1c7d20ad --- /dev/null +++ b/crypto/x509/v3_group_ac.c @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_GROUP_AC(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_GROUP_AC(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_GROUP_AC(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_GROUP_AC(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +const X509V3_EXT_METHOD ossl_v3_group_ac = { + NID_group_ac, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_GROUP_AC, + (X509V3_EXT_S2I)s2i_GROUP_AC, + 0, 0, + (X509V3_EXT_I2R)i2r_GROUP_AC, + (X509V3_EXT_R2I)r2i_GROUP_AC, + NULL +}; diff --git a/crypto/x509/v3_ind_iss.c b/crypto/x509/v3_ind_iss.c new file mode 100644 index 0000000000000..a2708dc4b5970 --- /dev/null +++ b/crypto/x509/v3_ind_iss.c @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_INDIRECT_ISSUER(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_INDIRECT_ISSUER(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_INDIRECT_ISSUER(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_INDIRECT_ISSUER(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +const X509V3_EXT_METHOD ossl_v3_indirect_issuer = { + NID_indirect_issuer, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_INDIRECT_ISSUER, + (X509V3_EXT_S2I)s2i_INDIRECT_ISSUER, + 0, 0, + (X509V3_EXT_I2R)i2r_INDIRECT_ISSUER, + (X509V3_EXT_R2I)r2i_INDIRECT_ISSUER, + NULL +}; diff --git a/crypto/x509/v3_iobo.c b/crypto/x509/v3_iobo.c new file mode 100644 index 0000000000000..31929a966da30 --- /dev/null +++ b/crypto/x509/v3_iobo.c @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_IOBO(X509V3_EXT_METHOD *method, + GENERAL_NAME *gn, BIO *out, + int indent) +{ + if (BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, gn) <= 0) { + return 0; + } + return BIO_puts(out, "\n"); +} + +const X509V3_EXT_METHOD ossl_v3_issued_on_behalf_of = { + NID_issued_on_behalf_of, 0, ASN1_ITEM_ref(GENERAL_NAME), + 0, 0, 0, 0, + 0, 0, + 0, 0, + (X509V3_EXT_I2R)i2r_IOBO, + 0, + NULL +}; diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c index ba8141b8c1b4c..50a3cb5087169 100644 --- a/crypto/x509/v3_ncons.c +++ b/crypto/x509/v3_ncons.c @@ -53,6 +53,26 @@ const X509V3_EXT_METHOD ossl_v3_name_constraints = { NULL }; +const X509V3_EXT_METHOD ossl_v3_delegated_name_constraints = { + NID_delegated_name_constraints, 0, + ASN1_ITEM_ref(NAME_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + 0, v2i_NAME_CONSTRAINTS, + i2r_NAME_CONSTRAINTS, 0, + NULL +}; + +const X509V3_EXT_METHOD ossl_v3_holder_name_constraints = { + NID_holder_name_constraints, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(NAME_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + 0, v2i_NAME_CONSTRAINTS, + i2r_NAME_CONSTRAINTS, 0, + NULL +}; + ASN1_SEQUENCE(GENERAL_SUBTREE) = { ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), diff --git a/crypto/x509/v3_no_ass.c b/crypto/x509/v3_no_ass.c new file mode 100644 index 0000000000000..eb9a0b83942c9 --- /dev/null +++ b/crypto/x509/v3_no_ass.c @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_NO_ASSERTION(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_NO_ASSERTION(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_NO_ASSERTION(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_NO_ASSERTION(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +const X509V3_EXT_METHOD ossl_v3_no_assertion = { + NID_no_assertion, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_NO_ASSERTION, + (X509V3_EXT_S2I)s2i_NO_ASSERTION, + 0, 0, + (X509V3_EXT_I2R)i2r_NO_ASSERTION, + (X509V3_EXT_R2I)r2i_NO_ASSERTION, + NULL +}; diff --git a/crypto/x509/v3_no_rev_avail.c b/crypto/x509/v3_no_rev_avail.c new file mode 100644 index 0000000000000..b3c67859c8c7b --- /dev/null +++ b/crypto/x509/v3_no_rev_avail.c @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_NO_REV_AVAIL(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_NO_REV_AVAIL(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_NO_REV_AVAIL(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_NO_REV_AVAIL(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +const X509V3_EXT_METHOD ossl_v3_no_rev_avail = { + NID_no_rev_avail, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_NO_REV_AVAIL, + (X509V3_EXT_S2I)s2i_NO_REV_AVAIL, + 0, 0, + (X509V3_EXT_I2R)i2r_NO_REV_AVAIL, + (X509V3_EXT_R2I)r2i_NO_REV_AVAIL, + NULL +}; diff --git a/crypto/x509/v3_rolespec.c b/crypto/x509/v3_rolespec.c new file mode 100644 index 0000000000000..968866a43c79f --- /dev/null +++ b/crypto/x509/v3_rolespec.c @@ -0,0 +1,123 @@ +/* + * Copyright 1999-2021 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 + +ASN1_SEQUENCE(ROLE_SPEC_CERT_ID) = { + ASN1_EXP(ROLE_SPEC_CERT_ID, roleName, GENERAL_NAME, 0), + ASN1_EXP(ROLE_SPEC_CERT_ID, roleCertIssuer, GENERAL_NAME, 1), + ASN1_IMP_OPT(ROLE_SPEC_CERT_ID, roleCertSerialNumber, ASN1_INTEGER, 2), + ASN1_IMP_SEQUENCE_OF_OPT(ROLE_SPEC_CERT_ID, roleCertLocator, GENERAL_NAME, 3), +} ASN1_SEQUENCE_END(ROLE_SPEC_CERT_ID) + +IMPLEMENT_ASN1_FUNCTIONS(ROLE_SPEC_CERT_ID) + +ASN1_ITEM_TEMPLATE(ROLE_SPEC_CERT_ID_SYNTAX) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ROLE_SPEC_CERT_ID_SYNTAX, ROLE_SPEC_CERT_ID) +ASN1_ITEM_TEMPLATE_END(ROLE_SPEC_CERT_ID_SYNTAX) + +IMPLEMENT_ASN1_FUNCTIONS(ROLE_SPEC_CERT_ID_SYNTAX) + +// This was copied from crypto/x509/x_attrib.c +static int ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) +{ + BIGNUM *num_bn; + int result = 0; + char *hex; + + num_bn = ASN1_INTEGER_to_BN(num, NULL); + if (num_bn == NULL) + return -1; + if ((hex = BN_bn2hex(num_bn))) { + result = BIO_write(bio, "0x", 2) > 0; + result = result && BIO_write(bio, hex, strlen(hex)) > 0; + OPENSSL_free(hex); + } + BN_free(num_bn); + + return result; +} + +static int i2r_ROLE_SPEC_CERT_ID(X509V3_EXT_METHOD *method, + ROLE_SPEC_CERT_ID *rscid, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*sRole Name: ", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, rscid->roleName) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + if (BIO_printf(out, "%*sRole Certificate Issuer: ", indent, "") <= 0) { + return 0; + } + if (GENERAL_NAME_print(out, rscid->roleCertIssuer) <= 0) { + return 0; + } + if (rscid->roleCertSerialNumber) { + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + if (BIO_printf(out, "%*sRole Certificate Serial Number: ", indent, "") <= 0) { + return 0; + } + if (ASN1_INTEGER_print_bio(out, rscid->roleCertSerialNumber) <= 0) { + return 0; + } + } + if (rscid->roleCertLocator) { + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + if (BIO_printf(out, "%*sRole Certificate Locator:\n", indent, "") <= 0) { + return 0; + } + if (ossl_print_gens(out, rscid->roleCertLocator, indent) <= 0) { + return 0; + } + } + return BIO_puts(out, "\n"); +} + +static int i2r_ROLE_SPEC_CERT_ID_SYNTAX(X509V3_EXT_METHOD *method, + ROLE_SPEC_CERT_ID_SYNTAX *rscids, + BIO *out, int indent) +{ + ROLE_SPEC_CERT_ID *rscid; + int i; + for (i = 0; i < sk_ROLE_SPEC_CERT_ID_num(rscids); i++) { + if (i > 0 && BIO_puts(out, "\n") <= 0) { + return 0; + } + if (BIO_printf(out, "%*sRole Specification Certificate Identifier #%d:\n", indent, "", i+1) <= 0) { + return 0; + } + rscid = sk_ROLE_SPEC_CERT_ID_value(rscids, i); + if (i2r_ROLE_SPEC_CERT_ID(method, rscid, out, indent + 4) != 1) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_role_spec_cert_identifier = { + NID_role_spec_cert_identifier, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ROLE_SPEC_CERT_ID_SYNTAX), + 0, 0, 0, 0, + 0, 0, + 0, + 0, + (X509V3_EXT_I2R)i2r_ROLE_SPEC_CERT_ID_SYNTAX, + NULL, + NULL +}; diff --git a/crypto/x509/v3_sda.c b/crypto/x509/v3_sda.c new file mode 100644 index 0000000000000..44fefb83d182b --- /dev/null +++ b/crypto/x509/v3_sda.c @@ -0,0 +1,92 @@ +/* + * Copyright 1999-2021 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 + +ASN1_ITEM_TEMPLATE(ATTRIBUTES_SYNTAX) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Attributes, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(ATTRIBUTES_SYNTAX) + +IMPLEMENT_ASN1_FUNCTIONS(ATTRIBUTES_SYNTAX) + +static int i2r_ATTRIBUTES_SYNTAX(X509V3_EXT_METHOD *method, + ATTRIBUTES_SYNTAX *attrlst, + BIO *out, int indent) +{ + X509_ATTRIBUTE *attr; + ASN1_TYPE *av; + int i, j, attr_nid; + if (!attrlst) { + if (BIO_printf(out, "\n") <= 0) { + return 0; + } + return 1; + } + if (!sk_X509_ATTRIBUTE_num(attrlst)) { + if (BIO_printf(out, "\n") <= 0) { + return 0; + } + return 1; + } + for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) { + ASN1_OBJECT *attr_obj; + attr = sk_X509_ATTRIBUTE_value(attrlst, i); + attr_obj = X509_ATTRIBUTE_get0_object(attr); + attr_nid = OBJ_obj2nid(attr_obj); + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) + return 0; + if (attr_nid == NID_undef) { + if (i2a_ASN1_OBJECT(out, attr_obj) <= 0) { + return 0; + } + if (BIO_puts(out, ":\n") <= 0) { + return 0; + } + } else if (BIO_printf(out, "%s:\n", OBJ_nid2ln(attr_nid)) <= 0) { + return 0; + } + + if (X509_ATTRIBUTE_count(attr)) { + for (j = 0; j < X509_ATTRIBUTE_count(attr); j++) + { + av = X509_ATTRIBUTE_get0_type(attr, j); + if (print_attribute_value(out, attr_nid, av, indent + 4) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + } else if (BIO_printf(out, "%*s\n", indent + 4, "") <= 0) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_subj_dir_attrs = { + NID_subject_directory_attributes, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ATTRIBUTES_SYNTAX), + 0, 0, 0, 0, + 0, 0, 0, 0, + (X509V3_EXT_I2R)i2r_ATTRIBUTES_SYNTAX, + 0, + NULL +}; + +const X509V3_EXT_METHOD ossl_v3_associated_info = { + NID_associated_information, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ATTRIBUTES_SYNTAX), + 0, 0, 0, 0, + 0, 0, 0, 0, + (X509V3_EXT_I2R)i2r_ATTRIBUTES_SYNTAX, + 0, + NULL +}; diff --git a/crypto/x509/v3_single_use.c b/crypto/x509/v3_single_use.c new file mode 100644 index 0000000000000..d11cfbe5aa4de --- /dev/null +++ b/crypto/x509/v3_single_use.c @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_SINGLE_USE(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent); + +static int i2r_SINGLE_USE(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_SINGLE_USE(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_SINGLE_USE(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_SINGLE_USE(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +const X509V3_EXT_METHOD ossl_v3_single_use = { + NID_single_use, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_SINGLE_USE, + (X509V3_EXT_S2I)s2i_SINGLE_USE, + 0, 0, + (X509V3_EXT_I2R)i2r_SINGLE_USE, + (X509V3_EXT_R2I)r2i_SINGLE_USE, + NULL +}; diff --git a/crypto/x509/v3_soa_id.c b/crypto/x509/v3_soa_id.c new file mode 100644 index 0000000000000..987d3e909abe6 --- /dev/null +++ b/crypto/x509/v3_soa_id.c @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2021 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 + +static int i2r_SOA_IDENTIFIER(X509V3_EXT_METHOD *method, + void *su, BIO *out, + int indent) +{ + return 1; +} + +static void *r2i_SOA_IDENTIFIER(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *value) +{ + return ASN1_NULL_new(); +} + +static char *i2s_SOA_IDENTIFIER(const X509V3_EXT_METHOD *method, void *val) +{ + return OPENSSL_strdup("NULL"); +} + +static void *s2i_SOA_IDENTIFIER(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +const X509V3_EXT_METHOD ossl_v3_soa_identifier = { + NID_soa_identifier, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_SOA_IDENTIFIER, + (X509V3_EXT_S2I)s2i_SOA_IDENTIFIER, + 0, 0, + (X509V3_EXT_I2R)i2r_SOA_IDENTIFIER, + (X509V3_EXT_R2I)r2i_SOA_IDENTIFIER, + NULL +}; diff --git a/crypto/x509/v3_timespec.c b/crypto/x509/v3_timespec.c new file mode 100644 index 0000000000000..2fec0c4bf0749 --- /dev/null +++ b/crypto/x509/v3_timespec.c @@ -0,0 +1,853 @@ +/* + * Copyright 1999-2021 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 + +ASN1_SEQUENCE(TIME_SPEC_ABSOLUTE) = { + ASN1_EXP_OPT(TIME_SPEC_ABSOLUTE, startTime, ASN1_GENERALIZEDTIME, 0), + ASN1_EXP_OPT(TIME_SPEC_ABSOLUTE, endTime, ASN1_GENERALIZEDTIME, 1), +} ASN1_SEQUENCE_END(TIME_SPEC_ABSOLUTE) + +ASN1_SEQUENCE(DAY_TIME) = { + ASN1_EXP_OPT(DAY_TIME, hour, ASN1_INTEGER, 0), + ASN1_EXP_OPT(DAY_TIME, minute, ASN1_INTEGER, 1), + ASN1_EXP_OPT(DAY_TIME, second, ASN1_INTEGER, 2), +} ASN1_SEQUENCE_END(DAY_TIME) + +ASN1_SEQUENCE(DAY_TIME_BAND) = { + ASN1_EXP_OPT(DAY_TIME_BAND, startDayTime, DAY_TIME, 0), + ASN1_EXP_OPT(DAY_TIME_BAND, endDayTime, DAY_TIME, 1), +} ASN1_SEQUENCE_END(DAY_TIME_BAND) + +ASN1_CHOICE(NAMED_DAY) = { + ASN1_SET_OF(NAMED_DAY, choice.intNamedDays, ASN1_ENUMERATED), + ASN1_SIMPLE(NAMED_DAY, choice.bitNamedDays, ASN1_BIT_STRING), +} ASN1_CHOICE_END(NAMED_DAY) + +ASN1_CHOICE(TIME_SPEC_X_DAY_OF) = { + ASN1_EXP(TIME_SPEC_X_DAY_OF, choice.first, NAMED_DAY, 1), + ASN1_EXP(TIME_SPEC_X_DAY_OF, choice.second, NAMED_DAY, 2), + ASN1_EXP(TIME_SPEC_X_DAY_OF, choice.third, NAMED_DAY, 3), + ASN1_EXP(TIME_SPEC_X_DAY_OF, choice.fourth, NAMED_DAY, 4), + ASN1_EXP(TIME_SPEC_X_DAY_OF, choice.fifth, NAMED_DAY, 5), +} ASN1_CHOICE_END(TIME_SPEC_X_DAY_OF) + +ASN1_CHOICE(TIME_SPEC_DAY) = { + ASN1_SET_OF(TIME_SPEC_DAY, choice.intDay, ASN1_INTEGER), + ASN1_SIMPLE(TIME_SPEC_DAY, choice.bitDay, ASN1_BIT_STRING), + ASN1_SIMPLE(TIME_SPEC_DAY, choice.dayOf, TIME_SPEC_X_DAY_OF), +} ASN1_CHOICE_END(TIME_SPEC_DAY) + +ASN1_CHOICE(TIME_SPEC_WEEKS) = { + ASN1_SIMPLE(TIME_SPEC_WEEKS, choice.allWeeks, ASN1_NULL), + ASN1_SET_OF(TIME_SPEC_WEEKS, choice.intWeek, ASN1_INTEGER), + ASN1_SIMPLE(TIME_SPEC_WEEKS, choice.bitWeek, ASN1_BIT_STRING), +} ASN1_CHOICE_END(TIME_SPEC_WEEKS) + +ASN1_CHOICE(TIME_SPEC_MONTH) = { + ASN1_SIMPLE(TIME_SPEC_MONTH, choice.allMonths, ASN1_NULL), + ASN1_SET_OF(TIME_SPEC_MONTH, choice.intMonth, ASN1_INTEGER), + ASN1_SIMPLE(TIME_SPEC_MONTH, choice.bitMonth, ASN1_BIT_STRING), +} ASN1_CHOICE_END(TIME_SPEC_MONTH) + +ASN1_SEQUENCE(TIME_PERIOD) = { + ASN1_EXP_SET_OF_OPT(TIME_PERIOD, timesOfDay, DAY_TIME_BAND, 0), + ASN1_EXP_OPT(TIME_PERIOD, days, TIME_SPEC_DAY, 1), + ASN1_EXP_OPT(TIME_PERIOD, weeks, TIME_SPEC_WEEKS, 2), + ASN1_EXP_OPT(TIME_PERIOD, months, TIME_SPEC_MONTH, 3), + ASN1_EXP_SET_OF_OPT(TIME_PERIOD, years, ASN1_INTEGER, 4), +} ASN1_SEQUENCE_END(TIME_PERIOD) + +ASN1_CHOICE(TIME_SPEC_TIME) = { + ASN1_SIMPLE(TIME_SPEC_TIME, choice.absolute, TIME_SPEC_ABSOLUTE), + ASN1_SET_OF(TIME_SPEC_TIME, choice.periodic, TIME_PERIOD) +} ASN1_CHOICE_END(TIME_SPEC_TIME) + +ASN1_SEQUENCE(TIME_SPEC) = { + ASN1_SIMPLE(TIME_SPEC, time, TIME_SPEC_TIME), + ASN1_OPT(TIME_SPEC, notThisTime, ASN1_FBOOLEAN), + ASN1_OPT(TIME_SPEC, timeZone, ASN1_INTEGER), +} ASN1_SEQUENCE_END(TIME_SPEC) + +IMPLEMENT_ASN1_FUNCTIONS(TIME_SPEC_ABSOLUTE) +IMPLEMENT_ASN1_FUNCTIONS(TIME_SPEC_TIME) +IMPLEMENT_ASN1_FUNCTIONS(TIME_SPEC) + +static int i2r_TIME_SPEC_ABSOLUTE(X509V3_EXT_METHOD *method, + TIME_SPEC_ABSOLUTE *time, + BIO *out, int indent) +{ + if (time->startTime != NULL && time->endTime != NULL) { + if (!BIO_puts(out, "Any time between ")) { + return 0; + } + if (!ossl_asn1_time_print_ex(out, time->startTime, 0)) { + return 0; + } + if (!BIO_puts(out, " and ")) { + return 0; + } + if (!ossl_asn1_time_print_ex(out, time->endTime, 0)) { + return 0; + } + } else if (time->startTime != NULL) { + if (!BIO_puts(out, "Any time after ")) { + return 0; + } + if (!ossl_asn1_time_print_ex(out, time->startTime, 0)) { + return 0; + } + BIO_printf(out, "%.*s", time->startTime->length, time->startTime->data); + } else if (time->endTime != NULL) { + if (!BIO_puts(out, "Any time until ")) { + return 0; + } + if (!ossl_asn1_time_print_ex(out, time->endTime, 0)) { + return 0; + } + } else { // Invalid: there must be SOME time specified. + return BIO_puts(out, "INVALID (EMPTY)"); + } + return 1; +} + +static int i2r_DAY_TIME(X509V3_EXT_METHOD *method, + DAY_TIME *dt, + BIO *out, int indent) +{ + int64_t h; + int64_t m; + int64_t s; + + if (!ASN1_INTEGER_get_int64(&h, dt->hour)) { + return 0; + } + if (dt->minute && !ASN1_INTEGER_get_int64(&m, dt->minute)) { + return 0; + } + if (dt->minute && !ASN1_INTEGER_get_int64(&s, dt->second)) { + return 0; + } + return BIO_printf(out, "%02ld:%02ld:%02ld", h, m, s); +} + +static int i2r_DAY_TIME_BAND(X509V3_EXT_METHOD *method, + DAY_TIME_BAND *band, + BIO *out, int indent) +{ + if (band->startDayTime) { + if (!i2r_DAY_TIME(method, band->startDayTime, out, indent)) { + return 0; + } + } else { + if (!BIO_puts(out, "00:00:00")) { + return 0; + } + } + if (!BIO_puts(out, " - ")) { + return 0; + } + if (band->endDayTime) { + if (!i2r_DAY_TIME(method, band->endDayTime, out, indent)) { + return 0; + } + } else { + if (!BIO_puts(out, "23:59:59")) { + return 0; + } + } + return 1; +} + +static int print_int_month (BIO *out, int64_t month) { + switch (month) { + case (TIME_SPEC_INT_MONTH_JAN): return BIO_puts(out, "JAN"); + case (TIME_SPEC_INT_MONTH_FEB): return BIO_puts(out, "FEB"); + case (TIME_SPEC_INT_MONTH_MAR): return BIO_puts(out, "MAR"); + case (TIME_SPEC_INT_MONTH_APR): return BIO_puts(out, "APR"); + case (TIME_SPEC_INT_MONTH_MAY): return BIO_puts(out, "MAY"); + case (TIME_SPEC_INT_MONTH_JUN): return BIO_puts(out, "JUN"); + case (TIME_SPEC_INT_MONTH_JUL): return BIO_puts(out, "JUL"); + case (TIME_SPEC_INT_MONTH_AUG): return BIO_puts(out, "AUG"); + case (TIME_SPEC_INT_MONTH_SEP): return BIO_puts(out, "SEP"); + case (TIME_SPEC_INT_MONTH_OCT): return BIO_puts(out, "OCT"); + case (TIME_SPEC_INT_MONTH_NOV): return BIO_puts(out, "NOV"); + case (TIME_SPEC_INT_MONTH_DEC): return BIO_puts(out, "DEC"); + default: return 0; + } + return 0; +} + +static int print_bit_month (BIO *out, ASN1_BIT_STRING *bs) { + int i = 0; + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_JAN)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "JAN")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_FEB)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "FEB")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_MAR)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "MAR")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_APR)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "APR")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_MAY)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "MAY")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_JUN)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "JUN")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_JUL)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "JUL")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_AUG)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "AUG")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_SEP)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "SEP")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_OCT)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "OCT")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_NOV)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "NOV")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_MONTH_DEC)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "DEC")) { + return 0; + } + } + return 1; +} + +/* It might seem like you could just print the bits of the +string numerically, but the fifth bit has the special meaning +of "the final week" imputed to it by the text of ITU Rec. X.520. */ +static int print_bit_week (BIO *out, ASN1_BIT_STRING *bs) { + int i = 0; + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_WEEKS_1)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "first")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_WEEKS_2)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "second")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_WEEKS_3)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "third")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_WEEKS_4)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "fourth")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_BIT_WEEKS_5)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "final")) { + return 0; + } + } + return 1; +} + +static int print_day_of_week (BIO *out, ASN1_BIT_STRING *bs) { + int i = 0; + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_SUN)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "SUN")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_MON)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "MON")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_TUE)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "TUE")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_WED)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "WED")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_THU)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "THU")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_FRI)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "FRI")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, TIME_SPEC_DAY_BIT_SAT)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "SAT")) { + return 0; + } + } + return 1; +} + +static int print_int_day_of_week (BIO *out, int64_t month) { + switch (month) { + case (TIME_SPEC_DAY_INT_SUN): return BIO_puts(out, "SUN"); + case (TIME_SPEC_DAY_INT_MON): return BIO_puts(out, "MON"); + case (TIME_SPEC_DAY_INT_TUE): return BIO_puts(out, "TUE"); + case (TIME_SPEC_DAY_INT_WED): return BIO_puts(out, "WED"); + case (TIME_SPEC_DAY_INT_THU): return BIO_puts(out, "THU"); + case (TIME_SPEC_DAY_INT_FRI): return BIO_puts(out, "FRI"); + case (TIME_SPEC_DAY_INT_SAT): return BIO_puts(out, "SAT"); + default: return 0; + } + return 0; +} + +static int print_int_named_day (BIO *out, int64_t nd) { + switch (nd) { + case (NAMED_DAY_INT_SUN): return BIO_puts(out, "SUN"); + case (NAMED_DAY_INT_MON): return BIO_puts(out, "MON"); + case (NAMED_DAY_INT_TUE): return BIO_puts(out, "TUE"); + case (NAMED_DAY_INT_WED): return BIO_puts(out, "WED"); + case (NAMED_DAY_INT_THU): return BIO_puts(out, "THU"); + case (NAMED_DAY_INT_FRI): return BIO_puts(out, "FRI"); + case (NAMED_DAY_INT_SAT): return BIO_puts(out, "SAT"); + default: return 0; + } + return 0; +} + +static int print_bit_named_day (BIO *out, ASN1_BIT_STRING *bs) { + int i = 0; + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_SUN)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "SUN")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_MON)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "MON")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_TUE)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "TUE")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_WED)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "WED")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_THU)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "THU")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_FRI)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "FRI")) { + return 0; + } + } + if (ASN1_BIT_STRING_get_bit(bs, NAMED_DAY_BIT_SAT)) { + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + i++; + if (!BIO_puts(out, "SAT")) { + return 0; + } + } + return 1; +} + +static int i2r_PERIOD(X509V3_EXT_METHOD *method, + TIME_PERIOD *p, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*sPeriod:\n", indent, "") <= 0) { + return 0; + } + int i; + if (p->timesOfDay) { + DAY_TIME_BAND *band; + BIO_printf(out, "%*sDaytime bands:\n", indent + 4, ""); + for (i = 0; i < sk_DAY_TIME_BAND_num(p->timesOfDay); i++) { + band = sk_DAY_TIME_BAND_value(p->timesOfDay, i); + if (BIO_printf(out, "%*s", indent + 8, "") <= 0) { + return 0; + } + if (!i2r_DAY_TIME_BAND(method, band, out, indent + 8)) { + return 0; + } + if (!BIO_puts(out, "\n")) { + return 0; + } + } + if (!BIO_puts(out, "\n")) { + return 0; + } + } + if (p->days) { + if (p->days->type == TIME_SPEC_DAY_TYPE_INT) { + if (p->weeks != NULL) { + if (!BIO_printf(out, "%*sDays of the week: ", indent + 4, "")) { + return 0; + } + } else if (p->months != NULL) { + if (!BIO_printf(out, "%*sDays of the month: ", indent + 4, "")) { + return 0; + } + } else if (p->years != NULL) { + if (!BIO_printf(out, "%*sDays of the year: ", indent + 4, "")) { + return 0; + } + } + } else { + if (!BIO_printf(out, "%*sDays: ", indent + 4, "")) { + return 0; + } + } + + switch (p->days->type) { + case (TIME_SPEC_DAY_TYPE_INT): { + for (i = 0; i < sk_ASN1_INTEGER_num(p->days->choice.intDay); i++) { + ASN1_INTEGER *big_day; + int64_t day; + + big_day = sk_ASN1_INTEGER_value(p->days->choice.intDay, i); + if (!ASN1_INTEGER_get_int64(&day, big_day)) { + return 0; + } + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + // If weeks is defined, then print day of week by name. + if (p->weeks != NULL) { + if (!print_int_day_of_week(out, day)) { + return 0; + } + } else if (!BIO_printf(out, "%ld", day)) { + return 0; + } + } + break; + } + case (TIME_SPEC_DAY_TYPE_BIT): { + if (!print_day_of_week(out, p->days->choice.bitDay)) { + return 0; + } + break; + } + case (TIME_SPEC_DAY_TYPE_DAY_OF): { + NAMED_DAY *nd; + switch (p->days->choice.dayOf->type) { + case (TIME_SPEC_X_DAY_OF_FIRST): { + if (!BIO_puts(out, "FIRST ")) { + return 0; + } + nd = p->days->choice.dayOf->choice.first; + break; + } + case (TIME_SPEC_X_DAY_OF_SECOND): { + if (!BIO_puts(out, "SECOND ")) { + return 0; + } + nd = p->days->choice.dayOf->choice.second; + break; + } + case (TIME_SPEC_X_DAY_OF_THIRD): { + if (!BIO_puts(out, "THIRD ")) { + return 0; + } + nd = p->days->choice.dayOf->choice.third; + break; + } + case (TIME_SPEC_X_DAY_OF_FOURTH): { + if (!BIO_puts(out, "FOURTH ")) { + return 0; + } + nd = p->days->choice.dayOf->choice.fourth; + break; + } + case (TIME_SPEC_X_DAY_OF_FIFTH): { + if (!BIO_puts(out, "FIFTH ")) { + return 0; + } + nd = p->days->choice.dayOf->choice.fifth; + break; + } + default: return 0; + } + switch (nd->type) { + case (NAMED_DAY_TYPE_INT): { + int64_t day; + + if (!ASN1_INTEGER_get_int64(&day, nd->choice.intNamedDays)) { + return 0; + } + if (!print_int_named_day(out, day)) { + return 0; + } + break; + } + case (NAMED_DAY_TYPE_BIT): { + if (!print_bit_named_day(out, nd->choice.bitNamedDays)) { + return 0; + } + break; + } + default: return 0; + } + break; + } + default: return 0; + } + if (!BIO_puts(out, "\n")) { + return 0; + } + } + if (p->weeks) { + if (p->weeks->type == TIME_SPEC_WEEKS_TYPE_INT) { + if (p->months != NULL) { + if (!BIO_printf(out, "%*sWeeks of the month: ", indent + 4, "")) { + return 0; + } + } else if (p->years != NULL) { + if (!BIO_printf(out, "%*sWeeks of the year: ", indent + 4, "")) { + return 0; + } + } + } else { + if (!BIO_printf(out, "%*sWeeks: ", indent + 4, "")) { + return 0; + } + } + + switch (p->weeks->type) { + case (TIME_SPEC_WEEKS_TYPE_ALL): { + if (!BIO_puts(out, "ALL")) { + return 0; + } + break; + } + case (TIME_SPEC_WEEKS_TYPE_INT): { + for (i = 0; i < sk_ASN1_INTEGER_num(p->weeks->choice.intWeek); i++) { + ASN1_INTEGER *big_week; + int64_t week; + + big_week = sk_ASN1_INTEGER_value(p->weeks->choice.intWeek, i); + if (!ASN1_INTEGER_get_int64(&week, big_week)) { + return 0; + } + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + if (!BIO_printf(out, "%ld", week)) { + return 0; + } + } + break; + } + case (TIME_SPEC_WEEKS_TYPE_BIT): { + if (!print_bit_week(out, p->weeks->choice.bitWeek)) { + return 0; + } + break; + } + default: return 0; + } + if (!BIO_puts(out, "\n")) { + return 0; + } + } + if (p->months) { + if (!BIO_printf(out, "%*sMonths: ", indent + 4, "")) { + return 0; + } + switch (p->months->type) { + case (TIME_SPEC_MONTH_TYPE_ALL): { + if (!BIO_puts(out, "ALL")) { + return 0; + } + break; + } + case (TIME_SPEC_MONTH_TYPE_INT): { + for (i = 0; i < sk_ASN1_INTEGER_num(p->months->choice.intMonth); i++) { + ASN1_INTEGER *big_month; + int64_t month; + + big_month = sk_ASN1_INTEGER_value(p->months->choice.intMonth, i); + if (!ASN1_INTEGER_get_int64(&month, big_month)) { + return 0; + } + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + if (!print_int_month(out, month)) { + return 0; + } + } + break; + } + case (TIME_SPEC_MONTH_TYPE_BIT): { + if (!print_bit_month(out, p->months->choice.bitMonth)) { + return 0; + } + break; + } + default: return 0; + } + if (!BIO_puts(out, "\n")) { + return 0; + } + } + if (p->years) { + if (!BIO_printf(out, "%*sYears: ", indent + 4, "")) { + return 0; + } + for (i = 0; i < sk_ASN1_INTEGER_num(p->years); i++) { + ASN1_INTEGER *big_year; + int64_t year; + + big_year = sk_ASN1_INTEGER_value(p->years, i); + if (!ASN1_INTEGER_get_int64(&year, big_year)) { + return 0; + } + if (i > 0 && !BIO_puts(out, ", ")) { + return 0; + } + if (!BIO_printf(out, "%04ld", year)) { + return 0; + } + } + } + return 1; +} + +static int i2r_TIME_SPEC_TIME(X509V3_EXT_METHOD *method, + TIME_SPEC_TIME *time, + BIO *out, int indent) +{ + TIME_PERIOD *tp; + int i; + switch (time->type) { + case (TIME_SPEC_TIME_TYPE_ABSOLUTE): { + if (BIO_printf(out, "%*sAbsolute: ", indent, "") <= 0) { + return 0; + } + if (i2r_TIME_SPEC_ABSOLUTE(method, time->choice.absolute, out, indent + 4) <= 0) { + return 0; + } + return BIO_puts(out, "\n"); + } + case (TIME_SPEC_TIME_TYPE_PERIODIC): { + if (BIO_printf(out, "%*sPeriodic:\n", indent, "") <= 0) { + return 0; + } + for (i = 0; i < sk_TIME_PERIOD_num(time->choice.periodic); i++) { + if (i > 0 && !BIO_puts(out, "\n")) { + return 0; + } + tp = sk_TIME_PERIOD_value(time->choice.periodic, i); + if (!i2r_PERIOD(method, tp, out, indent + 4)) { + return 0; + } + } + return BIO_puts(out, "\n"); + } + default: return 0; + } + return 0; +} + +static int i2r_TIME_SPEC(X509V3_EXT_METHOD *method, + TIME_SPEC *time, + BIO *out, int indent) +{ + if (time->timeZone) { + int64_t tz; + if (ASN1_INTEGER_get_int64(&tz, time->timeZone) != 1) { + return 0; + } + if (BIO_printf(out, "%*sTimezone: UTC%+03ld:00\n", indent, "", tz) <= 0) { + return 0; + } + } + if (time->notThisTime > 0) { + if (BIO_printf(out, "%*sNOT this time:\n", indent, "") <= 0) { + return 0; + } + } else if (BIO_printf(out, "%*sTime:\n", indent, "") <= 0) { + return 0; + } + return i2r_TIME_SPEC_TIME(method, time->time, out, indent + 4); +} + +const X509V3_EXT_METHOD ossl_v3_time_specification = { + NID_time_specification, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(TIME_SPEC), + 0, 0, 0, 0, + 0, 0, + 0, + 0, + (X509V3_EXT_I2R)i2r_TIME_SPEC, + NULL, + NULL +}; diff --git a/crypto/x509/v3_usernotice.c b/crypto/x509/v3_usernotice.c new file mode 100644 index 0000000000000..51ad2a625216b --- /dev/null +++ b/crypto/x509/v3_usernotice.c @@ -0,0 +1,51 @@ +/* + * Copyright 1999-2021 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 + + +ASN1_ITEM_TEMPLATE(USER_NOTICE_SYNTAX) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, USER_NOTICE_SYNTAX, USERNOTICE) +ASN1_ITEM_TEMPLATE_END(USER_NOTICE_SYNTAX) + +IMPLEMENT_ASN1_FUNCTIONS(USER_NOTICE_SYNTAX) + +static int i2r_USER_NOTICE_SYNTAX(X509V3_EXT_METHOD *method, + USER_NOTICE_SYNTAX *uns, + BIO *out, int indent) +{ + int i; + USERNOTICE *unotice; + if (BIO_printf(out, "%*sUser Notices:\n", indent, "") <= 0) { + return 0; + } + for (i = 0; i < sk_USERNOTICE_num(uns); i++) { + unotice = sk_USERNOTICE_value(uns, i); + if (print_notice(out, unotice, indent + 4) <= 0) { + return 0; + } + if (BIO_puts(out, "\n") <= 0) { + return 0; + } + } + return 1; +} + +const X509V3_EXT_METHOD ossl_v3_user_notice = { + NID_user_notice, 0, + ASN1_ITEM_ref(USER_NOTICE_SYNTAX), + 0, 0, 0, 0, + 0, + 0, + 0, 0, + (X509V3_EXT_I2R)i2r_USER_NOTICE_SYNTAX, + 0, + NULL +}; diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c index 1a18174995196..613794abf95b6 100644 --- a/crypto/x509/v3_utl.c +++ b/crypto/x509/v3_utl.c @@ -1356,3 +1356,16 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, } return 1; } + +int ossl_print_gens(BIO *out, GENERAL_NAMES *gens, int indent) +{ + int i; + + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + if (i > 0) + BIO_puts(out, "\n"); + BIO_printf(out, "%*s", indent + 4, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + } + return 1; +} \ No newline at end of file diff --git a/crypto/x509/x509_acert.c b/crypto/x509/x509_acert.c new file mode 100644 index 0000000000000..d653f7a2ecf31 --- /dev/null +++ b/crypto/x509/x509_acert.c @@ -0,0 +1,352 @@ +/* + * Copyright 2021 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 + +/* + * OpenSSL ASN.1 template translation of RFC 5755 4.1. + */ + +ASN1_SEQUENCE(OSSL_OBJECT_DIGEST_INFO) = { + ASN1_SIMPLE(OSSL_OBJECT_DIGEST_INFO, digestedObjectType, ASN1_ENUMERATED), + ASN1_OPT(OSSL_OBJECT_DIGEST_INFO, otherObjectTypeID, ASN1_OBJECT), + ASN1_SIMPLE(OSSL_OBJECT_DIGEST_INFO, digestAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OSSL_OBJECT_DIGEST_INFO, objectDigest, ASN1_BIT_STRING), +} ASN1_SEQUENCE_END(OSSL_OBJECT_DIGEST_INFO) + +ASN1_SEQUENCE(X509_ACERT_ISSUER_V2FORM) = { + ASN1_SEQUENCE_OF_OPT(X509_ACERT_ISSUER_V2FORM, issuerName, GENERAL_NAME), + ASN1_IMP_OPT(X509_ACERT_ISSUER_V2FORM, baseCertificateId, OSSL_ISSUER_SERIAL, 0), + ASN1_IMP_OPT(X509_ACERT_ISSUER_V2FORM, objectDigestInfo, OSSL_OBJECT_DIGEST_INFO, 1), +} ASN1_SEQUENCE_END(X509_ACERT_ISSUER_V2FORM) + +ASN1_CHOICE(X509_ACERT_ISSUER) = { + ASN1_SEQUENCE_OF(X509_ACERT_ISSUER, u.v1Form, GENERAL_NAME), + ASN1_IMP(X509_ACERT_ISSUER, u.v2Form, X509_ACERT_ISSUER_V2FORM, 0), +} ASN1_CHOICE_END(X509_ACERT_ISSUER) + +ASN1_SEQUENCE(X509_HOLDER) = { + ASN1_IMP_OPT(X509_HOLDER, baseCertificateID, OSSL_ISSUER_SERIAL, 0), + ASN1_IMP_SEQUENCE_OF_OPT(X509_HOLDER, entityName, GENERAL_NAME, 1), + ASN1_IMP_OPT(X509_HOLDER, objectDigestInfo, OSSL_OBJECT_DIGEST_INFO, 2), +} ASN1_SEQUENCE_END(X509_HOLDER) + +ASN1_SEQUENCE(X509_ACERT_INFO) = { + ASN1_EMBED(X509_ACERT_INFO, version, ASN1_INTEGER), + ASN1_EMBED(X509_ACERT_INFO, holder, X509_HOLDER), + ASN1_EMBED(X509_ACERT_INFO, issuer, X509_ACERT_ISSUER), + ASN1_EMBED(X509_ACERT_INFO, signature, X509_ALGOR), + ASN1_EMBED(X509_ACERT_INFO, serialNumber, ASN1_INTEGER), + ASN1_EMBED(X509_ACERT_INFO, validityPeriod, X509_VAL), + ASN1_SEQUENCE_OF(X509_ACERT_INFO, attributes, X509_ATTRIBUTE), + ASN1_OPT(X509_ACERT_INFO, issuerUID, ASN1_BIT_STRING), + ASN1_SEQUENCE_OF_OPT(X509_ACERT_INFO, extensions, X509_EXTENSION), +} ASN1_SEQUENCE_END(X509_ACERT_INFO) + +ASN1_SEQUENCE(X509_ACERT) = { + ASN1_SIMPLE(X509_ACERT, acinfo, X509_ACERT_INFO), + ASN1_EMBED(X509_ACERT, sig_alg, X509_ALGOR), + ASN1_EMBED(X509_ACERT, signature, ASN1_BIT_STRING), +} ASN1_SEQUENCE_END(X509_ACERT) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ACERT) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ACERT) +IMPLEMENT_ASN1_FUNCTIONS(X509_ACERT_INFO) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_OBJECT_DIGEST_INFO) +IMPLEMENT_ASN1_FUNCTIONS(X509_ACERT_ISSUER_V2FORM) +IMPLEMENT_ASN1_FUNCTIONS(X509_ACERT_ISSUER) +IMPLEMENT_ASN1_FUNCTIONS(X509_HOLDER) + +static X509_NAME *get_dirName(const GENERAL_NAMES *names) +{ + GENERAL_NAME *dirName; + + if (sk_GENERAL_NAME_num(names) != 1) + return NULL; + + dirName = sk_GENERAL_NAME_value(names, 0); + if (dirName->type != GEN_DIRNAME) + return NULL; + + return dirName->d.directoryName; +} + +void OSSL_OBJECT_DIGEST_INFO_get0_digest(OSSL_OBJECT_DIGEST_INFO *o, + ASN1_ENUMERATED **digestedObjectType, + X509_ALGOR **digestAlgorithm, + ASN1_BIT_STRING **digest) +{ + if (digestedObjectType != NULL) + *digestedObjectType = o->digestedObjectType; + if (digestAlgorithm != NULL) + *digestAlgorithm = o->digestAlgorithm; + if (digest != NULL) + *digest = o->objectDigest; +} + +X509_NAME *OSSL_ISSUER_SERIAL_get0_issuer(OSSL_ISSUER_SERIAL *isss) +{ + return get_dirName(isss->issuer); +} + +ASN1_INTEGER *OSSL_ISSUER_SERIAL_get0_serial(OSSL_ISSUER_SERIAL *isss) +{ + return &isss->serial; +} + +ASN1_BIT_STRING *OSSL_ISSUER_SERIAL_get0_issuerUID(OSSL_ISSUER_SERIAL *isss) +{ + return isss->issuerUID; +} + +long X509_ACERT_get_version(const X509_ACERT *x) +{ + return ASN1_INTEGER_get(&x->acinfo->version); +} + +void X509_ACERT_get0_signature(const X509_ACERT *x, + const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg) +{ + if (psig != NULL) + *psig = &x->signature; + if (palg != NULL) + *palg = &x->sig_alg; +} + +int X509_ACERT_get_signature_nid(const X509_ACERT *x) +{ + return OBJ_obj2nid(x->sig_alg.algorithm); +} + +GENERAL_NAMES *X509_ACERT_get0_holder_entityName(const X509_ACERT *x) +{ + return x->acinfo->holder.entityName; +} + +OSSL_ISSUER_SERIAL *X509_ACERT_get0_holder_baseCertId(const X509_ACERT *x) +{ + return x->acinfo->holder.baseCertificateID; +} + +OSSL_OBJECT_DIGEST_INFO *X509_ACERT_get0_holder_digest(const X509_ACERT *x) +{ + return x->acinfo->holder.objectDigestInfo; +} + +X509_NAME *X509_ACERT_get0_issuerName(const X509_ACERT *x) +{ + return get_dirName(x->acinfo->issuer.u.v2Form->issuerName); +} + +ASN1_BIT_STRING *X509_ACERT_get0_issuerUID(X509_ACERT *x) +{ + return x->acinfo->issuerUID; +} + +const X509_ALGOR *X509_ACERT_get0_info_sigalg(const X509_ACERT *x) +{ + return &x->acinfo->signature; +} + +ASN1_INTEGER *X509_ACERT_get0_serialNumber(X509_ACERT *x) +{ + return &x->acinfo->serialNumber; +} + +const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notBefore(const X509_ACERT *x) +{ + ASN1_GENERALIZEDTIME *gentime = x->acinfo->validityPeriod.notBefore; + + if (gentime->type != V_ASN1_GENERALIZEDTIME) + return 0; + return gentime; +} + +const ASN1_GENERALIZEDTIME *X509_ACERT_get0_notAfter(const X509_ACERT *x) +{ + ASN1_GENERALIZEDTIME *gentime = x->acinfo->validityPeriod.notAfter; + + if (gentime->type != V_ASN1_GENERALIZEDTIME) + return 0; + return gentime; +} + +/* Attribute management functions */ + +int X509_ACERT_get_attr_count(const X509_ACERT *x) +{ + return X509at_get_attr_count(x->acinfo->attributes); +} + +int X509_ACERT_get_attr_by_NID(const X509_ACERT *x, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(x->acinfo->attributes, nid, lastpos); +} + +int X509_ACERT_get_attr_by_OBJ(const X509_ACERT *x, const ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(x->acinfo->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *X509_ACERT_get_attr(const X509_ACERT *x, int loc) +{ + return X509at_get_attr(x->acinfo->attributes, loc); +} + +X509_ATTRIBUTE *X509_ACERT_delete_attr(X509_ACERT *x, int loc) +{ + return X509at_delete_attr(x->acinfo->attributes, loc); +} + +const STACK_OF(X509_EXTENSION) *X509_ACERT_get0_extensions(const X509_ACERT *x) +{ + return x->acinfo->extensions; +} + +int X509_ACERT_add1_attr(X509_ACERT *x, X509_ATTRIBUTE *attr) +{ + STACK_OF(X509_ATTRIBUTE) **attrs = &x->acinfo->attributes; + + return (X509at_add1_attr(attrs, attr) != NULL); +} + +int X509_ACERT_add1_attr_by_OBJ(X509_ACERT *x, const ASN1_OBJECT *obj, + int type, const void *bytes, int len) +{ + STACK_OF(X509_ATTRIBUTE) **attrs = &x->acinfo->attributes; + + return (X509at_add1_attr_by_OBJ(attrs, obj, type, bytes, len) != NULL); +} + +int X509_ACERT_add1_attr_by_NID(X509_ACERT *x, int nid, int type, + const void *bytes, int len) +{ + STACK_OF(X509_ATTRIBUTE) **attrs = &x->acinfo->attributes; + + return (X509at_add1_attr_by_NID(attrs, nid, type, bytes, len) != NULL); +} + +int X509_ACERT_add1_attr_by_txt(X509_ACERT *x, const char *attrname, int type, + const unsigned char *bytes, int len) +{ + STACK_OF(X509_ATTRIBUTE) **attrs = &x->acinfo->attributes; + + return (X509at_add1_attr_by_txt(attrs, attrname, type, bytes, len) != NULL); +} + +static int check_asn1_attribute(const char **value) +{ + const char *p = *value; + + if (strncmp(p, "ASN1:", 5) != 0) + return 0; + + p += 5; + while (ossl_isspace(*p)) + p++; + + *value = p; + return 1; +} + +int X509_ACERT_add_attr_nconf(CONF *conf, const char *section, + int strtype, X509_ACERT *acert) +{ + int ret = 0, i; + STACK_OF(CONF_VALUE) *attr_sk = NCONF_get_section(conf, section); + + if (attr_sk == NULL) + goto err; + + for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { + int att_len; + unsigned char *att_data = NULL; + CONF_VALUE *v = sk_CONF_VALUE_value(attr_sk, i); + const char *value = v->value; + + if (check_asn1_attribute(&value) == 0) { + ret = X509_ACERT_add1_attr_by_txt(acert, v->name, strtype, + (unsigned char *)value, -1); + if (!ret) + goto err; + } else { + ASN1_TYPE *asn1 = ASN1_generate_nconf(value, conf); + if (asn1 == NULL) + goto err; + + att_len = i2d_ASN1_TYPE(asn1, &att_data); + + ret = X509_ACERT_add1_attr_by_txt(acert, v->name, V_ASN1_SEQUENCE, + att_data, att_len); + ASN1_TYPE_free(asn1); + OPENSSL_free(att_data); + + if (!ret) + goto err; + } + } + ret = 1; +err: + return ret; +} + +int X509_acert_get_ext_count(const X509_ACERT *x) +{ + return X509v3_get_ext_count(x->acinfo->extensions); +} + +int X509_acert_get_ext_by_NID(const X509_ACERT *x, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(x->acinfo->extensions, nid, lastpos); +} + +int X509_acert_get_ext_by_OBJ(const X509_ACERT *x, const ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(x->acinfo->extensions, obj, lastpos); +} + +int X509_acert_get_ext_by_critical(const X509_ACERT *x, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(x->acinfo->extensions, crit, lastpos); +} + +X509_EXTENSION *X509_acert_get_ext(const X509_ACERT *x, int loc) +{ + return X509v3_get_ext(x->acinfo->extensions, loc); +} + +X509_EXTENSION *X509_acert_delete_ext(X509_ACERT *x, int loc) +{ + return X509v3_delete_ext(x->acinfo->extensions, loc); +} + +int X509_acert_add_ext(X509_ACERT *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->acinfo->extensions), ex, loc) != NULL); +} + +void *X509_acert_get_ext_d2i(const X509_ACERT *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->acinfo->extensions, nid, crit, idx); +} + +int X509_acert_add1_ext_i2d(X509_ACERT *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->acinfo->extensions, nid, value, crit, flags); +} diff --git a/crypto/x509/x509aset.c b/crypto/x509/x509aset.c new file mode 100644 index 0000000000000..ec5592092f2cf --- /dev/null +++ b/crypto/x509/x509aset.c @@ -0,0 +1,171 @@ +/* + * Copyright 2021 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 + +static int replace_gentime(ASN1_STRING **dest, ASN1_GENERALIZEDTIME *src) +{ + ASN1_STRING *s; + + if (src->type != V_ASN1_GENERALIZEDTIME) + return 0; + + if (*dest == src) + return 1; + + s = ASN1_STRING_dup(src); + if (s == NULL) + goto oom; + + ASN1_STRING_free(*dest); + *dest = s; + + return 1; + +oom: + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return 0; +} + +static int replace_dirName(GENERAL_NAMES **names, const X509_NAME *dirName) +{ + GENERAL_NAME *gen_name = NULL; + STACK_OF(GENERAL_NAME) *new_names = NULL; + X509_NAME *name_copy = NULL; + + if ((name_copy = X509_NAME_dup(dirName)) == NULL) + goto oom; + + if ((new_names = sk_GENERAL_NAME_new_null()) == NULL) + goto oom; + + if ((gen_name = GENERAL_NAME_new()) == NULL) + goto oom; + + if (sk_GENERAL_NAME_push(new_names, gen_name) <= 0) + goto err; + + GENERAL_NAME_set0_value(gen_name, GEN_DIRNAME, name_copy); + + GENERAL_NAMES_free(*names); + *names = new_names; + + return 1; + +oom: + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); +err: + GENERAL_NAME_free(gen_name); + sk_GENERAL_NAME_free(new_names); + X509_NAME_free(name_copy); + return 0; +} + +void OSSL_OBJECT_DIGEST_INFO_set0_digest(OSSL_OBJECT_DIGEST_INFO *o, + ASN1_ENUMERATED *digestedObjectType, + X509_ALGOR *digestAlgorithm, + ASN1_BIT_STRING *digest) +{ + ASN1_ENUMERATED_free(o->digestedObjectType); + X509_ALGOR_free(o->digestAlgorithm); + ASN1_BIT_STRING_free(o->objectDigest); + + o->digestedObjectType = digestedObjectType; + o->digestAlgorithm = digestAlgorithm; + o->objectDigest = digest; +} + +int OSSL_ISSUER_SERIAL_set1_issuer(OSSL_ISSUER_SERIAL *isss, X509_NAME *issuer) +{ + return replace_dirName(&isss->issuer, issuer); +} + +int OSSL_ISSUER_SERIAL_set1_serial(OSSL_ISSUER_SERIAL *isss, + ASN1_INTEGER *serial) +{ + return ASN1_STRING_copy(&isss->serial, serial); +} + +int OSSL_ISSUER_SERIAL_set1_issuerUID(OSSL_ISSUER_SERIAL *isss, + ASN1_BIT_STRING *uid) +{ + ASN1_BIT_STRING_free(isss->issuerUID); + isss->issuerUID = ASN1_STRING_dup(uid); + if (isss->issuerUID == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +int X509_ACERT_set_version(X509_ACERT *x, long version) +{ + return ASN1_INTEGER_set(&x->acinfo->version, version); +} + +void X509_ACERT_set0_holder_entityName(X509_ACERT *x, GENERAL_NAMES *names) +{ + GENERAL_NAMES_free(x->acinfo->holder.entityName); + x->acinfo->holder.entityName = names; +} + +void X509_ACERT_set0_holder_baseCertId(X509_ACERT *x, + OSSL_ISSUER_SERIAL *isss) +{ + OSSL_ISSUER_SERIAL_free(x->acinfo->holder.baseCertificateID); + x->acinfo->holder.baseCertificateID = isss; +} + +void X509_ACERT_set0_holder_digest(X509_ACERT *x, + OSSL_OBJECT_DIGEST_INFO *dinfo) +{ + OSSL_OBJECT_DIGEST_INFO_free(x->acinfo->holder.objectDigestInfo); + x->acinfo->holder.objectDigestInfo = dinfo; +} + +int X509_ACERT_set1_issuerName(X509_ACERT *x, const X509_NAME *name) +{ + X509_ACERT_ISSUER_V2FORM *v2Form; + + v2Form = x->acinfo->issuer.u.v2Form; + + /* only v2Form is supported, so always create that version */ + if (v2Form == NULL) { + v2Form = X509_ACERT_ISSUER_V2FORM_new(); + if (v2Form == NULL) + goto oom; + x->acinfo->issuer.u.v2Form = v2Form; + x->acinfo->issuer.type = X509_ACERT_ISSUER_V2; + } + + return replace_dirName(&(v2Form->issuerName), name); + +oom: + ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + return 0; +} + +int X509_ACERT_set1_serialNumber(X509_ACERT *x, ASN1_INTEGER *serial) +{ + return ASN1_STRING_copy(&x->acinfo->serialNumber, serial); +} + +int X509_ACERT_set1_notBefore(X509_ACERT *x, ASN1_GENERALIZEDTIME *time) +{ + return replace_gentime(&x->acinfo->validityPeriod.notBefore, time); +} + +int X509_ACERT_set1_notAfter(X509_ACERT *x, ASN1_GENERALIZEDTIME *time) +{ + return replace_gentime(&x->acinfo->validityPeriod.notAfter, time); +} diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index e4c5c16f76b18..a69e5d5892c0a 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -27,6 +27,8 @@ #include "crypto/pkcs7.h" #include "crypto/x509.h" #include "crypto/rsa.h" +#include "crypto/x509_acert.h" +#include "openssl/x509_acert.h" int X509_verify(X509 *a, EVP_PKEY *r) { @@ -169,6 +171,36 @@ X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) ASN1_ITEM_rptr(X509_CRL)); } +int X509_ACERT_sign(X509_ACERT *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->acinfo->enc.modified = 1; + return ASN1_item_sign_ex(ASN1_ITEM_rptr(X509_ACERT_INFO), &x->acinfo->signature, + &x->sig_alg, + &x->signature, x->acinfo, NULL, + pkey, md, NULL, NULL); +} + +int X509_ACERT_sign_ctx(X509_ACERT *x, EVP_MD_CTX *ctx) +{ + x->acinfo->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_ACERT_INFO), &x->acinfo->signature, + &x->sig_alg, &x->signature, + x->acinfo, ctx); +} + +int X509_ACERT_verify_ex(X509_ACERT *a, EVP_PKEY *r, OSSL_LIB_CTX *libctx, + const char *propq) +{ + return ASN1_item_verify_ex(ASN1_ITEM_rptr(X509_ACERT_INFO), &a->sig_alg, + &a->signature, a->acinfo, NULL, + r, libctx, propq); +} + +int X509_ACERT_verify(X509_ACERT *a, EVP_PKEY *r) +{ + return X509_ACERT_verify_ex(a, r, NULL, NULL); +} + int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { return @@ -820,3 +852,25 @@ EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) { return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); } + +#ifndef OPENSSL_NO_STDIO +X509_ACERT *d2i_X509_ACERT_fp(FILE *fp, X509_ACERT **acert) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_ACERT), fp, acert); +} + +int i2d_X509_ACERT_fp(FILE *fp, const X509_ACERT *acert) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_ACERT), fp, acert); +} +#endif + +X509_ACERT *d2i_X509_ACERT_bio(BIO *bp, X509_ACERT **acert) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_ACERT), bp, acert); +} + +int i2d_X509_ACERT_bio(BIO *bp, const X509_ACERT *acert) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_ACERT), bp, acert); +} \ No newline at end of file diff --git a/crypto/x509/x_attrib.c b/crypto/x509/x_attrib.c index 5c7e622d1a0bc..8f66d2b83adc8 100644 --- a/crypto/x509/x_attrib.c +++ b/crypto/x509/x_attrib.c @@ -12,7 +12,9 @@ #include #include #include +#include #include "x509_local.h" +#include /*- * X509_ATTRIBUTE: this has the following form: @@ -56,3 +58,304 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value) ASN1_TYPE_free(val); return NULL; } + +static int ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) +{ + BIGNUM *num_bn; + int result = 0; + char *hex; + + num_bn = ASN1_INTEGER_to_BN(num, NULL); + if (num_bn == NULL) + return -1; + if ((hex = BN_bn2hex(num_bn))) { + result = BIO_write(bio, "0x", 2) > 0; + result = result && BIO_write(bio, hex, strlen(hex)) > 0; + OPENSSL_free(hex); + } + BN_free(num_bn); + + return result; +} + +int print_hex(BIO *out, unsigned char *buf, int len) +{ + int i; + for (i = 0; i < len; i++) { + if (BIO_printf(out, "%02X ", buf[i]) <= 0) { + return 0; + } + } + return 1; +} + +int print_attribute_value(BIO *out, int obj_nid, const ASN1_TYPE *av, int indent) +{ + unsigned char *value; + X509_NAME *xn = NULL; + int64_t int_val; + PLATFORM_CONFIG *pc = NULL; + TCG_PLATFORM_SPEC *ps = NULL; + TCG_CRED_TYPE *ct = NULL; + MANUFACTURER_ID *mid = NULL; + TBB_SECURITY_ASSERTIONS *tbb = NULL; + URI_REFERENCE *uri = NULL; + + // This switch-case is only for syntaxes that are not encoded as a single + // primitively-constructed value universal ASN.1 type. + switch (obj_nid) { + case NID_undef: break; // Unrecognized OID. + // Attribute types with DN syntax. + case NID_member: + case NID_roleOccupant: + case NID_seeAlso: + case NID_manager: + case NID_documentAuthor: + case NID_secretary: + case NID_associatedName: + case NID_dITRedirect: + case NID_owner: + value = av->value.sequence->data; + if ((xn = d2i_X509_NAME(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE DISTINGUISHED NAME)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (X509_NAME_print_ex(out, xn, indent, 0) <= 0) { + return 0; + } + X509_NAME_free(xn); + return 1; + + case NID_tcg_at_platformConfiguration_v2: + value = av->value.sequence->data; + if ((pc = d2i_PLATFORM_CONFIG(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE PLATFORM CONFIG)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (PLATFORM_CONFIG_print(out, pc, indent) <= 0) { + return 0; + } + PLATFORM_CONFIG_free(pc); + return 1; + + case NID_tcg_at_tcgPlatformSpecification: + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + value = av->value.sequence->data; + if ((ps = d2i_TCG_PLATFORM_SPEC(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE PLATFORM SPECIFICATION)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (TCG_PLATFORM_SPEC_print(out, ps) <= 0) { + return 0; + } + TCG_PLATFORM_SPEC_free(ps); + return 1; + + case NID_tcg_at_tcgCredentialType: + value = av->value.sequence->data; + if ((ct = d2i_TCG_CRED_TYPE(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE PLATFORM CERT CREDENTIAL TYPE)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (TCG_CRED_TYPE_print(out, ct, indent) <= 0) { + return 0; + } + TCG_CRED_TYPE_free(ct); + return 1; + + case NID_tcg_at_platformManufacturerId: + value = av->value.sequence->data; + if ((mid = d2i_MANUFACTURER_ID(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE PLATFORM MANUFACTURER ID)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (MANUFACTURER_ID_print(out, mid, indent) <= 0) { + return 0; + } + MANUFACTURER_ID_free(mid); + return 1; + + case NID_tcg_at_tbbSecurityAssertions: + value = av->value.sequence->data; + if ((tbb = d2i_TBB_SECURITY_ASSERTIONS(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE TBB SECURITY ASSERTIONS)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (TBB_SECURITY_ASSERTIONS_print(out, tbb, indent) <= 0) { + return 0; + } + TBB_SECURITY_ASSERTIONS_free(tbb); + return 1; + + case NID_tcg_at_platformConfigUri: + value = av->value.sequence->data; + if ((uri = d2i_URI_REFERENCE(NULL, (const unsigned char**)&(av->value.sequence->data), av->value.sequence->length)) == NULL) { + BIO_puts(out, "(COULD NOT DECODE TBB SECURITY ASSERTIONS)\n"); + return 0; + } + // d2i_ functions increment the ppin pointer. See doc/man3/d2i_X509.pod. + // This resets the pointer. We don't want to corrupt this value. + av->value.sequence->data = value; + if (URI_REFERENCE_print(out, uri, indent) <= 0) { + return 0; + } + URI_REFERENCE_free(uri); + return 1; + + default: break; + } + + switch (av->type) { + case V_ASN1_BOOLEAN: + if (av->value.boolean) { + return BIO_printf(out, "%*sTRUE", indent, ""); + } else { + return BIO_printf(out, "%*sFALSE", indent, ""); + } + + case V_ASN1_INTEGER: + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + if (ASN1_INTEGER_get_int64(&int_val, av->value.integer) > 0) { + return BIO_printf(out, "%ld", int_val); + } else { + return ASN1_INTEGER_print_bio(out, av->value.integer); + } + + case V_ASN1_ENUMERATED: + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + if (ASN1_ENUMERATED_get_int64(&int_val, av->value.enumerated) > 0) { + return BIO_printf(out, "%ld", int_val); + } else { + return ASN1_INTEGER_print_bio(out, av->value.enumerated); + } + + case V_ASN1_BIT_STRING: + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + return print_hex(out, av->value.bit_string->data, + av->value.bit_string->length); + + case V_ASN1_OCTET_STRING: + case V_ASN1_VIDEOTEXSTRING: + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + return print_hex(out, av->value.octet_string->data, + av->value.octet_string->length); + + case V_ASN1_NULL: + return BIO_printf(out, "%*sNULL", indent, ""); + + case V_ASN1_OBJECT: + if (indent && BIO_printf(out, "%*s", indent, "") <= 0) { + return 0; + } + return print_oid(out, av->value.object); + + /* ObjectDescriptor is an IMPLICIT GraphicString, but GeneralString is a + superset supported by OpenSSL, so we will use that anywhere a GraphicString + is needed here. */ + case V_ASN1_GENERALSTRING: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_OBJECT_DESCRIPTOR: + return BIO_printf(out, "%*s%.*s", indent, "", + av->value.generalstring->length, + av->value.generalstring->data); + + /* EXTERNAL */ + /* EMBEDDED PDV */ + + case V_ASN1_UTF8STRING: + return BIO_printf(out, "%*s%.*s", indent, "", + av->value.utf8string->length, + av->value.utf8string->data); + + case V_ASN1_REAL: + return BIO_printf(out, "%*sREAL", indent, ""); + + /* RELATIVE-OID */ + /* TIME */ + + case V_ASN1_SEQUENCE: + return ASN1_parse_dump(out, av->value.sequence->data, + av->value.sequence->length, indent, 1); + + case V_ASN1_SET: + return ASN1_parse_dump(out, av->value.set->data, + av->value.set->length, indent, 1); + + /* + UTCTime ::= [UNIVERSAL 23] IMPLICIT VisibleString + GeneralizedTime ::= [UNIVERSAL 24] IMPLICIT VisibleString + VisibleString is a superset for NumericString, so it will work for that. + */ + case V_ASN1_VISIBLESTRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_NUMERICSTRING: + return BIO_printf(out, "%*s%.*s", indent, "", + av->value.visiblestring->length, + av->value.visiblestring->data); + + case V_ASN1_PRINTABLESTRING: + return BIO_printf(out, "%*s%.*s", indent, "", + av->value.printablestring->length, + av->value.printablestring->data); + + case V_ASN1_T61STRING: + return BIO_printf(out, "%*s%.*s", indent, "", + av->value.t61string->length, + av->value.t61string->data); + + case V_ASN1_IA5STRING: + return BIO_printf(out, "%*s%.*s", indent, "", + av->value.ia5string->length, + av->value.ia5string->data); + + /* UniversalString */ + /* CHARACTER STRING */ + + case V_ASN1_BMPSTRING: + value = (unsigned char *)OPENSSL_uni2asc(av->value.bmpstring->data, + av->value.bmpstring->length); + int ret = BIO_printf(out, "%*s%s", indent, "", value); + OPENSSL_free(value); + return ret; + + /* DATE */ + /* TIME-OF-DAY */ + /* DATE-TIME */ + /* DURATION */ + /* OID-IRI */ + /* RELATIVE-OID-IRI */ + + /* Would it be approriate to just hexdump? */ + default: + return BIO_printf(out, "%*s", indent, "", av->type); + } +} \ No newline at end of file diff --git a/crypto/x509/x_ietfatt.c b/crypto/x509/x_ietfatt.c new file mode 100644 index 0000000000000..aeac1722e118d --- /dev/null +++ b/crypto/x509/x_ietfatt.c @@ -0,0 +1,184 @@ +/* + * Copyright 2021 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 + +/*- + * Definition of IetfAttrSyntax from RFC 5755 4.4 + * + * IetfAttrSyntax ::= SEQUENCE { + * policyAuthority [0] GeneralNames OPTIONAL, + * values SEQUENCE OF CHOICE { + * octets OCTET STRING, + * oid OBJECT IDENTIFIER, + * string UTF8String + * } + * } + * + * Section 4.4.2 states that all values in the sequence MUST use the + * same choice of value (octect, oid or string). This restriction is + * not explicitly enforced by the current implementation. + */ + +struct OSSL_IETF_ATTR_SYNTAX_VALUE_st { + int type; + union { + ASN1_OCTET_STRING *octets; + ASN1_OBJECT *oid; + ASN1_UTF8STRING *string; + } u; +}; + +struct OSSL_IETF_ATTR_SYNTAX_st { + GENERAL_NAMES *policyAuthority; + STACK_OF(OSSL_IETF_ATTR_SYNTAX_VALUE) *values; +}; + +ASN1_CHOICE(OSSL_IETF_ATTR_SYNTAX_VALUE) = { + ASN1_SIMPLE(OSSL_IETF_ATTR_SYNTAX_VALUE, u.octets, ASN1_OCTET_STRING), + ASN1_SIMPLE(OSSL_IETF_ATTR_SYNTAX_VALUE, u.oid, ASN1_OBJECT), + ASN1_SIMPLE(OSSL_IETF_ATTR_SYNTAX_VALUE, u.string, ASN1_UTF8STRING), +} ASN1_CHOICE_END(OSSL_IETF_ATTR_SYNTAX_VALUE) + +ASN1_SEQUENCE(OSSL_IETF_ATTR_SYNTAX) = { + ASN1_IMP_SEQUENCE_OF_OPT(OSSL_IETF_ATTR_SYNTAX, policyAuthority, GENERAL_NAME, 0), + ASN1_SEQUENCE_OF(OSSL_IETF_ATTR_SYNTAX, values, OSSL_IETF_ATTR_SYNTAX_VALUE), +} ASN1_SEQUENCE_END(OSSL_IETF_ATTR_SYNTAX) + +IMPLEMENT_ASN1_FUNCTIONS(OSSL_IETF_ATTR_SYNTAX) +IMPLEMENT_ASN1_FUNCTIONS(OSSL_IETF_ATTR_SYNTAX_VALUE) + +int OSSL_IETF_ATTR_SYNTAX_get_value_num(const OSSL_IETF_ATTR_SYNTAX *a) +{ + if (a->values == NULL) + return 0; + + return sk_OSSL_IETF_ATTR_SYNTAX_VALUE_num(a->values); +} + +const GENERAL_NAMES * +OSSL_IETF_ATTR_SYNTAX_get0_policyAuthority(const OSSL_IETF_ATTR_SYNTAX *a) +{ + return a->policyAuthority; +} + +void OSSL_IETF_ATTR_SYNTAX_set0_policyAuthority(OSSL_IETF_ATTR_SYNTAX *a, + GENERAL_NAMES *names) +{ + GENERAL_NAMES_free(a->policyAuthority); + a->policyAuthority = names; +} + +void *OSSL_IETF_ATTR_SYNTAX_get0_value(const OSSL_IETF_ATTR_SYNTAX *a, int ind, int *type) +{ + OSSL_IETF_ATTR_SYNTAX_VALUE *val; + + val = sk_OSSL_IETF_ATTR_SYNTAX_VALUE_value(a->values, ind); + if (type != NULL) + *type = val->type; + + switch (val->type) { + case OSSL_IETFAS_OCTETS: + return val->u.octets; + case OSSL_IETFAS_OID: + return val->u.oid; + case OSSL_IETFAS_STRING: + return val->u.string; + } + + return NULL; +} + +int OSSL_IETF_ATTR_SYNTAX_add1_value(OSSL_IETF_ATTR_SYNTAX *a, int type, void *data) +{ + OSSL_IETF_ATTR_SYNTAX_VALUE *val; + + if (data == NULL) + return 0; + + if (a->values == NULL) { + if ((a->values = sk_OSSL_IETF_ATTR_SYNTAX_VALUE_new_null()) == NULL) + goto oom; + } + + if ((val = OSSL_IETF_ATTR_SYNTAX_VALUE_new()) == NULL) + goto oom; + + val->type = type; + switch (type) { + case OSSL_IETFAS_OCTETS: + val->u.octets = data; + break; + case OSSL_IETFAS_OID: + val->u.oid = data; + break; + case OSSL_IETFAS_STRING: + val->u.string = data; + break; + } + + if (sk_OSSL_IETF_ATTR_SYNTAX_VALUE_push(a->values, val) <= 0) { + OSSL_IETF_ATTR_SYNTAX_VALUE_free(val); + return 0; + } + + return 1; + +oom: + ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + return 0; +} + +int OSSL_IETF_ATTR_SYNTAX_print(BIO *bp, OSSL_IETF_ATTR_SYNTAX *a, int indent) +{ + int i; + + if (a->policyAuthority != NULL) { + for (i = 0; i < sk_GENERAL_NAME_num(a->policyAuthority); i++) { + if (BIO_printf(bp, "%*s", indent, "") <= 0) + goto err; + + if (GENERAL_NAME_print(bp, sk_GENERAL_NAME_value(a->policyAuthority, + i)) <= 0) + goto err; + + if (BIO_printf(bp, "\n") <= 0) + goto err; + } + } + + for (i = 0; i < OSSL_IETF_ATTR_SYNTAX_get_value_num(a); i++) { + char oidstr[80]; + int ietf_type; + void *attr_value = OSSL_IETF_ATTR_SYNTAX_get0_value(a, i, &ietf_type); + + if (BIO_printf(bp, "%*s", indent, "") <= 0) + goto err; + + switch (ietf_type) { + case OSSL_IETFAS_OID: + OBJ_obj2txt(oidstr, sizeof(oidstr), attr_value, 0); + BIO_printf(bp, "%.*s", (int) sizeof(oidstr), oidstr); + break; + case OSSL_IETFAS_OCTETS: + case OSSL_IETFAS_STRING: + ASN1_STRING_print(bp, attr_value); + break; + } + } + if (BIO_printf(bp, "\n") <= 0) + goto err; + + return 1; + +err: + return 0; +} diff --git a/crypto/x509/x_iserial.c b/crypto/x509/x_iserial.c new file mode 100644 index 0000000000000..dfa1643776609 --- /dev/null +++ b/crypto/x509/x_iserial.c @@ -0,0 +1,33 @@ +#include +#include +#include + +ASN1_SEQUENCE(OSSL_ISSUER_SERIAL) = { + ASN1_SIMPLE(OSSL_ISSUER_SERIAL, issuer, GENERAL_NAMES), + ASN1_EMBED(OSSL_ISSUER_SERIAL, serial, ASN1_INTEGER), + ASN1_OPT(OSSL_ISSUER_SERIAL, issuerUID, ASN1_BIT_STRING), +} ASN1_SEQUENCE_END(OSSL_ISSUER_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS(OSSL_ISSUER_SERIAL) + +int i2r_ISSUER_SERIAL(X509V3_EXT_METHOD *method, + OSSL_ISSUER_SERIAL *iss, + BIO *out, int indent) +{ + if (iss->issuer != NULL) { + BIO_printf(out, "%*sIssuer Names:\n", indent, ""); + ossl_print_gens(out, iss->issuer, indent); + BIO_puts(out, "\n"); + } + BIO_printf(out, "%*sIssuer Serial: ", indent, ""); + if (i2a_ASN1_INTEGER(out, &iss->serial) <= 0) + return 0; + BIO_puts(out, "\n"); + if (iss->issuerUID != NULL) { + BIO_printf(out, "%*sIssuer UID: ", indent, ""); + if (i2a_ASN1_STRING(out, iss->issuerUID, V_ASN1_BIT_STRING) <= 0) + return 0; + BIO_puts(out, "\n"); + } + return 1; +} diff --git a/crypto/x509/x_unotice.c b/crypto/x509/x_unotice.c new file mode 100644 index 0000000000000..a8f364dfaf11a --- /dev/null +++ b/crypto/x509/x_unotice.c @@ -0,0 +1,46 @@ +#include + +int print_notice(BIO *out, USERNOTICE *notice, int indent) +{ + int i; + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + if (BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", + ref->organization->length, + ref->organization->data) <= 0) { + return 0; + } + if (BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "") <= 0) { + return 0; + } + for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i && BIO_puts(out, ", ") <= 0) { + return 0; + } + if (num == NULL && BIO_puts(out, "(null)") <= 0) + return 0; + else { + tmp = i2s_ASN1_INTEGER(NULL, num); + if (tmp == NULL) + return 0; + if (BIO_puts(out, tmp) <= 0) { + return 0; + } + OPENSSL_free(tmp); + } + } + if (notice->exptext && BIO_puts(out, "\n") <= 0) { + return 0; + } + } + if (notice->exptext) + return BIO_printf(out, "%*sExplicit Text: %.*s", indent, "", + notice->exptext->length, + notice->exptext->data); + return 1; +} diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index 75c5c9223acce..d8e5078f36aec 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -14,6 +14,7 @@ #include #include #include "crypto/x509.h" +#include ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), @@ -314,3 +315,25 @@ ASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x) { return x->distinguishing_id; } + +OSSL_ISSUER_SERIAL *X509_get_issuer_serial (X509 *x) +{ + STACK_OF(GENERAL_NAME) *issuer = sk_GENERAL_NAME_new(NULL); + ASN1_INTEGER serial; + ASN1_BIT_STRING *issuerUID; + + GENERAL_NAME *gn = GENERAL_NAME_new(); + gn->type = GEN_DIRNAME; + gn->d.dirn = x->cert_info.issuer; + if (sk_GENERAL_NAME_push(issuer, gn) <= 0) + return NULL; + + serial = x->cert_info.serialNumber; + issuerUID = x->cert_info.issuerUID; + + OSSL_ISSUER_SERIAL *iss_ser = OSSL_ISSUER_SERIAL_new(); + iss_ser->issuer = issuer; + iss_ser->serial = serial; + iss_ser->issuerUID = issuerUID; + return iss_ser; +} diff --git a/doc/build.info b/doc/build.info index 197fead8d813a..dcfce6012fc19 100644 --- a/doc/build.info +++ b/doc/build.info @@ -4,6 +4,12 @@ DEPEND[html/man1/CA.pl.html]=man1/CA.pl.pod GENERATE[html/man1/CA.pl.html]=man1/CA.pl.pod DEPEND[man/man1/CA.pl.1]=man1/CA.pl.pod GENERATE[man/man1/CA.pl.1]=man1/CA.pl.pod +DEPEND[html/man1/openssl-acert.html]=man1/openssl-acert.pod +GENERATE[html/man1/openssl-acert.html]=man1/openssl-acert.pod +DEPEND[man/man1/openssl-acert.1]=man1/openssl-acert.pod +GENERATE[man/man1/openssl-acert.1]=man1/openssl-acert.pod +DEPEND[man1/openssl-acert.pod]{pod}=man1/openssl-acert.pod.in +GENERATE[man1/openssl-acert.pod]=man1/openssl-acert.pod.in DEPEND[html/man1/openssl-asn1parse.html]=man1/openssl-asn1parse.pod GENERATE[html/man1/openssl-asn1parse.html]=man1/openssl-asn1parse.pod DEPEND[man/man1/openssl-asn1parse.1]=man1/openssl-asn1parse.pod @@ -348,6 +354,7 @@ DEPEND[man/man1/tsget.1]=man1/tsget.pod GENERATE[man/man1/tsget.1]=man1/tsget.pod IMAGEDOCS[man1]= HTMLDOCS[man1]=html/man1/CA.pl.html \ +html/man1/openssl-acert.html \ html/man1/openssl-asn1parse.html \ html/man1/openssl-ca.html \ html/man1/openssl-ciphers.html \ @@ -408,6 +415,7 @@ html/man1/openssl-x509.html \ html/man1/openssl.html \ html/man1/tsget.html MANDOCS[man1]=man/man1/CA.pl.1 \ +man/man1/openssl-acert.1 \ man/man1/openssl-asn1parse.1 \ man/man1/openssl-ca.1 \ man/man1/openssl-ciphers.1 \ @@ -1703,6 +1711,10 @@ DEPEND[html/man3/OSSL_HTTP_transfer.html]=man3/OSSL_HTTP_transfer.pod GENERATE[html/man3/OSSL_HTTP_transfer.html]=man3/OSSL_HTTP_transfer.pod DEPEND[man/man3/OSSL_HTTP_transfer.3]=man3/OSSL_HTTP_transfer.pod GENERATE[man/man3/OSSL_HTTP_transfer.3]=man3/OSSL_HTTP_transfer.pod +DEPEND[html/man3/OSSL_IETF_ATTR_SYNTAX.html]=man3/OSSL_IETF_ATTR_SYNTAX.pod +GENERATE[html/man3/OSSL_IETF_ATTR_SYNTAX.html]=man3/OSSL_IETF_ATTR_SYNTAX.pod +DEPEND[man/man3/OSSL_IETF_ATTR_SYNTAX.3]=man3/OSSL_IETF_ATTR_SYNTAX.pod +GENERATE[man/man3/OSSL_IETF_ATTR_SYNTAX.3]=man3/OSSL_IETF_ATTR_SYNTAX.pod DEPEND[html/man3/OSSL_ITEM.html]=man3/OSSL_ITEM.pod GENERATE[html/man3/OSSL_ITEM.html]=man3/OSSL_ITEM.pod DEPEND[man/man3/OSSL_ITEM.3]=man3/OSSL_ITEM.pod @@ -2767,6 +2779,10 @@ DEPEND[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod GENERATE[html/man3/X509V3_set_ctx.html]=man3/X509V3_set_ctx.pod DEPEND[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod GENERATE[man/man3/X509V3_set_ctx.3]=man3/X509V3_set_ctx.pod +DEPEND[html/man3/X509_ACERT_get0_holder_baseCertId.html]=man3/X509_ACERT_get0_holder_baseCertId.pod +GENERATE[html/man3/X509_ACERT_get0_holder_baseCertId.html]=man3/X509_ACERT_get0_holder_baseCertId.pod +DEPEND[man/man3/X509_ACERT_get0_holder_baseCertId.3]=man3/X509_ACERT_get0_holder_baseCertId.pod +GENERATE[man/man3/X509_ACERT_get0_holder_baseCertId.3]=man3/X509_ACERT_get0_holder_baseCertId.pod DEPEND[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod GENERATE[html/man3/X509_ALGOR_dup.html]=man3/X509_ALGOR_dup.pod DEPEND[man/man3/X509_ALGOR_dup.3]=man3/X509_ALGOR_dup.pod @@ -2863,6 +2879,10 @@ DEPEND[html/man3/X509_add_cert.html]=man3/X509_add_cert.pod GENERATE[html/man3/X509_add_cert.html]=man3/X509_add_cert.pod DEPEND[man/man3/X509_add_cert.3]=man3/X509_add_cert.pod GENERATE[man/man3/X509_add_cert.3]=man3/X509_add_cert.pod +DEPEND[html/man3/X509_attr_cert_verify.html]=man3/X509_attr_cert_verify.pod +GENERATE[html/man3/X509_attr_cert_verify.html]=man3/X509_attr_cert_verify.pod +DEPEND[man/man3/X509_attr_cert_verify.3]=man3/X509_attr_cert_verify.pod +GENERATE[man/man3/X509_attr_cert_verify.3]=man3/X509_attr_cert_verify.pod DEPEND[html/man3/X509_check_ca.html]=man3/X509_check_ca.pod GENERATE[html/man3/X509_check_ca.html]=man3/X509_check_ca.pod DEPEND[man/man3/X509_check_ca.3]=man3/X509_check_ca.pod @@ -3317,6 +3337,7 @@ html/man3/OSSL_HPKE_CTX_new.html \ html/man3/OSSL_HTTP_REQ_CTX.html \ html/man3/OSSL_HTTP_parse_url.html \ html/man3/OSSL_HTTP_transfer.html \ +html/man3/OSSL_IETF_ATTR_SYNTAX.html \ html/man3/OSSL_ITEM.html \ html/man3/OSSL_LIB_CTX.html \ html/man3/OSSL_PARAM.html \ @@ -3583,6 +3604,7 @@ html/man3/UI_create_method.html \ html/man3/UI_new.html \ html/man3/X509V3_get_d2i.html \ html/man3/X509V3_set_ctx.html \ +html/man3/X509_ACERT_get0_holder_baseCertId.html \ html/man3/X509_ALGOR_dup.html \ html/man3/X509_CRL_get0_by_serial.html \ html/man3/X509_EXTENSION_set_object.html \ @@ -3607,6 +3629,7 @@ html/man3/X509_STORE_new.html \ html/man3/X509_STORE_set_verify_cb_func.html \ html/man3/X509_VERIFY_PARAM_set_flags.html \ html/man3/X509_add_cert.html \ +html/man3/X509_attr_cert_verify.html \ html/man3/X509_check_ca.html \ html/man3/X509_check_host.html \ html/man3/X509_check_issued.html \ @@ -3952,6 +3975,7 @@ man/man3/OSSL_HPKE_CTX_new.3 \ man/man3/OSSL_HTTP_REQ_CTX.3 \ man/man3/OSSL_HTTP_parse_url.3 \ man/man3/OSSL_HTTP_transfer.3 \ +man/man3/OSSL_IETF_ATTR_SYNTAX.3 \ man/man3/OSSL_ITEM.3 \ man/man3/OSSL_LIB_CTX.3 \ man/man3/OSSL_PARAM.3 \ @@ -4218,6 +4242,7 @@ man/man3/UI_create_method.3 \ man/man3/UI_new.3 \ man/man3/X509V3_get_d2i.3 \ man/man3/X509V3_set_ctx.3 \ +man/man3/X509_ACERT_get0_holder_baseCertId.3 \ man/man3/X509_ALGOR_dup.3 \ man/man3/X509_CRL_get0_by_serial.3 \ man/man3/X509_EXTENSION_set_object.3 \ @@ -4242,6 +4267,7 @@ man/man3/X509_STORE_new.3 \ man/man3/X509_STORE_set_verify_cb_func.3 \ man/man3/X509_VERIFY_PARAM_set_flags.3 \ man/man3/X509_add_cert.3 \ +man/man3/X509_attr_cert_verify.3 \ man/man3/X509_check_ca.3 \ man/man3/X509_check_host.3 \ man/man3/X509_check_issued.3 \ diff --git a/doc/man1/build.info b/doc/man1/build.info index b796fce42fdd9..829d13c9d17f4 100644 --- a/doc/man1/build.info +++ b/doc/man1/build.info @@ -2,6 +2,7 @@ # turned into appropriate DEPEND and GENERATE lines. All we need here are # the additional dependencies on ../perlvars.pm. +DEPEND[openssl-acert.pod]=../perlvars.pm DEPEND[openssl-asn1parse.pod]=../perlvars.pm DEPEND[openssl-ca.pod]=../perlvars.pm DEPEND[openssl-ciphers.pod]=../perlvars.pm diff --git a/doc/man1/openssl-acert.pod.in b/doc/man1/openssl-acert.pod.in new file mode 100644 index 0000000000000..af626b807ba98 --- /dev/null +++ b/doc/man1/openssl-acert.pod.in @@ -0,0 +1,337 @@ +=pod +{- OpenSSL::safe::output_do_not_edit_headers(); -} + +=head1 NAME + +openssl-acert - RFC 5755 attribute certificate generate and display command + +=head1 SYNOPSIS + +B B +[B<-help>] +[B<-inform> B|B] +[B<-outform> B|B] +[B<-in> I] +[B<-passin> I] +[B<-out> I] +[B<-text>] +[B<-noout>] +[B<-verify>] +[B<-new>] +[B<-I>] +[B<-config> I] +[B<-section> I] +[B<-new>] +[B<-holder> I] +[B<-use-holder-basecertid>] +[B<-use-holder-name>] +[B<-target-cert>] +[B<-asserted-before>] +[B<-AA> I|I] +[B<-AAkey> I|I] +[B<-keyform> B|B|B|B] +[B<-days> I] +[B<-set_serial> I] +[B<-startdate> I] +[B<-enddate> I] +[B<-addext> I] +[B<-acertexts> I
] +[B<-utf8>] +[B<-certopt>] +[B<-sigopt> I:I] +[B<-verbose>] +{- $OpenSSL::safe::opt_name_synopsis -} +{- $OpenSSL::safe::opt_engine_synopsis -} +{- $OpenSSL::safe::opt_provider_synopsis -} + +=head1 DESCRIPTION + +This command primarily creates and parses attributes certificates as defined +by RFC5755. + +=head1 OPTIONS + +=over 4 + +=item B<-help> + +Print out a usage message. + +=item B<-inform> B|B, B<-outform> B|B + +The input and output formats; unspecified by default. +See L for details. + +The data is a attribute certificate. + +=item B<-in> I + +This specifies the input filename to read an attribute certificate from +or standard input if this option is not specified. An attribute certificate +is only read if B<-new> is not specified. + +=item B<-sigopt> I:I + +Pass options to the signature algorithm during sign operations. +Names and values of these options are algorithm-specific. + +=item B<-passin> I + +The password source for the attribute authority certificate. +For more information about the format of B +see L. + +=item B<-out> I + +This specifies the output filename to write to or standard output by default. + +=item B<-text> + +Prints out the attribute certificate in text form. + +=item B<-noout> + +This option prevents output of the encoded version of the attribute certificate. + +=item B<-verify> + +Verifies the attribute certificate signature and whether it corresponds to the +supplied B<-holder> and B<-AA> certificates. + +=item B<-new> + +This option generates a new attribute certificate. The attributes +must be specified in a configuration file. + +A holder certificate must be specified with the B<-holder> option. +An attribute authority certificate and signing key must be specified +with the B<-AA> and, if necessary, the B<-AAkey> options. + +=item B<-holder> I + +Specifies the holder certificate to issue the attribute certificate for when +the B<-new> option is given. Used to verify an attribute certificate when +the B<-verify> option is given. + +=item B<-use-holder-basecertid> + +Use the holder certificate's serial number and issuer name to identify the +holder in the new attribute certificate. + +=item B<-use-holder-name> + +Use the holder certificate's subject name to identify the holder +in the new attribute certificate. + +=item B<-target-cert> I + +The target certificate file, from which a TARGET (using the targetCert +alternative) is constructed and compared against the targets listed in the +targetingInformation X.509v3 extension, if it is present. This argument takes +effect if the B command is used with the B<-verify> option. + +Verification will not fail if the targetingInformation extension does not +exist in the verified attribute certificate, but it will fail if the extension +is present and the target does not appear in the list of targets. + +=item B<-asserted-before> + +Specifies whether the verified attribute certificate has been asserted once +before. If provided, this causes verification of an attribute certificate to +fail if the singleUse X.509v3 extension is present. This argument only takes +effect if the B command is used with the B<-verify> option. + +=item B<-AA> I|I + +Specifies the Attribute Authority certificate to be used for signing with the +B<-new> option. The AA certificate is also used to verify an attribute +certificate when the B<-verify> option is given. + +=item B<-AAkey> I|I + +This specifies the attribute authority's private key to use for signing +signing attribute certificates produced using the B<-new> option. + +=item B<-keyform> B|B|B|B + +The format of the private key; unspecified by default. +See L for details. + +=item B<-I> + +This specifies the message digest to sign the attribute certificate. +Any digest supported by the OpenSSL B command can be used. +This overrides the digest algorithm specified in +the configuration file. + +Some public key algorithms may override this choice. For instance, DSA +signatures always use SHA1, GOST R 34.10 signatures always use +GOST R 34.11-94 (B<-md_gost94>), Ed25519 and Ed448 never use any digest. + +=item B<-config> I + +This allows an alternative configuration file to be specified. +Optional; for a description of the default value, +see L. + +=item B<-section> I + +Specifies the name of the section to use; the default is B. + +=item B<-startdate> I + +This option sets the validity start date of the attribute certificate +generated with the B<-new> option. The date format is YYYYMMDDHHMMSSZ +(The same format as an ASN1 GeneralizedTime structure). The current +date will be used when this option is not specified. + +=item B<-enddate> I + +This option sets the validity end date of the attribute certificate +generated with the B<-new> option. The date format is YYYYMMDDHHMMSSZ +(The same format as an ASN1 GeneralizedTime structure). + +=item B<-days> I + +When the B<-new> option is being used this specifies the number of +days to certify the certificate for, otherwise it is ignored. I should +be a positive integer. The default is 1 day. + +=item B<-set_serial> I + +Serial number to use when outputting a self-signed certificate. +This may be specified as a decimal value or a hex value if preceded by C<0x>. +If not given, a large random number will be used. + +=item B<-addext> I + +Add a specific extension to the attribute certificate if the B<-new> option is +present. The argument must have the form of +a key=value pair as it would appear in a config file. + +This option can be given multiple times. + +=item B<-acertexts> I
+ +These options specify alternative sections to include certificate +extensions (if the B<-new> option is present). +This allows several different sections to +be used in the same configuration file to specify attribute certificates +for a variety of purposes. + +=item B<-utf8> + +This option causes field values to be interpreted as UTF8 strings, by +default they are interpreted as ASCII. This means that the field +values, whether prompted from a terminal or obtained from a +configuration file, must be valid UTF8 strings. + +=item B<-certopt> I