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.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?
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  {
237  //Parse X.509 certificate
238  error = x509ParseCertificateEx(derCert, derCertLen, certInfo,
239  TRUE);
240 
241  //Check status code
242  if(!error)
243  {
244  //Copy the X.500 distinguished name
245  osMemcpy(subjectDn, certInfo->tbsCert.subject.raw.value,
246  certInfo->tbsCert.subject.raw.length);
247 
248  //Total length of the payload
249  *subjectDnLen = certInfo->tbsCert.subject.raw.length;
250  }
251 
252  //Release previously allocated memory
253  ikeFreeMem(certInfo);
254  }
255  else
256  {
257  //Failed to allocate memory
258  error = ERROR_OUT_OF_MEMORY;
259  }
260 
261  //Release previously allocated memory
262  ikeFreeMem(derCert);
263  }
264  }
265  else
266  {
267  //Failed to allocate memory
268  error = ERROR_OUT_OF_MEMORY;
269  }
270  }
271 
272  //Return status code
273  return error;
274 }
275 
276 
277 /**
278  * @brief Format list of acceptable certification authorities
279  * @param[in] trustedCaList List of trusted CA (PEM format)
280  * @param[in] trustedCaListLen Total length of the list
281  * @param[out] certAuth List of SHA-1 hashes of the public keys of trusted CAs
282  * @param[in,out] certAuthLen Actual length of the list, in bytes
283  * @return Error code
284  **/
285 
287  size_t trustedCaListLen, uint8_t *certAuth, size_t *certAuthLen)
288 {
289 #if (SHA1_SUPPORT == ENABLED)
290  error_t error;
291  size_t n;
292  size_t derCertLen;
293  uint8_t *derCert;
294  X509CertInfo *certInfo;
295 
296  //Initialize status code
297  error = NO_ERROR;
298 
299  //Allocate a memory buffer to store X.509 certificate info
300  certInfo = ikeAllocMem(sizeof(X509CertInfo));
301 
302  //Successful memory allocation?
303  if(certInfo != NULL)
304  {
305  //Loop through the list of trusted CA certificates
306  while(trustedCaListLen > 0 && !error)
307  {
308  //The first pass calculates the length of the DER-encoded certificate
309  error = pemImportCertificate(trustedCaList, trustedCaListLen, NULL,
310  &derCertLen, &n);
311 
312  //Check status code
313  if(!error)
314  {
315  //Allocate a memory buffer to hold the DER-encoded certificate
316  derCert = ikeAllocMem(derCertLen);
317 
318  //Successful memory allocation?
319  if(derCert != NULL)
320  {
321  //The second pass decodes the PEM certificate
322  error = pemImportCertificate(trustedCaList, trustedCaListLen,
323  derCert, &derCertLen, NULL);
324 
325  //Check status code
326  if(!error)
327  {
328  //Parse X.509 certificate
329  error = x509ParseCertificate(derCert, derCertLen, certInfo);
330  }
331 
332  //Valid CA certificate?
333  if(!error)
334  {
335  //The Certification Authority value is a concatenated list of
336  //SHA-1 hashes of the public keys of trusted Certification
337  //Authorities (CAs). Each is encoded as the SHA-1 hash of the
338  //SubjectPublicKeyInfo element
341  certAuth + *certAuthLen);
342 
343  //Check status code
344  if(!error)
345  {
346  //Ensure the SHA-1 digest value is not a duplicate
347  if(!ikeIsDuplicateCa(certAuth, *certAuthLen,
348  certAuth + *certAuthLen))
349  {
350  //The 20-octet hashes are concatenated and included with no
351  //other formatting
352  *certAuthLen += IKE_SHA1_DIGEST_SIZE;
353  }
354  }
355  }
356  else
357  {
358  //Discard current CA certificate
359  error = NO_ERROR;
360  }
361 
362  //Free previously allocated memory
363  ikeFreeMem(derCert);
364  }
365  else
366  {
367  //Failed to allocate memory
368  error = ERROR_OUT_OF_MEMORY;
369  }
370 
371  //Point to the next CA of the list
372  trustedCaList += n;
373  trustedCaListLen -= n;
374  }
375  else
376  {
377  //End of file detected
378  trustedCaListLen = 0;
379  error = NO_ERROR;
380  }
381  }
382 
383  //Free previously allocated memory
384  ikeFreeMem(certInfo);
385  }
386  else
387  {
388  //Failed to allocate memory
389  error = ERROR_OUT_OF_MEMORY;
390  }
391 
392  //Return status code
393  return error;
394 #else
395  //SHA-1 is not supported
396  return NO_ERROR;
397 #endif
398 }
399 
400 
401 /**
402  * @brief Test whether the provided SHA-1 digest value is a duplicate
403  * @param[in] certAuth List of SHA-1 hashes of the public keys of trusted CAs
404  * @param[in] certAuthLen Length of the list, in bytes
405  * @param[in] digest SHA-1 digest to be checked for duplicate value
406  * @return TRUE if the SHA-1 digest value is a duplicate, else FALSE
407  **/
408 
409 bool_t ikeIsDuplicateCa(const uint8_t *certAuth, size_t certAuthLen,
410  const uint8_t *digest)
411 {
412  size_t i;
413  bool_t flag;
414 
415  //Initialize flag
416  flag = FALSE;
417 
418  //The Certification Authority value is a concatenated list of SHA-1 hashes
419  //of the public keys of trusted Certification Authorities (CAs)
420  for(i = 0; i < certAuthLen; i += IKE_SHA1_DIGEST_SIZE)
421  {
422  //Compare SHA-1 digest values
423  if(osMemcmp(certAuth + i, digest, IKE_SHA1_DIGEST_SIZE) == 0)
424  {
425  //The SHA-1 hash is a duplicate
426  flag = TRUE;
427  }
428  }
429 
430  //Return TRUE if the SHA-1 hash value is a duplicate
431  return flag;
432 }
433 
434 
435 /**
436  * @brief Parse certificate chain
437  * @param[in] sa Pointer to the IKE SA
438  * @param[in] padEntry Pointer to the PAD entry
439  * @param[in] message Pointer to the received IKE message
440  * @param[in] length Length of the IKE message, in bytes
441  * @return Error code
442  **/
443 
445  const uint8_t *message, size_t length)
446 {
447  error_t error;
448  error_t certValidResult;
449  uint_t i;
450  size_t n;
451  X509CertInfo *certInfo;
452  X509CertInfo *issuerCertInfo;
453  IkeCertPayload *certPayload;
454 
455  //Initialize X.509 certificates
456  certInfo = NULL;
457  issuerCertInfo = NULL;
458 
459  //Start of exception handling block
460  do
461  {
462  //Allocate a memory buffer to store X.509 certificate info
463  certInfo = ikeAllocMem(sizeof(X509CertInfo));
464  //Failed to allocate memory?
465  if(certInfo == NULL)
466  {
467  //Report an error
468  error = ERROR_OUT_OF_MEMORY;
469  break;
470  }
471 
472  //Allocate a memory buffer to store the parent certificate
473  issuerCertInfo = ikeAllocMem(sizeof(X509CertInfo));
474  //Failed to allocate memory?
475  if(issuerCertInfo == NULL)
476  {
477  //Report an error
478  error = ERROR_OUT_OF_MEMORY;
479  break;
480  }
481 
482  //The first CERT payload holds the public key used to validate the
483  //sender's AUTH payload (refer to RFC7296, section 3.6)
484  certPayload = (IkeCertPayload *) ikeGetPayload(message, length,
486  //CERT payload no found?
487  if(certPayload == NULL)
488  {
489  //Report an error
490  error = ERROR_INVALID_MESSAGE;
491  break;
492  }
493 
494  //Retrieve the length of the CERT payload
495  n = ntohs(certPayload->header.payloadLength);
496 
497  //Malformed Certificate payload?
498  if(n < sizeof(IkeCertPayload))
499  {
500  //Report an error
501  error = ERROR_INVALID_MESSAGE;
502  break;
503  }
504 
505  //Determine the length of the Certificate Data field
506  n -= sizeof(IkeCertPayload);
507 
508  //Display ASN.1 structure
509  error = asn1DumpObject(certPayload->certData, n, 0);
510  //Any error to report?
511  if(error)
512  break;
513 
514  //Parse end-entity certificate
515  error = x509ParseCertificate(certPayload->certData, n, certInfo);
516  //Failed to parse the X.509 certificate?
517  if(error)
518  {
519  //Report an error
520  error = ERROR_BAD_CERTIFICATE;
521  break;
522  }
523 
524  //Check certificate key usage
525  error = ikeCheckKeyUsage(certInfo);
526  //Any error to report?
527  if(error)
528  break;
529 
530  //Check if the end-entity certificate can be matched with a trusted CA
531  certValidResult = ikeValidateCertificate(sa, padEntry, certInfo, 0);
532 
533  //Check validation result
534  if(certValidResult != NO_ERROR && certValidResult != ERROR_UNKNOWN_CA)
535  {
536  //The certificate is not valid
537  error = certValidResult;
538  break;
539  }
540 
541  //PKIX path validation
542  for(i = 0; length > 0; i++)
543  {
544  //If a chain of certificates needs to be sent, multiple CERT payloads
545  //are used (refer to RFC 7296, section 3.6)
546  certPayload = (IkeCertPayload *) ikeGetPayload(message, length,
547  IKE_PAYLOAD_TYPE_CERT, i + 1);
548  //End of certificate chain?
549  if(certPayload == NULL)
550  {
551  //We are done
552  error = NO_ERROR;
553  break;
554  }
555 
556  //Retrieve the length of the CERT payload
557  n = ntohs(certPayload->header.payloadLength);
558 
559  //Malformed Certificate payload?
560  if(n < sizeof(IkeCertPayload))
561  {
562  //Report an error
563  error = ERROR_INVALID_MESSAGE;
564  break;
565  }
566 
567  //Determine the length of the Certificate Data field
568  n -= sizeof(IkeCertPayload);
569 
570  //Display ASN.1 structure
571  error = asn1DumpObject(certPayload->certData, n, 0);
572  //Any error to report?
573  if(error)
574  break;
575 
576  //Parse intermediate certificate
577  error = x509ParseCertificate(certPayload->certData, n, issuerCertInfo);
578  //Failed to parse the X.509 certificate?
579  if(error)
580  {
581  //Report an error
582  error = ERROR_BAD_CERTIFICATE;
583  break;
584  }
585 
586  //Certificate chain validation in progress?
587  if(certValidResult == ERROR_UNKNOWN_CA)
588  {
589  //Validate current certificate
590  error = x509ValidateCertificate(certInfo, issuerCertInfo, i);
591  //Certificate validation failed?
592  if(error)
593  break;
594 
595  //Check the version of the certificate
596  if(issuerCertInfo->tbsCert.version < X509_VERSION_3)
597  {
598  //Conforming implementations may choose to reject all version 1
599  //and version 2 intermediate certificates (refer to RFC 5280,
600  //section 6.1.4)
601  error = ERROR_BAD_CERTIFICATE;
602  break;
603  }
604 
605  //Check if the intermediate certificate can be matched with a
606  //trusted CA
607  certValidResult = ikeValidateCertificate(sa, padEntry,
608  issuerCertInfo, i);
609 
610  //Check validation result
611  if(certValidResult != NO_ERROR && certValidResult != ERROR_UNKNOWN_CA)
612  {
613  //The certificate is not valid
614  error = certValidResult;
615  break;
616  }
617  }
618 
619  //Keep track of the issuer certificate
620  *certInfo = *issuerCertInfo;
621  }
622 
623  //Certificate chain validation failed?
624  if(error == NO_ERROR && certValidResult != NO_ERROR)
625  {
626  //A valid certificate chain or partial chain was received, but the
627  //certificate was not accepted because the CA certificate could not
628  //be matched with a known, trusted CA
629  error = ERROR_UNKNOWN_CA;
630  }
631 
632  //End of exception handling block
633  } while(0);
634 
635  //Free previously allocated memory
636  ikeFreeMem(certInfo);
637  ikeFreeMem(issuerCertInfo);
638 
639  //Return status code
640  return error;
641 }
642 
643 
644 /**
645  * @brief Verify certificate against root CAs
646  * @param[in] sa Pointer to the IKE SA
647  * @param[in] padEntry Pointer to the PAD entry
648  * @param[in] certInfo X.509 certificate to be verified
649  * @param[in] pathLen Certificate path length
650  * @return Error code
651  **/
652 
654  const X509CertInfo *certInfo, uint_t pathLen)
655 {
656  error_t error;
657  size_t pemCertLen;
658  const char_t *trustedCaList;
659  size_t trustedCaListLen;
660  uint8_t *derCert;
661  size_t derCertLen;
662  IkeContext *context;
663  X509CertInfo *caCertInfo;
664 
665  //Initialize status code
666  error = ERROR_UNKNOWN_CA;
667 
668  //Point to the IKE context
669  context = sa->context;
670 
671  //Any registered callback?
672  if(context->certVerifyCallback != NULL)
673  {
674  //Invoke user callback function
675  error = context->certVerifyCallback(sa, certInfo, pathLen);
676  }
677 
678  //Check status code
679  if(error == NO_ERROR)
680  {
681  //The certificate is valid
682  }
683  else if(error == ERROR_UNKNOWN_CA)
684  {
685  //Check whether the certificate should be checked against root CAs
686  if(padEntry->trustedCaListLen > 0)
687  {
688  //Point to the first trusted CA certificate
689  trustedCaList = padEntry->trustedCaList;
690  //Get the total length, in bytes, of the trusted CA list
691  trustedCaListLen = padEntry->trustedCaListLen;
692 
693  //Allocate a memory buffer to store X.509 certificate info
694  caCertInfo = ikeAllocMem(sizeof(X509CertInfo));
695 
696  //Successful memory allocation?
697  if(caCertInfo != NULL)
698  {
699  //Loop through the list of trusted CA certificates
700  while(trustedCaListLen > 0 && error == ERROR_UNKNOWN_CA)
701  {
702  //The first pass calculates the length of the DER-encoded
703  //certificate
704  error = pemImportCertificate(trustedCaList, trustedCaListLen,
705  NULL, &derCertLen, &pemCertLen);
706 
707  //Check status code
708  if(!error)
709  {
710  //Allocate a memory buffer to hold the DER-encoded certificate
711  derCert = ikeAllocMem(derCertLen);
712 
713  //Successful memory allocation?
714  if(derCert != NULL)
715  {
716  //The second pass decodes the PEM certificate
717  error = pemImportCertificate(trustedCaList,
718  trustedCaListLen, derCert, &derCertLen, NULL);
719 
720  //Check status code
721  if(!error)
722  {
723  //Parse X.509 certificate
724  error = x509ParseCertificate(derCert, derCertLen,
725  caCertInfo);
726  }
727 
728  //Check status code
729  if(!error)
730  {
731  //Validate the certificate with the current CA
732  error = x509ValidateCertificate(certInfo, caCertInfo,
733  pathLen);
734  }
735 
736  //Check status code
737  if(!error)
738  {
739  //The certificate is issued by a trusted CA
740  error = NO_ERROR;
741  }
742  else
743  {
744  //The certificate cannot be matched with the current CA
745  error = ERROR_UNKNOWN_CA;
746  }
747 
748  //Free previously allocated memory
749  ikeFreeMem(derCert);
750  }
751  else
752  {
753  //Failed to allocate memory
754  error = ERROR_OUT_OF_MEMORY;
755  }
756 
757  //Advance read pointer
758  trustedCaList += pemCertLen;
759  trustedCaListLen -= pemCertLen;
760  }
761  else
762  {
763  //No more CA certificates in the list
764  trustedCaListLen = 0;
765  error = ERROR_UNKNOWN_CA;
766  }
767  }
768 
769  //Free previously allocated memory
770  ikeFreeMem(caCertInfo);
771  }
772  else
773  {
774  //Failed to allocate memory
775  error = ERROR_OUT_OF_MEMORY;
776  }
777  }
778  else
779  {
780  //Do not check the certificate against root CAs
781  error = NO_ERROR;
782  }
783  }
784  else if(error == ERROR_BAD_CERTIFICATE ||
786  error == ERROR_UNKNOWN_CERTIFICATE ||
787  error == ERROR_CERTIFICATE_REVOKED ||
788  error == ERROR_CERTIFICATE_EXPIRED ||
789  error == ERROR_HANDSHAKE_FAILED)
790  {
791  //The certificate is not valid
792  }
793  else
794  {
795  //Report an error
796  error = ERROR_BAD_CERTIFICATE;
797  }
798 
799  //Return status code
800  return error;
801 }
802 
803 
804 /**
805  * @brief Check certificate key usage
806  * @param[in] certInfo Pointer to the X.509 certificate
807  * @return Error code
808  **/
809 
811 {
812  error_t error;
813  const X509KeyUsage *keyUsage;
814  const X509ExtendedKeyUsage *extKeyUsage;
815 
816  //Initialize status code
817  error = NO_ERROR;
818 
819  //Point to the KeyUsage extension
820  keyUsage = &certInfo->tbsCert.extensions.keyUsage;
821 
822  //Check if the KeyUsage extension is present
823  if(keyUsage->bitmap != 0)
824  {
825  //If KeyUsage is present and does not mention digitalSignature or
826  //nonRepudiation, then reject the certificate (refer to RFC4945,
827  //section 5.1.3.2)
828  if((keyUsage->bitmap & X509_KEY_USAGE_DIGITAL_SIGNATURE) == 0 &&
829  (keyUsage->bitmap & X509_KEY_USAGE_NON_REPUDIATION) == 0)
830  {
831  error = ERROR_BAD_CERTIFICATE;
832  }
833  }
834 
835  //Point to the ExtendedKeyUsage extension
836  extKeyUsage = &certInfo->tbsCert.extensions.extKeyUsage;
837 
838  //Check if the ExtendedKeyUsage extension is present
839  if(extKeyUsage->bitmap != 0)
840  {
841  //If ExtendedKeyUsage is present and contains either id-kp-ipsecIKE or
842  //anyExtendedKeyUsage, continue. Otherwise, reject certificate (refer
843  //to RFC 4945, section 5.1.3.12)
844  if((extKeyUsage->bitmap & X509_EXT_KEY_USAGE_IPSEC_IKE) == 0)
845  {
846  error = ERROR_BAD_CERTIFICATE;
847  }
848  }
849 
850  //Return status code
851  return error;
852 }
853 
854 #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:1120
@ 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:856
#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
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:61
@ X509_KEY_USAGE_NON_REPUDIATION
Definition: x509_common.h:527
PEM file import functions.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
X.509 certificate.
Definition: x509_common.h:1119
error_t
Error codes.
Definition: error.h:43
@ 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 x509ParseCertificateEx(const uint8_t *data, size_t length, X509CertInfo *certInfo, bool_t ignoreUnknown)
Parse a X.509 certificate.
error_t ikeCheckKeyUsage(const X509CertInfo *certInfo)
Check certificate key usage.
X.509 certificate validation.
@ 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