x509_sign_format.c
Go to the documentation of this file.
1 /**
2  * @file x509_signature_format.c
3  * @brief RSA/DSA/ECDSA/EdDSA signature formatting
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pkix/x509_sign_format.h"
38 #include "encoding/asn1.h"
39 #include "debug.h"
40 
41 //Check crypto library configuration
42 #if (X509_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Format SignatureAlgorithm structure
47  * @param[in] signatureAlgo Pointer to the SignatureAlgorithm structure
48  * @param[out] output Buffer where to format the ASN.1 structure
49  * @param[out] written Length of the resulting ASN.1 structure
50  * @return Error code
51  **/
52 
54  uint8_t *output, size_t *written)
55 {
56  error_t error;
57  size_t n;
58  size_t length;
59  uint8_t *p;
60  Asn1Tag tag;
61  X509SignatureAlgo signAlgo;
62  const HashAlgo *hashAlgo;
63 
64  //Point to the buffer where to write the ASN.1 structure
65  p = output;
66  //Length of the ASN.1 structure
67  length = 0;
68 
69  //Retrieve the signature algorithm that will be used to sign the certificate
70  error = x509GetSignHashAlgo(signatureAlgo, &signAlgo, &hashAlgo);
71  //Unsupported signature algorithm?
72  if(error)
73  return error;
74 
75  //The Algorithm field contains the OID for the algorithm used by the CA
76  //to sign the certificate
77  tag.constructed = FALSE;
80  tag.length = signatureAlgo->oid.length;
81  tag.value = signatureAlgo->oid.value;
82 
83  //Write the corresponding ASN.1 tag
84  error = asn1WriteTag(&tag, FALSE, p, &n);
85  //Any error to report?
86  if(error)
87  return error;
88 
89  //Advance data pointer
91  length += n;
92 
93 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
94  //RSA signature algorithm?
95  if(signAlgo == X509_SIGN_ALGO_RSA)
96  {
97  //For RSA signature algorithm, the parameters component of that type
98  //shall be the ASN.1 type NULL (refer to RFC 3279, section 2.2.1)
99  tag.constructed = FALSE;
101  tag.objType = ASN1_TYPE_NULL;
102  tag.length = 0;
103  tag.value = NULL;
104 
105  //Write the corresponding ASN.1 tag
106  error = asn1WriteTag(&tag, FALSE, p, &n);
107  }
108  else
109 #endif
110 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
111  //RSA-PSS signature algorithm?
112  if(signAlgo == X509_SIGN_ALGO_RSA_PSS)
113  {
114  //The parameters must be present when used in the algorithm identifier
115  //associated with a signature value (refer to RFC 4055, section 3.1)
116  error = x509FormatRsaPssParameters(&signatureAlgo->rsaPssParams, p, &n);
117  }
118  else
119 #endif
120 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
121  //DSA signature algorithm?
122  if(signAlgo == X509_SIGN_ALGO_DSA)
123  {
124  //For DSA signature algorithm, the encoding shall omit the parameters
125  //field (refer to RFC 3279, section 2.2.2)
126  n = 0;
127  }
128  else
129 #endif
130 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
131  //ECDSA signature algorithm?
132  if(signAlgo == X509_SIGN_ALGO_ECDSA)
133  {
134  //For ECDSA signature algorithm, the encoding must omit the parameters
135  //field (refer to RFC 3279, section 2.2.3)
136  n = 0;
137  }
138  else
139 #endif
140 #if (X509_SM2_SUPPORT == ENABLED && SM2_SUPPORT == ENABLED)
141  //SM2 signature algorithm?
142  if(signAlgo == X509_SIGN_ALGO_SM2)
143  {
144  //If the signature algorithm is SM2, no parameters are involved
145  n = 0;
146  }
147  else
148 #endif
149 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
150  //Ed25519 signature algorithm?
151  if(signAlgo == X509_SIGN_ALGO_ED25519)
152  {
153  //The parameters must be absent (refer to RFC 8410, section 6)
154  n = 0;
155  }
156  else
157 #endif
158 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
159  //Ed448 signature algorithm?
160  if(signAlgo == X509_SIGN_ALGO_ED448)
161  {
162  //The parameters must be absent (refer to RFC 8410, section 6)
163  n = 0;
164  }
165  else
166 #endif
167 #if (X509_MLDSA44_SUPPORT == ENABLED && MLDSA44_SUPPORT == ENABLED)
168  //ML-DSA-44 signature algorithm?
169  if(signAlgo == X509_SIGN_ALGO_MLDSA44)
170  {
171  //The parameters must be absent (refer to RFC 9881, section 3)
172  n = 0;
173  }
174  else
175 #endif
176 #if (X509_MLDSA65_SUPPORT == ENABLED && MLDSA65_SUPPORT == ENABLED)
177  //ML-DSA-65 signature algorithm?
178  if(signAlgo == X509_SIGN_ALGO_MLDSA65)
179  {
180  //The parameters must be absent (refer to RFC 9881, section 3)
181  n = 0;
182  }
183  else
184 #endif
185 #if (X509_MLDSA87_SUPPORT == ENABLED && MLDSA87_SUPPORT == ENABLED)
186  //ML-DSA-87 signature algorithm?
187  if(signAlgo == X509_SIGN_ALGO_MLDSA87)
188  {
189  //The parameters must be absent (refer to RFC 9881, section 3)
190  n = 0;
191  }
192  else
193 #endif
194  //Invalid signature algorithm?
195  {
196  //Report an error
198  }
199 
200  //Check status code
201  if(error)
202  return error;
203 
204  //Advance data pointer
205  ASN1_INC_POINTER(p, n);
206  length += n;
207 
208  //The Algorithm and Parameters fields are encapsulated within a sequence
209  tag.constructed = TRUE;
212  tag.length = length;
213 
214  //Write the corresponding ASN.1 tag
215  error = asn1InsertHeader(&tag, output, &n);
216  //Any error to report?
217  if(error)
218  return error;
219 
220  //Total number of bytes that have been written
221  *written = length + n;
222 
223  //Successful processing
224  return NO_ERROR;
225 }
226 
227 
228 /**
229  * @brief Format SignatureValue field
230  * @param[in] prngAlgo PRNG algorithm
231  * @param[in] prngContext Pointer to the PRNG context
232  * @param[in] tbsCert Pointer to the TBSCertificate to be signed
233  * @param[in] signAlgoId Signature algorithm identifier
234  * @param[in] publicKeyInfo Signer's public key information
235  * @param[in] privateKey Signer's private key
236  * @param[out] output Buffer where to format the ASN.1 structure
237  * @param[out] written Length of the resulting ASN.1 structure
238  * @return Error code
239  **/
240 
241 error_t x509FormatSignatureValue(const PrngAlgo *prngAlgo, void *prngContext,
242  const X509OctetString *tbsCert, const X509SignAlgoId *signAlgoId,
243  const X509SubjectPublicKeyInfo *publicKeyInfo, const void *privateKey,
244  uint8_t *output, size_t *written)
245 {
246  error_t error;
247  size_t n;
248  uint8_t *p;
249  Asn1Tag tag;
250 
251  //Point to the buffer where to write the ASN.1 structure
252  p = output;
253 
254  //If the output parameter is NULL, then the function calculates the length
255  //of the ASN.1 structure without copying any data
256  if(p != NULL)
257  {
258  //The bit string shall contain an initial octet which encodes the number
259  //of unused bits in the final subsequent octet
260  p[0] = 0;
261 
262  //Advance data pointer
263  p++;
264  }
265 
266  //The ASN.1 DER-encoded tbsCertificate is used as the input to the signature
267  //function
268  error = x509GenerateSignature(prngAlgo, prngContext, tbsCert, signAlgoId,
269  privateKey, p, &n);
270  //Any error to report?
271  if(error)
272  return error;
273 
274  //The signature is encapsulated within a bit string
275  tag.constructed = FALSE;
278  tag.length = n + 1;
279 
280  //Write the corresponding ASN.1 tag
281  error = asn1InsertHeader(&tag, output, &n);
282  //Any error to report?
283  if(error)
284  return error;
285 
286  //Total number of bytes that have been written
287  *written = tag.totalLength;
288 
289  //Successful processing
290  return NO_ERROR;
291 }
292 
293 
294 /**
295  * @brief Format RSASSA-PSS parameters
296  * @param[in] rsaPssParams Pointer to the RSA-PSS parameters
297  * @param[out] output Buffer where to format the ASN.1 structure
298  * @param[out] written Length of the resulting ASN.1 structure
299  * @return Error code
300  **/
301 
303  uint8_t *output, size_t *written)
304 {
305  error_t error;
306  size_t n;
307  size_t length;
308  uint8_t *p;
309  Asn1Tag tag;
310 
311  //Point to the buffer where to write the ASN.1 structure
312  p = output;
313  //Length of the ASN.1 structure
314  length = 0;
315 
316  //Format hashAlgorithm parameter
317  error = x509FormatRsaPssHashAlgo(rsaPssParams, p, &n);
318  //Any error to report?
319  if(error)
320  return error;
321 
322  //Advance data pointer
323  ASN1_INC_POINTER(p, n);
324  length += n;
325 
326  //Format maskGenAlgorithm parameter
327  error = x509FormatRsaPssMaskGenAlgo(rsaPssParams, p, &n);
328  //Any error to report?
329  if(error)
330  return error;
331 
332  //Advance data pointer
333  ASN1_INC_POINTER(p, n);
334  length += n;
335 
336  //Format saltLength parameter
337  error = x509FormatRsaPssSaltLength(rsaPssParams, p, &n);
338  //Any error to report?
339  if(error)
340  return error;
341 
342  //Advance data pointer
343  ASN1_INC_POINTER(p, n);
344  length += n;
345 
346  //The RSASSA-PSS parameters are encapsulated within a sequence
347  tag.constructed = TRUE;
350  tag.length = length;
351 
352  //Write the corresponding ASN.1 tag
353  error = asn1InsertHeader(&tag, output, &n);
354  //Any error to report?
355  if(error)
356  return error;
357 
358  //Total number of bytes that have been written
359  *written = tag.totalLength;
360 
361  //Successful processing
362  return NO_ERROR;
363 }
364 
365 
366 /**
367  * @brief Format RSASSA-PSS hash algorithm
368  * @param[in] rsaPssParams Pointer to the RSA-PSS parameters
369  * @param[out] output Buffer where to format the ASN.1 structure
370  * @param[out] written Length of the resulting ASN.1 structure
371  * @return Error code
372  **/
373 
375  uint8_t *output, size_t *written)
376 {
377  error_t error;
378  size_t n;
379  Asn1Tag tag;
380 
381  //Length of the ASN.1 structure
382  n = 0;
383 
384  //The default hash algorithm is SHA-1
385  if(rsaPssParams->hashAlgo.value != NULL &&
386  rsaPssParams->hashAlgo.length > 0)
387  {
388  //Write the hash algorithm identifier
389  tag.constructed = FALSE;
392  tag.length = rsaPssParams->hashAlgo.length;
393  tag.value = rsaPssParams->hashAlgo.value;
394 
395  //Write the corresponding ASN.1 tag
396  error = asn1WriteTag(&tag, FALSE, output, &n);
397  //Any error to report?
398  if(error)
399  return error;
400 
401  //The hashAlgorithm parameter is encapsulated within a sequence
402  tag.constructed = TRUE;
405  tag.length = n;
406 
407  //Write the corresponding ASN.1 tag
408  error = asn1InsertHeader(&tag, output, &n);
409  //Any error to report?
410  if(error)
411  return error;
412 
413  //Get the length of the resulting sequence
414  n = tag.totalLength;
415 
416  //Explicit tagging shall be used to encode each parameter
417  tag.constructed = TRUE;
419  tag.objType = 0;
420  tag.length = n;
421 
422  //Write the corresponding ASN.1 tag
423  error = asn1InsertHeader(&tag, output, &n);
424  //Any error to report?
425  if(error)
426  return error;
427 
428  //Get the length of the resulting tag
429  n = tag.totalLength;
430  }
431 
432  //Total number of bytes that have been written
433  *written = n;
434 
435  //Successful processing
436  return NO_ERROR;
437 }
438 
439 
440 /**
441  * @brief Format RSASSA-PSS mask generation algorithm
442  * @param[in] rsaPssParams Pointer to the RSA-PSS parameters
443  * @param[out] output Buffer where to format the ASN.1 structure
444  * @param[out] written Length of the resulting ASN.1 structure
445  * @return Error code
446  **/
447 
449  uint8_t *output, size_t *written)
450 {
451  error_t error;
452  size_t n;
453  size_t length;
454  uint8_t *p;
455  Asn1Tag tag;
456 
457  //Point to the buffer where to write the ASN.1 structure
458  p = output;
459  //Length of the ASN.1 structure
460  length = 0;
461 
462  //The default mask generation function is MGF1
463  if(rsaPssParams->maskGenAlgo.value != NULL &&
464  rsaPssParams->maskGenAlgo.length > 0)
465  {
466  //Write the mask generation algorithm identifier
467  tag.constructed = FALSE;
470  tag.length = rsaPssParams->maskGenAlgo.length;
471  tag.value = rsaPssParams->maskGenAlgo.value;
472 
473  //Write the corresponding ASN.1 tag
474  error = asn1WriteTag(&tag, FALSE, p, &n);
475  //Any error to report?
476  if(error)
477  return error;
478 
479  //Advance data pointer
480  ASN1_INC_POINTER(p, n);
481  length += n;
482 
483  //Write the algorithm identifier of the one-way hash function employed
484  //with the mask generation function
485  error = x509FormatRsaPssMaskGenHashAlgo(rsaPssParams, p, &n);
486  //Any error to report?
487  if(error)
488  return error;
489 
490  //Advance data pointer
491  ASN1_INC_POINTER(p, n);
492  length += n;
493 
494  //The maskGenAlgorithm parameter is encapsulated within a sequence
495  tag.constructed = TRUE;
498  tag.length = length;
499 
500  //Write the corresponding ASN.1 tag
501  error = asn1InsertHeader(&tag, output, &n);
502  //Any error to report?
503  if(error)
504  return error;
505 
506  //Get the length of the resulting sequence
507  n = tag.totalLength;
508 
509  //Explicit tagging shall be used to encode each parameter
510  tag.constructed = TRUE;
512  tag.objType = 1;
513  tag.length = n;
514 
515  //Write the corresponding ASN.1 tag
516  error = asn1InsertHeader(&tag, output, &n);
517  //Any error to report?
518  if(error)
519  return error;
520 
521  //Get the length of the resulting tag
522  length = tag.totalLength;
523  }
524 
525  //Total number of bytes that have been written
526  *written = length;
527 
528  //Successful processing
529  return NO_ERROR;
530 }
531 
532 
533 /**
534  * @brief Format RSASSA-PSS mask generation hash algorithm
535  * @param[in] rsaPssParams Pointer to the RSA-PSS parameters
536  * @param[out] output Buffer where to format the ASN.1 structure
537  * @param[out] written Length of the resulting ASN.1 structure
538  * @return Error code
539  **/
540 
542  uint8_t *output, size_t *written)
543 {
544  error_t error;
545  size_t n;
546  Asn1Tag tag;
547 
548  //Length of the ASN.1 structure
549  n = 0;
550 
551  //The default hash algorithm is SHA-1
552  if(rsaPssParams->maskGenHashAlgo.value != NULL &&
553  rsaPssParams->maskGenHashAlgo.length > 0)
554  {
555  //Write the algorithm identifier of the one-way hash function employed
556  //with the mask generation function
557  tag.constructed = FALSE;
560  tag.length = rsaPssParams->maskGenHashAlgo.length;
561  tag.value = rsaPssParams->maskGenHashAlgo.value;
562 
563  //Write the corresponding ASN.1 tag
564  error = asn1WriteTag(&tag, FALSE, output, &n);
565  //Any error to report?
566  if(error)
567  return error;
568 
569  //The hash algorithm identifier is encapsulated within a sequence
570  tag.constructed = TRUE;
573  tag.length = n;
574 
575  //Write the corresponding ASN.1 tag
576  error = asn1InsertHeader(&tag, output, &n);
577  //Any error to report?
578  if(error)
579  return error;
580 
581  //Get the length of the resulting sequence
582  n = tag.totalLength;
583  }
584 
585  //Total number of bytes that have been written
586  *written = n;
587 
588  //Successful processing
589  return NO_ERROR;
590 }
591 
592 
593 /**
594  * @brief Format RSASSA-PSS salt length
595  * @param[in] rsaPssParams Pointer to the RSA-PSS parameters
596  * @param[out] output Buffer where to format the ASN.1 structure
597  * @param[out] written Length of the resulting ASN.1 structure
598  * @return Error code
599  **/
600 
602  uint8_t *output, size_t *written)
603 {
604  error_t error;
605  size_t n;
606  Asn1Tag tag;
607 
608  //Length of the ASN.1 structure
609  n = 0;
610 
611  //The default length of the salt is 20
612  if(rsaPssParams->saltLen != 20)
613  {
614  //Write the length of the salt
615  error = asn1WriteInt32((int32_t) rsaPssParams->saltLen, FALSE, output, &n);
616  //Any error to report?
617  if(error)
618  return error;
619 
620  //Explicit tagging shall be used to encode the saltLength parameter
621  tag.constructed = TRUE;
623  tag.objType = 2;
624  tag.length = n;
625 
626  //Write the corresponding ASN.1 tag
627  error = asn1InsertHeader(&tag, output, &n);
628  //Any error to report?
629  if(error)
630  return error;
631 
632  //Get the length of the resulting tag
633  n = tag.totalLength;
634  }
635 
636  //Total number of bytes that have been written
637  *written = n;
638 
639  //Successful processing
640  return NO_ERROR;
641 }
642 
643 #endif
@ X509_SIGN_ALGO_MLDSA65
Definition: x509_common.h:689
#define PrngAlgo
Definition: crypto.h:1049
X509OctetString hashAlgo
Definition: x509_common.h:1121
uint8_t p
Definition: ndp.h:300
#define TRUE
Definition: os_port.h:50
error_t asn1InsertHeader(Asn1Tag *tag, uint8_t *data, size_t *written)
Insert an ASN.1 tag header.
Definition: asn1.c:643
error_t x509FormatRsaPssSaltLength(const X509RsaPssParameters *rsaPssParams, uint8_t *output, size_t *written)
Format RSASSA-PSS salt length.
X509OctetString maskGenHashAlgo
Definition: x509_common.h:1123
error_t x509GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId, const void *privateKey, uint8_t *output, size_t *written)
Signature generation.
@ X509_SIGN_ALGO_MLDSA44
Definition: x509_common.h:688
size_t totalLength
Definition: asn1.h:111
size_t length
Definition: asn1.h:109
#define FALSE
Definition: os_port.h:46
X509SignatureAlgo
Signature algorithms.
Definition: x509_common.h:679
error_t
Error codes.
Definition: error.h:43
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
error_t x509FormatRsaPssHashAlgo(const X509RsaPssParameters *rsaPssParams, uint8_t *output, size_t *written)
Format RSASSA-PSS hash algorithm.
ASN.1 tag.
Definition: asn1.h:105
#define ASN1_INC_POINTER(p, n)
Definition: asn1.h:58
@ X509_SIGN_ALGO_ECDSA
Definition: x509_common.h:684
error_t x509FormatSignatureValue(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsCert, const X509SignAlgoId *signAlgoId, const X509SubjectPublicKeyInfo *publicKeyInfo, const void *privateKey, uint8_t *output, size_t *written)
Format SignatureValue field.
error_t x509FormatRsaPssMaskGenAlgo(const X509RsaPssParameters *rsaPssParams, uint8_t *output, size_t *written)
Format RSASSA-PSS mask generation algorithm.
General definitions for cryptographic algorithms.
error_t x509GetSignHashAlgo(const X509SignAlgoId *signAlgoId, X509SignatureAlgo *signAlgo, const HashAlgo **hashAlgo)
Get the signature and hash algorithms that match the specified identifier.
Definition: x509_common.c:433
error_t x509FormatRsaPssMaskGenHashAlgo(const X509RsaPssParameters *rsaPssParams, uint8_t *output, size_t *written)
Format RSASSA-PSS mask generation hash algorithm.
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
error_t x509FormatSignatureAlgo(const X509SignAlgoId *signatureAlgo, uint8_t *output, size_t *written)
Format SignatureAlgorithm structure.
uint_t objClass
Definition: asn1.h:107
@ X509_SIGN_ALGO_MLDSA87
Definition: x509_common.h:690
uint8_t length
Definition: tcp.h:375
X509OctetString oid
Definition: x509_common.h:1134
X509OctetString maskGenAlgo
Definition: x509_common.h:1122
@ X509_SIGN_ALGO_RSA
Definition: x509_common.h:681
RSA/DSA/ECDSA/EdDSA signature generation.
@ X509_SIGN_ALGO_RSA_PSS
Definition: x509_common.h:682
uint8_t n
Subject Public Key Information extension.
Definition: x509_common.h:878
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
bool_t constructed
Definition: asn1.h:106
RSASSA-PSS parameters.
Definition: x509_common.h:1120
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:77
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:83
const uint8_t * value
Definition: x509_common.h:732
Common interface for hash algorithms.
Definition: crypto.h:1165
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:74
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
@ X509_SIGN_ALGO_SM2
Definition: x509_common.h:685
Octet string.
Definition: x509_common.h:731
@ X509_SIGN_ALGO_ED25519
Definition: x509_common.h:686
error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data, size_t *written)
Write a 32-bit integer to the output stream.
Definition: asn1.c:781
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:1136
const uint8_t * value
Definition: asn1.h:110
Signature algorithm identifier.
Definition: x509_common.h:1133
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:108
error_t x509FormatRsaPssParameters(const X509RsaPssParameters *rsaPssParams, uint8_t *output, size_t *written)
Format RSASSA-PSS parameters.
ASN.1 (Abstract Syntax Notation One)
@ X509_SIGN_ALGO_DSA
Definition: x509_common.h:683
@ X509_SIGN_ALGO_ED448
Definition: x509_common.h:687
@ ASN1_TYPE_NULL
Definition: asn1.h:76