/src/boringssl/crypto/x509/x_req.cc
Line | Count | Source |
1 | | // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #include <stdio.h> |
16 | | |
17 | | #include <openssl/asn1t.h> |
18 | | #include <openssl/x509.h> |
19 | | |
20 | | #include "internal.h" |
21 | | |
22 | | |
23 | | using namespace bssl; |
24 | | |
25 | | // X509_REQ_INFO is handled in an unusual way to get round invalid encodings. |
26 | | // Some broken certificate requests don't encode the attributes field if it |
27 | | // is empty. This is in violation of PKCS#10 but we need to tolerate it. We |
28 | | // do this by making the attributes field OPTIONAL then using the callback to |
29 | | // initialise it to an empty STACK. This means that the field will be |
30 | | // correctly encoded unless we NULL out the field. |
31 | | |
32 | | static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
33 | 0 | void *exarg) { |
34 | 0 | bssl::X509_REQ_INFO *rinf = (bssl::X509_REQ_INFO *)*pval; |
35 | |
|
36 | 0 | if (operation == ASN1_OP_NEW_POST) { |
37 | 0 | rinf->attributes = sk_X509_ATTRIBUTE_new_null(); |
38 | 0 | if (!rinf->attributes) { |
39 | 0 | return 0; |
40 | 0 | } |
41 | 0 | } |
42 | | |
43 | 0 | if (operation == ASN1_OP_D2I_POST) { |
44 | | // The only defined CSR version is v1(0). For compatibility, we also accept |
45 | | // a hypothetical v3(2). Although not defined, older versions of certbot |
46 | | // use it. See https://github.com/certbot/certbot/pull/9334. |
47 | 0 | long version = ASN1_INTEGER_get(rinf->version); |
48 | 0 | if (version != X509_REQ_VERSION_1 && version != 2) { |
49 | 0 | OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); |
50 | 0 | return 0; |
51 | 0 | } |
52 | 0 | } |
53 | | |
54 | 0 | return 1; |
55 | 0 | } |
56 | | |
57 | | BSSL_NAMESPACE_BEGIN |
58 | | |
59 | | ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { |
60 | | ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), |
61 | | ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), |
62 | | ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), |
63 | | // This isn't really OPTIONAL but it gets around invalid encodings. |
64 | | ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0), |
65 | | } ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) |
66 | | |
67 | | IMPLEMENT_ASN1_FUNCTIONS_const(X509_REQ_INFO) |
68 | | |
69 | | ASN1_SEQUENCE(X509_REQ) = { |
70 | | ASN1_SIMPLE(X509_REQ, req_info, bssl::X509_REQ_INFO), |
71 | | ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), |
72 | | ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING), |
73 | | } ASN1_SEQUENCE_END(X509_REQ) |
74 | | |
75 | | BSSL_NAMESPACE_END |
76 | | |
77 | | IMPLEMENT_ASN1_FUNCTIONS_const(X509_REQ) |
78 | | |
79 | | IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_REQ) |