Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/x509/crq.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2003-2016 Free Software Foundation, Inc.
3
 * Copyright (C) 2012-2016 Nikos Mavrogiannopoulos
4
 * Copyright (C) 2016-2017 Red Hat, Inc.
5
 *
6
 * Author: Nikos Mavrogiannopoulos
7
 *
8
 * This file is part of GnuTLS.
9
 *
10
 * The GnuTLS is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public License
12
 * as published by the Free Software Foundation; either version 2.1 of
13
 * the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful, but
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
22
 *
23
 */
24
25
/* This file contains functions to handle PKCS #10 certificate
26
   requests, see RFC 2986.
27
 */
28
29
#include "gnutls_int.h"
30
31
#include <datum.h>
32
#include <global.h>
33
#include "errors.h"
34
#include <common.h>
35
#include <x509.h>
36
#include <x509_b64.h>
37
#include <gnutls/x509-ext.h>
38
#include "x509_int.h"
39
#include <libtasn1.h>
40
#include <pk.h>
41
#include "attributes.h"
42
43
/**
44
 * gnutls_x509_crq_init:
45
 * @crq: A pointer to the type to be initialized
46
 *
47
 * This function will initialize a PKCS#10 certificate request
48
 * structure.
49
 *
50
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
51
 *   negative error value.
52
 **/
53
int gnutls_x509_crq_init(gnutls_x509_crq_t * crq)
54
0
{
55
0
  int result;
56
57
0
  *crq = NULL;
58
0
  FAIL_IF_LIB_ERROR;
59
60
0
  *crq = gnutls_calloc(1, sizeof(gnutls_x509_crq_int));
61
0
  if (!*crq)
62
0
    return GNUTLS_E_MEMORY_ERROR;
63
64
0
  result = asn1_create_element(_gnutls_get_pkix(),
65
0
             "PKIX1.pkcs-10-CertificationRequest",
66
0
             &((*crq)->crq));
67
0
  if (result != ASN1_SUCCESS) {
68
0
    gnutls_assert();
69
0
    gnutls_free(*crq);
70
0
    return _gnutls_asn2err(result);
71
0
  }
72
73
0
  return 0;
74
0
}
75
76
/**
77
 * gnutls_x509_crq_deinit:
78
 * @crq: the type to be deinitialized
79
 *
80
 * This function will deinitialize a PKCS#10 certificate request
81
 * structure.
82
 **/
83
void gnutls_x509_crq_deinit(gnutls_x509_crq_t crq)
84
0
{
85
0
  if (!crq)
86
0
    return;
87
88
0
  if (crq->crq)
89
0
    asn1_delete_structure(&crq->crq);
90
91
0
  gnutls_free(crq);
92
0
}
93
94
0
#define PEM_CRQ "NEW CERTIFICATE REQUEST"
95
0
#define PEM_CRQ2 "CERTIFICATE REQUEST"
96
97
/**
98
 * gnutls_x509_crq_import:
99
 * @crq: The data to store the parsed certificate request.
100
 * @data: The DER or PEM encoded certificate.
101
 * @format: One of DER or PEM
102
 *
103
 * This function will convert the given DER or PEM encoded certificate
104
 * request to a #gnutls_x509_crq_t type.  The output will be
105
 * stored in @crq.
106
 *
107
 * If the Certificate is PEM encoded it should have a header of "NEW
108
 * CERTIFICATE REQUEST".
109
 *
110
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
111
 *   negative error value.
112
 **/
113
int
114
gnutls_x509_crq_import(gnutls_x509_crq_t crq,
115
           const gnutls_datum_t * data,
116
           gnutls_x509_crt_fmt_t format)
117
0
{
118
0
  int result = 0, need_free = 0;
119
0
  gnutls_datum_t _data;
120
121
0
  if (crq == NULL) {
122
0
    gnutls_assert();
123
0
    return GNUTLS_E_INVALID_REQUEST;
124
0
  }
125
126
0
  _data.data = data->data;
127
0
  _data.size = data->size;
128
129
  /* If the Certificate is in PEM format then decode it
130
   */
131
0
  if (format == GNUTLS_X509_FMT_PEM) {
132
    /* Try the first header */
133
0
    result =
134
0
        _gnutls_fbase64_decode(PEM_CRQ, data->data, data->size,
135
0
             &_data);
136
137
0
    if (result < 0) /* Go for the second header */
138
0
      result =
139
0
          _gnutls_fbase64_decode(PEM_CRQ2, data->data,
140
0
               data->size, &_data);
141
142
0
    if (result < 0) {
143
0
      gnutls_assert();
144
0
      return result;
145
0
    }
146
147
0
    need_free = 1;
148
0
  }
149
150
0
  result =
151
0
      _asn1_strict_der_decode(&crq->crq, _data.data, _data.size, NULL);
152
0
  if (result != ASN1_SUCCESS) {
153
0
    result = _gnutls_asn2err(result);
154
0
    gnutls_assert();
155
0
    goto cleanup;
156
0
  }
157
158
0
  result = 0;
159
160
0
 cleanup:
161
0
  if (need_free)
162
0
    _gnutls_free_datum(&_data);
163
0
  return result;
164
0
}
165
166
/**
167
 * gnutls_x509_crq_get_signature_algorithm:
168
 * @crq: should contain a #gnutls_x509_cr_t type
169
 *
170
 * This function will return a value of the #gnutls_sign_algorithm_t
171
 * enumeration that is the signature algorithm that has been used to
172
 * sign this certificate request.
173
 *
174
 * Since 3.6.0 this function never returns a negative error code.
175
 * Error cases and unknown/unsupported signature algorithms are
176
 * mapped to %GNUTLS_SIGN_UNKNOWN.
177
 *
178
 * Returns: a #gnutls_sign_algorithm_t value
179
 *
180
 * Since: 3.4.0
181
 **/
182
int gnutls_x509_crq_get_signature_algorithm(gnutls_x509_crq_t crq)
183
0
{
184
0
  return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(crq->crq,
185
0
                     "signatureAlgorithm"));
186
0
}
187
188
/**
189
 * gnutls_x509_crq_get_private_key_usage_period:
190
 * @crq: should contain a #gnutls_x509_crq_t type
191
 * @activation: The activation time
192
 * @expiration: The expiration time
193
 * @critical: the extension status
194
 *
195
 * This function will return the expiration and activation
196
 * times of the private key of the certificate.
197
 *
198
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
199
 * if the extension is not present, otherwise a negative error value.
200
 **/
201
int
202
gnutls_x509_crq_get_private_key_usage_period(gnutls_x509_crq_t crq,
203
               time_t * activation,
204
               time_t * expiration,
205
               unsigned int *critical)
206
0
{
207
0
  int result, ret;
208
0
  asn1_node c2 = NULL;
209
0
  uint8_t buf[128];
210
0
  size_t buf_size = sizeof(buf);
211
212
0
  if (crq == NULL) {
213
0
    gnutls_assert();
214
0
    return GNUTLS_E_INVALID_REQUEST;
215
0
  }
216
217
0
  ret = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.16", 0,
218
0
               buf, &buf_size, critical);
219
0
  if (ret < 0)
220
0
    return gnutls_assert_val(ret);
221
222
0
  result = asn1_create_element
223
0
      (_gnutls_get_pkix(), "PKIX1.PrivateKeyUsagePeriod", &c2);
224
0
  if (result != ASN1_SUCCESS) {
225
0
    gnutls_assert();
226
0
    ret = _gnutls_asn2err(result);
227
0
    goto cleanup;
228
0
  }
229
230
0
  result = _asn1_strict_der_decode(&c2, buf, buf_size, NULL);
231
0
  if (result != ASN1_SUCCESS) {
232
0
    gnutls_assert();
233
0
    ret = _gnutls_asn2err(result);
234
0
    goto cleanup;
235
0
  }
236
237
0
  if (activation)
238
0
    *activation = _gnutls_x509_get_time(c2, "notBefore", 1);
239
240
0
  if (expiration)
241
0
    *expiration = _gnutls_x509_get_time(c2, "notAfter", 1);
242
243
0
  ret = 0;
244
245
0
 cleanup:
246
0
  asn1_delete_structure(&c2);
247
248
0
  return ret;
249
0
}
250
251
/**
252
 * gnutls_x509_crq_get_dn:
253
 * @crq: should contain a #gnutls_x509_crq_t type
254
 * @buf: a pointer to a structure to hold the name (may be %NULL)
255
 * @buf_size: initially holds the size of @buf
256
 *
257
 * This function will copy the name of the Certificate request subject
258
 * to the provided buffer.  The name will be in the form
259
 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC 2253. The output string
260
 * @buf will be ASCII or UTF-8 encoded, depending on the certificate
261
 * data.
262
 *
263
 * This function does not output a fully RFC4514 compliant string, if
264
 * that is required see gnutls_x509_crq_get_dn3().
265
 *
266
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
267
 *   long enough, and in that case the *@buf_size will be updated with
268
 *   the required size.  On success 0 is returned.
269
 **/
270
int gnutls_x509_crq_get_dn(gnutls_x509_crq_t crq, char *buf, size_t *buf_size)
271
0
{
272
0
  if (crq == NULL) {
273
0
    gnutls_assert();
274
0
    return GNUTLS_E_INVALID_REQUEST;
275
0
  }
276
277
0
  return _gnutls_x509_parse_dn(crq->crq,
278
0
             "certificationRequestInfo.subject.rdnSequence",
279
0
             buf, buf_size, GNUTLS_X509_DN_FLAG_COMPAT);
280
0
}
281
282
/**
283
 * gnutls_x509_crq_get_dn2:
284
 * @crq: should contain a #gnutls_x509_crq_t type
285
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
286
 *
287
 * This function will allocate buffer and copy the name of the Certificate 
288
 * request. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
289
 * described in RFC4514. The output string will be ASCII or UTF-8
290
 * encoded, depending on the certificate data.
291
 *
292
 * This function does not output a fully RFC4514 compliant string, if
293
 * that is required see gnutls_x509_crq_get_dn3().
294
 *
295
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
296
 *   negative error value. and a negative error code on error.
297
 *
298
 * Since: 3.1.10
299
 **/
300
int gnutls_x509_crq_get_dn2(gnutls_x509_crq_t crq, gnutls_datum_t * dn)
301
0
{
302
0
  if (crq == NULL) {
303
0
    gnutls_assert();
304
0
    return GNUTLS_E_INVALID_REQUEST;
305
0
  }
306
307
0
  return _gnutls_x509_get_dn(crq->crq,
308
0
           "certificationRequestInfo.subject.rdnSequence",
309
0
           dn, GNUTLS_X509_DN_FLAG_COMPAT);
310
0
}
311
312
/**
313
 * gnutls_x509_crq_get_dn3:
314
 * @crq: should contain a #gnutls_x509_crq_t type
315
 * @dn: a pointer to a structure to hold the name; must be freed using gnutls_free()
316
 * @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
317
 *
318
 * This function will allocate buffer and copy the name of the Certificate 
319
 * request. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
320
 * described in RFC4514. The output string will be ASCII or UTF-8
321
 * encoded, depending on the certificate data.
322
 *
323
 * When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
324
 * format will match the format output by previous to 3.5.6 versions of GnuTLS
325
 * which was not not fully RFC4514-compliant.
326
 *
327
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
328
 *   negative error value. and a negative error code on error.
329
 *
330
 * Since: 3.5.7
331
 **/
332
int gnutls_x509_crq_get_dn3(gnutls_x509_crq_t crq, gnutls_datum_t * dn,
333
          unsigned flags)
334
0
{
335
0
  if (crq == NULL) {
336
0
    gnutls_assert();
337
0
    return GNUTLS_E_INVALID_REQUEST;
338
0
  }
339
340
0
  return _gnutls_x509_get_dn(crq->crq,
341
0
           "certificationRequestInfo.subject.rdnSequence",
342
0
           dn, flags);
343
0
}
344
345
/**
346
 * gnutls_x509_crq_get_dn_by_oid:
347
 * @crq: should contain a gnutls_x509_crq_t type
348
 * @oid: holds an Object Identifier in a null terminated string
349
 * @indx: In case multiple same OIDs exist in the RDN, this specifies
350
 *   which to get. Use (0) to get the first one.
351
 * @raw_flag: If non-zero returns the raw DER data of the DN part.
352
 * @buf: a pointer to a structure to hold the name (may be %NULL)
353
 * @buf_size: initially holds the size of @buf
354
 *
355
 * This function will extract the part of the name of the Certificate
356
 * request subject, specified by the given OID. The output will be
357
 * encoded as described in RFC2253. The output string will be ASCII
358
 * or UTF-8 encoded, depending on the certificate data.
359
 *
360
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
361
 * If raw flag is (0), this function will only return known OIDs as
362
 * text. Other OIDs will be DER encoded, as described in RFC2253 --
363
 * in hex format with a '\#' prefix.  You can check about known OIDs
364
 * using gnutls_x509_dn_oid_known().
365
 *
366
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
367
 *   not long enough, and in that case the *@buf_size will be
368
 *   updated with the required size.  On success 0 is returned.
369
 **/
370
int
371
gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq_t crq, const char *oid,
372
            unsigned indx, unsigned int raw_flag,
373
            void *buf, size_t *buf_size)
374
0
{
375
0
  gnutls_datum_t td;
376
0
  int ret;
377
378
0
  if (crq == NULL) {
379
0
    gnutls_assert();
380
0
    return GNUTLS_E_INVALID_REQUEST;
381
0
  }
382
383
0
  ret = _gnutls_x509_parse_dn_oid
384
0
      (crq->crq,
385
0
       "certificationRequestInfo.subject.rdnSequence",
386
0
       oid, indx, raw_flag, &td);
387
0
  if (ret < 0)
388
0
    return gnutls_assert_val(ret);
389
390
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
391
0
}
392
393
/**
394
 * gnutls_x509_crq_get_dn_oid:
395
 * @crq: should contain a gnutls_x509_crq_t type
396
 * @indx: Specifies which DN OID to get. Use (0) to get the first one.
397
 * @oid: a pointer to a structure to hold the name (may be %NULL)
398
 * @sizeof_oid: initially holds the size of @oid
399
 *
400
 * This function will extract the requested OID of the name of the
401
 * certificate request subject, specified by the given index.
402
 *
403
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
404
 *   not long enough, and in that case the *@sizeof_oid will be
405
 *   updated with the required size.  On success 0 is returned.
406
 **/
