Home | History | Annotate | Line # | Download | only in lib
      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