NCBI C++ ToolKit
x509write_csr.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * X.509 Certificate Signing Request writing
3  *
4  * Copyright The Mbed TLS Contributors
5  * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  */
7 /*
8  * References:
9  * - CSRs: PKCS#10 v1.7 aka RFC 2986
10  * - attributes: PKCS#9 v2.0 aka RFC 2985
11  */
12 
13 #include "common.h"
14 
15 #if defined(MBEDTLS_X509_CSR_WRITE_C)
16 
17 #include "x509_internal.h"
18 #include "mbedtls/x509_csr.h"
19 #include "mbedtls/asn1write.h"
20 #include "mbedtls/error.h"
21 #include "mbedtls/oid.h"
22 #include "mbedtls/platform_util.h"
23 
24 #if defined(MBEDTLS_USE_PSA_CRYPTO)
25 #include "psa/crypto.h"
26 #include "psa_util_internal.h"
27 #include "mbedtls/psa_util.h"
28 #endif /* MBEDTLS_USE_PSA_CRYPTO */
29 
30 #include <string.h>
31 #include <stdlib.h>
32 
33 #if defined(MBEDTLS_PEM_WRITE_C)
34 #include "mbedtls/pem.h"
35 #endif
36 
37 #include "mbedtls/platform.h"
38 
40 {
41  memset(ctx, 0, sizeof(mbedtls_x509write_csr));
42 }
43 
45 {
48 
50 }
51 
53 {
54  ctx->md_alg = md_alg;
55 }
56 
58 {
59  ctx->key = key;
60 }
61 
63  const char *subject_name)
64 {
65  return mbedtls_x509_string_to_names(&ctx->subject, subject_name);
66 }
67 
69  const char *oid, size_t oid_len,
70  int critical,
71  const unsigned char *val, size_t val_len)
72 {
73  return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len,
74  critical, val, val_len);
75 }
76 
78  const mbedtls_x509_san_list *san_list)
79 {
80  return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list);
81 }
82 
84 {
85  unsigned char buf[4] = { 0 };
86  unsigned char *c;
88 
89  c = buf + 4;
90 
91  ret = mbedtls_asn1_write_named_bitstring(&c, buf, &key_usage, 8);
92  if (ret < 3 || ret > 4) {
93  return ret;
94  }
95 
98  0, c, (size_t) ret);
99  if (ret != 0) {
100  return ret;
101  }
102 
103  return 0;
104 }
105 
107  unsigned char ns_cert_type)
108 {
109  unsigned char buf[4] = { 0 };
110  unsigned char *c;
112 
113  c = buf + 4;
114 
115  ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8);
116  if (ret < 3 || ret > 4) {
117  return ret;
118  }
119 
122  0, c, (size_t) ret);
123  if (ret != 0) {
124  return ret;
125  }
126 
127  return 0;
128 }
129 
130 static int x509write_csr_der_internal(mbedtls_x509write_csr *ctx,
131  unsigned char *buf,
132  size_t size,
133  unsigned char *sig, size_t sig_size,
134  int (*f_rng)(void *, unsigned char *, size_t),
135  void *p_rng)
136 {
138  const char *sig_oid;
139  size_t sig_oid_len = 0;
140  unsigned char *c, *c2;
141  unsigned char hash[MBEDTLS_MD_MAX_SIZE];
142  size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
143  size_t len = 0;
144  mbedtls_pk_type_t pk_alg;
145 #if defined(MBEDTLS_USE_PSA_CRYPTO)
146  size_t hash_len;
147  psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(ctx->md_alg);
148 #endif /* MBEDTLS_USE_PSA_CRYPTO */
149 
150  /* Write the CSR backwards starting from the end of buf */
151  c = buf + size;
152 
154  ctx->extensions));
155 
156  if (len) {
160  &c, buf,
162 
166  &c, buf,
168 
173 
177  &c, buf,
179  }
180 
184  &c, buf,
186 
188  buf, (size_t) (c - buf)));
189  c -= pub_len;
190  len += pub_len;
191 
192  /*
193  * Subject ::= Name
194  */
196  ctx->subject));
197 
198  /*
199  * Version ::= INTEGER { v1(0), v2(1), v3(2) }
200  */
202 
206  &c, buf,
208 
209  /*
210  * Sign the written CSR data into the sig buffer
211  * Note: hash errors can happen only after an internal error
212  */
213 #if defined(MBEDTLS_USE_PSA_CRYPTO)
214  if (psa_hash_compute(hash_alg,
215  c,
216  len,
217  hash,
218  sizeof(hash),
219  &hash_len) != PSA_SUCCESS) {
221  }
222 #else /* MBEDTLS_USE_PSA_CRYPTO */
223  ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, len, hash);
224  if (ret != 0) {
225  return ret;
226  }
227 #endif
228  if ((ret = mbedtls_pk_sign(ctx->key, ctx->md_alg, hash, 0,
229  sig, sig_size, &sig_len,
230  f_rng, p_rng)) != 0) {
231  return ret;
232  }
233 
234  if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_RSA)) {
235  pk_alg = MBEDTLS_PK_RSA;
236  } else if (mbedtls_pk_can_do(ctx->key, MBEDTLS_PK_ECDSA)) {
237  pk_alg = MBEDTLS_PK_ECDSA;
238  } else {
240  }
241 
242  if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg,
243  &sig_oid, &sig_oid_len)) != 0) {
244  return ret;
245  }
246 
247  /*
248  * Move the written CSR data to the start of buf to create space for
249  * writing the signature into buf.
250  */
251  memmove(buf, c, len);
252 
253  /*
254  * Write sig and its OID into buf backwards from the end of buf.
255  * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len
256  * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed.
257  */
258  c2 = buf + size;
259  MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len,
260  mbedtls_x509_write_sig(&c2, buf + len, sig_oid, sig_oid_len,
261  sig, sig_len, pk_alg));
262 
263  /*
264  * Compact the space between the CSR data and signature by moving the
265  * CSR data to the start of the signature.
266  */
267  c2 -= len;
268  memmove(c2, buf, len);
269 
270  /* ASN encode the total size and tag the CSR data with it. */
271  len += sig_and_oid_len;
275  &c2, buf,
277 
278  /* Zero the unused bytes at the start of buf */
279  memset(buf, 0, (size_t) (c2 - buf));
280 
281  return (int) len;
282 }
283 
285  size_t size,
286  int (*f_rng)(void *, unsigned char *, size_t),
287  void *p_rng)
288 {
289  int ret;
290  unsigned char *sig;
291 
294  }
295 
296  ret = x509write_csr_der_internal(ctx, buf, size,
298  f_rng, p_rng);
299 
300  mbedtls_free(sig);
301 
302  return ret;
303 }
304 
305 #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
306 #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
307 
308 #if defined(MBEDTLS_PEM_WRITE_C)
309 int mbedtls_x509write_csr_pem(mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
310  int (*f_rng)(void *, unsigned char *, size_t),
311  void *p_rng)
312 {
314  size_t olen = 0;
315 
316  if ((ret = mbedtls_x509write_csr_der(ctx, buf, size,
317  f_rng, p_rng)) < 0) {
318  return ret;
319  }
320 
321  if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CSR, PEM_END_CSR,
322  buf + size - ret,
323  ret, buf, size, &olen)) != 0) {
324  return ret;
325  }
326 
327  return 0;
328 }
329 #endif /* MBEDTLS_PEM_WRITE_C */
330 
331 #endif /* MBEDTLS_X509_CSR_WRITE_C */
ASN.1 buffer writing functionality.
#define MBEDTLS_ASN1_CHK_ADD(g, f)
Definition: asn1write.h:17
Platform Security Architecture cryptography module.
CS_CONTEXT * ctx
Definition: t0006.c:12
#define NULL
Definition: ncbistd.hpp:225
#define MBEDTLS_ASN1_SEQUENCE
Definition: asn1.h:72
#define MBEDTLS_ASN1_SET
Definition: asn1.h:73
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC
Definition: asn1.h:83
#define MBEDTLS_ASN1_CONSTRUCTED
Definition: asn1.h:82
#define MBEDTLS_OID_SIZE(x)
Returns the size of the binary string, without the trailing \0.
Definition: asn1.h:113
uint32_t psa_algorithm_t
Encoding of a cryptographic algorithm.
Definition: crypto_types.h:134
#define PSA_SUCCESS
The action was completed successfully.
Definition: crypto_values.h:57
psa_status_t psa_hash_compute(psa_algorithm_t alg, const uint8_t *input, size_t input_length, uint8_t *hash, size_t hash_size, size_t *hash_length)
Calculate the hash (digest) of a message.
#define MBEDTLS_ERR_X509_ALLOC_FAILED
Allocation of memory failed.
Definition: x509.h:77
#define MBEDTLS_ERR_X509_INVALID_ALG
The algorithm tag or value is invalid.
Definition: x509.h:55
char * buf
int len
mbedtls_md_type_t
Supported message digests.
Definition: md.h:47
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output)
This function calculates the message-digest of a buffer, with respect to a configurable message-diges...
const mbedtls_md_info_t * mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
This function returns the message-digest information associated with the given digest type.
#define MBEDTLS_MD_MAX_SIZE
Definition: md.h:79
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
#define mbedtls_x509write_csr_set_extension
#define mbedtls_platform_zeroize
#define mbedtls_x509write_csr_set_key_usage
#define mbedtls_x509write_csr_init
#define mbedtls_x509write_csr_set_md_alg
#define mbedtls_asn1_write_int
#define mbedtls_asn1_write_oid
#define mbedtls_x509write_csr_free
#define mbedtls_asn1_write_tag
#define mbedtls_x509write_csr_der
#define mbedtls_x509write_csr_pem
#define mbedtls_x509write_csr_set_subject_alternative_name
#define mbedtls_asn1_free_named_data_list
#define mbedtls_x509write_csr_set_subject_name
#define mbedtls_pem_write_buffer
#define mbedtls_asn1_write_len
#define mbedtls_asn1_write_named_bitstring
#define mbedtls_x509write_csr_set_ns_cert_type
#define mbedtls_x509write_csr_set_key
#define mbedtls_pk_write_pubkey_der
Object Identifier (OID) database.
#define MBEDTLS_OID_PKCS9_CSR_EXT_REQ
extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14}
Definition: oid.h:343
#define MBEDTLS_OID_KEY_USAGE
id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
Definition: oid.h:153
#define MBEDTLS_OID_NS_CERT_TYPE
Definition: oid.h:176
int mbedtls_oid_get_oid_by_sig_alg(mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, const char **oid, size_t *olen)
Translate md_type and pk_type into SignatureAlgorithm OID.
#define memmove(a, b, c)
Privacy Enhanced Mail (PEM) decoding.
int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
Tell if a context can do the operation given by type.
mbedtls_pk_type_t
Public key types.
Definition: pk.h:73
@ MBEDTLS_PK_ECDSA
Definition: pk.h:78
@ MBEDTLS_PK_RSA
Definition: pk.h:75
int mbedtls_pk_sign(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, unsigned char *sig, size_t sig_size, size_t *sig_len, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Make signature, including padding if relevant.
#define MBEDTLS_PK_SIGNATURE_MAX_SIZE
Maximum size of a signature made by mbedtls_pk_sign().
Definition: pk.h:122
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
#define mbedtls_free
Definition: platform.h:166
#define mbedtls_calloc
Definition: platform.h:167
Common and shared functions used by multiple modules in the Mbed TLS library.
Utility functions for the use of the PSA Crypto library.
Internal utility functions for use of PSA Crypto.
Error to string translation.
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
This is a bug in the library.
Definition: error.h:100
#define MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
Hardware accelerator failed.
Definition: error.h:103
Definition: _hash_fun.h:40
Public key container.
Definition: pk.h:220
Container for writing a CSR.
Definition: x509_csr.h:66
int mbedtls_x509_string_to_names(mbedtls_asn1_named_data **head, const char *name)
Convert the certificate DN string name into a linked list of mbedtls_x509_name (equivalent to mbedtls...
X.509 certificate signing request parsing and writing.
int mbedtls_x509_write_extensions(unsigned char **p, unsigned char *start, mbedtls_asn1_named_data *first)
int mbedtls_x509_set_extension(mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, int critical, const unsigned char *val, size_t val_len)
int mbedtls_x509_write_names(unsigned char **p, unsigned char *start, mbedtls_asn1_named_data *first)
int mbedtls_x509_write_sig(unsigned char **p, unsigned char *start, const char *oid, size_t oid_len, unsigned char *sig, size_t size, mbedtls_pk_type_t pk_alg)
int mbedtls_x509_write_set_san_common(mbedtls_asn1_named_data **extensions, const mbedtls_x509_san_list *san_list)
Modified on Sat May 25 14:17:04 2024 by modify_doxy.py rev. 669887