407
int
408
gnutls_x509_crq_get_dn_oid(gnutls_x509_crq_t crq,
409
         unsigned indx, void *oid, size_t *sizeof_oid)
410
0
{
411
0
  if (crq == NULL) {
412
0
    gnutls_assert();
413
0
    return GNUTLS_E_INVALID_REQUEST;
414
0
  }
415
416
0
  return _gnutls_x509_get_dn_oid(crq->crq,
417
0
               "certificationRequestInfo.subject.rdnSequence",
418
0
               indx, oid, sizeof_oid);
419
0
}
420
421
/**
422
 * gnutls_x509_crq_get_challenge_password:
423
 * @crq: should contain a #gnutls_x509_crq_t type
424
 * @pass: will hold a (0)-terminated password string
425
 * @pass_size: Initially holds the size of @pass.
426
 *
427
 * This function will return the challenge password in the request.
428
 * The challenge password is intended to be used for requesting a
429
 * revocation of the certificate.
430
 *
431
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
432
 *   negative error value.
433
 **/
434
int
435
gnutls_x509_crq_get_challenge_password(gnutls_x509_crq_t crq,
436
               char *pass, size_t *pass_size)
437
0
{
438
0
  gnutls_datum_t td;
439
0
  int ret;
440
441
0
  if (crq == NULL) {
442
0
    gnutls_assert();
443
0
    return GNUTLS_E_INVALID_REQUEST;
444
0
  }
445
446
0
  ret =
447
0
      _x509_parse_attribute(crq->crq,
448
0
          "certificationRequestInfo.attributes",
449
0
          "1.2.840.113549.1.9.7", 0, 0, &td);
450
0
  if (ret < 0)
451
0
    return gnutls_assert_val(ret);
452
453
0
  return _gnutls_strdatum_to_buf(&td, pass, pass_size);
454
0
}
455
456
/**
457
 * gnutls_x509_crq_set_attribute_by_oid:
458
 * @crq: should contain a #gnutls_x509_crq_t type
459
 * @oid: holds an Object Identifier in a null-terminated string
460
 * @buf: a pointer to a structure that holds the attribute data
461
 * @buf_size: holds the size of @buf
462
 *
463
 * This function will set the attribute in the certificate request
464
 * specified by the given Object ID. The provided attribute must be be DER
465
 * encoded.
466
 *
467
 * Attributes in a certificate request is an optional set of data
468
 * appended to the request. Their interpretation depends on the CA policy.
469
 *
470
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
471
 *   negative error value.
472
 **/
473
int
474
gnutls_x509_crq_set_attribute_by_oid(gnutls_x509_crq_t crq,
475
             const char *oid, void *buf,
476
             size_t buf_size)
477
0
{
478
0
  gnutls_datum_t data;
479
480
0
  data.data = buf;
481
0
  data.size = buf_size;
482
483
0
  if (crq == NULL) {
484
0
    gnutls_assert();
485
0
    return GNUTLS_E_INVALID_REQUEST;
486
0
  }
487
488
0
  return _x509_set_attribute(crq->crq,
489
0
           "certificationRequestInfo.attributes", oid,
490
0
           &data);
491
0
}
492
493
/**
494
 * gnutls_x509_crq_get_attribute_by_oid:
495
 * @crq: should contain a #gnutls_x509_crq_t type
496
 * @oid: holds an Object Identifier in null-terminated string
497
 * @indx: In case multiple same OIDs exist in the attribute list, this
498
 *   specifies which to get, use (0) to get the first one
499
 * @buf: a pointer to a structure to hold the attribute data (may be %NULL)
500
 * @buf_size: initially holds the size of @buf
501
 *
502
 * This function will return the attribute in the certificate request
503
 * specified by the given Object ID.  The attribute will be DER
504
 * encoded.
505
 *
506
 * Attributes in a certificate request is an optional set of data
507
 * appended to the request. Their interpretation depends on the CA policy.
508
 *
509
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
510
 *   negative error value.
511
 **/
512
int
513
gnutls_x509_crq_get_attribute_by_oid(gnutls_x509_crq_t crq,
514
             const char *oid, unsigned indx, void *buf,
515
             size_t *buf_size)
516
0
{
517
0
  int ret;
518
0
  gnutls_datum_t td;
519
520
0
  if (crq == NULL) {
521
0
    gnutls_assert();
522
0
    return GNUTLS_E_INVALID_REQUEST;
523
0
  }
524
525
0
  ret =
526
0
      _x509_parse_attribute(crq->crq,
527
0
          "certificationRequestInfo.attributes", oid,
528
0
          indx, 1, &td);
529
0
  if (ret < 0)
530
0
    return gnutls_assert_val(ret);
531
532
0
  return _gnutls_strdatum_to_buf(&td, buf, buf_size);
533
0
}
534
535
/**
536
 * gnutls_x509_crq_set_dn_by_oid:
537
 * @crq: should contain a #gnutls_x509_crq_t type
538
 * @oid: holds an Object Identifier in a (0)-terminated string
539
 * @raw_flag: must be 0, or 1 if the data are DER encoded
540
 * @data: a pointer to the input data
541
 * @sizeof_data: holds the size of @data
542
 *
543
 * This function will set the part of the name of the Certificate
544
 * request subject, specified by the given OID.  The input string
545
 * should be ASCII or UTF-8 encoded.
546
 *
547
 * Some helper macros with popular OIDs can be found in gnutls/x509.h
548
 * With this function you can only set the known OIDs.  You can test
549
 * for known OIDs using gnutls_x509_dn_oid_known().  For OIDs that are
550
 * not known (by gnutls) you should properly DER encode your data, and
551
 * call this function with raw_flag set.
552
 *
553
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
554
 *   negative error value.
555
 **/
556
int
557
gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq_t crq, const char *oid,
558
            unsigned int raw_flag, const void *data,
559
            unsigned int sizeof_data)
560
0
{
561
0
  if (sizeof_data == 0 || data == NULL || crq == NULL) {
562
0
    return GNUTLS_E_INVALID_REQUEST;
563
0
  }
564
565
0
  return _gnutls_x509_set_dn_oid(crq->crq,
566
0
               "certificationRequestInfo.subject",
567
0
               oid, raw_flag, data, sizeof_data);
568
0
}
569
570
/**
571
 * gnutls_x509_crq_set_version:
572
 * @crq: should contain a #gnutls_x509_crq_t type
573
 * @version: holds the version number, for v1 Requests must be 1
574
 *
575
 * This function will set the version of the certificate request.  For
576
 * version 1 requests this must be one.
577
 *
578
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
579
 *   negative error value.
580
 **/
581
int gnutls_x509_crq_set_version(gnutls_x509_crq_t crq, unsigned int version)
582
0
{
583
0
  int result;
584
0
  unsigned char null = version;
585
586
0
  if (crq == NULL) {
587
0
    gnutls_assert();
588
0
    return GNUTLS_E_INVALID_REQUEST;
589
0
  }
590
591
0
  if (null > 0)
592
0
    null--;
593
594
0
  result =
595
0
      asn1_write_value(crq->crq, "certificationRequestInfo.version",
596
0
           &null, 1);
597
0
  if (result != ASN1_SUCCESS) {
598
0
    gnutls_assert();
599
0
    return _gnutls_asn2err(result);
600
0
  }
601
602
0
  return 0;
603
0
}
604
605
/**
606
 * gnutls_x509_crq_get_version:
607
 * @crq: should contain a #gnutls_x509_crq_t type
608
 *
609
 * This function will return the version of the specified Certificate
610
 * request.
611
 *
612
 * Returns: version of certificate request, or a negative error code on
613
 *   error.
614
 **/
615
int gnutls_x509_crq_get_version(gnutls_x509_crq_t crq)
616
0
{
617
0
  uint8_t version[8];
618
0
  int len, result;
619
620
0
  if (crq == NULL) {
621
0
    gnutls_assert();
622
0
    return GNUTLS_E_INVALID_REQUEST;
623
0
  }
624
625
0
  len = sizeof(version);
626
0
  if ((result =
627
0
       asn1_read_value(crq->crq, "certificationRequestInfo.version",
628
0
           version, &len)) != ASN1_SUCCESS) {
629
630
0
    if (result == ASN1_ELEMENT_NOT_FOUND)
631
0
      return 1; /* the DEFAULT version */
632
0
    gnutls_assert();
633
0
    return _gnutls_asn2err(result);
634
0
  }
635
636
0
  return (int)version[0] + 1;
637
0
}
638
639
/**
640
 * gnutls_x509_crq_set_key:
641
 * @crq: should contain a #gnutls_x509_crq_t type
642
 * @key: holds a private key
643
 *
644
 * This function will set the public parameters from the given private
645
 * key to the request.  
646
 *
647
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
648
 *   negative error value.
649
 **/
