ike_certificate.c
Go to the documentation of this file.
1 /**
2  * @file ike_certificate.c
3  * @brief X.509 certificate handling
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC 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.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IKE_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ike/ike.h"
36 #include "ike/ike_certificate.h"
37 #include "ike/ike_payload_parse.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "pkix/pem_import.h"
41 #include "pkix/x509_cert_parse.h"
43 #include "debug.h"
44 
45 //Check IKEv2 library configuration
46 #if (IKE_SUPPORT == ENABLED && IKE_CERT_AUTH_SUPPORT == ENABLED)
47 
48 
49 /**
50  * @brief Retrieve the certificate type
51  * @param[in] certInfo X.509 certificate
52  * @param[out] certType Certificate type
53  * @return Error code
54  **/
55 
57  IkeCertType *certType)
58 {
59  error_t error;
60  size_t oidLen;
61  const uint8_t *oid;
62 
63  //Initialize status code
64  error = NO_ERROR;
65 
66  //Point to the public key identifier
69 
70 #if (IKE_RSA_SIGN_SUPPORT == ENABLED || IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
71  //RSA public key?
73  {
74  //Save certificate type
75  *certType = IKE_CERT_TYPE_RSA;
76  }
77  else
78 #endif
79 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
80  //RSA-PSS public key?
82  {
83  //Save certificate type
84  *certType = IKE_CERT_TYPE_RSA_PSS;
85  }
86  else
87 #endif
88 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
89  //DSA public key?
90  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
91  {
92  //Save certificate type
93  *certType = IKE_CERT_TYPE_DSA;
94  }
95  else
96 #endif
97 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
98  //EC public key?
100  {
101  const X509EcParameters *params;
102 
103  //Point to the EC parameters
104  params = &certInfo->tbsCert.subjectPublicKeyInfo.ecParams;
105 
106 #if (IKE_ECP_256_SUPPORT == ENABLED)
107  //NIST P-256 elliptic curve?
108  if(!oidComp(params->namedCurve.value, params->namedCurve.length,
109  SECP256R1_OID, sizeof(SECP256R1_OID)))
110  {
111  *certType = IKE_CERT_TYPE_ECDSA_P256;
112  }
113  else
114 #endif
115 #if (IKE_ECP_384_SUPPORT == ENABLED)
116  //NIST P-384 elliptic curve?
117  if(!oidComp(params->namedCurve.value, params->namedCurve.length,
118  SECP384R1_OID, sizeof(SECP384R1_OID)))
119  {
120  *certType = IKE_CERT_TYPE_ECDSA_P384;
121  }
122  else
123 #endif
124 #if (IKE_ECP_521_SUPPORT == ENABLED)
125  //NIST P-521 elliptic curve?
126  if(!oidComp(params->namedCurve.value, params->namedCurve.length,
127  SECP521R1_OID, sizeof(SECP521R1_OID)))
128  {
129  *certType = IKE_CERT_TYPE_ECDSA_P521;
130  }
131  else
132 #endif
133 #if (IKE_BRAINPOOLP256R1_SUPPORT == ENABLED)
134  //brainpoolP256r1 elliptic curve?
135  if(!oidComp(params->namedCurve.value, params->namedCurve.length,
137  {
139  }
140  else
141 #endif
142 #if (IKE_BRAINPOOLP384R1_SUPPORT == ENABLED)
143  //brainpoolP384r1 elliptic curve?
144  if(!oidComp(params->namedCurve.value, params->namedCurve.length,
146  {
148  }
149  else
150 #endif
151 #if (IKE_BRAINPOOLP512R1_SUPPORT == ENABLED)
152  //brainpoolP512r1 elliptic curve?
153  if(!oidComp(params->namedCurve.value, params->namedCurve.length,
155  {
157  }
158  else
159 #endif
160  //Unknown elliptic curve?
161  {
162  error = ERROR_BAD_CERTIFICATE;
163  }
164  }
165  else
166 #endif
167 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
168  //Ed25519 public key?
169  if(!oidComp(oid, oidLen, ED25519_OID, sizeof(ED25519_OID)))
170  {
171  //Save certificate type
172  *certType = IKE_CERT_TYPE_ED25519;
173  }
174  else
175 #endif
176 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
177  //Ed448 public key?
178  if(!oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
179  {
180  //Save certificate type
181  *certType = IKE_CERT_TYPE_ED448;
182  }
183  else
184 #endif
185  //Invalid public key?
186  {
187  //The certificate does not contain any valid public key
188  error = ERROR_BAD_CERTIFICATE;
189  }
190 
191  //Return status code
192  return error;
193 }
194 
195 
196 /**
197  * @brief Extract subject's DN from certificate
198  * @param[in] cert Certificate (PEM format)
199  * @param[in] certLen Length of the certificate
200  * @param[out] subjectDn Buffer where to copy the X.500 distinguished name
201  * @param[out] subjectDnLen Length of the X.500 distinguished name
202  * @return Error code
203  **/
204 
205 error_t ikeGetCertSubjectDn(const char_t *cert, size_t certLen,
206  uint8_t *subjectDn, size_t *subjectDnLen)
207 {
208  error_t error;
209  uint8_t *derCert;
210  size_t derCertLen;
211  X509CertInfo *certInfo;
212 
213  //The first pass calculates the length of the DER-encoded certificate
214  error = pemImportCertificate(cert, certLen, NULL, &derCertLen, NULL);
215 
216  //Check status code
217  if(!error)
218  {
219  //Allocate a memory buffer to hold the DER-encoded certificate
220  derCert = ikeAllocMem(derCertLen);
221 
222  //Successful memory allocation?
223  if(derCert != NULL)
224  {
225  //The second pass decodes the PEM certificate
226  error = pemImportCertificate(cert, certLen, derCert, &derCertLen,
227  NULL);
228 
229  //Check status code
230  if(!error)
231  {
232  //Allocate a memory buffer to store X.509 certificate info
233  certInfo = ikeAllocMem(sizeof(X509CertInfo));
234 
235  //Successful memory allocation?
236  if(certInfo != NULL)
237  {
238  //Parse X.509 certificate
239  error = x509ParseCertificateEx(derCert, derCertLen, certInfo,
240  TRUE);
241 
242  //Check status code
243  if(!error)
244  {
245  //Copy the X.500 distinguished name
246  osMemcpy(subjectDn, certInfo->tbsCert.subject.raw.value,
247  certInfo->tbsCert.subject.raw.length);
248 
249  //Total length of the payload
250  *subjectDnLen = certInfo->tbsCert.subject.raw.length;
251  }
252 
253  //Release previously allocated memory
254  ikeFreeMem(certInfo);
255  }
256  else
257  {
258  //Failed to allocate memory
259  error = ERROR_OUT_OF_MEMORY;
260  }
261 
262  //Release previously allocated memory
263  ikeFreeMem(derCert);
264  }
265  }
266  else
267  {
268  //Failed to allocate memory
269  error = ERROR_OUT_OF_MEMORY;
270  }
271  }
272 
273  //Return status code
274  return error;
275 }
276 
277 
278 /**
279  * @brief Format list of acceptable certification authorities
280  * @param[in] trustedCaList List of trusted CA (PEM format)
281  * @param[in] trustedCaListLen Total length of the list
282  * @param[out] certAuth List of SHA-1 hashes of the public keys of trusted CAs
283  * @param[in,out] certAuthLen Actual length of the list, in bytes
284  * @return Error code
285  **/
286 
288  size_t trustedCaListLen, uint8_t *certAuth, size_t *certAuthLen)
289 {
290 #if (SHA1_SUPPORT == ENABLED)
291  error_t error;
292  size_t n;
293  size_t derCertLen;
294  uint8_t *derCert;
295  X509CertInfo *certInfo;
296 
297  //Initialize status code
298  error = NO_ERROR;
299 
300  //Allocate a memory buffer to store X.509 certificate info
301  certInfo = ikeAllocMem(sizeof(X509CertInfo));
302 
303  //Successful memory allocation?
304  if(certInfo != NULL)
305  {
306  //Loop through the list of trusted CA certificates
307  while(trustedCaListLen > 0 && !error)
308  {
309  //The first pass calculates the length of the DER-encoded certificate
310  error = pemImportCertificate(trustedCaList, trustedCaListLen, NULL,
311  &derCertLen, &n);
312 
313  //Check status code
314  if(!error)
315  {
316  //Allocate a memory buffer to hold the DER-encoded certificate
317  derCert = ikeAllocMem(derCertLen);
318 
319  //Successful memory allocation?
320  if(derCert != NULL)
321  {
322  //The second pass decodes the PEM certificate
323  error = pemImportCertificate(trustedCaList, trustedCaListLen,
324  derCert, &derCertLen, NULL);
325 
326  //Check status code
327  if(!error)
328  {
329  //Parse X.509 certificate
330  error = x509ParseCertificate(derCert, derCertLen, certInfo);
331  }
332 
333  //Valid CA certificate?
334  if(!error)
335  {
336  //The Certification Authority value is a concatenated list of
337  //SHA-1 hashes of the public keys of trusted Certification
338  //Authorities (CAs). Each is encoded as the SHA-1 hash of the
339  //SubjectPublicKeyInfo element
342  certAuth + *certAuthLen);
343 
344  //Check status code
345  if(!error)
346  {
347  //Ensure the SHA-1 digest value is not a duplicate
348  if(!ikeIsDuplicateCa(certAuth, *certAuthLen,
349  certAuth + *certAuthLen))
350  {
351  //The 20-octet hashes are concatenated and included with no
352  //other formatting
353  *certAuthLen += IKE_SHA1_DIGEST_SIZE;
354  }
355  }
356  }
357  else
358  {
359  //Discard current CA certificate
360  error = NO_ERROR;
361  }
362 
363  //Free previously allocated memory
364  ikeFreeMem(derCert);
365  }
366  else
367  {
368  //Failed to allocate memory
369  error = ERROR_OUT_OF_MEMORY;
370  }
371 
372  //Point to the next CA of the list
373  trustedCaList += n;
374  trustedCaListLen -= n;
375  }
376  else
377  {
378  //End of file detected
379  trustedCaListLen = 0;
380  error = NO_ERROR;
381  }
382  }
383 
384  //Free previously allocated memory
385  ikeFreeMem(certInfo);
386  }
387  else
388  {
389  //Failed to allocate memory
390  error = ERROR_OUT_OF_MEMORY;
391  }
392 
393  //Return status code
394  return error;
395 #else
396  //SHA-1 is not supported
397  return NO_ERROR;
398 #endif
399 }
400 
401 
402 /**
403  * @brief Test whether the provided SHA-1 digest value is a duplicate
404  * @param[in] certAuth List of SHA-1 hashes of the public keys of trusted CAs
405  * @param[in] certAuthLen Length of the list, in bytes
406  * @param[in] digest SHA-1 digest to be checked for duplicate value
407  * @return TRUE if the SHA-1 digest value is a duplicate, else FALSE
408  **/
409 
410 bool_t ikeIsDuplicateCa(const uint8_t *certAuth, size_t certAuthLen,
411  const uint8_t *digest)
412 {
413  size_t i;
414  bool_t flag;
415 
416  //Initialize flag
417  flag = FALSE;
418 
419  //The Certification Authority value is a concatenated list of SHA-1 hashes
420  //of the public keys of trusted Certification Authorities (CAs)
421  for(i = 0; i < certAuthLen; i += IKE_SHA1_DIGEST_SIZE)
422  {
423  //Compare SHA-1 digest values
424  if(osMemcmp(certAuth + i, digest, IKE_SHA1_DIGEST_SIZE) == 0)
425  {
426  //The SHA-1 hash is a duplicate
427  flag = TRUE;
428  }
429  }
430 
431  //Return TRUE if the SHA-1 hash value is a duplicate
432  return flag;
433 }
434 
435 
436 /**
437  * @brief Parse certificate chain
438  * @param[in] sa Pointer to the IKE SA
439  * @param[in] padEntry Pointer to the PAD entry
440  * @param[in] message Pointer to the received IKE message
441  * @param[in] length Length of the IKE message, in bytes
442  * @return Error code
443  **/
444 
446  const uint8_t *message, size_t length)
447 {
448  error_t error;
449  error_t certValidResult;
450  uint_t i;
451  size_t n;
452  X509CertInfo *certInfo;
453  X509CertInfo *issuerCertInfo;
454  IkeCertPayload *certPayload;
455 
456  //Initialize X.509 certificates
457  certInfo = NULL;
458  issuerCertInfo = NULL;
459 
460  //Start of exception handling block
461  do
462  {
463  //Allocate a memory buffer to store X.509 certificate info
464  certInfo = ikeAllocMem(sizeof(X509CertInfo));
465  //Failed to allocate memory?
466  if(certInfo == NULL)
467  {
468  //Report an error
469  error = ERROR_OUT_OF_MEMORY;
470  break;
471  }
472 
473  //Allocate a memory buffer to store the parent certificate
474  issuerCertInfo = ikeAllocMem(sizeof(X509CertInfo));
475  //Failed to allocate memory?
476  if(issuerCertInfo == NULL)
477  {
478  //Report an error
479  error = ERROR_OUT_OF_MEMORY;
480  break;
481  }
482 
483  //The first CERT payload holds the public key used to validate the
484  //sender's AUTH payload (refer to RFC7296, section 3.6)
485  certPayload = (IkeCertPayload *) ikeGetPayload(message, length,
487  //CERT payload no found?
488  if(certPayload == NULL)
489  {
490  //Report an error
491  error = ERROR_INVALID_MESSAGE;
492  break;
493  }
494 
495  //Retrieve the length of the CERT payload
496  n = ntohs(certPayload->header.payloadLength);
497 
498  //Malformed Certificate payload?
499  if(n < sizeof(IkeCertPayload))
500  {
501  //Report an error
502  error = ERROR_INVALID_MESSAGE;
503  break;
504  }
505 
506  //Determine the length of the Certificate Data field
507  n -= sizeof(IkeCertPayload);
508 
509  //Display ASN.1 structure
510  error = asn1DumpObject(certPayload->certData, n, 0);
511  //Any error to report?
512  if(error)
513  break;
514 
515  //Parse end-entity certificate
516  error = x509ParseCertificate(certPayload->certData, n, certInfo);
517  //Failed to parse the X.509 certificate?
518  if(error)
519  {
520  //Report an error
521  error = ERROR_BAD_CERTIFICATE;
522  break;
523  }
524 
525  //Check certificate key usage
526  error = ikeCheckKeyUsage(certInfo);
527  //Any error to report?
528  if(error)
529  break;
530 
531  //Check if the end-entity certificate can be matched with a trusted CA
532  certValidResult = ikeValidateCertificate(sa, padEntry, certInfo, 0);
533 
534  //Check validation result
535  if(certValidResult != NO_ERROR && certValidResult != ERROR_UNKNOWN_CA)
536  {
537  //The certificate is not valid
538  error = certValidResult;
539  break;
540  }
541 
542  //PKIX path validation
543  for(i = 0; length > 0; i++)
544  {
545  //If a chain of certificates needs to be sent, multiple CERT payloads
546  //are used (refer to RFC 7296, section 3.6)
547  certPayload = (IkeCertPayload *) ikeGetPayload(message, length,
548  IKE_PAYLOAD_TYPE_CERT, i + 1);
549  //End of certificate chain?
550  if(certPayload == NULL)
551  {
552  //We are done
553  error = NO_ERROR;
554  break;
555  }
556 
557  //Retrieve the length of the CERT payload
558  n = ntohs(certPayload->header.payloadLength);
559 
560  //Malformed Certificate payload?
561  if(n < sizeof(IkeCertPayload))
562  {
563  //Report an error
564  error = ERROR_INVALID_MESSAGE;
565  break;
566  }
567 
568  //Determine the length of the Certificate Data field
569  n -= sizeof(IkeCertPayload);
570 
571  //Display ASN.1 structure
572  error = asn1DumpObject(certPayload->certData, n, 0);
573  //Any error to report?
574  if(error)
575  break;
576 
577  //Parse intermediate certificate
578  error = x509ParseCertificate(certPayload->certData, n, issuerCertInfo);
579  //Failed to parse the X.509 certificate?
580  if(error)
581  {
582  //Report an error
583  error = ERROR_BAD_CERTIFICATE;
584  break;
585  }
586 
587  //Certificate chain validation in progress?
588  if(certValidResult == ERROR_UNKNOWN_CA)
589  {
590  //Validate current certificate
591  error = x509ValidateCertificate(certInfo, issuerCertInfo, i);
592  //Certificate validation failed?
593  if(error)
594  break;
595 
596  //Check the version of the certificate
597  if(issuerCertInfo->tbsCert.version < X509_VERSION_3)
598  {
599  //Conforming implementations may choose to reject all version 1
600  //and version 2 intermediate certificates (refer to RFC 5280,
601  //section 6.1.4)
602  error = ERROR_BAD_CERTIFICATE;
603  break;
604  }
605 
606  //Check if the intermediate certificate can be matched with a
607  //trusted CA
608  certValidResult = ikeValidateCertificate(sa, padEntry,
609  issuerCertInfo, i);
610 
611  //Check validation result
612  if(certValidResult != NO_ERROR && certValidResult != ERROR_UNKNOWN_CA)
613  {
614  //The certificate is not valid
615  error = certValidResult;
616  break;
617  }
618  }
619 
620  //Keep track of the issuer certificate
621  *certInfo = *issuerCertInfo;
622  }
623 
624  //Certificate chain validation failed?
625  if(error == NO_ERROR && certValidResult != NO_ERROR)
626  {
627  //A valid certificate chain or partial chain was received, but the
628  //certificate was not accepted because the CA certificate could not
629  //be matched with a known, trusted CA
630  error = ERROR_UNKNOWN_CA;
631  }
632 
633  //End of exception handling block
634  } while(0);
635 
636  //Free previously allocated memory
637  ikeFreeMem(certInfo);
638  ikeFreeMem(issuerCertInfo);
639 
640  //Return status code
641  return error;
642 }
643 
644 
645 /**
646  * @brief Verify certificate against root CAs
647  * @param[in] sa Pointer to the IKE SA
648  * @param[in] padEntry Pointer to the PAD entry
649  * @param[in] certInfo X.509 certificate to be verified
650  * @param[in] pathLen Certificate path length
651  * @return Error code
652  **/
653 
655  const X509CertInfo *certInfo, uint_t pathLen)
656 {
657  error_t error;
658  size_t pemCertLen;
659  const char_t *trustedCaList;
660  size_t trustedCaListLen;
661  uint8_t *derCert;
662  size_t derCertLen;
663  IkeContext *context;
664  X509CertInfo *caCertInfo;
665 
666  //Initialize status code
667  error = ERROR_UNKNOWN_CA;
668 
669  //Point to the IKE context
670  context = sa->context;
671 
672  //Any registered callback?
673  if(context->certVerifyCallback != NULL)
674  {
675  //Invoke user callback function
676  error = context->certVerifyCallback(sa, certInfo, pathLen);
677  }
678 
679  //Check status code
680  if(error == NO_ERROR)
681  {
682  //The certificate is valid
683  }
684  else if(error == ERROR_UNKNOWN_CA)
685  {
686  //Check whether the certificate should be checked against root CAs
687  if(padEntry->trustedCaListLen > 0)
688  {
689  //Point to the first trusted CA certificate
690  trustedCaList = padEntry->trustedCaList;
691  //Get the total length, in bytes, of the trusted CA list
692  trustedCaListLen = padEntry->trustedCaListLen;
693 
694  //Allocate a memory buffer to store X.509 certificate info
695  caCertInfo = ikeAllocMem(sizeof(X509CertInfo));
696 
697  //Successful memory allocation?
698  if(caCertInfo != NULL)
699  {
700  //Loop through the list of trusted CA certificates
701  while(trustedCaListLen > 0 && error == ERROR_UNKNOWN_CA)
702  {
703  //The first pass calculates the length of the DER-encoded
704  //certificate
705  error = pemImportCertificate(trustedCaList, trustedCaListLen,
706  NULL, &derCertLen, &pemCertLen);
707 
708  //Check status code
709  if(!error)
710  {
711  //Allocate a memory buffer to hold the DER-encoded certificate
712  derCert = ikeAllocMem(derCertLen);
713 
714  //Successful memory allocation?
715  if(derCert != NULL)
716  {
717  //The second pass decodes the PEM certificate
718  error = pemImportCertificate(trustedCaList,
719  trustedCaListLen, derCert, &derCertLen, NULL);
720 
721  //Check status code
722  if(!error)
723  {
724  //Parse X.509 certificate
725  error = x509ParseCertificate(derCert, derCertLen,
726  caCertInfo);
727  }
728 
729  //Check status code
730  if(!error)
731  {
732  //Validate the certificate with the current CA
733  error = x509ValidateCertificate(certInfo, caCertInfo,
734  pathLen);
735  }
736 
737  //Check status code
738  if(!error)
739  {
740  //The certificate is issued by a trusted CA
741  error = NO_ERROR;
742  }
743  else
744  {
745  //The certificate cannot be matched with the current CA
746  error = ERROR_UNKNOWN_CA;
747  }
748 
749  //Free previously allocated memory
750  ikeFreeMem(derCert);
751  }
752  else
753  {
754  //Failed to allocate memory
755  error = ERROR_OUT_OF_MEMORY;
756  }
757 
758  //Advance read pointer
759  trustedCaList += pemCertLen;
760  trustedCaListLen -= pemCertLen;
761  }
762  else
763  {
764  //No more CA certificates in the list
765  trustedCaListLen = 0;
766  error = ERROR_UNKNOWN_CA;
767  }
768  }
769 
770  //Free previously allocated memory
771  ikeFreeMem(caCertInfo);
772  }
773  else
774  {
775  //Failed to allocate memory
776  error = ERROR_OUT_OF_MEMORY;
777  }
778  }
779  else
780  {
781  //Do not check the certificate against root CAs
782  error = NO_ERROR;
783  }
784  }
785  else if(error == ERROR_BAD_CERTIFICATE ||
787  error == ERROR_UNKNOWN_CERTIFICATE ||
788  error == ERROR_CERTIFICATE_REVOKED ||
789  error == ERROR_CERTIFICATE_EXPIRED ||
790  error == ERROR_HANDSHAKE_FAILED)
791  {
792  //The certificate is not valid
793  }
794  else
795  {
796  //Report an error
797  error = ERROR_BAD_CERTIFICATE;
798  }
799 
800  //Return status code
801  return error;
802 }
803 
804 
805 /**
806  * @brief Check certificate key usage
807  * @param[in] certInfo Pointer to the X.509 certificate
808  * @return Error code
809  **/
810 
812 {
813  error_t error;
814  const X509KeyUsage *keyUsage;
815  const X509ExtendedKeyUsage *extKeyUsage;
816 
817  //Initialize status code
818  error = NO_ERROR;
819 
820  //Point to the KeyUsage extension
821  keyUsage = &certInfo->tbsCert.extensions.keyUsage;
822 
823  //Check if the KeyUsage extension is present
824  if(keyUsage->bitmap != 0)
825  {
826  //If KeyUsage is present and does not mention digitalSignature or
827  //nonRepudiation, then reject the certificate (refer to RFC4945,
828  //section 5.1.3.2)
829  if((keyUsage->bitmap & X509_KEY_USAGE_DIGITAL_SIGNATURE) == 0 &&
830  (keyUsage->bitmap & X509_KEY_USAGE_NON_REPUDIATION) == 0)
831  {
832  error = ERROR_BAD_CERTIFICATE;
833  }
834  }
835 
836  //Point to the ExtendedKeyUsage extension
837  extKeyUsage = &certInfo->tbsCert.extensions.extKeyUsage;
838 
839  //Check if the ExtendedKeyUsage extension is present
840  if(extKeyUsage->bitmap != 0)
841  {
842  //If ExtendedKeyUsage is present and contains either id-kp-ipsecIKE or
843  //anyExtendedKeyUsage, continue. Otherwise, reject certificate (refer
844  //to RFC 4945, section 5.1.3.12)
845  if((extKeyUsage->bitmap & X509_EXT_KEY_USAGE_IPSEC_IKE) == 0)
846  {
847  error = ERROR_BAD_CERTIFICATE;
848  }
849  }
850 
851  //Return status code
852  return error;
853 }
854 
855 #endif
error_t asn1DumpObject(const uint8_t *data, size_t length, uint_t level)
Display an ASN.1 data object.
Definition: asn1.c:706
ASN.1 (Abstract Syntax Notation One)
uint8_t message[]
Definition: chap.h:154
unsigned int uint_t
Definition: compiler_port.h:50
char char_t
Definition: compiler_port.h:48
int bool_t
Definition: compiler_port.h:53
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
uint8_t n
const uint8_t DSA_OID[7]
Definition: dsa.c:51
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:43
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:76
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:98
const uint8_t BRAINPOOLP512R1_OID[9]
Definition: ec_curves.c:90
const uint8_t BRAINPOOLP256R1_OID[9]
Definition: ec_curves.c:84
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:72
const uint8_t ED448_OID[3]
Definition: ec_curves.c:100
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:74
const uint8_t BRAINPOOLP384R1_OID[9]
Definition: ec_curves.c:88
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNKNOWN_CA
Definition: error.h:239
@ ERROR_CERTIFICATE_REVOKED
Definition: error.h:238
@ ERROR_UNSUPPORTED_CERTIFICATE
Definition: error.h:235
@ ERROR_INVALID_MESSAGE
Definition: error.h:105
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:232
@ ERROR_UNKNOWN_CERTIFICATE
Definition: error.h:236
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:237
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_BAD_CERTIFICATE
Definition: error.h:234
IKEv2 (Internet Key Exchange Protocol)
IkeCertPayload
Definition: ike.h:1378
#define IkeContext
Definition: ike.h:678
#define ikeFreeMem(p)
Definition: ike.h:633
IkeCertType
Certificate types.
Definition: ike.h:1222
@ IKE_CERT_TYPE_ECDSA_P384
Definition: ike.h:1228
@ IKE_CERT_TYPE_ECDSA_P521
Definition: ike.h:1229
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP256R1
Definition: ike.h:1230
@ IKE_CERT_TYPE_RSA_PSS
Definition: ike.h:1225
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP512R1
Definition: ike.h:1232
@ IKE_CERT_TYPE_RSA
Definition: ike.h:1224
@ IKE_CERT_TYPE_DSA
Definition: ike.h:1226
@ IKE_CERT_TYPE_ED25519
Definition: ike.h:1233
@ IKE_CERT_TYPE_ED448
Definition: ike.h:1234
@ IKE_CERT_TYPE_ECDSA_P256
Definition: ike.h:1227
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP384R1
Definition: ike.h:1231
@ IKE_PAYLOAD_TYPE_CERT
Certificate.
Definition: ike.h:732
#define IkeSaEntry
Definition: ike.h:682
#define ikeAllocMem(size)
Definition: ike.h:628
#define IKE_SHA1_DIGEST_SIZE
Definition: ike.h:674
error_t ikeGetCertSubjectDn(const char_t *cert, size_t certLen, uint8_t *subjectDn, size_t *subjectDnLen)
Extract subject's DN from certificate.
bool_t ikeIsDuplicateCa(const uint8_t *certAuth, size_t certAuthLen, const uint8_t *digest)
Test whether the provided SHA-1 digest value is a duplicate.
error_t ikeValidateCertificate(IkeSaEntry *sa, IpsecPadEntry *padEntry, const X509CertInfo *certInfo, uint_t pathLen)
Verify certificate against root CAs.
error_t ikeCheckKeyUsage(const X509CertInfo *certInfo)
Check certificate key usage.
error_t ikeGetCertificateType(const X509CertInfo *certInfo, IkeCertType *certType)
Retrieve the certificate type.
error_t ikeFormatCertAuthorities(const char_t *trustedCaList, size_t trustedCaListLen, uint8_t *certAuth, size_t *certAuthLen)
Format list of acceptable certification authorities.
error_t ikeParseCertificateChain(IkeSaEntry *sa, IpsecPadEntry *padEntry, const uint8_t *message, size_t length)
Parse certificate chain.
X.509 certificate handling.
const IkePayloadHeader * ikeGetPayload(const uint8_t *message, size_t length, uint8_t type, uint_t index)
Search an IKE message for a given payload type.
IKE payload parsing.
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:61
PEM file import functions.
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
Peer Authorization Database (PAD) entry.
Definition: ipsec.h:400
size_t trustedCaListLen
Trusted CA list (PEM format)
Definition: ipsec.h:408
const char_t * trustedCaList
Definition: ipsec.h:407
X.509 certificate.
Definition: x509_common.h:1064
X509TbsCertificate tbsCert
Definition: x509_common.h:1065
EC parameters.
Definition: x509_common.h:763
X509OctetString namedCurve
Definition: x509_common.h:764
Extended Key Usage extension.
Definition: x509_common.h:841
X509KeyUsage keyUsage
Definition: x509_common.h:1000
X509ExtendedKeyUsage extKeyUsage
Definition: x509_common.h:1001
Key Usage extension.
Definition: x509_common.h:830
uint16_t bitmap
Definition: x509_common.h:832
X509OctetString raw
Definition: x509_common.h:669
const uint8_t * value
Definition: x509_common.h:647
X509OctetString raw
Definition: x509_common.h:784
X509OctetString oid
Definition: x509_common.h:785
X509EcParameters ecParams
Definition: x509_common.h:795
X509Version version
Definition: x509_common.h:1048
X509Extensions extensions
Definition: x509_common.h:1055
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:1054
uint8_t length
Definition: tcp.h:368
error_t x509ParseCertificate(const uint8_t *data, size_t length, X509CertInfo *certInfo)
Parse a X.509 certificate.
error_t x509ParseCertificateEx(const uint8_t *data, size_t length, X509CertInfo *certInfo, bool_t ignoreUnknown)
Parse a X.509 certificate.
X.509 certificate parsing.
error_t x509ValidateCertificate(const X509CertInfo *certInfo, const X509CertInfo *issuerCertInfo, uint_t pathLen)
X.509 certificate validation.
X.509 certificate validation.
@ X509_EXT_KEY_USAGE_IPSEC_IKE
Definition: x509_common.h:498
@ X509_KEY_USAGE_DIGITAL_SIGNATURE
Definition: x509_common.h:471
@ X509_KEY_USAGE_NON_REPUDIATION
Definition: x509_common.h:472
@ X509_VERSION_3
Definition: x509_common.h:461