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