650
int gnutls_x509_crq_set_key(gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
651
0
{
652
0
  int result;
653
654
0
  if (crq == NULL) {
655
0
    gnutls_assert();
656
0
    return GNUTLS_E_INVALID_REQUEST;
657
0
  }
658
659
0
  result = _gnutls_x509_encode_and_copy_PKI_params
660
0
      (crq->crq, "certificationRequestInfo.subjectPKInfo", &key->params);
661
662
0
  if (result < 0) {
663
0
    gnutls_assert();
664
0
    return result;
665
0
  }
666
667
0
  return 0;
668
0
}
669
670
/**
671
 * gnutls_x509_crq_get_key_rsa_raw:
672
 * @crq: Holds the certificate
673
 * @m: will hold the modulus
674
 * @e: will hold the public exponent
675
 *
676
 * This function will export the RSA public key's parameters found in
677
 * the given structure.  The new parameters will be allocated using
678
 * gnutls_malloc() and will be stored in the appropriate datum.
679
 *
680
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
681
 *   negative error value.
682
 *
683
 * Since: 2.8.0
684
 **/
685
int
686
gnutls_x509_crq_get_key_rsa_raw(gnutls_x509_crq_t crq,
687
        gnutls_datum_t * m, gnutls_datum_t * e)
688
0
{
689
0
  int ret;
690
0
  gnutls_pk_params_st params;
691
692
0
  gnutls_pk_params_init(&params);
693
694
0
  if (crq == NULL) {
695
0
    gnutls_assert();
696
0
    return GNUTLS_E_INVALID_REQUEST;
697
0
  }
698
699
0
  ret = gnutls_x509_crq_get_pk_algorithm(crq, NULL);
700
0
  if (ret != GNUTLS_PK_RSA) {
701
0
    gnutls_assert();
702
0
    return GNUTLS_E_INVALID_REQUEST;
703
0
  }
704
705
0
  ret = _gnutls_x509_crq_get_mpis(crq, &params);
706
0
  if (ret < 0) {
707
0
    gnutls_assert();
708
0
    return ret;
709
0
  }
710
711
0
  ret = _gnutls_mpi_dprint(params.params[0], m);
712
0
  if (ret < 0) {
713
0
    gnutls_assert();
714
0
    goto cleanup;
715
0
  }
716
717
0
  ret = _gnutls_mpi_dprint(params.params[1], e);
718
0
  if (ret < 0) {
719
0
    gnutls_assert();
720
0
    _gnutls_free_datum(m);
721
0
    goto cleanup;
722
0
  }
723
724
0
  ret = 0;
725
726
0
 cleanup:
727
0
  gnutls_pk_params_release(&params);
728
0
  return ret;
729
0
}
730
731
/**
732
 * gnutls_x509_crq_set_key_rsa_raw:
733
 * @crq: should contain a #gnutls_x509_crq_t type
734
 * @m: holds the modulus
735
 * @e: holds the public exponent
736
 *
737
 * This function will set the public parameters from the given private
738
 * key to the request. Only RSA keys are currently supported.
739
 *
740
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
741
 *   negative error value.
742
 *
743
 * Since: 2.6.0
744
 **/
745
int
746
gnutls_x509_crq_set_key_rsa_raw(gnutls_x509_crq_t crq,
747
        const gnutls_datum_t * m,
748
        const gnutls_datum_t * e)
749
0
{
750
0
  int result, ret;
751
0
  size_t siz = 0;
752
0
  gnutls_pk_params_st temp_params;
753
754
0
  gnutls_pk_params_init(&temp_params);
755
756
0
  if (crq == NULL) {
757
0
    gnutls_assert();
758
0
    return GNUTLS_E_INVALID_REQUEST;
759
0
  }
760
761
0
  memset(&temp_params, 0, sizeof(temp_params));
762
763
0
  siz = m->size;
764
0
  if (_gnutls_mpi_init_scan_nz(&temp_params.params[0], m->data, siz)) {
765
0
    gnutls_assert();
766
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
767
0
    goto error;
768
0
  }
769
770
0
  siz = e->size;
771
0
  if (_gnutls_mpi_init_scan_nz(&temp_params.params[1], e->data, siz)) {
772
0
    gnutls_assert();
773
0
    ret = GNUTLS_E_MPI_SCAN_FAILED;
774
0
    goto error;
775
0
  }
776
777
0
  temp_params.params_nr = RSA_PUBLIC_PARAMS;
778
0
  temp_params.algo = GNUTLS_PK_RSA;
779
780
0
  result = _gnutls_x509_encode_and_copy_PKI_params
781
0
      (crq->crq, "certificationRequestInfo.subjectPKInfo", &temp_params);
782
783
0
  if (result < 0) {
784
0
    gnutls_assert();
785
0
    ret = result;
786
0
    goto error;
787
0
  }
788
789
0
  ret = 0;
790
791
0
 error:
792
0
  gnutls_pk_params_release(&temp_params);
793
0
  return ret;
794
0
}
795
796
/**
797
 * gnutls_x509_crq_set_challenge_password:
798
 * @crq: should contain a #gnutls_x509_crq_t type
799
 * @pass: holds a (0)-terminated password
800
 *
801
 * This function will set a challenge password to be used when
802
 * revoking the request.
803
 *
804
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
805
 *   negative error value.
806
 **/
807
int
808
gnutls_x509_crq_set_challenge_password(gnutls_x509_crq_t crq, const char *pass)
809
0
{
810
0
  int result;
811
0
  char *password = NULL;
812
813
0
  if (crq == NULL || pass == NULL) {
814
0
    gnutls_assert();
815
0
    return GNUTLS_E_INVALID_REQUEST;
816
0
  }
817
818
  /* Add the attribute.
819
   */
820
0
  result =
821
0
      asn1_write_value(crq->crq,
822
0
           "certificationRequestInfo.attributes", "NEW", 1);
823
0
  if (result != ASN1_SUCCESS) {
824
0
    gnutls_assert();
825
0
    return _gnutls_asn2err(result);
826
0
  }
827
828
0
  if (pass) {
829
0
    gnutls_datum_t out;
830
0
    result =
831
0
        _gnutls_utf8_password_normalize(pass, strlen(pass), &out,
832
0
                0);
833
0
    if (result < 0)
834
0
      return gnutls_assert_val(result);
835
836
0
    password = (char *)out.data;
837
0
  }
838
839
0
  assert(password != NULL);
840
841
0
  result = _gnutls_x509_encode_and_write_attribute
842
0
      ("1.2.840.113549.1.9.7", crq->crq,
843
0
       "certificationRequestInfo.attributes.?LAST", password,
844
0
       strlen(password), 1);
845
0
  if (result < 0) {
846
0
    gnutls_assert();
847
0
    goto cleanup;
848
0
  }
849
850
0
  result = 0;
851
852
0
 cleanup:
853
0
  gnutls_free(password);
854
0
  return result;
855
0
}
856
857
/**
858
 * gnutls_x509_crq_sign2:
859
 * @crq: should contain a #gnutls_x509_crq_t type
860
 * @key: holds a private key
861
 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA256
862
 * @flags: must be 0
863
 *
864
 * This function will sign the certificate request with a private key.
865
 * This must be the same key as the one used in
866
 * gnutls_x509_crt_set_key() since a certificate request is self
867
 * signed.
868
 *
869
 * This must be the last step in a certificate request generation
870
 * since all the previously set parameters are now signed.
871
 *
872
 * A known limitation of this function is, that a newly-signed request will not
873
 * be fully functional (e.g., for signature verification), until it
874
 * is exported an re-imported.
875
 *
876
 * After GnuTLS 3.6.1 the value of @dig may be %GNUTLS_DIG_UNKNOWN,
877
 * and in that case, a suitable but reasonable for the key algorithm will be selected.
878
 *
879
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
880
 *   %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
881
 *   information in the certificate request (e.g., the version using
882
 *   gnutls_x509_crq_set_version()).
883
 *
884
 **/
885
int
886
gnutls_x509_crq_sign2(gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
887
          gnutls_digest_algorithm_t dig, unsigned int flags)
888
0
{
889
0
  int result;
890
0
  gnutls_privkey_t privkey;
891
892
0
  if (crq == NULL) {
893
0
    gnutls_assert();
894
0
    return GNUTLS_E_INVALID_REQUEST;
895
0
  }
896
897
0
  result = gnutls_privkey_init(&privkey);
898
0
  if (result < 0) {
899
0
    gnutls_assert();
900
0
    return result;
901
0
  }
902
903
0
  result = gnutls_privkey_import_x509(privkey, key, 0);
904
0
  if (result < 0) {
905
0
    gnutls_assert();
906
0
    goto fail;
907
0
  }
908
909
0
  result = gnutls_x509_crq_privkey_sign(crq, privkey, dig, flags);
910
0
  if (result < 0) {
911
0
    gnutls_assert();
912
0
    goto fail;
913
0
  }
914
915
0
  result = 0;
916
917
0
 fail:
918
0
  gnutls_privkey_deinit(privkey);
919
920
0
  return result;
921
0
}
922
923
/**
924
 * gnutls_x509_crq_sign:
925
 * @crq: should contain a #gnutls_x509_crq_t type
926
 * @key: holds a private key
927
 *
928
 * This function is the same a gnutls_x509_crq_sign2() with no flags,
929
 * and an appropriate hash algorithm. The hash algorithm used may
930
 * vary between versions of GnuTLS, and it is tied to the security
931
 * level of the issuer's public key.
932
 *
933
 * A known limitation of this function is, that a newly-signed request will not
934
 * be fully functional (e.g., for signature verification), until it
935
 * is exported an re-imported.
936
 *
937
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
938
 *   negative error value.
939
 */
940
int gnutls_x509_crq_sign(gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
941
0
{
942
0
  return gnutls_x509_crq_sign2(crq, key, 0, 0);
943
0
}
944
945
/**
946
 * gnutls_x509_crq_export:
947
 * @crq: should contain a #gnutls_x509_crq_t type
948
 * @format: the format of output params. One of PEM or DER.
949
 * @output_data: will contain a certificate request PEM or DER encoded
950
 * @output_data_size: holds the size of output_data (and will be
951
 *   replaced by the actual size of parameters)
952
 *
953
 * This function will export the certificate request to a PEM or DER
954
 * encoded PKCS10 structure.
955
 *
956
 * If the buffer provided is not long enough to hold the output, then
957
 * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
958
 * *@output_data_size will be updated.
959
 *
960
 * If the structure is PEM encoded, it will have a header of "BEGIN
961
 * NEW CERTIFICATE REQUEST".
962
 *
963
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
964
 *   negative error value.
965
 **/
966
int
967
gnutls_x509_crq_export(gnutls_x509_crq_t crq,
968
           gnutls_x509_crt_fmt_t format, void *output_data,
969
           size_t *output_data_size)
970
0
{
971
0
  if (crq == NULL) {
972
0
    gnutls_assert();
973
0
    return GNUTLS_E_INVALID_REQUEST;
974
0
  }
975
976
0
  return _gnutls_x509_export_int(crq->crq, format, PEM_CRQ,
977
0
               output_data, output_data_size);
978
0
}
979
980
/**
981
 * gnutls_x509_crq_export2:
982
 * @crq: should contain a #gnutls_x509_crq_t type
983
 * @format: the format of output params. One of PEM or DER.
984
 * @out: will contain a certificate request PEM or DER encoded
985
 *
986
 * This function will export the certificate request to a PEM or DER
987
 * encoded PKCS10 structure.
988
 *
989
 * The output buffer is allocated using gnutls_malloc().
990
 *
991
 * If the structure is PEM encoded, it will have a header of "BEGIN
992
 * NEW CERTIFICATE REQUEST".
993
 *
994
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
995
 *   negative error value.
996
 *
997
 * Since 3.1.3
998
 **/
999
int
1000
gnutls_x509_crq_export2(gnutls_x509_crq_t crq,
1001
      gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
1002
0
{
1003
0
  if (crq == NULL) {
1004
0
    gnutls_assert();
1005
0
    return GNUTLS_E_INVALID_REQUEST;
1006
0
  }
1007
1008
0
  return _gnutls_x509_export_int2(crq->crq, format, PEM_CRQ, out);
1009
0
}
1010
1011
/**
1012
 * gnutls_x509_crq_get_pk_algorithm:
1013
 * @crq: should contain a #gnutls_x509_crq_t type
1014
 * @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
1015
 *
1016
 * This function will return the public key algorithm of a PKCS#10
1017
 * certificate request.
1018
 *
1019
 * If bits is non-%NULL, it should have enough size to hold the
1020
 * parameters size in bits.  For RSA the bits returned is the modulus.
1021
 * For DSA the bits returned are of the public exponent.
1022
 *
1023
 * Returns: a member of the #gnutls_pk_algorithm_t enumeration on
1024
 *   success, or a negative error code on error.
1025
 **/
1026
int gnutls_x509_crq_get_pk_algorithm(gnutls_x509_crq_t crq, unsigned int *bits)
1027
0
{
1028
0
  int result;
1029
1030
0
  if (crq == NULL) {
1031
0
    gnutls_assert();
1032
0
    return GNUTLS_E_INVALID_REQUEST;
1033
0
  }
1034
1035
0
  result = _gnutls_x509_get_pk_algorithm
1036
0
      (crq->crq, "certificationRequestInfo.subjectPKInfo", NULL, bits);
1037
0
  if (result < 0) {
1038
0
    gnutls_assert();
1039
0
    return result;
1040
0
  }
1041
1042
0
  return result;
1043
0
}
1044
1045
/**
1046
 * gnutls_x509_crq_get_spki;
1047
 * @crq: should contain a #gnutls_x509_crq_t type
1048
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
1049
 * @flags: must be zero
1050
 *
1051
 * This function will return the public key information of a PKCS#10
1052
 * certificate request. The provided @spki must be initialized.
1053
 *
1054
 * Returns: Zero on success, or a negative error code on error.
1055
 **/
1056
int
1057
gnutls_x509_crq_get_spki(gnutls_x509_crq_t crq,
1058
       gnutls_x509_spki_t spki, unsigned int flags)
1059
0
{
1060
0
  int result;
1061
0
  gnutls_x509_spki_st params;
1062
1063
0
  if (crq == NULL) {
1064
0
    gnutls_assert();
1065
0
    return GNUTLS_E_INVALID_REQUEST;
1066
0
  }
1067
1068
0
  memset(&params, 0, sizeof(params));
1069
1070
0
  spki->pk = gnutls_x509_crq_get_pk_algorithm(crq, NULL);
1071
1072
0
  result = _gnutls_x509_crq_read_spki_params(crq, &params);
1073
0
  if (result < 0) {
1074
0
    gnutls_assert();
1075
0
    return result;
1076
0
  }
1077
1078
0
  if (params.pk == GNUTLS_PK_UNKNOWN)
1079
0
    return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
1080
1081
0
  spki->rsa_pss_dig = params.rsa_pss_dig;
1082
0
  spki->salt_size = params.salt_size;
1083
1084
0
  return 0;
1085
0
}
1086
1087
/**
1088
 * gnutls_x509_crq_get_signature_oid:
1089
 * @crq: should contain a #gnutls_x509_crq_t type
1090
 * @oid: a pointer to a buffer to hold the OID (may be null)
1091
 * @oid_size: initially holds the size of @oid
1092
 *
1093
 * This function will return the OID of the signature algorithm
1094
 * that has been used to sign this certificate request. This function
1095
 * is useful in the case gnutls_x509_crq_get_signature_algorithm()
1096
 * returned %GNUTLS_SIGN_UNKNOWN.
1097
 *
1098
 * Returns: zero or a negative error code on error.
1099
 *
1100
 * Since: 3.5.0
1101
 **/
1102
int gnutls_x509_crq_get_signature_oid(gnutls_x509_crq_t crq, char *oid,
1103
              size_t *oid_size)
1104
0
{
1105
0
  char str[MAX_OID_SIZE];
1106
0
  int len, result, ret;
1107
0
  gnutls_datum_t out;
1108
1109
0
  len = sizeof(str);
1110
0
  result =
1111
0
      asn1_read_value(crq->crq, "signatureAlgorithm.algorithm", str,
1112
0
          &len);
1113
0
  if (result != ASN1_SUCCESS) {
1114
0
    gnutls_assert();
1115
0
    return _gnutls_asn2err(result);
1116
0
  }
1117
1118
0
  out.data = (void *)str;
1119
0
  out.size = len;
1120
1121
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1122
0
  if (ret < 0) {
1123
0
    gnutls_assert();
1124
0
    return ret;
1125
0
  }
1126
1127
0
  return 0;
1128
0
}
1129
1130
/**
1131
 * gnutls_x509_crq_get_pk_oid:
1132
 * @crq: should contain a #gnutls_x509_crq_t type
1133
 * @oid: a pointer to a buffer to hold the OID (may be null)
1134
 * @oid_size: initially holds the size of @oid
1135
 *
1136
 * This function will return the OID of the public key algorithm
1137
 * on that certificate request. This function
1138
 * is useful in the case gnutls_x509_crq_get_pk_algorithm()
1139
 * returned %GNUTLS_PK_UNKNOWN.
1140
 *
1141
 * Returns: zero or a negative error code on error.
1142
 *
1143
 * Since: 3.5.0
1144
 **/
1145
int gnutls_x509_crq_get_pk_oid(gnutls_x509_crq_t crq, char *oid,
1146
             size_t *oid_size)
1147
0
{
1148
0
  char str[MAX_OID_SIZE];
1149
0
  int len, result, ret;
1150
0
  gnutls_datum_t out;
1151
1152
0
  len = sizeof(str);
1153
0
  result =
1154
0
      asn1_read_value(crq->crq,
1155
0
          "certificationRequestInfo.subjectPKInfo.algorithm.algorithm",
1156
0
          str, &len);
1157
0
  if (result != ASN1_SUCCESS) {
1158
0
    gnutls_assert();
1159
0
    return _gnutls_asn2err(result);
1160
0
  }
1161
1162
0
  out.data = (void *)str;
1163
0
  out.size = len;
1164
1165
0
  ret = _gnutls_copy_string(&out, (void *)oid, oid_size);
1166
0
  if (ret < 0) {
1167
0
    gnutls_assert();
1168
0
    return ret;
1169
0
  }
1170
1171
0
  return 0;
1172
0
}
1173
1174
/**
1175
 * gnutls_x509_crq_get_attribute_info:
1176
 * @crq: should contain a #gnutls_x509_crq_t type
1177
 * @indx: Specifies which attribute number to get. Use (0) to get the first one.
1178
 * @oid: a pointer to a structure to hold the OID
1179
 * @sizeof_oid: initially holds the maximum size of @oid, on return
1180
 *   holds actual size of @oid.
1181
 *
1182
 * This function will return the requested attribute OID in the
1183
 * certificate, and the critical flag for it.  The attribute OID will
1184
 * be stored as a string in the provided buffer.  Use
1185
 * gnutls_x509_crq_get_attribute_data() to extract the data.
1186
 *
1187
 * If the buffer provided is not long enough to hold the output, then
1188
 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1189
 * returned.
1190
 *
1191
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1192
 *   negative error code in case of an error.  If your have reached the
1193
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1194
 *   will be returned.
1195
 *
1196
 * Since: 2.8.0
1197
 **/
1198
int
1199
gnutls_x509_crq_get_attribute_info(gnutls_x509_crq_t crq, unsigned indx,
1200
           void *oid, size_t *sizeof_oid)
1201
0
{
1202
0
  int result;
1203
0
  char name[MAX_NAME_SIZE];
1204
0
  int len;
1205
1206
0
  if (!crq) {
1207
0
    gnutls_assert();
1208
0
    return GNUTLS_E_INVALID_REQUEST;
1209
0
  }
1210
1211
0
  snprintf(name, sizeof(name),
1212
0
     "certificationRequestInfo.attributes.?%u.type", indx + 1);
1213
1214
0
  len = *sizeof_oid;
1215
0
  result = asn1_read_value(crq->crq, name, oid, &len);
1216
0
  *sizeof_oid = len;
1217
1218
0
  if (result == ASN1_ELEMENT_NOT_FOUND)
1219
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1220
0
  else if (result < 0) {
1221
0
    gnutls_assert();
1222
0
    return _gnutls_asn2err(result);
1223
0
  }
1224
1225
0
  return 0;
1226
1227
0
}
1228
1229
/**
1230
 * gnutls_x509_crq_get_attribute_data:
1231
 * @crq: should contain a #gnutls_x509_crq_t type
1232
 * @indx: Specifies which attribute number to get. Use (0) to get the first one.
1233
 * @data: a pointer to a structure to hold the data (may be null)
1234
 * @sizeof_data: initially holds the size of @oid
1235
 *
1236
 * This function will return the requested attribute data in the
1237
 * certificate request.  The attribute data will be stored as a string in the
1238
 * provided buffer.
1239
 *
1240
 * Use gnutls_x509_crq_get_attribute_info() to extract the OID.
1241
 * Use gnutls_x509_crq_get_attribute_by_oid() instead,
1242
 * if you want to get data indexed by the attribute OID rather than
1243
 * sequence.
1244
 *
1245
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1246
 *   negative error code in case of an error.  If your have reached the
1247
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1248
 *   will be returned.
1249
 *
1250
 * Since: 2.8.0
1251
 **/
1252
int
1253
gnutls_x509_crq_get_attribute_data(gnutls_x509_crq_t crq, unsigned indx,
1254
           void *data, size_t *sizeof_data)
1255
0
{
1256
0
  int result, len;
1257
0
  char name[MAX_NAME_SIZE];
1258
1259
0
  if (!crq) {
1260
0
    gnutls_assert();
1261
0
    return GNUTLS_E_INVALID_REQUEST;
1262
0
  }
1263
1264
0
  snprintf(name, sizeof(name),
1265
0
     "certificationRequestInfo.attributes.?%u.values.?1", indx + 1);
1266
1267
0
  len = *sizeof_data;
1268
0
  result = asn1_read_value(crq->crq, name, data, &len);
1269
0
  *sizeof_data = len;
1270
1271
0
  if (result == ASN1_ELEMENT_NOT_FOUND)
1272
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1273
0
  else if (result < 0) {
1274
0
    gnutls_assert();
1275
0
    return _gnutls_asn2err(result);
1276
0
  }
1277
1278
0
  return 0;
1279
0
}
1280
1281
/**
1282
 * gnutls_x509_crq_get_extension_info:
1283
 * @crq: should contain a #gnutls_x509_crq_t type
1284
 * @indx: Specifies which extension number to get. Use (0) to get the first one.
1285
 * @oid: a pointer to store the OID
1286
 * @sizeof_oid: initially holds the maximum size of @oid, on return
1287
 *   holds actual size of @oid.
1288
 * @critical: output variable with critical flag, may be NULL.
1289
 *
1290
 * This function will return the requested extension OID in the
1291
 * certificate, and the critical flag for it.  The extension OID will
1292
 * be stored as a string in the provided buffer.  Use
1293
 * gnutls_x509_crq_get_extension_data() to extract the data.
1294
 *
1295
 * If the buffer provided is not long enough to hold the output, then
1296
 * *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
1297
 * returned.
1298
 *
1299
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1300
 *   negative error code in case of an error.  If your have reached the
1301
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1302
 *   will be returned.
1303
 *
1304
 * Since: 2.8.0
1305
 **/
1306
int
1307
gnutls_x509_crq_get_extension_info(gnutls_x509_crq_t crq, unsigned indx,
1308
           void *oid, size_t *sizeof_oid,
1309
           unsigned int *critical)
1310
0
{
1311
0
  int result;
1312
0
  char str_critical[10];
1313
0
  char name[MAX_NAME_SIZE];
1314
0
  char *extensions = NULL;
1315
0
  size_t extensions_size = 0;
1316
0
  asn1_node c2;
1317
0
  int len;
1318
1319
0
  if (!crq) {
1320
0
    gnutls_assert();
1321
0
    return GNUTLS_E_INVALID_REQUEST;
1322
0
  }
1323
1324
  /* read extensionRequest */
1325
0
  result =
1326
0
      gnutls_x509_crq_get_attribute_by_oid(crq,
1327
0
             "1.2.840.113549.1.9.14",
1328
0
             0, NULL, &extensions_size);
1329
0
  if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
1330
0
    extensions = gnutls_malloc(extensions_size);
1331
0
    if (extensions == NULL) {
1332
0
      gnutls_assert();
1333
0
      return GNUTLS_E_MEMORY_ERROR;
1334
0
    }
1335
1336
0
    result = gnutls_x509_crq_get_attribute_by_oid(crq,
1337
0
                    "1.2.840.113549.1.9.14",
1338
0
                    0,
1339
0
                    extensions,
1340
0
                    &extensions_size);
1341
0
  }
1342
0
  if (result < 0) {
1343
0
    gnutls_assert();
1344
0
    goto out;
1345
0
  }
1346
1347
0
  result =
1348
0
      asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions", &c2);
1349
0
  if (result != ASN1_SUCCESS) {
1350
0
    gnutls_assert();
1351
0
    result = _gnutls_asn2err(result);
1352
0
    goto out;
1353
0
  }
1354
1355
0
  result =
1356
0
      _asn1_strict_der_decode(&c2, extensions, extensions_size, NULL);
1357
0
  if (result != ASN1_SUCCESS) {
1358
0
    gnutls_assert();
1359
0
    asn1_delete_structure(&c2);
1360
0
    result = _gnutls_asn2err(result);
1361
0
    goto out;
1362
0
  }
1363
1364
0
  snprintf(name, sizeof(name), "?%u.extnID", indx + 1);
1365
1366
0
  len = *sizeof_oid;
1367
0
  result = asn1_read_value(c2, name, oid, &len);
1368
0
  *sizeof_oid = len;
1369
1370
0
  if (result == ASN1_ELEMENT_NOT_FOUND) {
1371
0
    asn1_delete_structure(&c2);
1372
0
    result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1373
0
    goto out;
1374
0
  } else if (result < 0) {
1375
0
    gnutls_assert();
1376
0
    asn1_delete_structure(&c2);
1377
0
    result = _gnutls_asn2err(result);
1378
0
    goto out;
1379
0
  }
1380
1381
0
  snprintf(name, sizeof(name), "?%u.critical", indx + 1);
1382
0
  len = sizeof(str_critical);
1383
0
  result = asn1_read_value(c2, name, str_critical, &len);
1384
1385
0
  asn1_delete_structure(&c2);
1386
1387
0
  if (result < 0) {
1388
0
    gnutls_assert();
1389
0
    result = _gnutls_asn2err(result);
1390
0
    goto out;
1391
0
  }
1392
1393
0
  if (critical) {
1394
0
    if (str_critical[0] == 'T')
1395
0
      *critical = 1;
1396
0
    else
1397
0
      *critical = 0;
1398
0
  }
1399
1400
0
  result = 0;
1401
1402
0
 out:
1403
0
  gnutls_free(extensions);
1404
0
  return result;
1405
0
}
1406
1407
/**
1408
 * gnutls_x509_crq_get_extension_data:
1409
 * @crq: should contain a #gnutls_x509_crq_t type
1410
 * @indx: Specifies which extension number to get. Use (0) to get the first one.
1411
 * @data: a pointer to a structure to hold the data (may be null)
1412
 * @sizeof_data: initially holds the size of @oid
1413
 *
1414
 * This function will return the requested extension data in the
1415
 * certificate.  The extension data will be stored as a string in the
1416
 * provided buffer.
1417
 *
1418
 * Use gnutls_x509_crq_get_extension_info() to extract the OID and
1419
 * critical flag.  Use gnutls_x509_crq_get_extension_by_oid() instead,
1420
 * if you want to get data indexed by the extension OID rather than
1421
 * sequence.
1422
 *
1423
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1424
 *   negative error code in case of an error.  If your have reached the
1425
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1426
 *   will be returned.
1427
 *
1428
 * Since: 2.8.0
1429
 **/
1430
int
1431
gnutls_x509_crq_get_extension_data(gnutls_x509_crq_t crq, unsigned indx,
1432
           void *data, size_t *sizeof_data)
1433
0
{
1434
0
  int ret;
1435
0
  gnutls_datum_t raw;
1436
1437
0
  ret = gnutls_x509_crq_get_extension_data2(crq, indx, &raw);
1438
0
  if (ret < 0)
1439
0
    return gnutls_assert_val(ret);
1440
1441
0
  ret = _gnutls_copy_data(&raw, data, sizeof_data);
1442
0
  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && data == NULL)
1443
0
    ret = 0;
1444
0
  gnutls_free(raw.data);
1445
0
  return ret;
1446
0
}
1447
1448
/**
1449
 * gnutls_x509_crq_get_extension_data2:
1450
 * @crq: should contain a #gnutls_x509_crq_t type
1451
 * @extension_id: An X.509 extension OID.
1452
 * @indx: Specifies which extension OID to read. Use (0) to get the first one.
1453
 * @data: will contain the extension DER-encoded data
1454
 *
1455
 * This function will return the requested extension data in the
1456
 * certificate request.  The extension data will be allocated using
1457
 * gnutls_malloc().
1458
 *
1459
 * Use gnutls_x509_crq_get_extension_info() to extract the OID.
1460
 *
1461
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
1462
 *   otherwise a negative error code is returned.  If you have reached the
1463
 *   last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1464
 *   will be returned.
1465
 *
1466
 * Since: 3.3.0
1467
 **/
1468
int
1469
gnutls_x509_crq_get_extension_data2(gnutls_x509_crq_t crq,
1470
            unsigned indx, gnutls_datum_t * data)
1471
0
{
1472
0
  int ret, result;
1473
0
  char name[MAX_NAME_SIZE];
1474
0
  unsigned char *extensions = NULL;
1475
0
  size_t extensions_size = 0;
1476
0
  asn1_node c2 = NULL;
1477
1478
0
  if (!crq) {
1479
0
    gnutls_assert();
1480
0
    return GNUTLS_E_INVALID_REQUEST;
1481
0
  }
1482
1483
  /* read extensionRequest */
1484
0
  ret =
1485
0
      gnutls_x509_crq_get_attribute_by_oid(crq,
1486
0
             "1.2.840.113549.1.9.14",
1487
0
             0, NULL, &extensions_size);
1488
0
  if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
1489
0
    gnutls_assert();
1490
0
    if (ret == 0)
1491
0
      return GNUTLS_E_INTERNAL_ERROR;
1492
0
    return ret;
1493
0
  }
1494
1495
0
  extensions = gnutls_malloc(extensions_size);
1496
0
  if (extensions == NULL) {
1497
0
    gnutls_assert();
1498
0
    return GNUTLS_E_MEMORY_ERROR;
1499
0
  }
1500
1501
0
  ret =
1502
0
      gnutls_x509_crq_get_attribute_by_oid(crq,
1503
0
             "1.2.840.113549.1.9.14",
1504
0
             0, extensions,
1505
0
             &extensions_size);
1506
0
  if (ret < 0) {
1507
0
    gnutls_assert();
1508
0
    goto cleanup;
1509
0
  }
1510
1511
0
  result =
1512
0
      asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions", &c2);
1513
0
  if (result != ASN1_SUCCESS) {
1514
0
    gnutls_assert();
1515
0
    ret = _gnutls_asn2err(result);
1516
0
    goto cleanup;
1517
0
  }
1518
1519
0
  result =
1520
0
      _asn1_strict_der_decode(&c2, extensions, extensions_size, NULL);
1521
0
  if (result != ASN1_SUCCESS) {
1522
0
    gnutls_assert();
1523
0
    ret = _gnutls_asn2err(result);
1524
0
    goto cleanup;
1525
0
  }
1526
1527
0
  snprintf(name, sizeof(name), "?%u.extnValue", indx + 1);
1528
1529
0
  ret = _gnutls_x509_read_value(c2, name, data);
1530
0
  if (ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
1531
0
    ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1532
0
    goto cleanup;
1533
0
  } else if (ret < 0) {
1534
0
    gnutls_assert();
1535
0
    goto cleanup;
1536
0
  }
1537
1538
0
  ret = 0;
1539
0
 cleanup:
1540
0
  asn1_delete_structure(&c2);
1541
0
  gnutls_free(extensions);
1542
0
  return ret;
1543
0
}
1544
1545
/**
1546
 * gnutls_x509_crq_get_key_usage:
1547
 * @crq: should contain a #gnutls_x509_crq_t type
1548
 * @key_usage: where the key usage bits will be stored
1549
 * @critical: will be non-zero if the extension is marked as critical
1550
 *
1551
 * This function will return certificate's key usage, by reading the
1552
 * keyUsage X.509 extension (2.5.29.15).  The key usage value will
1553
 * ORed values of the: %GNUTLS_KEY_DIGITAL_SIGNATURE,
1554
 * %GNUTLS_KEY_NON_REPUDIATION, %GNUTLS_KEY_KEY_ENCIPHERMENT,
1555
 * %GNUTLS_KEY_DATA_ENCIPHERMENT, %GNUTLS_KEY_KEY_AGREEMENT,
1556
 * %GNUTLS_KEY_KEY_CERT_SIGN, %GNUTLS_KEY_CRL_SIGN,
1557
 * %GNUTLS_KEY_ENCIPHER_ONLY, %GNUTLS_KEY_DECIPHER_ONLY.
1558
 *
1559
 * Returns: the certificate key usage, or a negative error code in case of
1560
 *   parsing error.  If the certificate does not contain the keyUsage
1561
 *   extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be
1562
 *   returned.
1563
 *
1564
 * Since: 2.8.0
1565
 **/
