x509_cert_validate.c
Go to the documentation of this file.
1 /**
2  * @file x509_cert_validate.c
3  * @brief X.509 certificate validation
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneCrypto Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/crypto.h"
36 #include "encoding/asn1.h"
37 #include "encoding/oid.h"
38 #include "pkc/rsa.h"
39 #include "pkc/dsa.h"
40 #include "ecc/ecdsa.h"
41 #include "ecc/ed25519.h"
42 #include "ecc/ed448.h"
43 #include "debug.h"
44 
45 //Check crypto library configuration
46 #if (X509_SUPPORT == ENABLED)
47 
48 
49 /**
50  * @brief X.509 certificate validation
51  * @param[in] certInfo X.509 certificate to be verified
52  * @param[in] issuerCertInfo Issuer certificate
53  * @param[in] pathLength Certificate path length
54  * @return Error code
55  **/
56 
58  const X509CertificateInfo *issuerCertInfo, uint_t pathLength)
59 {
60  error_t error;
61  time_t currentTime;
62  X509SignatureAlgo signAlgo;
63  const HashAlgo *hashAlgo;
64  HashContext *hashContext;
65 
66  //Retrieve current time
67  currentTime = getCurrentUnixTime();
68 
69  //Any real-time clock implemented?
70  if(currentTime != 0)
71  {
72  DateTime currentDate;
73 
74  //Convert Unix timestamp to date
75  convertUnixTimeToDate(currentTime, &currentDate);
76 
77  //Check the certificate validity period
78  if(compareDateTime(&currentDate, &certInfo->validity.notBefore) < 0 ||
79  compareDateTime(&currentDate, &certInfo->validity.notAfter) > 0)
80  {
81  //The certificate has expired or is not yet valid
83  }
84  }
85 
86  //Make sure that the subject and issuer names chain correctly
87  if(!x509CompareName(certInfo->issuer.rawData, certInfo->issuer.rawDataLen,
88  issuerCertInfo->subject.rawData, issuerCertInfo->subject.rawDataLen))
89  {
90  //Report an error
91  return ERROR_BAD_CERTIFICATE;
92  }
93 
94  //X.509 version 3 certificate?
95  if(issuerCertInfo->version >= X509_VERSION_3)
96  {
97  //Ensure that the issuer certificate is a CA certificate
98  if(!issuerCertInfo->extensions.basicConstraints.cA)
99  return ERROR_BAD_CERTIFICATE;
100  }
101 
102  //Where pathLenConstraint does not appear, no limit is imposed
103  if(issuerCertInfo->extensions.basicConstraints.pathLenConstraint >= 0)
104  {
105  //The pathLenConstraint field gives the maximum number of non-self-issued
106  //intermediate certificates that may follow this certificate in a valid
107  //certification path
108  if(pathLength > (uint_t) issuerCertInfo->extensions.basicConstraints.pathLenConstraint)
109  return ERROR_BAD_CERTIFICATE;
110  }
111 
112  //Check if the keyUsage extension is present
113  if(issuerCertInfo->extensions.keyUsage != 0)
114  {
115  //If the keyUsage extension is present, then the subject public key must
116  //not be used to verify signatures on certificates unless the keyCertSign
117  //bit is set (refer to RFC 5280, section 4.2.1.3)
118  if(!(issuerCertInfo->extensions.keyUsage & X509_KEY_USAGE_KEY_CERT_SIGN))
119  return ERROR_BAD_CERTIFICATE;
120  }
121 
122  //Retrieve the signature algorithm that was used to sign the certificate
123  error = x509GetSignHashAlgo(&certInfo->signatureAlgo, &signAlgo, &hashAlgo);
124  //Unsupported signature algorithm?
125  if(error)
126  return error;
127 
128  //Ed25519 and Ed448 are used in PureEdDSA mode, without pre-hashing
129  if(hashAlgo != NULL)
130  {
131  //Allocate a memory buffer to hold the hash context
132  hashContext = cryptoAllocMem(hashAlgo->contextSize);
133  //Failed to allocate memory?
134  if(hashContext == NULL)
135  return ERROR_OUT_OF_MEMORY;
136 
137  //Initialize hash computation
138  hashAlgo->init(hashContext);
139 
140  //Digest the TBSCertificate structure using the specified hash algorithm
141  hashAlgo->update(hashContext, certInfo->tbsCertificate,
142  certInfo->tbsCertificateLen);
143 
144  //Finalize hash computation
145  hashAlgo->final(hashContext, NULL);
146 
147 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
148  //RSA signature algorithm?
149  if(signAlgo == X509_SIGN_ALGO_RSA)
150  {
151  uint_t k;
152  RsaPublicKey publicKey;
153 
154  //Initialize RSA public key
155  rsaInitPublicKey(&publicKey);
156 
157  //Get the RSA public key
158  error = x509ReadRsaPublicKey(&issuerCertInfo->subjectPublicKeyInfo,
159  &publicKey);
160 
161  //Check status code
162  if(!error)
163  {
164  //Get the length of the modulus, in bits
165  k = mpiGetBitLength(&publicKey.n);
166 
167  //Make sure the modulus is acceptable
168  if(k < X509_MIN_RSA_MODULUS_SIZE || k > X509_MAX_RSA_MODULUS_SIZE)
169  {
170  //Report an error
171  error = ERROR_INVALID_KEY;
172  }
173  }
174 
175  //Check status code
176  if(!error)
177  {
178  //Verify RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
179  error = rsassaPkcs1v15Verify(&publicKey, hashAlgo,
180  hashContext->digest, certInfo->signatureValue.data,
181  certInfo->signatureValue.length);
182  }
183 
184  //Release previously allocated resources
185  rsaFreePublicKey(&publicKey);
186  }
187  else
188 #endif
189 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
190  //RSA-PSS signature algorithm?
191  if(signAlgo == X509_SIGN_ALGO_RSA_PSS)
192  {
193  uint_t k;
194  RsaPublicKey publicKey;
195 
196  //Initialize RSA public key
197  rsaInitPublicKey(&publicKey);
198 
199  //Get the RSA public key
200  error = x509ReadRsaPublicKey(&issuerCertInfo->subjectPublicKeyInfo,
201  &publicKey);
202 
203  //Check status code
204  if(!error)
205  {
206  //Get the length of the modulus, in bits
207  k = mpiGetBitLength(&publicKey.n);
208 
209  //Make sure the modulus is acceptable
210  if(k < X509_MIN_RSA_MODULUS_SIZE || k > X509_MAX_RSA_MODULUS_SIZE)
211  {
212  //Report an error
213  error = ERROR_INVALID_KEY;
214  }
215  }
216 
217  //Check status code
218  if(!error)
219  {
220  //Retrieve the length of the salt
221  k = certInfo->signatureAlgo.rsaPssParams.saltLen;
222 
223  //Verify RSA signature (RSASSA-PSS signature scheme)
224  error = rsassaPssVerify(&publicKey, hashAlgo, k,
225  hashContext->digest, certInfo->signatureValue.data,
226  certInfo->signatureValue.length);
227  }
228 
229  //Release previously allocated resources
230  rsaFreePublicKey(&publicKey);
231  }
232  else
233 #endif
234 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
235  //DSA signature algorithm?
236  if(signAlgo == X509_SIGN_ALGO_DSA)
237  {
238  uint_t k;
239  DsaPublicKey publicKey;
241 
242  //Initialize DSA public key
243  dsaInitPublicKey(&publicKey);
244  //Initialize DSA signature
246 
247  //Get the DSA public key
248  error = x509ReadDsaPublicKey(&issuerCertInfo->subjectPublicKeyInfo,
249  &publicKey);
250 
251  //Check status code
252  if(!error)
253  {
254  //Get the length of the prime modulus, in bits
255  k = mpiGetBitLength(&publicKey.p);
256 
257  //Make sure the prime modulus is acceptable
258  if(k < X509_MIN_DSA_MODULUS_SIZE || k > X509_MAX_DSA_MODULUS_SIZE)
259  {
260  //Report an error
261  error = ERROR_INVALID_KEY;
262  }
263  }
264 
265  //Check status code
266  if(!error)
267  {
268  //Read the ASN.1 encoded signature
269  error = dsaReadSignature(certInfo->signatureValue.data,
270  certInfo->signatureValue.length, &signature);
271  }
272 
273  //Check status code
274  if(!error)
275  {
276  //Verify DSA signature
277  error = dsaVerifySignature(&publicKey, hashContext->digest,
278  hashAlgo->digestSize, &signature);
279  }
280 
281  //Release previously allocated resources
282  dsaFreePublicKey(&publicKey);
284  }
285  else
286 #endif
287 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
288  //ECDSA signature algorithm?
289  if(signAlgo == X509_SIGN_ALGO_ECDSA)
290  {
291  const EcCurveInfo *curveInfo;
292  EcDomainParameters params;
293  EcPoint publicKey;
295 
296  //Initialize EC domain parameters
297  ecInitDomainParameters(&params);
298  //Initialize ECDSA public key
299  ecInit(&publicKey);
300  //Initialize ECDSA signature
302 
303  //Retrieve EC domain parameters
304  curveInfo = x509GetCurveInfo(
305  issuerCertInfo->subjectPublicKeyInfo.ecParams.namedCurve,
307 
308  //Make sure the specified elliptic curve is supported
309  if(curveInfo != NULL)
310  {
311  //Load EC domain parameters
312  error = ecLoadDomainParameters(&params, curveInfo);
313  }
314  else
315  {
316  //Invalid EC domain parameters
317  error = ERROR_BAD_CERTIFICATE;
318  }
319 
320  //Check status code
321  if(!error)
322  {
323  //Retrieve the EC public key
324  error = ecImport(&params, &publicKey,
325  issuerCertInfo->subjectPublicKeyInfo.ecPublicKey.q,
326  issuerCertInfo->subjectPublicKeyInfo.ecPublicKey.qLen);
327  }
328 
329  //Check status code
330  if(!error)
331  {
332  //Read the ASN.1 encoded signature
333  error = ecdsaReadSignature(certInfo->signatureValue.data,
334  certInfo->signatureValue.length, &signature);
335  }
336 
337  //Check status code
338  if(!error)
339  {
340  //Verify ECDSA signature
341  error = ecdsaVerifySignature(&params, &publicKey,
342  hashContext->digest, hashAlgo->digestSize, &signature);
343  }
344 
345  //Release previously allocated resources
346  ecFreeDomainParameters(&params);
347  ecFree(&publicKey);
349  }
350  else
351 #endif
352  {
353  //The signature algorithm is not supported
355  }
356 
357  //Release hash algorithm context
358  cryptoFreeMem(hashContext);
359  }
360  else
361  {
362 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
363  //Ed25519 signature algorithm?
364  if(signAlgo == X509_SIGN_ALGO_ED25519)
365  {
366  const X509EcPublicKey *publicKey;
367 
368  //Point to the Ed25519 public key
369  publicKey = &issuerCertInfo->subjectPublicKeyInfo.ecPublicKey;
370 
371  //Check the length of the public key
372  if(publicKey->qLen == ED25519_PUBLIC_KEY_LEN)
373  {
374  //Check the length of the EdDSA signature
376  {
377  //Verify signature (PureEdDSA mode)
378  error = ed25519VerifySignature(publicKey->q,
379  certInfo->tbsCertificate, certInfo->tbsCertificateLen,
380  NULL, 0, 0, certInfo->signatureValue.data);
381  }
382  else
383  {
384  //The length of the EdDSA signature is not valid
385  error = ERROR_INVALID_SIGNATURE;
386  }
387  }
388  else
389  {
390  //The length of the Ed25519 public key is not valid
391  error = ERROR_ILLEGAL_PARAMETER;
392  }
393  }
394  else
395 #endif
396 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
397  //Ed448 signature algorithm?
398  if(signAlgo == X509_SIGN_ALGO_ED448)
399  {
400  const X509EcPublicKey *publicKey;
401 
402  //Point to the Ed448 public key
403  publicKey = &issuerCertInfo->subjectPublicKeyInfo.ecPublicKey;
404 
405  //Check the length of the public key
406  if(publicKey->qLen == ED448_PUBLIC_KEY_LEN)
407  {
408  //Check the length of the EdDSA signature
409  if(certInfo->signatureValue.length == ED448_SIGNATURE_LEN)
410  {
411  //Verify signature (PureEdDSA mode)
412  error = ed448VerifySignature(publicKey->q,
413  certInfo->tbsCertificate, certInfo->tbsCertificateLen,
414  NULL, 0, 0, certInfo->signatureValue.data);
415  }
416  else
417  {
418  //The length of the EdDSA signature is not valid
419  error = ERROR_INVALID_SIGNATURE;
420  }
421  }
422  else
423  {
424  //The length of the Ed448 public key is not valid
425  error = ERROR_ILLEGAL_PARAMETER;
426  }
427  }
428  else
429 #endif
430  {
431  //The signature algorithm is not supported
433  }
434  }
435 
436  //Return status code
437  return error;
438 }
439 
440 
441 /**
442  * @brief Check whether the certificate matches the specified FQDN
443  * @param[in] certInfo Pointer to the X.509 certificate
444  * @param[in] fqdn NULL-terminated string that contains the fully-qualified domain name
445  * @return Error code
446  **/
447 
449  const char_t *fqdn)
450 {
451  error_t error;
452  bool_t res;
453  uint_t i;
454  size_t n;
455  size_t length;
456  const uint8_t *data;
457  X509GeneralName generalName;
458 
459  //Valid FQDN name provided?
460  if(fqdn != NULL)
461  {
462  //Initialize flag
463  res = FALSE;
464 
465  //Total number of valid DNS names found in the SubjectAltName extension
466  i = 0;
467 
468  //Valid SubjectAltName extension?
469  if(certInfo->extensions.subjectAltName.rawDataLen > 0)
470  {
471  //The subject alternative name extension allows identities to be bound
472  //to the subject of the certificate. These identities may be included
473  //in addition to or in place of the identity in the subject field of
474  //the certificate
477 
478  //Loop through the list of subject alternative names
479  while(!res && length > 0)
480  {
481  //Parse GeneralName field
482  error = x509ParseGeneralName(data, length, &n, &generalName);
483  //Failed to decode ASN.1 tag?
484  if(error)
485  return error;
486 
487  //DNS name found?
488  if(generalName.type == X509_GENERAL_NAME_TYPE_DNS)
489  {
490  //Check whether the alternative name matches the specified FQDN
491  res = x509CompareSubjectName(generalName.value,
492  generalName.length, fqdn);
493 
494  //Increment counter
495  i++;
496  }
497 
498  //Next item
499  data += n;
500  length -= n;
501  }
502  }
503 
504  //No match?
505  if(!res)
506  {
507  //The implementation must not seek a match for a reference identifier
508  //of CN-ID if the presented identifiers include a DNS-ID, SRV-ID or
509  //URI-ID (refer to RFC 6125, section 6.4.4)
510  if(i == 0 && certInfo->subject.commonNameLen > 0)
511  {
512  //The implementation may as a last resort check the CN-ID for a match
514  certInfo->subject.commonNameLen, fqdn);
515  }
516  }
517 
518  //Check whether the subject name matches the specified FQDN
519  error = res ? NO_ERROR : ERROR_INVALID_NAME;
520  }
521  else
522  {
523  //If no valid FQDN name is provided, then the subject name of the
524  //certificate is not verified
525  error = NO_ERROR;
526  }
527 
528  //Return status code
529  return error;
530 }
531 
532 
533 /**
534  * @brief Check name constraints
535  * @param[in] subjectName Subject name to be verified
536  * @param[in] certInfo Pointer to the CA certificate
537  * @return Error code
538  **/
539 
541  const X509CertificateInfo *certInfo)
542 {
543  error_t error;
544  bool_t res;
545  size_t n;
546  size_t length;
547  const uint8_t *data;
548  X509GeneralName subtree;
549 
550  //Initialize error code
551  error = NO_ERROR;
552 
553  //Valid subject name provided?
554  if(subjectName != NULL)
555  {
556  //Point to the list of excluded name subtrees
559 
560  //Loop through the names constraints
561  while(length > 0)
562  {
563  //Parse GeneralSubtree field
564  error = x509ParseGeneralSubtree(data, length, &n, &subtree);
565  //Failed to decode ASN.1 tag?
566  if(error)
567  break;
568 
569  //DNS host name or DNS domain?
570  if(subtree.type == X509_GENERAL_NAME_TYPE_DNS)
571  {
572  //Check whether the subject name matches the subtree
573  res = x509CompareSubtree(subjectName, subtree.value, subtree.length);
574  //Any match?
575  if(res)
576  {
577  //The subject name is not acceptable
578  error = ERROR_INVALID_NAME;
579  break;
580  }
581  }
582 
583  //Next item
584  data += n;
585  length -= n;
586  }
587 
588  //Point to the list of permitted name subtrees
591 
592  //Loop through the names constraints
593  while(length > 0)
594  {
595  //Parse GeneralSubtree field
596  error = x509ParseGeneralSubtree(data, length, &n, &subtree);
597  //Failed to decode ASN.1 tag?
598  if(error)
599  break;
600 
601  //Assume an error
602  error = ERROR_INVALID_NAME;
603 
604  //DNS host name or DNS domain?
605  if(subtree.type == X509_GENERAL_NAME_TYPE_DNS)
606  {
607  //Check whether the subject name matches the subtree
608  res = x509CompareSubtree(subjectName, subtree.value, subtree.length);
609  //Any match?
610  if(res)
611  {
612  //The subject name is acceptable
613  error = NO_ERROR;
614  break;
615  }
616  }
617 
618  //Next item
619  data += n;
620  length -= n;
621  }
622  }
623  else
624  {
625  //If no valid subject name is provided, then the name constraints
626  //are not verified
627  }
628 
629  //Return status code
630  return error;
631 }
632 
633 
634 /**
635  * @brief Compare distinguished names
636  * @param[in] name1 Pointer to the first distinguished name
637  * @param[in] nameLen1 Length of the first distinguished name
638  * @param[in] name2 Pointer to the second distinguished name
639  * @param[in] nameLen2 Length of the second distinguished name
640  * @return Comparison result
641  **/
642 
643 bool_t x509CompareName(const uint8_t *name1, size_t nameLen1,
644  const uint8_t *name2, size_t nameLen2)
645 {
646  //Compare the length of the distinguished names
647  if(nameLen1 != nameLen2)
648  return FALSE;
649 
650  //Compare the contents of the distinguished names
651  if(cryptoMemcmp(name1, name2, nameLen1))
652  return FALSE;
653 
654  //The distinguished names match
655  return TRUE;
656 }
657 
658 
659 /**
660  * @brief Check whether the subject name matches the specified FQDN
661  * @param[in] subjectName Subject name
662  * @param[in] subjectNameLen Length of the subject name
663  * @param[in] fqdn NULL-terminated string that contains the fully-qualified domain name
664  * @return TRUE if the subject name matches the specified FQDN, else FALSE
665  **/
666 
668  size_t subjectNameLen, const char_t *fqdn)
669 {
670  size_t i;
671  size_t j;
672  size_t fqdnLen;
673 
674  //Retrieve the length of the FQDN
675  fqdnLen = cryptoStrlen(fqdn);
676 
677  //Initialize variables
678  i = 0;
679  j = 0;
680 
681  //Parse the subject name
682  while(i < subjectNameLen && j < fqdnLen)
683  {
684  //Wildcard name found?
685  if(subjectName[i] == '*')
686  {
687  //The implementation should not attempt to match a presented
688  //identifier in which the wildcard character comprises a label other
689  //than the left-most label (refer to RFC 6125, section 6.4.3)
690  if(i != 0)
691  {
692  break;
693  }
694 
695  //The implementation should not compare against anything but the
696  //left-most label of the reference identifier
697  if(fqdn[j] == '.')
698  {
699  i++;
700  }
701  else
702  {
703  j++;
704  }
705  }
706  else
707  {
708  //Perform case insensitive character comparison
709  if(cryptoTolower(subjectName[i]) != fqdn[j])
710  {
711  break;
712  }
713 
714  //Compare next characters
715  i++;
716  j++;
717  }
718  }
719 
720  //Check whether the subject name matches the specified FQDN
721  if(i == subjectNameLen && j == fqdnLen)
722  return TRUE;
723  else
724  return FALSE;
725 }
726 
727 
728 /**
729  * @brief Compare a subject name against the specified subtree
730  * @param[in] subjectName NULL-terminated string that contains the subject name
731  * @param[in] subtree Pointer to the subtree
732  * @param[in] subtreeLen Length of the subtree
733  * @return Comparison result
734  **/
735 
736 bool_t x509CompareSubtree(const char_t *subjectName,
737  const char_t *subtree, size_t subtreeLen)
738 {
739  int_t i;
740  int_t j;
741 
742  //Point to the last character of the subtree
743  i = subtreeLen - 1;
744  //Point to the last character of the subject name
745  j = cryptoStrlen(subjectName) - 1;
746 
747  //Parse the subtree
748  while(i >= 0 && j >= 0)
749  {
750  //Perform case insensitive character comparison
751  if(cryptoTolower(subtree[i]) != subjectName[j])
752  {
753  break;
754  }
755 
756  //The constraint may specify a host or a domain
757  if(subtree[i] == '.' && i == 0)
758  {
759  //When the constraint begins with a period, it may be expanded with
760  //one or more labels (refer to RFC 5280, section 4.2.1.10)
761  i = -1;
762  j = -1;
763  }
764  else
765  {
766  //Compare previous characters
767  i--;
768  j--;
769  }
770  }
771 
772  //Check whether the subject name matches the specified subtree
773  if(i < 0 && j < 0)
774  return TRUE;
775  else
776  return FALSE;
777 }
778 
779 #endif
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:39
EC domain parameters.
Definition: ec.h:61
error_t x509ReadRsaPublicKey(const X509SubjectPublicKeyInfo *subjectPublicKeyInfo, RsaPublicKey *key)
Read a RSA public key.
Definition: x509_common.c:184
char char_t
Definition: compiler_port.h:41
DateTime notAfter
Definition: x509_common.h:530
X509GeneralNameType type
Definition: x509_common.h:649
uint8_t digest[1]
Definition: crypto.h:1046
#define cryptoStrlen(s)
Definition: crypto.h:608
#define cryptoFreeMem(p)
Definition: crypto.h:578
error_t x509ValidateCertificate(const X509CertificateInfo *certInfo, const X509CertificateInfo *issuerCertInfo, uint_t pathLength)
X.509 certificate validation.
Debugging facilities.
Mpi n
Modulus.
Definition: rsa.h:48
uint8_t res[]
size_t permittedSubtreesLen
Definition: x509_common.h:637
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:91
const uint8_t * data
Definition: x509_common.h:739
General name.
Definition: x509_common.h:647
void dsaInitPublicKey(DsaPublicKey *key)
Initialize a DSA public key.
Definition: dsa.c:75
#define cryptoAllocMem(size)
Definition: crypto.h:573
ECDSA (Elliptic Curve Digital Signature Algorithm)
General definitions for cryptographic algorithms.
HashAlgoInit init
Definition: crypto.h:1063
bool_t x509CompareName(const uint8_t *name1, size_t nameLen1, const uint8_t *name2, size_t nameLen2)
Compare distinguished names.
Elliptic curve parameters.
Definition: ec_curves.h:290
size_t rawDataLen
Definition: x509_common.h:476
void rsaFreePublicKey(RsaPublicKey *key)
Release a RSA public key.
Definition: rsa.c:113
int_t compareDateTime(const DateTime *date1, const DateTime *date2)
Compare dates.
Definition: date_time.c:300
X509EcParameters ecParams
Definition: x509_common.h:613
const EcCurveInfo * x509GetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: x509_common.c:846
X509BasicConstraints basicConstraints
Definition: x509_common.h:696
X509EcPublicKey ecPublicKey
Definition: x509_common.h:614
error_t ecImport(const EcDomainParameters *params, EcPoint *r, const uint8_t *data, size_t length)
Convert an octet string to an EC point.
Definition: ec.c:208
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:41
void ecInit(EcPoint *r)
Initialize elliptic curve point.
Definition: ec.c:150
Generic hash algorithm context.
Definition: crypto.h:1044
const uint8_t * namedCurve
Definition: x509_common.h:579
error_t ecdsaVerifySignature(const EcDomainParameters *params, const EcPoint *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
Definition: ecdsa.c:524
error_t x509ReadDsaPublicKey(const X509SubjectPublicKeyInfo *subjectPublicKeyInfo, DsaPublicKey *key)
Read a DSA public key.
Definition: x509_common.c:235
bool_t x509CompareSubjectName(const char_t *subjectName, size_t subjectNameLen, const char_t *fqdn)
Check whether the subject name matches the specified FQDN.
size_t excludedSubtreesLen
Definition: x509_common.h:639
OID (Object Identifier)
#define ED448_SIGNATURE_LEN
Definition: ed448.h:41
#define TRUE
Definition: os_port.h:48
#define cryptoTolower(c)
Definition: crypto.h:626
DSA public key.
Definition: dsa.h:46
Elliptic curve point.
Definition: ec.h:49
ASN.1 (Abstract Syntax Notation One)
ECDSA signature.
Definition: ecdsa.h:46
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:67
error_t dsaVerifySignature(const DsaPublicKey *key, const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
DSA signature verification.
Definition: dsa.c:526
signed int int_t
Definition: compiler_port.h:42
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:190
RSA public key.
Definition: rsa.h:46
const char_t * value
Definition: x509_common.h:650
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:148
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:73
void convertUnixTimeToDate(time_t t, DateTime *date)
Convert Unix timestamp to date.
Definition: date_time.c:196
const uint8_t * rawData
Definition: x509_common.h:661
size_t namedCurveLen
Definition: x509_common.h:580
X509Extensions extensions
Definition: x509_common.h:758
X509SignatureValue signatureValue
Definition: x509_common.h:760
X509Version version
Definition: x509_common.h:752
#define X509_MAX_DSA_MODULUS_SIZE
Definition: x509_common.h:328
const uint8_t * permittedSubtrees
Definition: x509_common.h:636
size_t contextSize
Definition: crypto.h:1059
X509SubjectAltName subjectAltName
Definition: x509_common.h:700
Ed25519 elliptic curve (constant-time implementation)
size_t commonNameLen
Definition: x509_common.h:478
const uint8_t * q
Definition: x509_common.h:590
uint8_t signature
Definition: tls.h:1364
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:53
DSA (Digital Signature Algorithm)
Date and time representation.
Definition: date_time.h:44
const uint8_t * rawData
Definition: x509_common.h:475
DateTime notBefore
Definition: x509_common.h:529
X.509 certificate validation.
Mpi p
Prime modulus.
Definition: dsa.h:48
time_t getCurrentUnixTime(void)
Get current time.
Definition: date_time.c:178
error_t x509CheckSubjectName(const X509CertificateInfo *certInfo, const char_t *fqdn)
Check whether the certificate matches the specified FQDN.
X509Validity validity
Definition: x509_common.h:755
error_t x509GetSignHashAlgo(const X509SignatureAlgoId *signAlgoId, X509SignatureAlgo *signAlgo, const HashAlgo **hashAlgo)
Get the signature and hash algorithms that match the specified identifier.
Definition: x509_common.c:472
Success.
Definition: error.h:42
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:80
const uint8_t * tbsCertificate
Definition: x509_common.h:750
bool_t x509CompareSubtree(const char_t *subjectName, const char_t *subtree, size_t subtreeLen)
Compare a subject name against the specified subtree.
X509NameConstraints nameConstraints
Definition: x509_common.h:697
error_t
Error codes.
Definition: error.h:40
void ecFree(EcPoint *r)
Release an elliptic curve point.
Definition: ec.c:164
const uint8_t * excludedSubtrees
Definition: x509_common.h:638
RSA public-key cryptography standard.
error_t rsassaPkcs1v15Verify(const RsaPublicKey *key, const HashAlgo *hash, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PKCS1-v1_5 signature verification operation.
Definition: rsa.c:775
unsigned int uint_t
Definition: compiler_port.h:43
error_t x509CheckNameConstraints(const char_t *subjectName, const X509CertificateInfo *certInfo)
Check name constraints.
const char_t * commonName
Definition: x509_common.h:477
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:728
error_t ed448VerifySignature(const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, const uint8_t *signature)
EdDSA signature verification.
Definition: ed448.c:282
uint8_t data[]
Definition: dtls_misc.h:167
X509SignatureAlgoId signatureAlgo
Definition: x509_common.h:759
X.509 certificate.
Definition: x509_common.h:748
X509SignatureAlgo
Signature algorithms.
Definition: x509_common.h:426
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:757
error_t ed25519VerifySignature(const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, const uint8_t *signature)
EdDSA signature verification.
Definition: ed25519.c:313
void dsaFreePublicKey(DsaPublicKey *key)
Release a DSA public key.
Definition: dsa.c:90
HashAlgoFinal final
Definition: crypto.h:1065
#define cryptoMemcmp(p1, p2, length)
Definition: crypto.h:602
error_t x509ParseGeneralName(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralName field.
X.509 certificate parsing.
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:135
error_t rsassaPssVerify(const RsaPublicKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PSS signature verification operation.
Definition: rsa.c:1004
Ed448 elliptic curve (constant-time implementation)
error_t dsaReadSignature(const uint8_t *data, size_t length, DsaSignature *signature)
Read an ASN.1 encoded DSA signature.
Definition: dsa.c:320
size_t digestSize
Definition: crypto.h:1061
Common interface for hash algorithms.
Definition: crypto.h:1054
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
DSA signature.
Definition: dsa.h:72
void rsaInitPublicKey(RsaPublicKey *key)
Initialize a RSA public key.
Definition: rsa.c:100
error_t x509ParseGeneralSubtree(const uint8_t *data, size_t length, size_t *totalLength, X509GeneralName *generalName)
Parse GeneralSubtree field.
HashAlgoUpdate update
Definition: crypto.h:1064
#define FALSE
Definition: os_port.h:44
EC public key.
Definition: x509_common.h:588
#define X509_MAX_RSA_MODULUS_SIZE
Definition: x509_common.h:314
int bool_t
Definition: compiler_port.h:47
error_t ecdsaReadSignature(const uint8_t *data, size_t length, EcdsaSignature *signature)
Read an ASN.1 encoded ECDSA signature.
Definition: ecdsa.c:253
#define ED25519_PUBLIC_KEY_LEN
Definition: ed25519.h:39
uint16_t keyUsage
Definition: x509_common.h:698