TDLS: Do not reject TPK M3 when failing to process IEs
[mech_eap.git] / tests / test-rsa-sig-ver.c
1 /*
2  * Testing tool for RSA PKCS #1 v1.5 signature verification
3  * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "utils/includes.h"
10
11 #include "utils/common.h"
12 #include "crypto/crypto.h"
13 #include "tls/rsa.h"
14 #include "tls/asn1.h"
15 #include "tls/pkcs1.h"
16
17
18 static int cavp_rsa_sig_ver(const char *fname)
19 {
20         FILE *f;
21         int ret = 0;
22         char buf[15000], *pos, *pos2;
23         u8 msg[200], n[512], s[512], em[512], e[512];
24         size_t msg_len = 0, n_len = 0, s_len = 0, em_len, e_len = 0;
25         size_t tmp_len;
26         char sha_alg[20];
27         int ok = 0;
28
29         printf("CAVP RSA SigVer test vectors from %s\n", fname);
30
31         f = fopen(fname, "r");
32         if (f == NULL) {
33                 printf("%s does not exist - cannot validate CAVP RSA SigVer test vectors\n",
34                         fname);
35                 return 0;
36         }
37
38         while (fgets(buf, sizeof(buf), f)) {
39                 pos = os_strchr(buf, '=');
40                 if (pos == NULL)
41                         continue;
42                 pos2 = pos - 1;
43                 while (pos2 >= buf && *pos2 == ' ')
44                         *pos2-- = '\0';
45                 *pos++ = '\0';
46                 while (*pos == ' ')
47                         *pos++ = '\0';
48                 pos2 = os_strchr(pos, '\r');
49                 if (!pos2)
50                         pos2 = os_strchr(pos, '\n');
51                 if (pos2)
52                         *pos2 = '\0';
53                 else
54                         pos2 = pos + os_strlen(pos);
55
56                 if (os_strcmp(buf, "SHAAlg") == 0) {
57                         os_strlcpy(sha_alg, pos, sizeof(sha_alg));
58                 } else if (os_strcmp(buf, "Msg") == 0) {
59                         tmp_len = os_strlen(pos);
60                         if (tmp_len > sizeof(msg) * 2) {
61                                 printf("Too long Msg\n");
62                                 return -1;
63                         }
64                         msg_len = tmp_len / 2;
65                         if (hexstr2bin(pos, msg, msg_len) < 0) {
66                                 printf("Invalid hex string '%s'\n", pos);
67                                 ret++;
68                                 break;
69                         }
70                 } else if (os_strcmp(buf, "n") == 0) {
71                         tmp_len = os_strlen(pos);
72                         if (tmp_len > sizeof(n) * 2) {
73                                 printf("Too long n\n");
74                                 return -1;
75                         }
76                         n_len = tmp_len / 2;
77                         if (hexstr2bin(pos, n, n_len) < 0) {
78                                 printf("Invalid hex string '%s'\n", pos);
79                                 ret++;
80                                 break;
81                         }
82                 } else if (os_strcmp(buf, "e") == 0) {
83                         tmp_len = os_strlen(pos);
84                         if (tmp_len > sizeof(e) * 2) {
85                                 printf("Too long e\n");
86                                 return -1;
87                         }
88                         e_len = tmp_len / 2;
89                         if (hexstr2bin(pos, e, e_len) < 0) {
90                                 printf("Invalid hex string '%s'\n", pos);
91                                 ret++;
92                                 break;
93                         }
94                 } else if (os_strcmp(buf, "S") == 0) {
95                         tmp_len = os_strlen(pos);
96                         if (tmp_len > sizeof(s) * 2) {
97                                 printf("Too long S\n");
98                                 return -1;
99                         }
100                         s_len = tmp_len / 2;
101                         if (hexstr2bin(pos, s, s_len) < 0) {
102                                 printf("Invalid hex string '%s'\n", pos);
103                                 ret++;
104                                 break;
105                         }
106                 } else if (os_strncmp(buf, "EM", 2) == 0) {
107                         tmp_len = os_strlen(pos);
108                         if (tmp_len > sizeof(em) * 2)
109                                 return -1;
110                         em_len = tmp_len / 2;
111                         if (hexstr2bin(pos, em, em_len) < 0) {
112                                 printf("Invalid hex string '%s'\n", pos);
113                                 ret++;
114                                 break;
115                         }
116                 } else if (os_strcmp(buf, "Result") == 0) {
117                         const u8 *addr[1];
118                         size_t len[1];
119                         struct crypto_public_key *pk;
120                         int res;
121                         u8 hash[32];
122                         size_t hash_len;
123                         const struct asn1_oid *alg;
124
125                         addr[0] = msg;
126                         len[0] = msg_len;
127                         if (os_strcmp(sha_alg, "SHA1") == 0) {
128                                 if (sha1_vector(1, addr, len, hash) < 0)
129                                         return -1;
130                                 hash_len = 20;
131                                 alg = &asn1_sha1_oid;
132                         } else if (os_strcmp(sha_alg, "SHA256") == 0) {
133                                 if (sha256_vector(1, addr, len, hash) < 0)
134                                         return -1;
135                                 hash_len = 32;
136                                 alg = &asn1_sha256_oid;
137                         } else {
138                                 continue;
139                         }
140
141                         printf("\nExpected result: %s\n", pos);
142                         wpa_hexdump(MSG_INFO, "Hash(Msg)", hash, hash_len);
143
144                         pk = crypto_public_key_import_parts(n, n_len,
145                                                             e, e_len);
146                         if (pk == NULL) {
147                                 printf("Failed to import public key\n");
148                                 ret++;
149                                 continue;
150                         }
151
152                         res = pkcs1_v15_sig_ver(pk, s, s_len, alg,
153                                                 hash, hash_len);
154                         crypto_public_key_free(pk);
155                         if ((*pos == 'F' && !res) || (*pos != 'F' && res)) {
156                                 printf("FAIL\n");
157                                 ret++;
158                                 continue;
159                         }
160
161                         printf("PASS\n");
162                         ok++;
163                 }
164         }
165
166         fclose(f);
167
168         if (ret)
169                 printf("Test case failed\n");
170         else
171                 printf("%d test vectors OK\n", ok);
172
173         return ret;
174 }
175
176
177 int main(int argc, char *argv[])
178 {
179         int ret = 0;
180
181         wpa_debug_level = 0;
182
183         if (cavp_rsa_sig_ver("CAVP/SigVer15_186-3.rsp"))
184                 ret++;
185         if (cavp_rsa_sig_ver("CAVP/SigVer15EMTest.txt"))
186                 ret++;
187
188         return ret;
189 }