ua_pki_certificate.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
  2. * See http://creativecommons.org/publicdomain/zero/1.0/ for more information.
  3. *
  4. * Copyright 2018 (c) Mark Giraud, Fraunhofer IOSB
  5. */
  6. #include "ua_pki_certificate.h"
  7. #ifdef UA_ENABLE_ENCRYPTION
  8. #include <mbedtls/x509.h>
  9. #include <mbedtls/x509_crt.h>
  10. #endif
  11. /************/
  12. /* AllowAll */
  13. /************/
  14. static UA_StatusCode
  15. verifyAllowAll(void *verificationContext, const UA_ByteString *certificate) {
  16. return UA_STATUSCODE_GOOD;
  17. }
  18. static void
  19. deleteVerifyAllowAll(UA_CertificateVerification *cv) {
  20. }
  21. void UA_CertificateVerification_AcceptAll(UA_CertificateVerification *cv) {
  22. cv->verifyCertificate = verifyAllowAll;
  23. cv->deleteMembers = deleteVerifyAllowAll;
  24. }
  25. #ifdef UA_ENABLE_ENCRYPTION
  26. typedef struct {
  27. mbedtls_x509_crt certificateTrustList;
  28. mbedtls_x509_crl certificateRevocationList;
  29. } CertInfo;
  30. static UA_StatusCode
  31. certificateVerification_verify(void *verificationContext,
  32. const UA_ByteString *certificate) {
  33. CertInfo *ci = (CertInfo*)verificationContext;
  34. if(!ci)
  35. return UA_STATUSCODE_BADINTERNALERROR;
  36. /* Parse the certificate */
  37. mbedtls_x509_crt remoteCertificate;
  38. mbedtls_x509_crt_init(&remoteCertificate);
  39. int mbedErr = mbedtls_x509_crt_parse(&remoteCertificate, certificate->data,
  40. certificate->length);
  41. if(mbedErr) {
  42. /* char errBuff[300]; */
  43. /* mbedtls_strerror(mbedErr, errBuff, 300); */
  44. /* UA_LOG_WARNING(data->policyContext->securityPolicy->logger, UA_LOGCATEGORY_SECURITYPOLICY, */
  45. /* "Could not parse the remote certificate with error: %s", errBuff); */
  46. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  47. }
  48. /* Verify */
  49. mbedtls_x509_crt_profile crtProfile = {
  50. MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256),
  51. 0xFFFFFF, 0x000000, 128 * 8 // in bits
  52. }; // TODO: remove magic numbers
  53. uint32_t flags = 0;
  54. mbedErr = mbedtls_x509_crt_verify_with_profile(&remoteCertificate,
  55. &ci->certificateTrustList,
  56. &ci->certificateRevocationList,
  57. &crtProfile, NULL, &flags, NULL, NULL);
  58. // TODO: Extend verification
  59. if(mbedErr) {
  60. /* char buff[100]; */
  61. /* mbedtls_x509_crt_verify_info(buff, 100, "", flags); */
  62. /* UA_LOG_ERROR(channelContextData->policyContext->securityPolicy->logger, */
  63. /* UA_LOGCATEGORY_SECURITYPOLICY, */
  64. /* "Verifying the certificate failed with error: %s", buff); */
  65. mbedtls_x509_crt_free(&remoteCertificate);
  66. if(flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
  67. return UA_STATUSCODE_BADCERTIFICATEUNTRUSTED;
  68. if(flags & MBEDTLS_X509_BADCERT_FUTURE ||
  69. flags & MBEDTLS_X509_BADCERT_EXPIRED)
  70. return UA_STATUSCODE_BADCERTIFICATETIMEINVALID;
  71. if(flags & MBEDTLS_X509_BADCERT_REVOKED ||
  72. flags & MBEDTLS_X509_BADCRL_EXPIRED)
  73. return UA_STATUSCODE_BADCERTIFICATEREVOKED;
  74. return UA_STATUSCODE_BADSECURITYCHECKSFAILED;
  75. }
  76. mbedtls_x509_crt_free(&remoteCertificate);
  77. return UA_STATUSCODE_GOOD;
  78. }
  79. static void
  80. certificateVerification_deleteMembers(UA_CertificateVerification *cv) {
  81. CertInfo *ci = (CertInfo*)cv->context;
  82. if(!ci)
  83. return;
  84. mbedtls_x509_crt_free(&ci->certificateTrustList);
  85. mbedtls_x509_crl_free(&ci->certificateRevocationList);
  86. UA_free(ci);
  87. cv->context = NULL;
  88. }
  89. UA_StatusCode
  90. UA_CertificateVerification_Trustlist(UA_CertificateVerification *cv,
  91. const UA_ByteString *certificateTrustList,
  92. size_t certificateTrustListSize,
  93. const UA_ByteString *certificateRevocationList,
  94. size_t certificateRevocationListSize) {
  95. CertInfo *ci = (CertInfo*)malloc(sizeof(CertInfo));
  96. if(!ci)
  97. return UA_STATUSCODE_BADOUTOFMEMORY;
  98. mbedtls_x509_crt_init(&ci->certificateTrustList);
  99. mbedtls_x509_crl_init(&ci->certificateRevocationList);
  100. cv->context = (void*)ci;
  101. if(certificateTrustListSize > 0)
  102. cv->verifyCertificate = certificateVerification_verify;
  103. else
  104. cv->verifyCertificate = verifyAllowAll;
  105. cv->deleteMembers = certificateVerification_deleteMembers;
  106. int err = 0;
  107. for(size_t i = 0; i < certificateTrustListSize; i++) {
  108. err |= mbedtls_x509_crt_parse(&ci->certificateTrustList,
  109. certificateTrustList[i].data,
  110. certificateTrustList[i].length);
  111. }
  112. for(size_t i = 0; i < certificateRevocationListSize; i++) {
  113. err |= mbedtls_x509_crl_parse(&ci->certificateRevocationList,
  114. certificateRevocationList[i].data,
  115. certificateRevocationList[i].length);
  116. }
  117. if(err) {
  118. certificateVerification_deleteMembers(cv);
  119. return UA_STATUSCODE_BADINTERNALERROR;
  120. }
  121. return UA_STATUSCODE_GOOD;
  122. }
  123. #endif