1566
int
1567
gnutls_x509_crq_get_key_usage(gnutls_x509_crq_t crq,
1568
            unsigned int *key_usage, unsigned int *critical)
1569
0
{
1570
0
  int result;
1571
0
  uint8_t buf[128];
1572
0
  size_t buf_size = sizeof(buf);
1573
0
  gnutls_datum_t bd;
1574
1575
0
  if (crq == NULL) {
1576
0
    gnutls_assert();
1577
0
    return GNUTLS_E_INVALID_REQUEST;
1578
0
  }
1579
1580
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.15", 0,
1581
0
                  buf, &buf_size, critical);
1582
0
  if (result < 0) {
1583
0
    gnutls_assert();
1584
0
    return result;
1585
0
  }
1586
1587
0
  bd.data = buf;
1588
0
  bd.size = buf_size;
1589
0
  result = gnutls_x509_ext_import_key_usage(&bd, key_usage);
1590
0
  if (result < 0) {
1591
0
    gnutls_assert();
1592
0
    return result;
1593
0
  }
1594
1595
0
  return 0;
1596
0
}
1597
1598
/**
1599
 * gnutls_x509_crq_get_basic_constraints:
1600
 * @crq: should contain a #gnutls_x509_crq_t type
1601
 * @critical: will be non-zero if the extension is marked as critical
1602
 * @ca: pointer to output integer indicating CA status, may be NULL,
1603
 *   value is 1 if the certificate CA flag is set, 0 otherwise.
1604
 * @pathlen: pointer to output integer indicating path length (may be
1605
 *   NULL), non-negative error codes indicate a present pathLenConstraint
1606
 *   field and the actual value, -1 indicate that the field is absent.
1607
 *
1608
 * This function will read the certificate's basic constraints, and
1609
 * return the certificates CA status.  It reads the basicConstraints
1610
 * X.509 extension (2.5.29.19).
1611
 *
1612
 * Returns: If the certificate is a CA a positive value will be
1613
 *   returned, or (0) if the certificate does not have CA flag set.
1614
 *   A negative error code may be returned in case of errors.  If the
1615
 *   certificate does not contain the basicConstraints extension
1616
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1617
 *
1618
 * Since: 2.8.0
1619
 **/
