PolarSSL v1.3.9
test_suite_pem.c
Go to the documentation of this file.
1#if !defined(POLARSSL_CONFIG_FILE)
2#include <polarssl/config.h>
3#else
4#include POLARSSL_CONFIG_FILE
5#endif
6
7#ifdef POLARSSL_PEM_WRITE_C
8
9#include <polarssl/base64.h>
10#include <polarssl/pem.h>
11#endif /* POLARSSL_PEM_WRITE_C */
12
13
14#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
15#include "polarssl/memory.h"
16#endif
17
18#if defined(POLARSSL_PLATFORM_C)
19#include "polarssl/platform.h"
20#else
21#define polarssl_malloc malloc
22#define polarssl_free free
23#endif
24
25#ifdef _MSC_VER
26#include <basetsd.h>
27typedef UINT32 uint32_t;
28#else
29#include <inttypes.h>
30#endif
31
32#include <assert.h>
33#include <stdlib.h>
34#include <string.h>
35
36/*
37 * 32-bit integer manipulation macros (big endian)
38 */
39#ifndef GET_UINT32_BE
40#define GET_UINT32_BE(n,b,i) \
41{ \
42 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
43 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
44 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
45 | ( (uint32_t) (b)[(i) + 3] ); \
46}
47#endif
48
49#ifndef PUT_UINT32_BE
50#define PUT_UINT32_BE(n,b,i) \
51{ \
52 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
53 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
54 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
55 (b)[(i) + 3] = (unsigned char) ( (n) ); \
56}
57#endif
58
59static int unhexify(unsigned char *obuf, const char *ibuf)
60{
61 unsigned char c, c2;
62 int len = strlen(ibuf) / 2;
63 assert(!(strlen(ibuf) %1)); // must be even number of bytes
64
65 while (*ibuf != 0)
66 {
67 c = *ibuf++;
68 if( c >= '0' && c <= '9' )
69 c -= '0';
70 else if( c >= 'a' && c <= 'f' )
71 c -= 'a' - 10;
72 else if( c >= 'A' && c <= 'F' )
73 c -= 'A' - 10;
74 else
75 assert( 0 );
76
77 c2 = *ibuf++;
78 if( c2 >= '0' && c2 <= '9' )
79 c2 -= '0';
80 else if( c2 >= 'a' && c2 <= 'f' )
81 c2 -= 'a' - 10;
82 else if( c2 >= 'A' && c2 <= 'F' )
83 c2 -= 'A' - 10;
84 else
85 assert( 0 );
86
87 *obuf++ = ( c << 4 ) | c2;
88 }
89
90 return len;
91}
92
93static void hexify(unsigned char *obuf, const unsigned char *ibuf, int len)
94{
95 unsigned char l, h;
96
97 while (len != 0)
98 {
99 h = (*ibuf) / 16;
100 l = (*ibuf) % 16;
101
102 if( h < 10 )
103 *obuf++ = '0' + h;
104 else
105 *obuf++ = 'a' + h - 10;
106
107 if( l < 10 )
108 *obuf++ = '0' + l;
109 else
110 *obuf++ = 'a' + l - 10;
111
112 ++ibuf;
113 len--;
114 }
115}
116
124static unsigned char *zero_alloc( size_t len )
125{
126 void *p;
127 size_t actual_len = len != 0 ? len : 1;
128
129 p = polarssl_malloc( actual_len );
130 assert( p != NULL );
131
132 memset( p, 0x00, actual_len );
133
134 return( p );
135}
136
147static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
148{
149 unsigned char *obuf;
150
151 *olen = strlen(ibuf) / 2;
152
153 if( *olen == 0 )
154 return( zero_alloc( *olen ) );
155
156 obuf = polarssl_malloc( *olen );
157 assert( obuf != NULL );
158
159 (void) unhexify( obuf, ibuf );
160
161 return( obuf );
162}
163
173static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len )
174{
175#if !defined(__OpenBSD__)
176 size_t i;
177
178 if( rng_state != NULL )
179 rng_state = NULL;
180
181 for( i = 0; i < len; ++i )
182 output[i] = rand();
183#else
184 if( rng_state != NULL )
185 rng_state = NULL;
186
187 arc4random_buf( output, len );
188#endif /* !OpenBSD */
189
190 return( 0 );
191}
192
198static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
199{
200 if( rng_state != NULL )
201 rng_state = NULL;
202
203 memset( output, 0, len );
204
205 return( 0 );
206}
207
208typedef struct
209{
210 unsigned char *buf;
211 size_t length;
213
225static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
226{
227 rnd_buf_info *info = (rnd_buf_info *) rng_state;
228 size_t use_len;
229
230 if( rng_state == NULL )
231 return( rnd_std_rand( NULL, output, len ) );
232
233 use_len = len;
234 if( len > info->length )
235 use_len = info->length;
236
237 if( use_len )
238 {
239 memcpy( output, info->buf, use_len );
240 info->buf += use_len;
241 info->length -= use_len;
242 }
243
244 if( len - use_len > 0 )
245 return( rnd_std_rand( NULL, output + use_len, len - use_len ) );
246
247 return( 0 );
248}
249
257typedef struct
258{
259 uint32_t key[16];
260 uint32_t v0, v1;
262
271static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
272{
273 rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state;
274 uint32_t i, *k, sum, delta=0x9E3779B9;
275 unsigned char result[4], *out = output;
276
277 if( rng_state == NULL )
278 return( rnd_std_rand( NULL, output, len ) );
279
280 k = info->key;
281
282 while( len > 0 )
283 {
284 size_t use_len = ( len > 4 ) ? 4 : len;
285 sum = 0;
286
287 for( i = 0; i < 32; i++ )
288 {
289 info->v0 += (((info->v1 << 4) ^ (info->v1 >> 5)) + info->v1) ^ (sum + k[sum & 3]);
290 sum += delta;
291 info->v1 += (((info->v0 << 4) ^ (info->v0 >> 5)) + info->v0) ^ (sum + k[(sum>>11) & 3]);
292 }
293
294 PUT_UINT32_BE( info->v0, result, 0 );
295 memcpy( out, result, use_len );
296 len -= use_len;
297 out += 4;
298 }
299
300 return( 0 );
301}
302
303
304#include <stdio.h>
305#include <string.h>
306
307#if defined(POLARSSL_PLATFORM_C)
308#include "polarssl/platform.h"
309#else
310#define polarssl_printf printf
311#define polarssl_malloc malloc
312#define polarssl_free free
313#endif
314
315static int test_errors = 0;
316
317#ifdef POLARSSL_PEM_WRITE_C
318
319#define TEST_SUITE_ACTIVE
320
321static int test_assert( int correct, const char *test )
322{
323 if( correct )
324 return( 0 );
325
326 test_errors++;
327 if( test_errors == 1 )
328 printf( "FAILED\n" );
329 printf( " %s\n", test );
330
331 return( 1 );
332}
333
334#define TEST_ASSERT( TEST ) \
335 do { test_assert( (TEST) ? 1 : 0, #TEST ); \
336 if( test_errors) goto exit; \
337 } while (0)
338
339int verify_string( char **str )
340{
341 if( (*str)[0] != '"' ||
342 (*str)[strlen( *str ) - 1] != '"' )
343 {
344 printf( "Expected string (with \"\") for parameter and got: %s\n", *str );
345 return( -1 );
346 }
347
348 (*str)++;
349 (*str)[strlen( *str ) - 1] = '\0';
350
351 return( 0 );
352}
353
354int verify_int( char *str, int *value )
355{
356 size_t i;
357 int minus = 0;
358 int digits = 1;
359 int hex = 0;
360
361 for( i = 0; i < strlen( str ); i++ )
362 {
363 if( i == 0 && str[i] == '-' )
364 {
365 minus = 1;
366 continue;
367 }
368
369 if( ( ( minus && i == 2 ) || ( !minus && i == 1 ) ) &&
370 str[i - 1] == '0' && str[i] == 'x' )
371 {
372 hex = 1;
373 continue;
374 }
375
376 if( ! ( ( str[i] >= '0' && str[i] <= '9' ) ||
377 ( hex && ( ( str[i] >= 'a' && str[i] <= 'f' ) ||
378 ( str[i] >= 'A' && str[i] <= 'F' ) ) ) ) )
379 {
380 digits = 0;
381 break;
382 }
383 }
384
385 if( digits )
386 {
387 if( hex )
388 *value = strtol( str, NULL, 16 );
389 else
390 *value = strtol( str, NULL, 10 );
391
392 return( 0 );
393 }
394
395
396
397 printf( "Expected integer for parameter and got: %s\n", str );
398 return( -1 );
399}
400
401void test_suite_pem_write_buffer( char *start, char *end, char *buf_str, char *result_str )
402{
403 unsigned char buf[5000];
404 unsigned char *check_buf = NULL;
405 int ret;
406 size_t buf_len, olen = 0, olen2 = 0;
407
408 memset( buf, 0, sizeof( buf ) );
409
410 buf_len = unhexify( buf, buf_str );
411
412 ret = pem_write_buffer( start, end, buf, buf_len, NULL, 0, &olen );
414
415 check_buf = (unsigned char *) polarssl_malloc( olen );
416 TEST_ASSERT( check_buf != NULL );
417
418 memset( check_buf, 0, olen );
419 ret = pem_write_buffer( start, end, buf, buf_len, check_buf, olen, &olen2 );
420
421 TEST_ASSERT( olen2 <= olen );
422 TEST_ASSERT( olen > strlen( (char*) result_str ) );
423 TEST_ASSERT( ret == 0 );
424 TEST_ASSERT( strncmp( (char *) check_buf, (char *) result_str, olen ) == 0 );
425
426exit:
427 polarssl_free( check_buf );
428}
429
430
431#endif /* POLARSSL_PEM_WRITE_C */
432
433
434int dep_check( char *str )
435{
436 if( str == NULL )
437 return( 1 );
438
439
440
441 return( 1 );
442}
443
444int dispatch_test(int cnt, char *params[50])
445{
446 int ret;
447 ((void) cnt);
448 ((void) params);
449
450#if defined(TEST_SUITE_ACTIVE)
451 if( strcmp( params[0], "pem_write_buffer" ) == 0 )
452 {
453
454 char *param1 = params[1];
455 char *param2 = params[2];
456 char *param3 = params[3];
457 char *param4 = params[4];
458
459 if( cnt != 5 )
460 {
461 fprintf( stderr, "\nIncorrect argument count (%d != %d)\n", cnt, 5 );
462 return( 2 );
463 }
464
465 if( verify_string( &param1 ) != 0 ) return( 2 );
466 if( verify_string( &param2 ) != 0 ) return( 2 );
467 if( verify_string( &param3 ) != 0 ) return( 2 );
468 if( verify_string( &param4 ) != 0 ) return( 2 );
469
470 test_suite_pem_write_buffer( param1, param2, param3, param4 );
471 return ( 0 );
472
473 return ( 3 );
474 }
475 else
476
477 {
478 fprintf( stdout, "FAILED\nSkipping unknown test function '%s'\n", params[0] );
479 fflush( stdout );
480 return( 1 );
481 }
482#else
483 return( 3 );
484#endif
485 return( ret );
486}
487
488int get_line( FILE *f, char *buf, size_t len )
489{
490 char *ret;
491
492 ret = fgets( buf, len, f );
493 if( ret == NULL )
494 return( -1 );
495
496 if( strlen( buf ) && buf[strlen(buf) - 1] == '\n' )
497 buf[strlen(buf) - 1] = '\0';
498 if( strlen( buf ) && buf[strlen(buf) - 1] == '\r' )
499 buf[strlen(buf) - 1] = '\0';
500
501 return( 0 );
502}
503
504int parse_arguments( char *buf, size_t len, char *params[50] )
505{
506 int cnt = 0, i;
507 char *cur = buf;
508 char *p = buf, *q;
509
510 params[cnt++] = cur;
511
512 while( *p != '\0' && p < buf + len )
513 {
514 if( *p == '\\' )
515 {
516 p++;
517 p++;
518 continue;
519 }
520 if( *p == ':' )
521 {
522 if( p + 1 < buf + len )
523 {
524 cur = p + 1;
525 params[cnt++] = cur;
526 }
527 *p = '\0';
528 }
529
530 p++;
531 }
532
533 // Replace newlines, question marks and colons in strings
534 for( i = 0; i < cnt; i++ )
535 {
536 p = params[i];
537 q = params[i];
538
539 while( *p != '\0' )
540 {
541 if( *p == '\\' && *(p + 1) == 'n' )
542 {
543 p += 2;
544 *(q++) = '\n';
545 }
546 else if( *p == '\\' && *(p + 1) == ':' )
547 {
548 p += 2;
549 *(q++) = ':';
550 }
551 else if( *p == '\\' && *(p + 1) == '?' )
552 {
553 p += 2;
554 *(q++) = '?';
555 }
556 else
557 *(q++) = *(p++);
558 }
559 *q = '\0';
560 }
561
562 return( cnt );
563}
564
565int main()
566{
567 int ret, i, cnt, total_errors = 0, total_tests = 0, total_skipped = 0;
568 const char *filename = "/builddir/build/BUILD/polarssl-1.3.9/tests/suites/test_suite_pem.data";
569 FILE *file;
570 char buf[5000];
571 char *params[50];
572
573#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
574 unsigned char alloc_buf[1000000];
575 memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
576#endif
577
578 file = fopen( filename, "r" );
579 if( file == NULL )
580 {
581 fprintf( stderr, "Failed to open\n" );
582 return( 1 );
583 }
584
585 while( !feof( file ) )
586 {
587 int skip = 0;
588
589 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
590 break;
591 fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
592 fprintf( stdout, " " );
593 for( i = strlen( buf ) + 1; i < 67; i++ )
594 fprintf( stdout, "." );
595 fprintf( stdout, " " );
596 fflush( stdout );
597
598 total_tests++;
599
600 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
601 break;
602 cnt = parse_arguments( buf, strlen(buf), params );
603
604 if( strcmp( params[0], "depends_on" ) == 0 )
605 {
606 for( i = 1; i < cnt; i++ )
607 if( dep_check( params[i] ) != 0 )
608 skip = 1;
609
610 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
611 break;
612 cnt = parse_arguments( buf, strlen(buf), params );
613 }
614
615 if( skip == 0 )
616 {
617 test_errors = 0;
618 ret = dispatch_test( cnt, params );
619 }
620
621 if( skip == 1 || ret == 3 )
622 {
623 total_skipped++;
624 fprintf( stdout, "----\n" );
625 fflush( stdout );
626 }
627 else if( ret == 0 && test_errors == 0 )
628 {
629 fprintf( stdout, "PASS\n" );
630 fflush( stdout );
631 }
632 else if( ret == 2 )
633 {
634 fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
635 fclose(file);
636 exit( 2 );
637 }
638 else
639 total_errors++;
640
641 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
642 break;
643 if( strlen(buf) != 0 )
644 {
645 fprintf( stderr, "Should be empty %d\n", (int) strlen(buf) );
646 return( 1 );
647 }
648 }
649 fclose(file);
650
651 fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
652 if( total_errors == 0 )
653 fprintf( stdout, "PASSED" );
654 else
655 fprintf( stdout, "FAILED" );
656
657 fprintf( stdout, " (%d / %d tests (%d skipped))\n",
658 total_tests - total_errors, total_tests, total_skipped );
659
660#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
661#if defined(POLARSSL_MEMORY_DEBUG)
662 memory_buffer_alloc_status();
663#endif
665#endif
666
667 return( total_errors != 0 );
668}
669
670
RFC 1521 base64 encoding/decoding.
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL
Output buffer too small.
Definition: base64.h:32
Configuration options (set of defines)
Memory allocation layer (Deprecated to platform layer)
void memory_buffer_alloc_free(void)
Free the mutex for thread-safety and clear remaining memory.
int memory_buffer_alloc_init(unsigned char *buf, size_t len)
Initialize use of stack-based memory allocator.
Privacy Enhanced Mail (PEM) decoding.
PolarSSL Platform abstraction layer.
unsigned char * buf
Info structure for the pseudo random function.
int verify_int(char *str, int *value)
static int test_assert(int correct, const char *test)
int verify_string(char **str)
#define TEST_ASSERT(TEST)
static unsigned char * unhexify_alloc(const char *ibuf, size_t *olen)
Allocate and fill a buffer from hex data.
int dep_check(char *str)
int dispatch_test(int cnt, char *params[50])
#define polarssl_malloc
static void hexify(unsigned char *obuf, const unsigned char *ibuf, int len)
int parse_arguments(char *buf, size_t len, char *params[50])
#define polarssl_free
#define PUT_UINT32_BE(n, b, i)
static int rnd_pseudo_rand(void *rng_state, unsigned char *output, size_t len)
This function returns random based on a pseudo random function.
int get_line(FILE *f, char *buf, size_t len)
static int test_errors
static int rnd_buffer_rand(void *rng_state, unsigned char *output, size_t len)
This function returns random based on a buffer it receives.
static int unhexify(unsigned char *obuf, const char *ibuf)
static unsigned char * zero_alloc(size_t len)
Allocate and zeroize a buffer.
static int rnd_std_rand(void *rng_state, unsigned char *output, size_t len)
This function just returns data from rand().
int main()
static int rnd_zero_rand(void *rng_state, unsigned char *output, size_t len)
This function only returns zeros.