test_crypto_openssl.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define CRYPTO_RAND_PRIVATE
  7. #include "lib/crypt_ops/compat_openssl.h"
  8. #include "lib/crypt_ops/crypto_rand.h"
  9. #include "lib/encoding/binascii.h"
  10. #include "lib/malloc/malloc.h"
  11. #include "test/test.h"
  12. #include <openssl/evp.h>
  13. #include <openssl/rand.h>
  14. #include <string.h>
  15. /* Test for rectifying openssl RAND engine. */
  16. static void
  17. test_crypto_rng_engine(void *arg)
  18. {
  19. (void)arg;
  20. RAND_METHOD dummy_method;
  21. memset(&dummy_method, 0, sizeof(dummy_method));
  22. /* We should be a no-op if we're already on RAND_OpenSSL */
  23. tt_int_op(0, OP_EQ, crypto_force_rand_ssleay());
  24. tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
  25. /* We should correct the method if it's a dummy. */
  26. RAND_set_rand_method(&dummy_method);
  27. #ifdef LIBRESSL_VERSION_NUMBER
  28. /* On libressl, you can't override the RNG. */
  29. tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
  30. tt_int_op(0, OP_EQ, crypto_force_rand_ssleay());
  31. #else
  32. tt_assert(RAND_get_rand_method() == &dummy_method);
  33. tt_int_op(1, OP_EQ, crypto_force_rand_ssleay());
  34. #endif /* defined(LIBRESSL_VERSION_NUMBER) */
  35. tt_assert(RAND_get_rand_method() == RAND_OpenSSL());
  36. /* Make sure we aren't calling dummy_method */
  37. crypto_rand((void *) &dummy_method, sizeof(dummy_method));
  38. crypto_rand((void *) &dummy_method, sizeof(dummy_method));
  39. done:
  40. ;
  41. }
  42. #ifndef OPENSSL_1_1_API
  43. #define EVP_ENCODE_CTX_new() tor_malloc_zero(sizeof(EVP_ENCODE_CTX))
  44. #define EVP_ENCODE_CTX_free(ctx) tor_free(ctx)
  45. #endif
  46. /** Encode src into dest with OpenSSL's EVP Encode interface, returning the
  47. * length of the encoded data in bytes.
  48. */
  49. static int
  50. base64_encode_evp(char *dest, char *src, size_t srclen)
  51. {
  52. const unsigned char *s = (unsigned char*)src;
  53. EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
  54. int len, ret;
  55. EVP_EncodeInit(ctx);
  56. EVP_EncodeUpdate(ctx, (unsigned char *)dest, &len, s, (int)srclen);
  57. EVP_EncodeFinal(ctx, (unsigned char *)(dest + len), &ret);
  58. EVP_ENCODE_CTX_free(ctx);
  59. return ret+ len;
  60. }
  61. static void
  62. test_crypto_base64_encode_matches(void *arg)
  63. {
  64. (void)arg;
  65. int i, j;
  66. char data1[1024];
  67. char data2[1024];
  68. char data3[1024];
  69. for (i = 0; i < 256; i++) {
  70. /* Test the multiline format Base64 encoder with 0 .. 256 bytes of
  71. * output against OpenSSL.
  72. */
  73. const size_t enclen = base64_encode_size(i, BASE64_ENCODE_MULTILINE);
  74. data1[i] = i;
  75. j = base64_encode(data2, 1024, data1, i, BASE64_ENCODE_MULTILINE);
  76. tt_int_op(j, OP_EQ, enclen);
  77. j = base64_encode_evp(data3, data1, i);
  78. tt_int_op(j, OP_EQ, enclen);
  79. tt_mem_op(data2, OP_EQ, data3, enclen);
  80. tt_int_op(j, OP_EQ, strlen(data2));
  81. }
  82. done:
  83. ;
  84. }
  85. struct testcase_t crypto_openssl_tests[] = {
  86. { "rng_engine", test_crypto_rng_engine, TT_FORK, NULL, NULL },
  87. { "base64_encode_match", test_crypto_base64_encode_matches,
  88. TT_FORK, NULL, NULL },
  89. END_OF_TESTCASES
  90. };