Add copyright comment headers to appropriate files
[gssweb.git] / json_gssapi / test / GSSPseudoRandomTest.cpp
1 /*
2  * Copyright (c) 2014, 2015 JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34
35 #include <algorithm>
36 #include <string>
37
38 //#include <cppunit/TestFixture.h>
39 //#include <cppunit/extensions/HelperMacros.h>
40 #include <openssl/rand.h>
41
42 #include "cache/GSSContextCache.h"
43 #include "datamodel/GSSContext.h"
44 #include "command_mocks/MockPseudoRandom.h"
45 #include "GSSPseudoRandom.h"
46 #include "GSSPseudoRandomTest.h"
47
48 // Registers the fixture into the 'registry'
49 CPPUNIT_TEST_SUITE_REGISTRATION( GSSPseudoRandomTest );
50
51
52 // typedef OM_uint32 (*gss_pseudo_random_type) (
53 //     OM_uint32 *,        /* minor_status */
54 //     gss_ctx_id_t,       /* context */
55 //     int,                /* prf_key */
56 //     const gss_buffer_t, /* prf_in */
57 //     ssize_t,            /* desired_output_len */
58 //     gss_buffer_t);      /* prf_out */
59 OM_uint32 mock_gss_pseudo_random(
60     OM_uint32 *minor_status,
61     gss_ctx_id_t  context,
62     int prf_key,
63     const gss_buffer_t prf_in,
64     ssize_t desired_output_len,
65     gss_buffer_t prf_out)
66 {
67   /* Variables */
68   /* Error checking */
69   /* Setup */
70   /* Main */
71   MockPseudoRandom::context_handle = context;
72   MockPseudoRandom::key = prf_key;
73   MockPseudoRandom::inputMessageBuffer.setValue(prf_in);
74   MockPseudoRandom::desiredOutputLength = desired_output_len;
75   
76   *prf_out = *MockPseudoRandom::outputMessageBuffer.toGss();
77   
78   /* Cleanup */
79   /* Return */
80   return 0;
81 }
82
83
84 void GSSPseudoRandomTest::setUp()
85 {
86   CppUnit::TestFixture::setUp();
87   MockPseudoRandom::reset();
88 }
89
90
91 void GSSPseudoRandomTest::testConstructor()
92 {
93   /* Variables */
94   GSSPseudoRandom cmd = GSSPseudoRandom();
95   
96   /* Error checking */
97   /* Setup */
98   /* Main */
99   CPPUNIT_ASSERT_EQUAL_MESSAGE(
100     "The GSSPseudoRandom object has the wrong GSS function",
101     (void *)&gss_pseudo_random,
102     (void *)cmd.getGSSFunction()
103   );
104   
105   /* Cleanup */
106   /* Return */
107 }
108
109 /* 
110  * Test that the command calls into gss_pseudo_random with
111  * all of the correct values, and that the command reads
112  * all of the appropriate values back out of it.
113  */
114 void GSSPseudoRandomTest::testEmptyCall()
115 {
116   /* Variables */
117   GSSPseudoRandom cmd = GSSPseudoRandom(&mock_gss_pseudo_random);
118   gss_ctx_id_t desiredContext;
119   int prf_key;
120   ssize_t desired_output_len;
121   GSSBuffer prf_in((char *)"Input message");
122   
123   /* Error Checking */
124   /* Setup */
125   
126   // Populate cmd with what will be used to call into gss_pseudo_random
127     // taking the address of prf_key should be plenty random for testing the empty call.
128   desiredContext = (gss_ctx_id_t)&prf_key;
129   prf_key = rand();
130   desired_output_len = (ssize_t)(rand() + 50);  // Must be at least fifty bytes long
131   
132   cmd.setContextHandle(desiredContext);
133   cmd.setKey(prf_key);
134   cmd.setInputMessage( prf_in );
135   cmd.setDesiredOutputLength(desired_output_len);
136   
137   
138   // Populate the mock with what will be returned from gss_pseudo_random
139   MockPseudoRandom::minor_status = 0;
140   MockPseudoRandom::retVal = 0;
141   MockPseudoRandom::outputMessageBuffer.setValue((char *)"Output message");
142
143   
144   /* Main */
145   cmd.execute();
146   
147   // Do we populate the call to gss_pseudo_random correctly?
148   CPPUNIT_ASSERT_EQUAL_MESSAGE(
149     "The requested GSS context handle is not correct",
150     desiredContext,
151     MockPseudoRandom::context_handle
152   );
153   
154   CPPUNIT_ASSERT_EQUAL_MESSAGE(
155     "The requested pseudo random function key is not correct",
156     prf_key,
157     MockPseudoRandom::key
158   );
159   
160   CPPUNIT_ASSERT_EQUAL_MESSAGE(
161     "The requested desired output length is not correct",
162     desired_output_len,
163     MockPseudoRandom::desiredOutputLength
164   );
165   
166   CPPUNIT_ASSERT_EQUAL_MESSAGE(
167     "The requested input message is not correct",
168     prf_in.toString(),
169     MockPseudoRandom::inputMessageBuffer.toString()
170   );
171   
172   // Do we read the results of gss_pseudo_random correctly?
173   
174   CPPUNIT_ASSERT_EQUAL_MESSAGE(
175     "The requested output message is not correct",
176     MockPseudoRandom::outputMessageBuffer.toString(),
177     cmd.getOutputMessage().toString()
178   );
179   
180   CPPUNIT_ASSERT_EQUAL_MESSAGE(
181     "The return value is not correct",
182     MockPseudoRandom::retVal,
183     cmd.getRetVal()
184   );
185   
186   CPPUNIT_ASSERT_EQUAL_MESSAGE(
187     "The minor status value is not correct",
188     MockPseudoRandom::minor_status,
189     cmd.getMinorStatus()
190   );
191   
192   
193   
194   /* Cleanup */
195   /* Return */
196 }
197
198 /* JSON input
199  * 
200  * {"method":    "gss_pseudo_random",
201  *  "arguments": 
202  *   {
203  *     "context_handle":     "context handle key",
204  *     "prf_key":            ###,
205  *     "prf_in":             "la la la input message",
206  *     "desired_output_len": ####
207  *   }
208  * 
209  */
210 void GSSPseudoRandomTest::testConstructorWithJSONObject()
211 {
212   /* Variables */
213   GSSContext context( (gss_ctx_id_t)( (long)0 | rand() ),
214                      true );
215   std::string key = GSSContextCache::instance()->store(context);
216   
217   std::string input = "{ \
218          \"context_handle\": \"" + key + "\", \
219          \"prf_key\": 1234567890, \
220          \"prf_in\": \"mary had a little lamb\", \
221          \"desired_output_len\": 256 \
222     }";
223   json_error_t jsonErr;
224   JSONObject json = JSONObject::load(input.c_str(), 0, &jsonErr);
225   
226   GSSPseudoRandom cmd = GSSPseudoRandom(&json, &mock_gss_pseudo_random);
227
228   /* Error Checking */
229   /* Setup */
230   /* Main */
231   
232   CPPUNIT_ASSERT_EQUAL_MESSAGE(
233     "GSSWrap did not retrive the GSS context correctly",
234     context.getContext(),
235     cmd.getContextHandle()
236   );
237   
238   CPPUNIT_ASSERT_EQUAL_MESSAGE(
239     "GSSPseudoRandom did not parse the prf_key argument correctly.",
240     1234567890,
241     cmd.getKey()
242   );
243   
244   CPPUNIT_ASSERT_EQUAL_MESSAGE(
245     "GSSPseudoRandom did not parse the prf_in argument correctly.",
246     std::string("mary had a little lamb"),
247     cmd.getInputMessage().toString()
248   );
249   
250   CPPUNIT_ASSERT_EQUAL_MESSAGE(
251     "GSSPseudoRandom did not parse the desired_output_len argument correctly.",
252     256,
253     cmd.getDesiredOutputLength()
254   );
255   
256   /* Cleanup */
257   /* Return */
258 }
259
260 /* Desired JSON output:
261  * 
262  * {
263  *  "command":       "gss_pseudo_random",
264  *  "return_values": 
265  *  {
266  *      "major_status": 0,
267  *      "minor_status": 0,
268  *      "random_bytes": "asdf"
269  *  }
270  * }
271  */
272 void GSSPseudoRandomTest::testJSONMarshal()
273 {
274
275   /* Variables */
276   std::string output("dns@google.com");
277   JSONObject *result;
278   GSSPseudoRandom cmd = GSSPseudoRandom(&mock_gss_pseudo_random);
279   
280   /* Error checking */
281   /* Setup */
282   MockPseudoRandom::minor_status = 0;
283   MockPseudoRandom::retVal = 0;
284   MockPseudoRandom::outputMessageBuffer.setValue(output);
285   
286   /* Main */
287   cmd.execute();
288   result = cmd.toJSON();
289 //   std::cout << "\nGSSWrap JSON: \n" << result->dump() << "\n";
290   
291   CPPUNIT_ASSERT_EQUAL_MESSAGE(
292     "The return value was reported incorrectly",
293     (int)MockPseudoRandom::retVal,
294     (int)( (*result)["major_status"].integer() )
295   );
296   
297   CPPUNIT_ASSERT_EQUAL_MESSAGE(
298     "The minor_status value was reported incorrectly",
299     (int)MockPseudoRandom::minor_status,
300     (int)( (*result)["minor_status"].integer() )
301   );
302   
303   CPPUNIT_ASSERT_EQUAL_MESSAGE(
304     "The random bytes were reported incorrectly",
305     MockPseudoRandom::outputMessageBuffer.toString(),
306     std::string( (*result)["random_bytes"].string() )
307   );
308   
309   
310   /* Cleanup */
311   /* Return */
312 }
313
314   /* Variables */
315   /* Error Checking */
316   /* Setup */
317   /* Main */
318   /* Cleanup */
319   /* Return */