1620
int
1621
gnutls_x509_crq_get_basic_constraints(gnutls_x509_crq_t crq,
1622
              unsigned int *critical,
1623
              unsigned int *ca, int *pathlen)
1624
0
{
1625
0
  int result;
1626
0
  unsigned int tmp_ca;
1627
0
  uint8_t buf[256];
1628
0
  size_t buf_size = sizeof(buf);
1629
0
  gnutls_datum_t bd;
1630
1631
0
  if (crq == NULL) {
1632
0
    gnutls_assert();
1633
0
    return GNUTLS_E_INVALID_REQUEST;
1634
0
  }
1635
1636
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.19", 0,
1637
0
                  buf, &buf_size, critical);
1638
0
  if (result < 0) {
1639
0
    gnutls_assert();
1640
0
    return result;
1641
0
  }
1642
1643
0
  bd.data = buf;
1644
0
  bd.size = buf_size;
1645
0
  result =
1646
0
      gnutls_x509_ext_import_basic_constraints(&bd, &tmp_ca, pathlen);
1647
0
  if (ca)
1648
0
    *ca = tmp_ca;
1649
1650
0
  if (result < 0) {
1651
0
    gnutls_assert();
1652
0
    return result;
1653
0
  }
1654
1655
0
  return tmp_ca;
1656
0
}
1657
1658
static int
1659
get_subject_alt_name(gnutls_x509_crq_t crq,
1660
         unsigned int seq, void *ret,
1661
         size_t *ret_size, unsigned int *ret_type,
1662
         unsigned int *critical, int othername_oid)
1663
0
{
1664
0
  int result;
1665
0
  asn1_node c2 = NULL;
1666
0
  gnutls_x509_subject_alt_name_t type;
1667
0
  gnutls_datum_t dnsname = { NULL, 0 };
1668
0
  size_t dns_size = 0;
1669
1670
0
  if (crq == NULL) {
1671
0
    gnutls_assert();
1672
0
    return GNUTLS_E_INVALID_REQUEST;
1673
0
  }
1674
1675
0
  if (ret)
1676
0
    memset(ret, 0, *ret_size);
1677
0
  else
1678
0
    *ret_size = 0;
1679
1680
  /* Extract extension.
1681
   */
1682
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17", 0,
1683
0
                  NULL, &dns_size,
1684
0
                  critical);
1685
0
  if (result < 0) {
1686
0
    gnutls_assert();
1687
0
    return result;
1688
0
  }
1689
1690
0
  dnsname.size = dns_size;
1691
0
  dnsname.data = gnutls_malloc(dnsname.size);
1692
0
  if (dnsname.data == NULL) {
1693
0
    gnutls_assert();
1694
0
    return GNUTLS_E_MEMORY_ERROR;
1695
0
  }
1696
1697
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17", 0,
1698
0
                  dnsname.data,
1699
0
                  &dns_size, critical);
1700
0
  if (result < 0) {
1701
0
    gnutls_assert();
1702
0
    gnutls_free(dnsname.data);
1703
0
    return result;
1704
0
  }
1705
1706
0
  result = asn1_create_element
1707
0
      (_gnutls_get_pkix(), "PKIX1.SubjectAltName", &c2);
1708
0
  if (result != ASN1_SUCCESS) {
1709
0
    gnutls_assert();
1710
0
    gnutls_free(dnsname.data);
1711
0
    return _gnutls_asn2err(result);
1712
0
  }
1713
1714
0
  result = _asn1_strict_der_decode(&c2, dnsname.data, dnsname.size, NULL);
1715
0
  gnutls_free(dnsname.data);
1716
0
  if (result != ASN1_SUCCESS) {
1717
0
    gnutls_assert();
1718
0
    asn1_delete_structure(&c2);
1719
0
    return _gnutls_asn2err(result);
1720
0
  }
1721
1722
0
  result = _gnutls_parse_general_name(c2, "", seq, ret, ret_size,
1723
0
              ret_type, othername_oid);
1724
0
  asn1_delete_structure(&c2);
1725
0
  if (result < 0) {
1726
0
    return result;
1727
0
  }
1728
1729
0
  type = result;
1730
1731
0
  return type;
1732
0
}
1733
1734
/**
1735
 * gnutls_x509_crq_get_subject_alt_name:
1736
 * @crq: should contain a #gnutls_x509_crq_t type
1737
 * @seq: specifies the sequence number of the alt name, 0 for the
1738
 *   first one, 1 for the second etc.
1739
 * @ret: is the place where the alternative name will be copied to
1740
 * @ret_size: holds the size of ret.
1741
 * @ret_type: holds the #gnutls_x509_subject_alt_name_t name type
1742
 * @critical: will be non-zero if the extension is marked as critical
1743
 *   (may be null)
1744
 *
1745
 * This function will return the alternative names, contained in the
1746
 * given certificate.  It is the same as
1747
 * gnutls_x509_crq_get_subject_alt_name() except for the fact that it
1748
 * will return the type of the alternative name in @ret_type even if
1749
 * the function fails for some reason (i.e.  the buffer provided is
1750
 * not enough).
1751
 *
1752
 * Returns: the alternative subject name type on success, one of the
1753
 *   enumerated #gnutls_x509_subject_alt_name_t.  It will return
1754
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1755
 *   hold the value.  In that case @ret_size will be updated with the
1756
 *   required size.  If the certificate request does not have an
1757
 *   Alternative name with the specified sequence number then
1758
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1759
 *
1760
 * Since: 2.8.0
1761
 **/
1762
int
1763
gnutls_x509_crq_get_subject_alt_name(gnutls_x509_crq_t crq,
1764
             unsigned int seq, void *ret,
1765
             size_t *ret_size,
1766
             unsigned int *ret_type,
1767
             unsigned int *critical)
1768
0
{
1769
0
  return get_subject_alt_name(crq, seq, ret, ret_size, ret_type,
1770
0
            critical, 0);
1771
0
}
1772
1773
/**
1774
 * gnutls_x509_crq_get_subject_alt_othername_oid:
1775
 * @crq: should contain a #gnutls_x509_crq_t type
1776
 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1777
 * @ret: is the place where the otherName OID will be copied to
1778
 * @ret_size: holds the size of ret.
1779
 *
1780
 * This function will extract the type OID of an otherName Subject
1781
 * Alternative Name, contained in the given certificate, and return
1782
 * the type as an enumerated element.
1783
 *
1784
 * This function is only useful if
1785
 * gnutls_x509_crq_get_subject_alt_name() returned
1786
 * %GNUTLS_SAN_OTHERNAME.
1787
 *
1788
 * Returns: the alternative subject name type on success, one of the
1789
 *   enumerated gnutls_x509_subject_alt_name_t.  For supported OIDs,
1790
 *   it will return one of the virtual (GNUTLS_SAN_OTHERNAME_*) types,
1791
 *   e.g. %GNUTLS_SAN_OTHERNAME_XMPP, and %GNUTLS_SAN_OTHERNAME for
1792
 *   unknown OIDs.  It will return %GNUTLS_E_SHORT_MEMORY_BUFFER if
1793
 *   @ret_size is not large enough to hold the value.  In that case
1794
 *   @ret_size will be updated with the required size.  If the
1795
 *   certificate does not have an Alternative name with the specified
1796
 *   sequence number and with the otherName type then
1797
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1798
 *
1799
 * Since: 2.8.0
1800
 **/
1801
int
1802
gnutls_x509_crq_get_subject_alt_othername_oid(gnutls_x509_crq_t crq,
1803
                unsigned int seq,
1804
                void *ret, size_t *ret_size)
1805
0
{
1806
0
  return get_subject_alt_name(crq, seq, ret, ret_size, NULL, NULL, 1);
1807
0
}
1808
1809
/**
1810
 * gnutls_x509_crq_get_extension_by_oid:
1811
 * @crq: should contain a #gnutls_x509_crq_t type
1812
 * @oid: holds an Object Identifier in a null terminated string
1813
 * @indx: In case multiple same OIDs exist in the extensions, this
1814
 *   specifies which to get. Use (0) to get the first one.
1815
 * @buf: a pointer to a structure to hold the name (may be null)
1816
 * @buf_size: initially holds the size of @buf
1817
 * @critical: will be non-zero if the extension is marked as critical
1818
 *
1819
 * This function will return the extension specified by the OID in
1820
 * the certificate.  The extensions will be returned as binary data
1821
 * DER encoded, in the provided buffer.
1822
 *
1823
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1824
 *   negative error code in case of an error.  If the certificate does not
1825
 *   contain the specified extension
1826
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1827
 *
1828
 * Since: 2.8.0
1829
 **/
1830
int
1831
gnutls_x509_crq_get_extension_by_oid(gnutls_x509_crq_t crq,
1832
             const char *oid, unsigned indx,
1833
             void *buf, size_t *buf_size,
1834
             unsigned int *critical)
1835
0
{
1836
0
  int result;
1837
0
  unsigned int i;
1838
0
  char _oid[MAX_OID_SIZE];
1839
0
  size_t oid_size;
1840
1841
0
  for (i = 0;; i++) {
1842
0
    oid_size = sizeof(_oid);
1843
0
    result =
1844
0
        gnutls_x509_crq_get_extension_info(crq, i, _oid,
1845
0
                   &oid_size, critical);
1846
0
    if (result < 0) {
1847
0
      gnutls_assert();
1848
0
      return result;
1849
0
    }
1850
1851
0
    if (strcmp(oid, _oid) == 0) { /* found */
1852
0
      if (indx == 0)
1853
0
        return
1854
0
            gnutls_x509_crq_get_extension_data(crq,
1855
0
                       i,
1856
0
                       buf,
1857
0
                       buf_size);
1858
0
      else
1859
0
        indx--;
1860
0
    }
1861
0
  }
1862
1863
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1864
1865
0
}
1866
1867
/**
1868
 * gnutls_x509_crq_get_extension_by_oid2:
1869
 * @crq: should contain a #gnutls_x509_crq_t type
1870
 * @oid: holds an Object Identifier in a null terminated string
1871
 * @indx: In case multiple same OIDs exist in the extensions, this
1872
 *   specifies which to get. Use (0) to get the first one.
1873
 * @output: will hold the allocated extension data
1874
 * @critical: will be non-zero if the extension is marked as critical
1875
 *
1876
 * This function will return the extension specified by the OID in
1877
 * the certificate.  The extensions will be returned as binary data
1878
 * DER encoded, in the provided buffer.
1879
 *
1880
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1881
 *   negative error code in case of an error.  If the certificate does not
1882
 *   contain the specified extension
1883
 *   %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1884
 *
1885
 * Since: 3.3.8
1886
 **/
1887
int
1888
gnutls_x509_crq_get_extension_by_oid2(gnutls_x509_crq_t crq,
1889
              const char *oid, unsigned indx,
1890
              gnutls_datum_t * output,
1891
              unsigned int *critical)
