1 /*
2  * Test low-level token crypto routines.
3  *
4  * Test encrypting and decrypting data using the token algorithm.  We can test
5  * this with arbitrary data, since these routines don't care about the
6  * attribute formatting or content.
7  *
8  * Written by Russ Allbery <eagle@eyrie.org>
9  * Copyright 2012, 2013
10  *     The Board of Trustees of the Leland Stanford Junior University
11  *
12  * See LICENSE for licensing terms.
13  */
14 
15 #include <config.h>
16 #include <portable/system.h>
17 
18 #include <tests/tap/basic.h>
19 #include <webauth/basic.h>
20 #include <webauth/keys.h>
21 #include <webauth/tokens.h>
22 
23 
24 /*
25  * Read a token from a file name and store the resulting data and length in
26  * the provided arguments.
27  */
28 static void
read_token(const char * filename,void ** data,size_t * length)29 read_token(const char *filename, void **data, size_t *length)
30 {
31     char buffer[4096];
32     char *path;
33     FILE *token;
34 
35     path = test_file_path(filename);
36     if (path == NULL)
37         bail("cannot find test file %s", filename);
38     token = fopen(path, "rb");
39     if (token == NULL)
40         sysbail("cannot open %s", path);
41     test_file_path_free(path);
42     *length = fread(buffer, 1, sizeof(buffer), token);
43     if (*length == 0)
44         sysbail("cannot read %s", path);
45     fclose(token);
46     *data = bmalloc(*length);
47     memcpy(*data, buffer, *length);
48 }
49 
50 
51 int
main(void)52 main(void)
53 {
54     struct webauth_context *ctx;
55     struct webauth_keyring *ring;
56     char *keyring;
57     int s;
58     void *data, *out, *token;
59     size_t length, outlen;
60     const char raw_data[] = { ';', ';', 0, ';', 't', '4', 1, 255 };
61     const char app_raw[] =
62         "t=app;s=testuser;lt=N\2]\312;ia=p;san=c;loa=\0\0\0\1;ct=N\2]\254;"
63         "et=\177\377\377\320;";
64 
65     plan(10);
66 
67     if (webauth_context_init(&ctx, NULL) != WA_ERR_NONE)
68         bail("cannot initialize WebAuth context");
69 
70     /* Load the precreated keyring that we'll use for token encryption. */
71     keyring = test_file_path("data/keyring");
72     s = webauth_keyring_read(ctx, keyring, &ring);
73     if (s != WA_ERR_NONE)
74         bail("cannot read %s: %s", keyring, webauth_error_message(ctx, s));
75     test_file_path_free(keyring);
76 
77     /*
78      * Test encrypting and then decrypting data and make sure that the
79      * functions are symmetric.
80      */
81     s = webauth_token_encrypt(ctx, raw_data, sizeof(raw_data), &data, &length,
82                               ring);
83     if (s != WA_ERR_NONE)
84         diag("error: %s", webauth_error_message(ctx, s));
85     is_int(WA_ERR_NONE, s, "Token encryption works");
86     s = webauth_token_decrypt(ctx, data, length, &out, &outlen, ring);
87     if (s != WA_ERR_NONE)
88         diag("error: %s", webauth_error_message(ctx, s));
89     is_int(WA_ERR_NONE, s, "Token decryption works");
90     is_int(sizeof(raw_data), outlen, "...and output length is correct");
91     if (out == NULL)
92         ok(false, "...and output data is correct");
93     else
94         ok(memcmp(raw_data, out, sizeof(raw_data) - 1) == 0,
95            "...and output data is correct");
96 
97     /* Test encrypting and decrypting the empty token. */
98     s = webauth_token_encrypt(ctx, "", 0, &data, &length, ring);
99     if (s != WA_ERR_NONE)
100         diag("error: %s", webauth_error_message(ctx, s));
101     is_int(WA_ERR_NONE, s, "Encryption of empty token works");
102     s = webauth_token_decrypt(ctx, data, length, &out, &outlen, ring);
103     if (s != WA_ERR_NONE)
104         diag("error: %s", webauth_error_message(ctx, s));
105     is_int(WA_ERR_NONE, s, "Decryption of empty token works");
106     is_int(0, outlen, "...and output length is correct");
107 
108     /* Load some known data and decrypt it to verify the results. */
109     read_token("data/tokens/app-raw", &token, &length);
110     s = webauth_token_decrypt(ctx, token, length, &out, &outlen, ring);
111     if (s != WA_ERR_NONE)
112         diag("error: %s", webauth_error_message(ctx, s));
113     is_int(WA_ERR_NONE, s, "Decryption of app-raw works");
114     is_int(sizeof(app_raw) - 1, outlen, "...and output length is correct");
115     ok(memcmp(app_raw, out, sizeof(app_raw) - 1) == 0,
116        "...and output data is correct");
117 
118     /* Clean up. */
119     free(token);
120     webauth_context_free(ctx);
121     return 0;
122 }
123