1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <stdio.h> 11e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 12e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 13e1051a39Sopenharmony_ci#include <openssl/x509.h> 14e1051a39Sopenharmony_ci#include "crypto/x509.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci/*- 17e1051a39Sopenharmony_ci * X509_REQ_INFO is handled in an unusual way to get round 18e1051a39Sopenharmony_ci * invalid encodings. Some broken certificate requests don't 19e1051a39Sopenharmony_ci * encode the attributes field if it is empty. This is in 20e1051a39Sopenharmony_ci * violation of PKCS#10 but we need to tolerate it. We do 21e1051a39Sopenharmony_ci * this by making the attributes field OPTIONAL then using 22e1051a39Sopenharmony_ci * the callback to initialise it to an empty STACK. 23e1051a39Sopenharmony_ci * 24e1051a39Sopenharmony_ci * This means that the field will be correctly encoded unless 25e1051a39Sopenharmony_ci * we NULL out the field. 26e1051a39Sopenharmony_ci * 27e1051a39Sopenharmony_ci * As a result we no longer need the req_kludge field because 28e1051a39Sopenharmony_ci * the information is now contained in the attributes field: 29e1051a39Sopenharmony_ci * 1. If it is NULL then it's the invalid omission. 30e1051a39Sopenharmony_ci * 2. If it is empty it is the correct encoding. 31e1051a39Sopenharmony_ci * 3. If it is not empty then some attributes are present. 32e1051a39Sopenharmony_ci * 33e1051a39Sopenharmony_ci */ 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_cistatic int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, 36e1051a39Sopenharmony_ci void *exarg) 37e1051a39Sopenharmony_ci{ 38e1051a39Sopenharmony_ci X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; 39e1051a39Sopenharmony_ci 40e1051a39Sopenharmony_ci if (operation == ASN1_OP_NEW_POST) { 41e1051a39Sopenharmony_ci rinf->attributes = sk_X509_ATTRIBUTE_new_null(); 42e1051a39Sopenharmony_ci if (!rinf->attributes) 43e1051a39Sopenharmony_ci return 0; 44e1051a39Sopenharmony_ci } 45e1051a39Sopenharmony_ci return 1; 46e1051a39Sopenharmony_ci} 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_cistatic int req_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, 49e1051a39Sopenharmony_ci void *exarg) 50e1051a39Sopenharmony_ci{ 51e1051a39Sopenharmony_ci X509_REQ *ret = (X509_REQ *)*pval; 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci switch (operation) { 54e1051a39Sopenharmony_ci case ASN1_OP_D2I_PRE: 55e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(ret->distinguishing_id); 56e1051a39Sopenharmony_ci /* fall thru */ 57e1051a39Sopenharmony_ci case ASN1_OP_NEW_POST: 58e1051a39Sopenharmony_ci ret->distinguishing_id = NULL; 59e1051a39Sopenharmony_ci break; 60e1051a39Sopenharmony_ci 61e1051a39Sopenharmony_ci case ASN1_OP_FREE_POST: 62e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(ret->distinguishing_id); 63e1051a39Sopenharmony_ci OPENSSL_free(ret->propq); 64e1051a39Sopenharmony_ci break; 65e1051a39Sopenharmony_ci case ASN1_OP_DUP_POST: 66e1051a39Sopenharmony_ci { 67e1051a39Sopenharmony_ci X509_REQ *old = exarg; 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci if (!ossl_x509_req_set0_libctx(ret, old->libctx, old->propq)) 70e1051a39Sopenharmony_ci return 0; 71e1051a39Sopenharmony_ci if (old->req_info.pubkey != NULL) { 72e1051a39Sopenharmony_ci EVP_PKEY *pkey = X509_PUBKEY_get0(old->req_info.pubkey); 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_ci if (pkey != NULL) { 75e1051a39Sopenharmony_ci pkey = EVP_PKEY_dup(pkey); 76e1051a39Sopenharmony_ci if (pkey == NULL) { 77e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 78e1051a39Sopenharmony_ci return 0; 79e1051a39Sopenharmony_ci } 80e1051a39Sopenharmony_ci if (!X509_PUBKEY_set(&ret->req_info.pubkey, pkey)) { 81e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 82e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_INTERNAL_ERROR); 83e1051a39Sopenharmony_ci return 0; 84e1051a39Sopenharmony_ci } 85e1051a39Sopenharmony_ci EVP_PKEY_free(pkey); 86e1051a39Sopenharmony_ci } 87e1051a39Sopenharmony_ci } 88e1051a39Sopenharmony_ci } 89e1051a39Sopenharmony_ci break; 90e1051a39Sopenharmony_ci case ASN1_OP_GET0_LIBCTX: 91e1051a39Sopenharmony_ci { 92e1051a39Sopenharmony_ci OSSL_LIB_CTX **libctx = exarg; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci *libctx = ret->libctx; 95e1051a39Sopenharmony_ci } 96e1051a39Sopenharmony_ci break; 97e1051a39Sopenharmony_ci case ASN1_OP_GET0_PROPQ: 98e1051a39Sopenharmony_ci { 99e1051a39Sopenharmony_ci const char **propq = exarg; 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci *propq = ret->propq; 102e1051a39Sopenharmony_ci } 103e1051a39Sopenharmony_ci break; 104e1051a39Sopenharmony_ci } 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci return 1; 107e1051a39Sopenharmony_ci} 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ciASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { 110e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), 111e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), 112e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), 113e1051a39Sopenharmony_ci /* This isn't really OPTIONAL but it gets round invalid 114e1051a39Sopenharmony_ci * encodings 115e1051a39Sopenharmony_ci */ 116e1051a39Sopenharmony_ci ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) 117e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) 118e1051a39Sopenharmony_ci 119e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ciASN1_SEQUENCE_ref(X509_REQ, req_cb) = { 122e1051a39Sopenharmony_ci ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO), 123e1051a39Sopenharmony_ci ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR), 124e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) 125e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_REQ) 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_civoid X509_REQ_set0_distinguishing_id(X509_REQ *x, ASN1_OCTET_STRING *d_id) 132e1051a39Sopenharmony_ci{ 133e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(x->distinguishing_id); 134e1051a39Sopenharmony_ci x->distinguishing_id = d_id; 135e1051a39Sopenharmony_ci} 136e1051a39Sopenharmony_ci 137e1051a39Sopenharmony_ciASN1_OCTET_STRING *X509_REQ_get0_distinguishing_id(X509_REQ *x) 138e1051a39Sopenharmony_ci{ 139e1051a39Sopenharmony_ci return x->distinguishing_id; 140e1051a39Sopenharmony_ci} 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci/* 143e1051a39Sopenharmony_ci * This should only be used if the X509_REQ object was embedded inside another 144e1051a39Sopenharmony_ci * asn1 object and it needs a libctx to operate. 145e1051a39Sopenharmony_ci * Use X509_REQ_new_ex() instead if possible. 146e1051a39Sopenharmony_ci */ 147e1051a39Sopenharmony_ciint ossl_x509_req_set0_libctx(X509_REQ *x, OSSL_LIB_CTX *libctx, 148e1051a39Sopenharmony_ci const char *propq) 149e1051a39Sopenharmony_ci{ 150e1051a39Sopenharmony_ci if (x != NULL) { 151e1051a39Sopenharmony_ci x->libctx = libctx; 152e1051a39Sopenharmony_ci OPENSSL_free(x->propq); 153e1051a39Sopenharmony_ci x->propq = NULL; 154e1051a39Sopenharmony_ci if (propq != NULL) { 155e1051a39Sopenharmony_ci x->propq = OPENSSL_strdup(propq); 156e1051a39Sopenharmony_ci if (x->propq == NULL) 157e1051a39Sopenharmony_ci return 0; 158e1051a39Sopenharmony_ci } 159e1051a39Sopenharmony_ci } 160e1051a39Sopenharmony_ci return 1; 161e1051a39Sopenharmony_ci} 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_ciX509_REQ *X509_REQ_new_ex(OSSL_LIB_CTX *libctx, const char *propq) 164e1051a39Sopenharmony_ci{ 165e1051a39Sopenharmony_ci X509_REQ *req = NULL; 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_ci req = (X509_REQ *)ASN1_item_new((X509_REQ_it())); 168e1051a39Sopenharmony_ci if (!ossl_x509_req_set0_libctx(req, libctx, propq)) { 169e1051a39Sopenharmony_ci X509_REQ_free(req); 170e1051a39Sopenharmony_ci req = NULL; 171e1051a39Sopenharmony_ci } 172e1051a39Sopenharmony_ci return req; 173e1051a39Sopenharmony_ci} 174