1892
0
{
1893
0
  int result;
1894
0
  unsigned int i;
1895
0
  char _oid[MAX_OID_SIZE];
1896
0
  size_t oid_size;
1897
1898
0
  for (i = 0;; i++) {
1899
0
    oid_size = sizeof(_oid);
1900
0
    result =
1901
0
        gnutls_x509_crq_get_extension_info(crq, i, _oid,
1902
0
                   &oid_size, critical);
1903
0
    if (result < 0) {
1904
0
      gnutls_assert();
1905
0
      return result;
1906
0
    }
1907
1908
0
    if (strcmp(oid, _oid) == 0) { /* found */
1909
0
      if (indx == 0)
1910
0
        return
1911
0
            gnutls_x509_crq_get_extension_data2(crq,
1912
0
                  i,
1913
0
                  output);
1914
0
      else
1915
0
        indx--;
1916
0
    }
1917
0
  }
1918
1919
0
  return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1920
1921
0
}
1922
1923
/**
1924
 * gnutls_x509_crq_set_subject_alt_name:
1925
 * @crq: a certificate request of type #gnutls_x509_crq_t
1926
 * @nt: is one of the #gnutls_x509_subject_alt_name_t enumerations
1927
 * @data: The data to be set
1928
 * @data_size: The size of data to be set
1929
 * @flags: %GNUTLS_FSAN_SET to clear previous data or
1930
 *   %GNUTLS_FSAN_APPEND to append.
1931
 *
1932
 * This function will set the subject alternative name certificate
1933
 * extension.  It can set the following types:
1934
 *
1935
 * %GNUTLS_SAN_DNSNAME: as a text string
1936
 *
1937
 * %GNUTLS_SAN_RFC822NAME: as a text string
1938
 *
1939
 * %GNUTLS_SAN_URI: as a text string
1940
 *
1941
 * %GNUTLS_SAN_IPADDRESS: as a binary IP address (4 or 16 bytes)
1942
 *
1943
 * %GNUTLS_SAN_OTHERNAME_XMPP: as a UTF8 string
1944
 *
1945
 * Since version 3.5.7 the %GNUTLS_SAN_RFC822NAME, %GNUTLS_SAN_DNSNAME, and
1946
 * %GNUTLS_SAN_OTHERNAME_XMPP are converted to ACE format when necessary.
1947
 *
1948
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
1949
 *   negative error value.
1950
 *
1951
 * Since: 2.8.0
1952
 **/
1953
int
1954
gnutls_x509_crq_set_subject_alt_name(gnutls_x509_crq_t crq,
1955
             gnutls_x509_subject_alt_name_t nt,
1956
             const void *data,
1957
             unsigned int data_size, unsigned int flags)
1958
0
{
1959
0
  int result = 0;
1960
0
  gnutls_datum_t der_data = { NULL, 0 };
1961
0
  gnutls_datum_t prev_der_data = { NULL, 0 };
1962
0
  unsigned int critical = 0;
1963
0
  size_t prev_data_size = 0;
1964
1965
0
  if (crq == NULL) {
1966
0
    gnutls_assert();
1967
0
    return GNUTLS_E_INVALID_REQUEST;
1968
0
  }
1969
1970
  /* Check if the extension already exists.
1971
   */
1972
0
  if (flags & GNUTLS_FSAN_APPEND) {
1973
0
    result =
1974
0
        gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17",
1975
0
               0, NULL,
1976
0
               &prev_data_size,
1977
0
               &critical);
1978
0
    prev_der_data.size = prev_data_size;
1979
1980
0
    switch (result) {
1981
0
    case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
1982
      /* Replacing non-existing data means the same as set data. */
1983
0
      break;
1984
1985
0
    case GNUTLS_E_SUCCESS:
1986
0
      prev_der_data.data = gnutls_malloc(prev_der_data.size);
1987
0
      if (prev_der_data.data == NULL) {
1988
0
        gnutls_assert();
1989
0
        return GNUTLS_E_MEMORY_ERROR;
1990
0
      }
1991
1992
0
      result =
1993
0
          gnutls_x509_crq_get_extension_by_oid(crq,
1994
0
                 "2.5.29.17",
1995
0
                 0,
1996
0
                 prev_der_data.
1997
0
                 data,
1998
0
                 &prev_data_size,
1999
0
                 &critical);
2000
0
      if (result < 0) {
2001
0
        gnutls_assert();
2002
0
        gnutls_free(prev_der_data.data);
2003
0
        return result;
2004
0
      }
2005
0
      break;
2006
2007
0
    default:
2008
0
      gnutls_assert();
2009
0
      return result;
2010
0
    }
2011
0
  }
2012
2013
  /* generate the extension.
2014
   */
2015
0
  result =
2016
0
      _gnutls_x509_ext_gen_subject_alt_name(nt, NULL, data, data_size,
2017
0
              &prev_der_data, &der_data);
2018
0
  gnutls_free(prev_der_data.data);
2019
0
  if (result < 0) {
2020
0
    gnutls_assert();
2021
0
    goto finish;
2022
0
  }
2023
2024
0
  result =
2025
0
      _gnutls_x509_crq_set_extension(crq, "2.5.29.17", &der_data,
2026
0
             critical);
2027
2028
0
  _gnutls_free_datum(&der_data);
2029
2030
0
  if (result < 0) {
2031
0
    gnutls_assert();
2032
0
    return result;
2033
0
  }
2034
2035
0
  return 0;
2036
2037
0
 finish:
2038
0
  return result;
2039
0
}
2040
2041
/**
2042
 * gnutls_x509_crq_set_subject_alt_othername:
2043
 * @crq: a certificate request of type #gnutls_x509_crq_t
2044
 * @oid: is the othername OID
2045
 * @data: The data to be set
2046
 * @data_size: The size of data to be set
2047
 * @flags: %GNUTLS_FSAN_SET to clear previous data or
2048
 *   %GNUTLS_FSAN_APPEND to append.
2049
 *
2050
 * This function will set the subject alternative name certificate
2051
 * extension.  It can set the following types:
2052
 *
2053
 * The values set must be binary values and must be properly DER encoded.
2054
 *
2055
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2056
 *   negative error value.
2057
 *
2058
 * Since: 3.5.0
2059
 **/
2060
int
2061
gnutls_x509_crq_set_subject_alt_othername(gnutls_x509_crq_t crq,
2062
            const char *oid,
2063
            const void *data,
2064
            unsigned int data_size,
2065
            unsigned int flags)
2066
0
{
2067
0
  int result = 0;
2068
0
  gnutls_datum_t der_data = { NULL, 0 };
2069
0
  gnutls_datum_t encoded_data = { NULL, 0 };
2070
0
  gnutls_datum_t prev_der_data = { NULL, 0 };
2071
0
  unsigned int critical = 0;
2072
0
  size_t prev_data_size = 0;
2073
2074
0
  if (crq == NULL) {
2075
0
    gnutls_assert();
2076
0
    return GNUTLS_E_INVALID_REQUEST;
2077
0
  }
2078
2079
  /* Check if the extension already exists.
2080
   */
2081
0
  if (flags & GNUTLS_FSAN_APPEND) {
2082
0
    result =
2083
0
        gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.17",
2084
0
               0, NULL,
2085
0
               &prev_data_size,
2086
0
               &critical);
2087
0
    prev_der_data.size = prev_data_size;
2088
2089
0
    switch (result) {
2090
0
    case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2091
      /* Replacing non-existing data means the same as set data. */
2092
0
      break;
2093
2094
0
    case GNUTLS_E_SUCCESS:
2095
0
      prev_der_data.data = gnutls_malloc(prev_der_data.size);
2096
0
      if (prev_der_data.data == NULL) {
2097
0
        gnutls_assert();
2098
0
        return GNUTLS_E_MEMORY_ERROR;
2099
0
      }
2100
2101
0
      result =
2102
0
          gnutls_x509_crq_get_extension_by_oid(crq,
2103
0
                 "2.5.29.17",
2104
0
                 0,
2105
0
                 prev_der_data.
2106
0
                 data,
2107
0
                 &prev_data_size,
2108
0
                 &critical);
2109
0
      if (result < 0) {
2110
0
        gnutls_assert();
2111
0
        goto finish;
2112
0
      }
2113
0
      break;
2114
2115
0
    default:
2116
0
      gnutls_assert();
2117
0
      return result;
2118
0
    }
2119
0
  }
2120
2121
0
  result =
2122
0
      _gnutls_encode_othername_data(flags, data, data_size,
2123
0
            &encoded_data);
2124
0
  if (result < 0) {
2125
0
    gnutls_assert();
2126
0
    goto finish;
2127
0
  }
2128
2129
  /* generate the extension.
2130
   */
2131
0
  result =
2132
0
      _gnutls_x509_ext_gen_subject_alt_name(GNUTLS_SAN_OTHERNAME, oid,
2133
0
              encoded_data.data,
2134
0
              encoded_data.size,
2135
0
              &prev_der_data, &der_data);
2136
0
  if (result < 0) {
2137
0
    gnutls_assert();
2138
0
    goto finish;
2139
0
  }
2140
2141
0
  result =
2142
0
      _gnutls_x509_crq_set_extension(crq, "2.5.29.17", &der_data,
2143
0
             critical);
2144
2145
0
  if (result < 0) {
2146
0
    gnutls_assert();
2147
0
    goto finish;
2148
0
  }
2149
2150
0
  result = 0;
2151
2152
0
 finish:
2153
0
  _gnutls_free_datum(&prev_der_data);
2154
0
  _gnutls_free_datum(&der_data);
2155
0
  _gnutls_free_datum(&encoded_data);
2156
0
  return result;
2157
0
}
2158
2159
/**
2160
 * gnutls_x509_crq_set_basic_constraints:
2161
 * @crq: a certificate request of type #gnutls_x509_crq_t
2162
 * @ca: true(1) or false(0) depending on the Certificate authority status.
2163
 * @pathLenConstraint: non-negative error codes indicate maximum length of path,
2164
 *   and negative error codes indicate that the pathLenConstraints field should
2165
 *   not be present.
2166
 *
2167
 * This function will set the basicConstraints certificate extension.
2168
 *
2169
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2170
 *   negative error value.
2171
 *
2172
 * Since: 2.8.0
2173
 **/
2174
int
2175
gnutls_x509_crq_set_basic_constraints(gnutls_x509_crq_t crq,
2176
              unsigned int ca, int pathLenConstraint)
2177
0
{
2178
0
  int result;
2179
0
  gnutls_datum_t der_data;
2180
2181
0
  if (crq == NULL) {
2182
0
    gnutls_assert();
2183
0
    return GNUTLS_E_INVALID_REQUEST;
2184
0
  }
2185
2186
  /* generate the extension.
2187
   */
2188
0
  result =
2189
0
      gnutls_x509_ext_export_basic_constraints(ca, pathLenConstraint,
2190
0
                 &der_data);
2191
0
  if (result < 0) {
2192
0
    gnutls_assert();
2193
0
    return result;
2194
0
  }
2195
2196
0
  result = _gnutls_x509_crq_set_extension(crq, "2.5.29.19", &der_data, 1);
2197
2198
0
  _gnutls_free_datum(&der_data);
2199
2200
0
  if (result < 0) {
2201
0
    gnutls_assert();
2202
0
    return result;
2203
0
  }
2204
2205
0
  return 0;
2206
0
}
2207
2208
/**
2209
 * gnutls_x509_crq_set_key_usage:
2210
 * @crq: a certificate request of type #gnutls_x509_crq_t
2211
 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
2212
 *
2213
 * This function will set the keyUsage certificate extension.
2214
 *
2215
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2216
 *   negative error value.
2217
 *
2218
 * Since: 2.8.0
2219
 **/
2220
int gnutls_x509_crq_set_key_usage(gnutls_x509_crq_t crq, unsigned int usage)
2221
0
{
2222
0
  int result;
2223
0
  gnutls_datum_t der_data;
2224
2225
0
  if (crq == NULL) {
2226
0
    gnutls_assert();
2227
0
    return GNUTLS_E_INVALID_REQUEST;
2228
0
  }
2229
2230
  /* generate the extension.
2231
   */
2232
0
  result = gnutls_x509_ext_export_key_usage(usage, &der_data);
2233
0
  if (result < 0) {
2234
0
    gnutls_assert();
2235
0
    return result;
2236
0
  }
2237
2238
0
  result = _gnutls_x509_crq_set_extension(crq, "2.5.29.15", &der_data, 1);
2239
2240
0
  _gnutls_free_datum(&der_data);
2241
2242
0
  if (result < 0) {
2243
0
    gnutls_assert();
2244
0
    return result;
2245
0
  }
2246
2247
0
  return 0;
2248
0
}
2249
2250
/**
2251
 * gnutls_x509_crq_get_key_purpose_oid:
2252
 * @crq: should contain a #gnutls_x509_crq_t type
2253
 * @indx: This specifies which OID to return, use (0) to get the first one
2254
 * @oid: a pointer to store the OID (may be %NULL)
2255
 * @sizeof_oid: initially holds the size of @oid
2256
 * @critical: output variable with critical flag, may be %NULL.
2257
 *
2258
 * This function will extract the key purpose OIDs of the Certificate
2259
 * specified by the given index.  These are stored in the Extended Key
2260
 * Usage extension (2.5.29.37).  See the GNUTLS_KP_* definitions for
2261
 * human readable names.
2262
 *
2263
 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2264
 *   not long enough, and in that case the *@sizeof_oid will be
2265
 *   updated with the required size.  On success 0 is returned.
2266
 *
2267
 * Since: 2.8.0
2268
 **/
2269
int
2270
gnutls_x509_crq_get_key_purpose_oid(gnutls_x509_crq_t crq,
2271
            unsigned indx, void *oid,
2272
            size_t *sizeof_oid, unsigned int *critical)
2273
0
{
2274
0
  char tmpstr[MAX_NAME_SIZE];
2275
0
  int result, len;
2276
0
  gnutls_datum_t prev = { NULL, 0 };
2277
0
  asn1_node c2 = NULL;
2278
0
  size_t prev_size = 0;
2279
2280
0
  if (oid)
2281
0
    memset(oid, 0, *sizeof_oid);
2282
0
  else
2283
0
    *sizeof_oid = 0;
2284
2285
  /* Extract extension.
2286
   */
2287
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37", 0,
2288
0
                  NULL, &prev_size,
2289
0
                  critical);
2290
0
  prev.size = prev_size;
2291
2292
0
  if (result < 0) {
2293
0
    gnutls_assert();
2294
0
    return result;
2295
0
  }
2296
2297
0
  prev.data = gnutls_malloc(prev.size);
2298
0
  if (prev.data == NULL) {
2299
0
    gnutls_assert();
2300
0
    return GNUTLS_E_MEMORY_ERROR;
2301
0
  }
2302
2303
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37", 0,
2304
0
                  prev.data,
2305
0
                  &prev_size, critical);
2306
0
  if (result < 0) {
2307
0
    gnutls_assert();
2308
0
    gnutls_free(prev.data);
2309
0
    return result;
2310
0
  }
2311
2312
0
  result = asn1_create_element
2313
0
      (_gnutls_get_pkix(), "PKIX1.ExtKeyUsageSyntax", &c2);
