1 /* $OpenBSD: test_sshbuf_getput_crypto.c,v 1.1 2014/04/30 05:32:00 djm Exp $ */ 2 /* 3 * Regress test for sshbuf.h buffer API 4 * 5 * Placed in the public domain 6 */ 7 8 #include "includes.h" 9 10 #include <sys/types.h> 11 #include <sys/param.h> 12 #include <stdio.h> 13 #ifdef HAVE_STDINT_H 14 # include <stdint.h> 15 #endif 16 #include <stdlib.h> 17 #include <string.h> 18 19 #include <openssl/bn.h> 20 #include <openssl/objects.h> 21 #ifdef OPENSSL_HAS_NISTP256 22 # include <openssl/ec.h> 23 #endif 24 25 #include "../test_helper/test_helper.h" 26 #include "ssherr.h" 27 #include "sshbuf.h" 28 29 void sshbuf_getput_crypto_tests(void); 30 31 void 32 sshbuf_getput_crypto_tests(void) 33 { 34 struct sshbuf *p1; 35 BIGNUM *bn, *bn2; 36 /* This one has num_bits != num_bytes * 8 to test bignum1 encoding */ 37 const char *hexbn1 = "0102030405060708090a0b0c0d0e0f10"; 38 /* This one has MSB set to test bignum2 encoding negative-avoidance */ 39 const char *hexbn2 = "f0e0d0c0b0a0908070605040302010007fff11"; 40 u_char expbn1[] = { 41 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 42 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 43 }; 44 u_char expbn2[] = { 45 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0x90, 0x80, 46 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10, 0x00, 47 0x7f, 0xff, 0x11 48 }; 49 #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) 50 const u_char *d; 51 size_t s; 52 BIGNUM *bn_x, *bn_y; 53 int ec256_nid = NID_X9_62_prime256v1; 54 char *ec256_x = "0C828004839D0106AA59575216191357" 55 "34B451459DADB586677EF9DF55784999"; 56 char *ec256_y = "4D196B50F0B4E94B3C73E3A9D4CD9DF2" 57 "C8F9A35E42BDD047550F69D80EC23CD4"; 58 u_char expec256[] = { 59 0x04, 60 0x0c, 0x82, 0x80, 0x04, 0x83, 0x9d, 0x01, 0x06, 61 0xaa, 0x59, 0x57, 0x52, 0x16, 0x19, 0x13, 0x57, 62 0x34, 0xb4, 0x51, 0x45, 0x9d, 0xad, 0xb5, 0x86, 63 0x67, 0x7e, 0xf9, 0xdf, 0x55, 0x78, 0x49, 0x99, 64 0x4d, 0x19, 0x6b, 0x50, 0xf0, 0xb4, 0xe9, 0x4b, 65 0x3c, 0x73, 0xe3, 0xa9, 0xd4, 0xcd, 0x9d, 0xf2, 66 0xc8, 0xf9, 0xa3, 0x5e, 0x42, 0xbd, 0xd0, 0x47, 67 0x55, 0x0f, 0x69, 0xd8, 0x0e, 0xc2, 0x3c, 0xd4 68 }; 69 EC_KEY *eck; 70 EC_POINT *ecp; 71 #endif 72 int r; 73 74 #define MKBN(b, bnn) \ 75 do { \ 76 bnn = NULL; \ 77 ASSERT_INT_GT(BN_hex2bn(&bnn, b), 0); \ 78 } while (0) 79 80 TEST_START("sshbuf_put_bignum1"); 81 MKBN(hexbn1, bn); 82 p1 = sshbuf_new(); 83 ASSERT_PTR_NE(p1, NULL); 84 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0); 85 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 2); 86 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn)); 87 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn1, sizeof(expbn1)); 88 BN_free(bn); 89 sshbuf_free(p1); 90 TEST_DONE(); 91 92 TEST_START("sshbuf_put_bignum1 limited"); 93 MKBN(hexbn1, bn); 94 p1 = sshbuf_new(); 95 ASSERT_PTR_NE(p1, NULL); 96 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0); 97 r = sshbuf_put_bignum1(p1, bn); 98 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 99 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 100 BN_free(bn); 101 sshbuf_free(p1); 102 TEST_DONE(); 103 104 TEST_START("sshbuf_put_bignum1 bn2"); 105 MKBN(hexbn2, bn); 106 p1 = sshbuf_new(); 107 ASSERT_PTR_NE(p1, NULL); 108 ASSERT_INT_EQ(sshbuf_put_bignum1(p1, bn), 0); 109 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 2); 110 ASSERT_U16_EQ(PEEK_U16(sshbuf_ptr(p1)), (u_int16_t)BN_num_bits(bn)); 111 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 2, expbn2, sizeof(expbn2)); 112 BN_free(bn); 113 sshbuf_free(p1); 114 TEST_DONE(); 115 116 TEST_START("sshbuf_put_bignum1 bn2 limited"); 117 MKBN(hexbn2, bn); 118 p1 = sshbuf_new(); 119 ASSERT_PTR_NE(p1, NULL); 120 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 1), 0); 121 r = sshbuf_put_bignum1(p1, bn); 122 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 123 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 124 BN_free(bn); 125 sshbuf_free(p1); 126 TEST_DONE(); 127 128 TEST_START("sshbuf_put_bignum2"); 129 MKBN(hexbn1, bn); 130 p1 = sshbuf_new(); 131 ASSERT_PTR_NE(p1, NULL); 132 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); 133 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 4); 134 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn)); 135 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 4, expbn1, sizeof(expbn1)); 136 BN_free(bn); 137 sshbuf_free(p1); 138 TEST_DONE(); 139 140 TEST_START("sshbuf_put_bignum2 limited"); 141 MKBN(hexbn1, bn); 142 p1 = sshbuf_new(); 143 ASSERT_PTR_NE(p1, NULL); 144 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn1) + 3), 0); 145 r = sshbuf_put_bignum2(p1, bn); 146 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 147 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 148 BN_free(bn); 149 sshbuf_free(p1); 150 TEST_DONE(); 151 152 TEST_START("sshbuf_put_bignum2 bn2"); 153 MKBN(hexbn2, bn); 154 p1 = sshbuf_new(); 155 ASSERT_PTR_NE(p1, NULL); 156 ASSERT_INT_EQ(sshbuf_put_bignum2(p1, bn), 0); 157 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4 + 1); /* MSB */ 158 ASSERT_U32_EQ(PEEK_U32(sshbuf_ptr(p1)), (u_int32_t)BN_num_bytes(bn) + 1); 159 ASSERT_U8_EQ(*(sshbuf_ptr(p1) + 4), 0x00); 160 ASSERT_MEM_EQ(sshbuf_ptr(p1) + 5, expbn2, sizeof(expbn2)); 161 BN_free(bn); 162 sshbuf_free(p1); 163 TEST_DONE(); 164 165 TEST_START("sshbuf_put_bignum2 bn2 limited"); 166 MKBN(hexbn2, bn); 167 p1 = sshbuf_new(); 168 ASSERT_PTR_NE(p1, NULL); 169 ASSERT_INT_EQ(sshbuf_set_max_size(p1, sizeof(expbn2) + 3), 0); 170 r = sshbuf_put_bignum2(p1, bn); 171 ASSERT_INT_EQ(r, SSH_ERR_NO_BUFFER_SPACE); 172 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 0); 173 BN_free(bn); 174 sshbuf_free(p1); 175 TEST_DONE(); 176 177 TEST_START("sshbuf_get_bignum1"); 178 MKBN(hexbn1, bn); 179 p1 = sshbuf_new(); 180 ASSERT_PTR_NE(p1, NULL); 181 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); 182 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); 183 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1)); 184 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); 185 bn2 = BN_new(); 186 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0); 187 ASSERT_BIGNUM_EQ(bn, bn2); 188 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); 189 BN_free(bn); 190 BN_free(bn2); 191 sshbuf_free(p1); 192 TEST_DONE(); 193 194 TEST_START("sshbuf_get_bignum1 truncated"); 195 MKBN(hexbn1, bn); 196 p1 = sshbuf_new(); 197 ASSERT_PTR_NE(p1, NULL); 198 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); 199 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); 200 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1); 201 bn2 = BN_new(); 202 r = sshbuf_get_bignum1(p1, bn2); 203 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 204 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn1) - 1); 205 BN_free(bn); 206 BN_free(bn2); 207 sshbuf_free(p1); 208 TEST_DONE(); 209 210 TEST_START("sshbuf_get_bignum1 giant"); 211 MKBN(hexbn1, bn); 212 p1 = sshbuf_new(); 213 ASSERT_PTR_NE(p1, NULL); 214 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xffff), 0); 215 ASSERT_INT_EQ(sshbuf_reserve(p1, (0xffff + 7) / 8, NULL), 0); 216 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8)); 217 bn2 = BN_new(); 218 r = sshbuf_get_bignum1(p1, bn2); 219 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); 220 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + ((0xffff + 7) / 8)); 221 BN_free(bn); 222 BN_free(bn2); 223 sshbuf_free(p1); 224 TEST_DONE(); 225 226 TEST_START("sshbuf_get_bignum1 bn2"); 227 MKBN(hexbn2, bn); 228 p1 = sshbuf_new(); 229 ASSERT_PTR_NE(p1, NULL); 230 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); 231 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); 232 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2)); 233 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); 234 bn2 = BN_new(); 235 ASSERT_INT_EQ(sshbuf_get_bignum1(p1, bn2), 0); 236 ASSERT_BIGNUM_EQ(bn, bn2); 237 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); 238 BN_free(bn); 239 BN_free(bn2); 240 sshbuf_free(p1); 241 TEST_DONE(); 242 243 TEST_START("sshbuf_get_bignum1 bn2 truncated"); 244 MKBN(hexbn2, bn); 245 p1 = sshbuf_new(); 246 ASSERT_PTR_NE(p1, NULL); 247 ASSERT_INT_EQ(sshbuf_put_u16(p1, BN_num_bits(bn)), 0); 248 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); 249 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1); 250 bn2 = BN_new(); 251 r = sshbuf_get_bignum1(p1, bn2); 252 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 253 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2 + sizeof(expbn2) - 1); 254 BN_free(bn); 255 BN_free(bn2); 256 sshbuf_free(p1); 257 TEST_DONE(); 258 259 TEST_START("sshbuf_get_bignum2"); 260 MKBN(hexbn1, bn); 261 p1 = sshbuf_new(); 262 ASSERT_PTR_NE(p1, NULL); 263 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); 264 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1)), 0); 265 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + sizeof(expbn1)); 266 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); 267 bn2 = BN_new(); 268 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0); 269 ASSERT_BIGNUM_EQ(bn, bn2); 270 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); 271 BN_free(bn); 272 BN_free(bn2); 273 sshbuf_free(p1); 274 TEST_DONE(); 275 276 TEST_START("sshbuf_get_bignum2 truncated"); 277 MKBN(hexbn1, bn); 278 p1 = sshbuf_new(); 279 ASSERT_PTR_NE(p1, NULL); 280 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); 281 ASSERT_INT_EQ(sshbuf_put(p1, expbn1, sizeof(expbn1) - 1), 0); 282 bn2 = BN_new(); 283 r = sshbuf_get_bignum2(p1, bn2); 284 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 285 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn1) + 3); 286 BN_free(bn); 287 BN_free(bn2); 288 sshbuf_free(p1); 289 TEST_DONE(); 290 291 TEST_START("sshbuf_get_bignum2 giant"); 292 MKBN(hexbn1, bn); 293 p1 = sshbuf_new(); 294 ASSERT_PTR_NE(p1, NULL); 295 ASSERT_INT_EQ(sshbuf_put_u32(p1, 65536), 0); 296 ASSERT_INT_EQ(sshbuf_reserve(p1, 65536, NULL), 0); 297 bn2 = BN_new(); 298 r = sshbuf_get_bignum2(p1, bn2); 299 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_TOO_LARGE); 300 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 65536 + 4); 301 BN_free(bn); 302 BN_free(bn2); 303 sshbuf_free(p1); 304 TEST_DONE(); 305 306 TEST_START("sshbuf_get_bignum2 bn2"); 307 MKBN(hexbn2, bn); 308 p1 = sshbuf_new(); 309 ASSERT_PTR_NE(p1, NULL); 310 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); /* MSB */ 311 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); 312 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); 313 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 4 + 1 + sizeof(expbn2)); 314 ASSERT_INT_EQ(sshbuf_put_u16(p1, 0xd00f), 0); 315 bn2 = BN_new(); 316 ASSERT_INT_EQ(sshbuf_get_bignum2(p1, bn2), 0); 317 ASSERT_BIGNUM_EQ(bn, bn2); 318 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 2); 319 BN_free(bn); 320 BN_free(bn2); 321 sshbuf_free(p1); 322 TEST_DONE(); 323 324 TEST_START("sshbuf_get_bignum2 bn2 truncated"); 325 MKBN(hexbn2, bn); 326 p1 = sshbuf_new(); 327 ASSERT_PTR_NE(p1, NULL); 328 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn) + 1), 0); 329 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); 330 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2) - 1), 0); 331 bn2 = BN_new(); 332 r = sshbuf_get_bignum2(p1, bn2); 333 ASSERT_INT_EQ(r, SSH_ERR_MESSAGE_INCOMPLETE); 334 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 1 + 4 - 1); 335 BN_free(bn); 336 BN_free(bn2); 337 sshbuf_free(p1); 338 TEST_DONE(); 339 340 TEST_START("sshbuf_get_bignum2 bn2 negative"); 341 MKBN(hexbn2, bn); 342 p1 = sshbuf_new(); 343 ASSERT_PTR_NE(p1, NULL); 344 ASSERT_INT_EQ(sshbuf_put_u32(p1, BN_num_bytes(bn)), 0); 345 ASSERT_INT_EQ(sshbuf_put(p1, expbn2, sizeof(expbn2)), 0); 346 bn2 = BN_new(); 347 r = sshbuf_get_bignum2(p1, bn2); 348 ASSERT_INT_EQ(r, SSH_ERR_BIGNUM_IS_NEGATIVE); 349 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expbn2) + 4); 350 BN_free(bn); 351 BN_free(bn2); 352 sshbuf_free(p1); 353 TEST_DONE(); 354 355 #if defined(OPENSSL_HAS_ECC) && defined(OPENSSL_HAS_NISTP256) 356 TEST_START("sshbuf_put_ec"); 357 eck = EC_KEY_new_by_curve_name(ec256_nid); 358 ASSERT_PTR_NE(eck, NULL); 359 ecp = EC_POINT_new(EC_KEY_get0_group(eck)); 360 ASSERT_PTR_NE(ecp, NULL); 361 MKBN(ec256_x, bn_x); 362 MKBN(ec256_y, bn_y); 363 ASSERT_INT_EQ(EC_POINT_set_affine_coordinates_GFp( 364 EC_KEY_get0_group(eck), ecp, bn_x, bn_y, NULL), 1); 365 ASSERT_INT_EQ(EC_KEY_set_public_key(eck, ecp), 1); 366 BN_free(bn_x); 367 BN_free(bn_y); 368 EC_POINT_free(ecp); 369 p1 = sshbuf_new(); 370 ASSERT_PTR_NE(p1, NULL); 371 ASSERT_INT_EQ(sshbuf_put_eckey(p1, eck), 0); 372 ASSERT_INT_EQ(sshbuf_get_string_direct(p1, &d, &s), 0); 373 ASSERT_SIZE_T_EQ(s, sizeof(expec256)); 374 ASSERT_MEM_EQ(d, expec256, sizeof(expec256)); 375 sshbuf_free(p1); 376 EC_KEY_free(eck); 377 TEST_DONE(); 378 379 TEST_START("sshbuf_get_ec"); 380 eck = EC_KEY_new_by_curve_name(ec256_nid); 381 ASSERT_PTR_NE(eck, NULL); 382 p1 = sshbuf_new(); 383 ASSERT_PTR_NE(p1, NULL); 384 ASSERT_INT_EQ(sshbuf_put_string(p1, expec256, sizeof(expec256)), 0); 385 ASSERT_SIZE_T_EQ(sshbuf_len(p1), sizeof(expec256) + 4); 386 ASSERT_INT_EQ(sshbuf_put_u8(p1, 0x00), 0); 387 ASSERT_INT_EQ(sshbuf_get_eckey(p1, eck), 0); 388 bn_x = BN_new(); 389 bn_y = BN_new(); 390 ASSERT_PTR_NE(bn_x, NULL); 391 ASSERT_PTR_NE(bn_y, NULL); 392 ASSERT_INT_EQ(EC_POINT_get_affine_coordinates_GFp( 393 EC_KEY_get0_group(eck), EC_KEY_get0_public_key(eck), 394 bn_x, bn_y, NULL), 1); 395 MKBN(ec256_x, bn); 396 MKBN(ec256_y, bn2); 397 ASSERT_INT_EQ(BN_cmp(bn_x, bn), 0); 398 ASSERT_INT_EQ(BN_cmp(bn_y, bn2), 0); 399 ASSERT_SIZE_T_EQ(sshbuf_len(p1), 1); 400 sshbuf_free(p1); 401 EC_KEY_free(eck); 402 BN_free(bn_x); 403 BN_free(bn_y); 404 BN_free(bn); 405 BN_free(bn2); 406 TEST_DONE(); 407 #endif 408 } 409 410