Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / ceph_crypto.cc
1 #include "gtest/gtest.h"
2 #include "common/ceph_argparse.h"
3 #include "common/ceph_crypto.h"
4 #include "common/common_init.h"
5 #include "global/global_init.h"
6 #include "global/global_context.h"
7
8 class CryptoEnvironment: public ::testing::Environment {
9 public:
10   void SetUp() override {
11     ceph::crypto::init(g_ceph_context);
12   }
13 };
14
15 TEST(MD5, Simple) {
16   ceph::crypto::MD5 h;
17   h.Update((const byte*)"foo", 3);
18   unsigned char digest[CEPH_CRYPTO_MD5_DIGESTSIZE];
19   h.Final(digest);
20   int err;
21   unsigned char want_digest[CEPH_CRYPTO_MD5_DIGESTSIZE] = {
22     0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
23     0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
24   };
25   err = memcmp(digest, want_digest, CEPH_CRYPTO_MD5_DIGESTSIZE);
26   ASSERT_EQ(0, err);
27 }
28
29 TEST(MD5, MultiUpdate) {
30   ceph::crypto::MD5 h;
31   h.Update((const byte*)"", 0);
32   h.Update((const byte*)"fo", 2);
33   h.Update((const byte*)"", 0);
34   h.Update((const byte*)"o", 1);
35   h.Update((const byte*)"", 0);
36   unsigned char digest[CEPH_CRYPTO_MD5_DIGESTSIZE];
37   h.Final(digest);
38   int err;
39   unsigned char want_digest[CEPH_CRYPTO_MD5_DIGESTSIZE] = {
40     0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
41     0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
42   };
43   err = memcmp(digest, want_digest, CEPH_CRYPTO_MD5_DIGESTSIZE);
44   ASSERT_EQ(0, err);
45 }
46
47 TEST(MD5, Restart) {
48   ceph::crypto::MD5 h;
49   h.Update((const byte*)"bar", 3);
50   h.Restart();
51   h.Update((const byte*)"foo", 3);
52   unsigned char digest[CEPH_CRYPTO_MD5_DIGESTSIZE];
53   h.Final(digest);
54   int err;
55   unsigned char want_digest[CEPH_CRYPTO_MD5_DIGESTSIZE] = {
56     0xac, 0xbd, 0x18, 0xdb, 0x4c, 0xc2, 0xf8, 0x5c,
57     0xed, 0xef, 0x65, 0x4f, 0xcc, 0xc4, 0xa4, 0xd8,
58   };
59   err = memcmp(digest, want_digest, CEPH_CRYPTO_MD5_DIGESTSIZE);
60   ASSERT_EQ(0, err);
61 }
62
63 TEST(HMACSHA1, Simple) {
64   ceph::crypto::HMACSHA1 h((const byte*)"sekrit", 6);
65   h.Update((const byte*)"foo", 3);
66   unsigned char digest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
67   h.Final(digest);
68   int err;
69   unsigned char want_digest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE] = {
70     0x04, 0xbc, 0x52, 0x66, 0xb6, 0xff, 0xad, 0xad, 0x9d, 0x57,
71     0xce, 0x13, 0xea, 0x8c, 0xf5, 0x6b, 0xf9, 0x95, 0x2f, 0xd6,
72   };
73   err = memcmp(digest, want_digest, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
74   ASSERT_EQ(0, err);
75 }
76
77 TEST(HMACSHA1, MultiUpdate) {
78   ceph::crypto::HMACSHA1 h((const byte*)"sekrit", 6);
79   h.Update((const byte*)"", 0);
80   h.Update((const byte*)"fo", 2);
81   h.Update((const byte*)"", 0);
82   h.Update((const byte*)"o", 1);
83   h.Update((const byte*)"", 0);
84   unsigned char digest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
85   h.Final(digest);
86   int err;
87   unsigned char want_digest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE] = {
88     0x04, 0xbc, 0x52, 0x66, 0xb6, 0xff, 0xad, 0xad, 0x9d, 0x57,
89     0xce, 0x13, 0xea, 0x8c, 0xf5, 0x6b, 0xf9, 0x95, 0x2f, 0xd6,
90   };
91   err = memcmp(digest, want_digest, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
92   ASSERT_EQ(0, err);
93 }
94
95 TEST(HMACSHA1, Restart) {
96   ceph::crypto::HMACSHA1 h((const byte*)"sekrit", 6);
97   h.Update((const byte*)"bar", 3);
98   h.Restart();
99   h.Update((const byte*)"foo", 3);
100   unsigned char digest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE];
101   h.Final(digest);
102   int err;
103   unsigned char want_digest[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE] = {
104     0x04, 0xbc, 0x52, 0x66, 0xb6, 0xff, 0xad, 0xad, 0x9d, 0x57,
105     0xce, 0x13, 0xea, 0x8c, 0xf5, 0x6b, 0xf9, 0x95, 0x2f, 0xd6,
106   };
107   err = memcmp(digest, want_digest, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE);
108   ASSERT_EQ(0, err);
109 }
110
111 class ForkDeathTest : public ::testing::Test {
112  protected:
113   void SetUp() override {
114     // shutdown NSS so it can be reinitialized after the fork
115     // some data structures used by NSPR are only initialized once, and they
116     // will be cleaned up with ceph::crypto::shutdown(false), so we need to
117     // keep them around after fork.
118     ceph::crypto::shutdown(true);
119   }
120
121   void TearDown() override {
122     // undo the NSS shutdown we did in the parent process, after the
123     // test is done
124     ceph::crypto::init(g_ceph_context);
125   }
126 };
127
128 void do_simple_crypto() {
129   // ensure that the shutdown/fork/init sequence results in a working
130   // NSS crypto library; this function is run in the child, after the
131   // fork, and if you comment out the ceph::crypto::init, or if the
132   // trick were to fail, you would see this ending in an assert and
133   // not exit status 0
134   ceph::crypto::init(g_ceph_context);
135   ceph::crypto::MD5 h;
136   h.Update((const byte*)"foo", 3);
137   unsigned char digest[CEPH_CRYPTO_MD5_DIGESTSIZE];
138   h.Final(digest);
139   exit(0);
140 }
141
142 #if GTEST_HAS_DEATH_TEST
143 TEST_F(ForkDeathTest, MD5) {
144   ASSERT_EXIT(do_simple_crypto(), ::testing::ExitedWithCode(0), "^$");
145 }
146 #endif //GTEST_HAS_DEATH_TEST
147
148 int main(int argc, char **argv) {
149   std::vector<const char*> args(argv, argv + argc);
150   env_to_vec(args);
151   auto cct = global_init(NULL, args,
152                          CEPH_ENTITY_TYPE_CLIENT,
153                          CODE_ENVIRONMENT_UTILITY,
154                          CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
155   common_init_finish(g_ceph_context);
156   ::testing::InitGoogleTest(&argc, argv);
157   return RUN_ALL_TESTS();
158 }