Coverage Report

Created: 2025-07-23 07:18

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