1 1.1 christos /* 2 1.1 christos * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #include <string.h> 11 1.1 christos #include "apps.h" 12 1.1 christos 13 1.1 christos /* 14 1.1 christos * X509_ctrl_str() is sorely lacking in libcrypto, but is still needed to 15 1.1 christos * allow the application to process verification options in a manner similar 16 1.1 christos * to signature or other options that pass through EVP_PKEY_CTX_ctrl_str(), 17 1.1 christos * for uniformity. 18 1.1 christos * 19 1.1 christos * As soon as more stuff is added, the code will need serious rework. For 20 1.1 christos * the moment, it only handles the FIPS 196 / SM2 distinguishing ID. 21 1.1 christos */ 22 1.1 christos #ifdef EVP_PKEY_CTRL_SET1_ID 23 1.1 christos static ASN1_OCTET_STRING *mk_octet_string(void *value, size_t value_n) 24 1.1 christos { 25 1.1 christos ASN1_OCTET_STRING *v = ASN1_OCTET_STRING_new(); 26 1.1 christos 27 1.1 christos if (v == NULL) { 28 1.1 christos BIO_printf(bio_err, "error: allocation failed\n"); 29 1.1 christos } else if (!ASN1_OCTET_STRING_set(v, value, (int)value_n)) { 30 1.1 christos ASN1_OCTET_STRING_free(v); 31 1.1 christos v = NULL; 32 1.1 christos } 33 1.1 christos return v; 34 1.1 christos } 35 1.1 christos #endif 36 1.1 christos 37 1.1 christos static int x509_ctrl(void *object, int cmd, void *value, size_t value_n) 38 1.1 christos { 39 1.1 christos switch (cmd) { 40 1.1 christos #ifdef EVP_PKEY_CTRL_SET1_ID 41 1.1.1.2 christos case EVP_PKEY_CTRL_SET1_ID: { 42 1.1.1.2 christos ASN1_OCTET_STRING *v = mk_octet_string(value, value_n); 43 1.1 christos 44 1.1.1.2 christos if (v == NULL) { 45 1.1.1.2 christos BIO_printf(bio_err, 46 1.1.1.2 christos "error: setting distinguishing ID in certificate failed\n"); 47 1.1.1.2 christos return 0; 48 1.1 christos } 49 1.1.1.2 christos 50 1.1.1.2 christos X509_set0_distinguishing_id(object, v); 51 1.1.1.2 christos return 1; 52 1.1.1.2 christos } 53 1.1 christos #endif 54 1.1 christos default: 55 1.1 christos break; 56 1.1 christos } 57 1.1.1.2 christos return -2; /* typical EVP_PKEY return for "unsupported" */ 58 1.1 christos } 59 1.1 christos 60 1.1 christos static int x509_req_ctrl(void *object, int cmd, void *value, size_t value_n) 61 1.1 christos { 62 1.1 christos switch (cmd) { 63 1.1 christos #ifdef EVP_PKEY_CTRL_SET1_ID 64 1.1.1.2 christos case EVP_PKEY_CTRL_SET1_ID: { 65 1.1.1.2 christos ASN1_OCTET_STRING *v = mk_octet_string(value, value_n); 66 1.1 christos 67 1.1.1.2 christos if (v == NULL) { 68 1.1.1.2 christos BIO_printf(bio_err, 69 1.1.1.2 christos "error: setting distinguishing ID in certificate signing request failed\n"); 70 1.1.1.2 christos return 0; 71 1.1 christos } 72 1.1.1.2 christos 73 1.1.1.2 christos X509_REQ_set0_distinguishing_id(object, v); 74 1.1.1.2 christos return 1; 75 1.1.1.2 christos } 76 1.1 christos #endif 77 1.1 christos default: 78 1.1 christos break; 79 1.1 christos } 80 1.1.1.2 christos return -2; /* typical EVP_PKEY return for "unsupported" */ 81 1.1 christos } 82 1.1 christos 83 1.1 christos static int do_x509_ctrl_string(int (*ctrl)(void *object, int cmd, 84 1.1.1.2 christos void *value, size_t value_n), 85 1.1.1.2 christos void *object, const char *value) 86 1.1 christos { 87 1.1 christos int rv = 0; 88 1.1 christos char *stmp, *vtmp = NULL; 89 1.1 christos size_t vtmp_len = 0; 90 1.1 christos int cmd = 0; /* Will get command values that make sense somehow */ 91 1.1 christos 92 1.1 christos stmp = OPENSSL_strdup(value); 93 1.1 christos if (stmp == NULL) 94 1.1 christos return -1; 95 1.1 christos vtmp = strchr(stmp, ':'); 96 1.1 christos if (vtmp != NULL) { 97 1.1 christos *vtmp = 0; 98 1.1 christos vtmp++; 99 1.1 christos vtmp_len = strlen(vtmp); 100 1.1 christos } 101 1.1 christos 102 1.1 christos if (strcmp(stmp, "distid") == 0) { 103 1.1 christos #ifdef EVP_PKEY_CTRL_SET1_ID 104 1.1 christos cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */ 105 1.1 christos #endif 106 1.1 christos } else if (strcmp(stmp, "hexdistid") == 0) { 107 1.1 christos if (vtmp != NULL) { 108 1.1 christos void *hexid; 109 1.1 christos long hexid_len = 0; 110 1.1 christos 111 1.1 christos hexid = OPENSSL_hexstr2buf((const char *)vtmp, &hexid_len); 112 1.1 christos OPENSSL_free(stmp); 113 1.1 christos stmp = vtmp = hexid; 114 1.1 christos vtmp_len = (size_t)hexid_len; 115 1.1 christos } 116 1.1 christos #ifdef EVP_PKEY_CTRL_SET1_ID 117 1.1 christos cmd = EVP_PKEY_CTRL_SET1_ID; /* ... except we put it in X509 */ 118 1.1 christos #endif 119 1.1 christos } 120 1.1 christos 121 1.1 christos rv = ctrl(object, cmd, vtmp, vtmp_len); 122 1.1 christos 123 1.1 christos OPENSSL_free(stmp); 124 1.1 christos return rv; 125 1.1 christos } 126 1.1 christos 127 1.1 christos int x509_ctrl_string(X509 *x, const char *value) 128 1.1 christos { 129 1.1 christos return do_x509_ctrl_string(x509_ctrl, x, value); 130 1.1 christos } 131 1.1 christos 132 1.1 christos int x509_req_ctrl_string(X509_REQ *x, const char *value) 133 1.1 christos { 134 1.1 christos return do_x509_ctrl_string(x509_req_ctrl, x, value); 135 1.1 christos } 136