Coverage Report

Created: 2025-03-06 06:58

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