]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/x509/x_req.c
2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/asn1t.h>
13 #include <openssl/x509.h>
14 #include "crypto/x509.h"
17 * X509_REQ_INFO is handled in an unusual way to get round
18 * invalid encodings. Some broken certificate requests don't
19 * encode the attributes field if it is empty. This is in
20 * violation of PKCS#10 but we need to tolerate it. We do
21 * this by making the attributes field OPTIONAL then using
22 * the callback to initialise it to an empty STACK.
24 * This means that the field will be correctly encoded unless
25 * we NULL out the field.
27 * As a result we no longer need the req_kludge field because
28 * the information is now contained in the attributes field:
29 * 1. If it is NULL then it's the invalid omission.
30 * 2. If it is empty it is the correct encoding.
31 * 3. If it is not empty then some attributes are present.
35 static int rinf_cb(int operation
, ASN1_VALUE
**pval
, const ASN1_ITEM
*it
,
38 X509_REQ_INFO
*rinf
= (X509_REQ_INFO
*)*pval
;
40 if (operation
== ASN1_OP_NEW_POST
) {
41 rinf
->attributes
= sk_X509_ATTRIBUTE_new_null();
42 if (!rinf
->attributes
)
48 static int req_cb(int operation
, ASN1_VALUE
**pval
, const ASN1_ITEM
*it
,
51 X509_REQ
*ret
= (X509_REQ
*)*pval
;
55 ASN1_OCTET_STRING_free(ret
->distinguishing_id
);
57 case ASN1_OP_NEW_POST
:
58 ret
->distinguishing_id
= NULL
;
61 case ASN1_OP_FREE_POST
:
62 ASN1_OCTET_STRING_free(ret
->distinguishing_id
);
64 case ASN1_OP_DUP_POST
:
66 X509_REQ
*old
= exarg
;
68 if (!ossl_x509_req_set0_libctx(ret
, old
->libctx
, old
->propq
))
77 ASN1_SEQUENCE_enc(X509_REQ_INFO
, enc
, rinf_cb
) = {
78 ASN1_SIMPLE(X509_REQ_INFO
, version
, ASN1_INTEGER
),
79 ASN1_SIMPLE(X509_REQ_INFO
, subject
, X509_NAME
),
80 ASN1_SIMPLE(X509_REQ_INFO
, pubkey
, X509_PUBKEY
),
81 /* This isn't really OPTIONAL but it gets round invalid
84 ASN1_IMP_SET_OF_OPT(X509_REQ_INFO
, attributes
, X509_ATTRIBUTE
, 0)
85 } ASN1_SEQUENCE_END_enc(X509_REQ_INFO
, X509_REQ_INFO
)
87 IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO
)
89 ASN1_SEQUENCE_ref(X509_REQ
, req_cb
) = {
90 ASN1_EMBED(X509_REQ
, req_info
, X509_REQ_INFO
),
91 ASN1_EMBED(X509_REQ
, sig_alg
, X509_ALGOR
),
92 ASN1_SIMPLE(X509_REQ
, signature
, ASN1_BIT_STRING
)
93 } ASN1_SEQUENCE_END_ref(X509_REQ
, X509_REQ
)
95 IMPLEMENT_ASN1_FUNCTIONS(X509_REQ
)
97 IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ
)
99 void X509_REQ_set0_distinguishing_id(X509_REQ
*x
, ASN1_OCTET_STRING
*d_id
)
101 ASN1_OCTET_STRING_free(x
->distinguishing_id
);
102 x
->distinguishing_id
= d_id
;
105 ASN1_OCTET_STRING
*X509_REQ_get0_distinguishing_id(X509_REQ
*x
)
107 return x
->distinguishing_id
;
111 * This should only be used if the X509_REQ object was embedded inside another
112 * asn1 object and it needs a libctx to operate.
113 * Use X509_REQ_new_ex() instead if possible.
115 int ossl_x509_req_set0_libctx(X509_REQ
*x
, OSSL_LIB_CTX
*libctx
,
120 OPENSSL_free(x
->propq
);
123 x
->propq
= OPENSSL_strdup(propq
);
124 if (x
->propq
== NULL
)
131 X509_REQ
*X509_REQ_new_ex(OSSL_LIB_CTX
*libctx
, const char *propq
)
133 X509_REQ
*req
= NULL
;
135 req
= (X509_REQ
*)ASN1_item_new((X509_REQ_it()));
136 if (!ossl_x509_req_set0_libctx(req
, libctx
, propq
)) {