2314
0
  if (result != ASN1_SUCCESS) {
2315
0
    gnutls_assert();
2316
0
    gnutls_free(prev.data);
2317
0
    return _gnutls_asn2err(result);
2318
0
  }
2319
2320
0
  result = _asn1_strict_der_decode(&c2, prev.data, prev.size, NULL);
2321
0
  gnutls_free(prev.data);
2322
0
  if (result != ASN1_SUCCESS) {
2323
0
    gnutls_assert();
2324
0
    asn1_delete_structure(&c2);
2325
0
    return _gnutls_asn2err(result);
2326
0
  }
2327
2328
0
  indx++;
2329
  /* create a string like "?1"
2330
   */
2331
0
  snprintf(tmpstr, sizeof(tmpstr), "?%u", indx);
2332
2333
0
  len = *sizeof_oid;
2334
0
  result = asn1_read_value(c2, tmpstr, oid, &len);
2335
2336
0
  *sizeof_oid = len;
2337
0
  asn1_delete_structure(&c2);
2338
2339
0
  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND) {
2340
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2341
0
  }
2342
2343
0
  if (result != ASN1_SUCCESS) {
2344
0
    if (result != ASN1_MEM_ERROR)
2345
0
      gnutls_assert();
2346
0
    return _gnutls_asn2err(result);
2347
0
  }
2348
2349
0
  return 0;
2350
0
}
2351
2352
/**
2353
 * gnutls_x509_crq_set_key_purpose_oid:
2354
 * @crq: a certificate of type #gnutls_x509_crq_t
2355
 * @oid: a pointer to a null-terminated string that holds the OID
2356
 * @critical: Whether this extension will be critical or not
2357
 *
2358
 * This function will set the key purpose OIDs of the Certificate.
2359
 * These are stored in the Extended Key Usage extension (2.5.29.37)
2360
 * See the GNUTLS_KP_* definitions for human readable names.
2361
 *
2362
 * Subsequent calls to this function will append OIDs to the OID list.
2363
 *
2364
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2365
 *   negative error value.
2366
 *
2367
 * Since: 2.8.0
2368
 **/
2369
int
2370
gnutls_x509_crq_set_key_purpose_oid(gnutls_x509_crq_t crq,
2371
            const void *oid, unsigned int critical)
2372
0
{
2373
0
  int result;
2374
0
  gnutls_datum_t prev = { NULL, 0 }, der_data;
2375
0
  asn1_node c2 = NULL;
2376
0
  size_t prev_size = 0;
2377
2378
  /* Read existing extension, if there is one.
2379
   */
2380
0
  result = gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37", 0,
2381
0
                  NULL, &prev_size,
2382
0
                  &critical);
2383
0
  prev.size = prev_size;
2384
2385
0
  switch (result) {
2386
0
  case GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE:
2387
    /* No existing extension, that's fine. */
2388
0
    break;
2389
2390
0
  case GNUTLS_E_SUCCESS:
2391
0
    prev.data = gnutls_malloc(prev.size);
2392
0
    if (prev.data == NULL) {
2393
0
      gnutls_assert();
2394
0
      return GNUTLS_E_MEMORY_ERROR;
2395
0
    }
2396
2397
0
    result =
2398
0
        gnutls_x509_crq_get_extension_by_oid(crq, "2.5.29.37",
2399
0
               0, prev.data,
2400
0
               &prev_size, &critical);
2401
0
    if (result < 0) {
2402
0
      gnutls_assert();
2403
0
      gnutls_free(prev.data);
2404
0
      return result;
2405
0
    }
2406
0
    break;
2407
2408
0
  default:
2409
0
    gnutls_assert();
2410
0
    return result;
2411
0
  }
2412
2413
0
  result = asn1_create_element(_gnutls_get_pkix(),
2414
0
             "PKIX1.ExtKeyUsageSyntax", &c2);
2415
0
  if (result != ASN1_SUCCESS) {
2416
0
    gnutls_assert();
2417
0
    gnutls_free(prev.data);
2418
0
    return _gnutls_asn2err(result);
2419
0
  }
2420
2421
0
  if (prev.data) {
2422
    /* decode it.
2423
     */
2424
0
    result =
2425
0
        _asn1_strict_der_decode(&c2, prev.data, prev.size, NULL);
2426
0
    gnutls_free(prev.data);
2427
0
    if (result != ASN1_SUCCESS) {
2428
0
      gnutls_assert();
2429
0
      asn1_delete_structure(&c2);
2430
0
      return _gnutls_asn2err(result);
2431
0
    }
2432
0
  }
2433
2434
  /* generate the extension.
2435
   */
2436
  /* 1. create a new element.
2437
   */
2438
0
  result = asn1_write_value(c2, "", "NEW", 1);
2439
0
  if (result != ASN1_SUCCESS) {
2440
0
    gnutls_assert();
2441
0
    asn1_delete_structure(&c2);
2442
0
    return _gnutls_asn2err(result);
2443
0
  }
2444
2445
  /* 2. Add the OID.
2446
   */
2447
0
  result = asn1_write_value(c2, "?LAST", oid, 1);
2448
0
  if (result != ASN1_SUCCESS) {
2449
0
    gnutls_assert();
2450
0
    asn1_delete_structure(&c2);
2451
0
    return _gnutls_asn2err(result);
2452
0
  }
2453
2454
0
  result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
2455
0
  asn1_delete_structure(&c2);
2456
2457
0
  if (result != ASN1_SUCCESS) {
2458
0
    gnutls_assert();
2459
0
    return _gnutls_asn2err(result);
2460
0
  }
2461
2462
0
  result = _gnutls_x509_crq_set_extension(crq, "2.5.29.37",
2463
0
            &der_data, critical);
2464
0
  _gnutls_free_datum(&der_data);
2465
0
  if (result < 0) {
2466
0
    gnutls_assert();
2467
0
    return result;
2468
0
  }
2469
2470
0
  return 0;
2471
0
}
2472
2473
/**
2474
 * gnutls_x509_crq_get_key_id:
2475
 * @crq: a certificate of type #gnutls_x509_crq_t
2476
 * @flags: should be one of the flags from %gnutls_keyid_flags_t
2477
 * @output_data: will contain the key ID
2478
 * @output_data_size: holds the size of output_data (and will be
2479
 *   replaced by the actual size of parameters)
2480
 *
2481
 * This function will return a unique ID that depends on the public key
2482
 * parameters.  This ID can be used in checking whether a certificate
2483
 * corresponds to the given private key.
2484
 *
2485
 * If the buffer provided is not long enough to hold the output, then
2486
 * *@output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2487
 * be returned.  The output will normally be a SHA-1 hash output,
2488
 * which is 20 bytes.
2489
 *
2490
 * Returns: In case of failure a negative error code will be
2491
 *   returned, and 0 on success.
2492
 *
2493
 * Since: 2.8.0
2494
 **/
2495
int
2496
gnutls_x509_crq_get_key_id(gnutls_x509_crq_t crq, unsigned int flags,
2497
         unsigned char *output_data, size_t *output_data_size)
2498
0
{
2499
0
  int ret = 0;
2500
0
  gnutls_pk_params_st params;
2501
2502
0
  if (crq == NULL) {
2503
0
    gnutls_assert();
2504
0
    return GNUTLS_E_INVALID_REQUEST;
2505
0
  }
2506
2507
0
  ret = _gnutls_x509_crq_get_mpis(crq, &params);
2508
0
  if (ret < 0) {
2509
0
    gnutls_assert();
2510
0
    return ret;
2511
0
  }
2512
2513
0
  ret = _gnutls_get_key_id(&params, output_data, output_data_size, flags);
2514
2515
0
  gnutls_pk_params_release(&params);
2516
2517
0
  return ret;
2518
0
}
2519
2520
/**
2521
 * gnutls_x509_crq_privkey_sign:
2522
 * @crq: should contain a #gnutls_x509_crq_t type
2523
 * @key: holds a private key
2524
 * @dig: The message digest to use, i.e., %GNUTLS_DIG_SHA1
2525
 * @flags: must be 0
2526
 *
2527
 * This function will sign the certificate request with a private key.
2528
 * This must be the same key as the one used in
2529
 * gnutls_x509_crt_set_key() since a certificate request is self
2530
 * signed.
2531
 *
2532
 * This must be the last step in a certificate request generation
2533
 * since all the previously set parameters are now signed.
2534
 *
2535
 * A known limitation of this function is, that a newly-signed request will not
2536
 * be fully functional (e.g., for signature verification), until it
2537
 * is exported an re-imported.
2538
 *
2539
 * After GnuTLS 3.6.1 the value of @dig may be %GNUTLS_DIG_UNKNOWN,
2540
 * and in that case, a suitable but reasonable for the key algorithm will be selected.
2541
 *
2542
 * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code.
2543
 *   %GNUTLS_E_ASN1_VALUE_NOT_FOUND is returned if you didn't set all
2544
 *   information in the certificate request (e.g., the version using
2545
 *   gnutls_x509_crq_set_version()).
2546
 *
2547
 * Since: 2.12.0
2548
 **/
2549
int
2550
gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
2551
           gnutls_digest_algorithm_t dig, unsigned int flags)
2552
0
{
2553
0
  int result;
2554
0
  gnutls_datum_t signature;
2555
0
  gnutls_datum_t tbs;
2556
0
  gnutls_pk_algorithm_t pk;
2557
0
  gnutls_x509_spki_st params;
2558
0
  const gnutls_sign_entry_st *se;
2559
2560
0
  if (crq == NULL) {
2561
0
    gnutls_assert();
2562
0
    return GNUTLS_E_INVALID_REQUEST;
2563
0
  }
2564
2565
  /* Make sure version field is set. */
2566
0
  if (gnutls_x509_crq_get_version(crq) == GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
2567
0
    result = gnutls_x509_crq_set_version(crq, 1);
2568
0
    if (result < 0) {
2569
0
      gnutls_assert();
2570
0
      return result;
2571
0
    }
2572
0
  }
2573
2574
0
  if (dig == 0) {
2575
    /* attempt to find a reasonable choice */
2576
0
    gnutls_pubkey_t pubkey;
2577
0
    int ret;
2578
2579
0
    ret = gnutls_pubkey_init(&pubkey);
2580
0
    if (ret < 0)
2581
0
      return gnutls_assert_val(ret);
2582
2583
0
    ret = gnutls_pubkey_import_privkey(pubkey, key, 0, 0);
2584
0
    if (ret < 0) {
2585
0
      gnutls_pubkey_deinit(pubkey);
2586
0
      return gnutls_assert_val(ret);
2587
0
    }
2588
0
    ret =
2589
0
        gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &dig,
2590
0
                     NULL);
2591
0
    gnutls_pubkey_deinit(pubkey);
2592
2593
0
    if (ret < 0)
2594
0
      return gnutls_assert_val(ret);
2595
0
  }
2596
2597
0
  result = _gnutls_privkey_get_spki_params(key, &params);
2598
0
  if (result < 0) {
2599
0
    gnutls_assert();
2600
0
    return result;
2601
0
  }
2602
2603
0
  pk = gnutls_privkey_get_pk_algorithm(key, NULL);
2604
0
  result = _gnutls_privkey_update_spki_params(key, pk, dig, 0, &params);
2605
0
  if (result < 0) {
2606
0
    gnutls_assert();
2607
0
    return result;
2608
0
  }
2609
2610
  /* Step 1. Self sign the request.
2611
   */
2612
0
  result =
2613
0
      _gnutls_x509_get_tbs(crq->crq, "certificationRequestInfo", &tbs);
2614
2615
0
  if (result < 0) {
2616
0
    gnutls_assert();
2617
0
    return result;
2618
0
  }
2619
2620
0
  se = _gnutls_pk_to_sign_entry(params.pk, dig);
2621
0
  if (se == NULL)
2622
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2623
2624
0
  FIX_SIGN_PARAMS(params, flags, dig);
2625
2626
0
  result = privkey_sign_and_hash_data(key, se, &tbs, &signature, &params);
2627
0
  gnutls_free(tbs.data);
2628
2629
0
  if (result < 0) {
2630
0
    gnutls_assert();
2631
0
    return result;
2632
0
  }
2633
2634
  /* Step 2. write the signature (bits)
2635
   */
2636
0
  result =
2637
0
      asn1_write_value(crq->crq, "signature", signature.data,
2638
0
           signature.size * 8);
2639
2640
0
  _gnutls_free_datum(&signature);
2641
2642
0
  if (result != ASN1_SUCCESS) {
2643
0
    gnutls_assert();
2644
0
    return _gnutls_asn2err(result);
2645
0
  }
2646
2647
  /* Step 3. Write the signatureAlgorithm field.
2648
   */
2649
0
  result =
2650
0
      _gnutls_x509_write_sign_params(crq->crq, "signatureAlgorithm",
2651
0
             se, &params);
2652
0
  if (result < 0) {
2653
0
    gnutls_assert();
2654
0
    return result;
2655
0
  }
2656
2657
0
  return 0;
2658
0
}
2659
2660
/**
2661
 * gnutls_x509_crq_verify:
2662
 * @crq: is the crq to be verified
2663
 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
2664
 *
2665
 * This function will verify self signature in the certificate
2666
 * request and return its status.
2667
 *
2668
 * Returns: In case of a verification failure %GNUTLS_E_PK_SIG_VERIFY_FAILED 
2669
 * is returned, and zero or positive code on success.
2670
 *
2671
 * Since 2.12.0
2672
 **/
