ua_pki_certificate.c 4.9 KB

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