2673
int gnutls_x509_crq_verify(gnutls_x509_crq_t crq, unsigned int flags)
2674
0
{
2675
0
  gnutls_datum_t data = { NULL, 0 };
2676
0
  gnutls_datum_t signature = { NULL, 0 };
2677
0
  gnutls_pk_params_st params;
2678
0
  gnutls_x509_spki_st sign_params;
2679
0
  const gnutls_sign_entry_st *se;
2680
0
  int ret;
2681
2682
0
  gnutls_pk_params_init(&params);
2683
2684
0
  ret =
2685
0
      _gnutls_x509_get_signed_data(crq->crq, NULL,
2686
0
           "certificationRequestInfo", &data);
2687
0
  if (ret < 0) {
2688
0
    gnutls_assert();
2689
0
    return ret;
2690
0
  }
2691
2692
0
  ret =
2693
0
      _gnutls_x509_get_signature_algorithm(crq->crq,
2694
0
             "signatureAlgorithm");
2695
0
  if (ret < 0) {
2696
0
    gnutls_assert();
2697
0
    goto cleanup;
2698
0
  }
2699
2700
0
  se = _gnutls_sign_to_entry(ret);
2701
0
  if (se == NULL) {
2702
0
    gnutls_assert();
2703
0
    ret = GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM;
2704
0
    goto cleanup;
2705
0
  }
2706
2707
0
  ret = _gnutls_x509_get_signature(crq->crq, "signature", &signature);
2708
0
  if (ret < 0) {
2709
0
    gnutls_assert();
2710
0
    goto cleanup;
2711
0
  }
2712
2713
0
  ret = _gnutls_x509_crq_get_mpis(crq, &params);
2714
0
  if (ret < 0) {
2715
0
    gnutls_assert();
2716
0
    goto cleanup;
2717
0
  }
2718
2719
0
  ret = _gnutls_x509_read_sign_params(crq->crq,
2720
0
              "signatureAlgorithm", &sign_params);
2721
0
  if (ret < 0) {
2722
0
    gnutls_assert();
2723
0
    goto cleanup;
2724
0
  }
2725
2726
0
  ret =
2727
0
      pubkey_verify_data(se, hash_to_entry(se->hash), &data, &signature,
2728
0
             &params, &sign_params, flags);
2729
0
  if (ret < 0) {
2730
0
    gnutls_assert();
2731
0
    goto cleanup;
2732
0
  }
2733
2734
0
  ret = 0;
2735
2736
0
 cleanup:
2737
0
  _gnutls_free_datum(&data);
2738
0
  _gnutls_free_datum(&signature);
2739
0
  gnutls_pk_params_release(&params);
2740
2741
0
  return ret;
2742
0
}
2743
2744
/**
2745
 * gnutls_x509_crq_set_private_key_usage_period:
2746
 * @crq: a certificate of type #gnutls_x509_crq_t
2747
 * @activation: The activation time
2748
 * @expiration: The expiration time
2749
 *
2750
 * This function will set the private key usage period extension (2.5.29.16).
2751
 *
2752
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2753
 *   negative error value.
2754
 **/
2755
int
2756
gnutls_x509_crq_set_private_key_usage_period(gnutls_x509_crq_t crq,
2757
               time_t activation,
2758
               time_t expiration)
2759
0
{
2760
0
  int result;
2761
0
  gnutls_datum_t der_data;
2762
0
  asn1_node c2 = NULL;
2763
2764
0
  if (crq == NULL) {
2765
0
    gnutls_assert();
2766
0
    return GNUTLS_E_INVALID_REQUEST;
2767
0
  }
2768
2769
0
  result =
2770
0
      asn1_create_element(_gnutls_get_pkix(),
2771
0
        "PKIX1.PrivateKeyUsagePeriod", &c2);
2772
0
  if (result != ASN1_SUCCESS) {
2773
0
    gnutls_assert();
2774
0
    return _gnutls_asn2err(result);
2775
0
  }
2776
2777
0
  result = _gnutls_x509_set_time(c2, "notBefore", activation, 1);
2778
0
  if (result < 0) {
2779
0
    gnutls_assert();
2780
0
    goto cleanup;
2781
0
  }
2782
2783
0
  result = _gnutls_x509_set_time(c2, "notAfter", expiration, 1);
2784
0
  if (result < 0) {
2785
0
    gnutls_assert();
2786
0
    goto cleanup;
2787
0
  }
2788
2789
0
  result = _gnutls_x509_der_encode(c2, "", &der_data, 0);
2790
0
  if (result < 0) {
2791
0
    gnutls_assert();
2792
0
    goto cleanup;
2793
0
  }
2794
2795
0
  result = _gnutls_x509_crq_set_extension(crq, "2.5.29.16", &der_data, 0);
2796
2797
0
  _gnutls_free_datum(&der_data);
2798
2799
0
 cleanup:
2800
0
  asn1_delete_structure(&c2);
2801
2802
0
  return result;
2803
0
}
2804
2805
/**
2806
 * gnutls_x509_crq_get_tlsfeatures:
2807
 * @crq: An X.509 certificate request
2808
 * @features: If the function succeeds, the
2809
 *   features will be stored in this variable.
2810
 * @flags: zero or %GNUTLS_EXT_FLAG_APPEND
2811
 * @critical: the extension status
2812
 *
2813
 * This function will get the X.509 TLS features
2814
 * extension structure from the certificate request.
2815
 * The returned structure needs to be freed using
2816
 * gnutls_x509_tlsfeatures_deinit().
2817
 *
2818
 * When the @flags is set to %GNUTLS_EXT_FLAG_APPEND,
2819
 * then if the @features structure is empty this function will behave
2820
 * identically as if the flag was not set. Otherwise if there are elements 
2821
 * in the @features structure then they will be merged with.
2822
 *
2823
 * Note that @features must be initialized prior to calling this function.
2824
 *
2825
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2826
 *   otherwise a negative error value.
2827
 *
2828
 * Since: 3.5.1
2829
 **/
2830
int gnutls_x509_crq_get_tlsfeatures(gnutls_x509_crq_t crq,
2831
            gnutls_x509_tlsfeatures_t features,
2832
            unsigned int flags, unsigned int *critical)
2833
0
{
2834
0
  int ret;
2835
0
  gnutls_datum_t der = { NULL, 0 };
2836
2837
0
  if (crq == NULL) {
2838
0
    gnutls_assert();
2839
0
    return GNUTLS_E_INVALID_REQUEST;
2840
0
  }
2841
2842
0
  if ((ret =
2843
0
       gnutls_x509_crq_get_extension_by_oid2(crq,
2844
0
               GNUTLS_X509EXT_OID_TLSFEATURES,
2845
0
               0, &der, critical)) < 0) {
2846
0
    return ret;
2847
0
  }
2848
2849
0
  if (der.size == 0 || der.data == NULL) {
2850
0
    gnutls_assert();
2851
0
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2852
0
  }
2853
2854
0
  ret = gnutls_x509_ext_import_tlsfeatures(&der, features, flags);
2855
0
  if (ret < 0) {
2856
0
    gnutls_assert();
2857
0
    goto cleanup;
2858
0
  }
2859
2860
0
  ret = 0;
2861
0
 cleanup:
2862
0
  gnutls_free(der.data);
2863
0
  return ret;
2864
0
}
2865
2866
/**
2867
 * gnutls_x509_crq_set_tlsfeatures:
2868
 * @crq: An X.509 certificate request
2869
 * @features: If the function succeeds, the
2870
 *   features will be added to the certificate
2871
 *   request.
2872
 *
2873
 * This function will set the certificate request's
2874
 * X.509 TLS extension from the given structure.
2875
 *
2876
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
2877
 *   otherwise a negative error value.
2878
 *
2879
 * Since: 3.5.1
2880
 **/
2881
int gnutls_x509_crq_set_tlsfeatures(gnutls_x509_crq_t crq,
2882
            gnutls_x509_tlsfeatures_t features)
2883
0
{
2884
0
  int ret;
2885
0
  gnutls_datum_t der;
2886
2887
0
  if (crq == NULL || features == NULL) {
2888
0
    gnutls_assert();
2889
0
    return GNUTLS_E_INVALID_REQUEST;
2890
0
  }
2891
2892
0
  ret = gnutls_x509_ext_export_tlsfeatures(features, &der);
2893
0
  if (ret < 0) {
2894
0
    gnutls_assert();
2895
0
    return ret;
2896
0
  }
2897
2898
0
  ret =
2899
0
      _gnutls_x509_crq_set_extension(crq, GNUTLS_X509EXT_OID_TLSFEATURES,
2900
0
             &der, 0);
2901
2902
0
  _gnutls_free_datum(&der);
2903
2904
0
  if (ret < 0) {
2905
0
    gnutls_assert();
2906
0
  }
2907
2908
0
  return ret;
2909
0
}
2910
2911
/**
2912
 * gnutls_x509_crq_set_extension_by_oid:
2913
 * @crq: a certificate of type #gnutls_x509_crq_t
2914
 * @oid: holds an Object Identifier in null terminated string
2915
 * @buf: a pointer to a DER encoded data
2916
 * @sizeof_buf: holds the size of @buf
2917
 * @critical: should be non-zero if the extension is to be marked as critical
2918
 *
2919
 * This function will set an the extension, by the specified OID, in
2920
 * the certificate request.  The extension data should be binary data DER
2921
 * encoded.
2922
 *
2923
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2924
 *   negative error value.
2925
 **/
2926
int
2927
gnutls_x509_crq_set_extension_by_oid(gnutls_x509_crq_t crq,
2928
             const char *oid, const void *buf,
2929
             size_t sizeof_buf, unsigned int critical)
2930
0
{
2931
0
  int result;
2932
0
  gnutls_datum_t der_data;
2933
2934
0
  der_data.data = (void *)buf;
2935
0
  der_data.size = sizeof_buf;
2936
2937
0
  if (crq == NULL) {
2938
0
    gnutls_assert();
2939
0
    return GNUTLS_E_INVALID_REQUEST;
2940
0
  }
2941
2942
0
  result = _gnutls_x509_crq_set_extension(crq, oid, &der_data, critical);
2943
0
  if (result < 0) {
2944
0
    gnutls_assert();
2945
0
    return result;
2946
0
  }
2947
2948
0
  return 0;
2949
2950
0
}
2951
2952
/**
2953
 * gnutls_x509_crq_set_spki:
2954
 * @crq: a certificate request of type #gnutls_x509_crq_t
2955
 * @spki: a SubjectPublicKeyInfo structure of type #gnutls_x509_spki_t
2956
 * @flags: must be zero
2957
 *
2958
 * This function will set the certificate request's subject public key
2959
 * information explicitly. This is intended to be used in the cases
2960
 * where a single public key (e.g., RSA) can be used for multiple
2961
 * signature algorithms (RSA PKCS1-1.5, and RSA-PSS).
2962
 *
2963
 * To export the public key (i.e., the SubjectPublicKeyInfo part), check
2964
 * gnutls_pubkey_import_x509().
2965
 *
2966
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
2967
 *   negative error value.
2968
 *
2969
 * Since: 3.6.0
2970
 **/
2971
int
2972
gnutls_x509_crq_set_spki(gnutls_x509_crq_t crq,
2973
       const gnutls_x509_spki_t spki, unsigned int flags)
2974
0
{
2975
0
  int ret;
2976
0
  gnutls_pk_algorithm_t crq_pk;
2977
0
  gnutls_x509_spki_st tpki;
2978
0
  gnutls_pk_params_st params;
2979
0
  unsigned bits;
2980
2981
0
  if (crq == NULL) {
2982
0
    gnutls_assert();
2983
0
    return GNUTLS_E_INVALID_REQUEST;
2984
0
  }
2985
2986
0
  ret = _gnutls_x509_crq_get_mpis(crq, &params);
2987
0
  if (ret < 0) {
2988
0
    gnutls_assert();
2989
0
    return ret;
2990
0
  }
2991
2992
0
  bits = pubkey_to_bits(&params);
2993
0
  crq_pk = params.algo;
2994
2995
0
  if (!_gnutls_pk_are_compat(crq_pk, spki->pk)) {
2996
0
    ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
2997
0
    goto cleanup;
2998
0
  }
2999
3000
0
  if (spki->pk != GNUTLS_PK_RSA_PSS) {
3001
0
    if (crq_pk == spki->pk) {
3002
0
      ret = 0;
3003
0
      goto cleanup;
3004
0
    }
3005
3006
0
    gnutls_assert();
3007
0
    ret = GNUTLS_E_INVALID_REQUEST;
3008
0
    goto cleanup;
3009
0
  }
3010
3011
0
  memset(&tpki, 0, sizeof(gnutls_x509_spki_st));
3012
3013
0
  if (crq_pk == GNUTLS_PK_RSA) {
3014
0
    const mac_entry_st *me;
3015
3016
0
    me = hash_to_entry(spki->rsa_pss_dig);
3017
0
    if (unlikely(me == NULL)) {
3018
0
      gnutls_assert();
3019
0
      ret = GNUTLS_E_INVALID_REQUEST;
3020
0
      goto cleanup;
3021
0
    }
3022
3023
0
    tpki.pk = spki->pk;
3024
0
    tpki.rsa_pss_dig = spki->rsa_pss_dig;
3025
3026
    /* If salt size is zero, find the optimal salt size. */
3027
0
    if (spki->salt_size == 0) {
3028
0
      ret =
3029
0
          _gnutls_find_rsa_pss_salt_size(bits, me,
3030
0
                 spki->salt_size);
3031
0
      if (ret < 0) {
3032
0
        gnutls_assert();
3033
0
        goto cleanup;
3034
0
      }
3035
0
      tpki.salt_size = ret;
3036
0
    } else
3037
0
      tpki.salt_size = spki->salt_size;
3038
0
  } else if (crq_pk == GNUTLS_PK_RSA_PSS) {
3039
0
    ret = _gnutls_x509_crq_read_spki_params(crq, &tpki);
3040
0
    if (ret < 0) {
3041
0
      gnutls_assert();
3042
0
      goto cleanup;
3043
0
    }
3044
3045
0
    tpki.salt_size = spki->salt_size;
3046
0
    tpki.rsa_pss_dig = spki->rsa_pss_dig;
3047
0
  }
3048
3049
0
  memcpy(&params.spki, &tpki, sizeof(tpki));
3050
0
  ret = _gnutls_x509_check_pubkey_params(&params);
3051
0
  if (ret < 0) {
3052
0
    gnutls_assert();
3053
0
    goto cleanup;
3054
0
  }
3055
3056
0
  ret = _gnutls_x509_write_spki_params(crq->crq,
3057
0
               "certificationRequestInfo."
3058
0
               "subjectPKInfo."
3059
0
               "algorithm", &tpki);
3060
0
  if (ret < 0) {
3061
0
    gnutls_assert();
3062
0
    goto cleanup;
3063
0
  }
3064
3065
0
  ret = 0;
3066
0
 cleanup:
3067
0
  gnutls_pk_params_release(&params);
3068
0
  return ret;
3069
0
}