PolarSSL v1.3.9
test_suite_pkwrite.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_PK_WRITE_C
8#ifdef POLARSSL_BIGNUM_C
9#ifdef POLARSSL_FS_IO
10
11#include <polarssl/pk.h>
12#include <polarssl/pem.h>
13#include <polarssl/oid.h>
14#endif /* POLARSSL_PK_WRITE_C */
15#endif /* POLARSSL_BIGNUM_C */
16#endif /* POLARSSL_FS_IO */
17
18
19#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
20#include "polarssl/memory.h"
21#endif
22
23#if defined(POLARSSL_PLATFORM_C)
24#include "polarssl/platform.h"
25#else
26#define polarssl_malloc malloc
27#define polarssl_free free
28#endif
29
30#ifdef _MSC_VER
31#include <basetsd.h>
32typedef UINT32 uint32_t;
33#else
34#include <inttypes.h>
35#endif
36
37#include <assert.h>
38#include <stdlib.h>
39#include <string.h>
40
41/*
42 * 32-bit integer manipulation macros (big endian)
43 */
44#ifndef GET_UINT32_BE
45#define GET_UINT32_BE(n,b,i) \
46{ \
47 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
48 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
49 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
50 | ( (uint32_t) (b)[(i) + 3] ); \
51}
52#endif
53
54#ifndef PUT_UINT32_BE
55#define PUT_UINT32_BE(n,b,i) \
56{ \
57 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
58 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
59 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
60 (b)[(i) + 3] = (unsigned char) ( (n) ); \
61}
62#endif
63
64static int unhexify(unsigned char *obuf, const char *ibuf)
65{
66 unsigned char c, c2;
67 int len = strlen(ibuf) / 2;
68 assert(!(strlen(ibuf) %1)); // must be even number of bytes
69
70 while (*ibuf != 0)
71 {
72 c = *ibuf++;
73 if( c >= '0' && c <= '9' )
74 c -= '0';
75 else if( c >= 'a' && c <= 'f' )
76 c -= 'a' - 10;
77 else if( c >= 'A' && c <= 'F' )
78 c -= 'A' - 10;
79 else
80 assert( 0 );
81
82 c2 = *ibuf++;
83 if( c2 >= '0' && c2 <= '9' )
84 c2 -= '0';
85 else if( c2 >= 'a' && c2 <= 'f' )
86 c2 -= 'a' - 10;
87 else if( c2 >= 'A' && c2 <= 'F' )
88 c2 -= 'A' - 10;
89 else
90 assert( 0 );
91
92 *obuf++ = ( c << 4 ) | c2;
93 }
94
95 return len;
96}
97
98static void hexify(unsigned char *obuf, const unsigned char *ibuf, int len)
99{
100 unsigned char l, h;
101
102 while (len != 0)
103 {
104 h = (*ibuf) / 16;
105 l = (*ibuf) % 16;
106
107 if( h < 10 )
108 *obuf++ = '0' + h;
109 else
110 *obuf++ = 'a' + h - 10;
111
112 if( l < 10 )
113 *obuf++ = '0' + l;
114 else
115 *obuf++ = 'a' + l - 10;
116
117 ++ibuf;
118 len--;
119 }
120}
121
129static unsigned char *zero_alloc( size_t len )
130{
131 void *p;
132 size_t actual_len = len != 0 ? len : 1;
133
134 p = polarssl_malloc( actual_len );
135 assert( p != NULL );
136
137 memset( p, 0x00, actual_len );
138
139 return( p );
140}
141
152static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen )
153{
154 unsigned char *obuf;
155
156 *olen = strlen(ibuf) / 2;
157
158 if( *olen == 0 )
159 return( zero_alloc( *olen ) );
160
161 obuf = polarssl_malloc( *olen );
162 assert( obuf != NULL );
163
164 (void) unhexify( obuf, ibuf );
165
166 return( obuf );
167}
168
178static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len )
179{
180#if !defined(__OpenBSD__)
181 size_t i;
182
183 if( rng_state != NULL )
184 rng_state = NULL;
185
186 for( i = 0; i < len; ++i )
187 output[i] = rand();
188#else
189 if( rng_state != NULL )
190 rng_state = NULL;
191
192 arc4random_buf( output, len );
193#endif /* !OpenBSD */
194
195 return( 0 );
196}
197
203static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len )
204{
205 if( rng_state != NULL )
206 rng_state = NULL;
207
208 memset( output, 0, len );
209
210 return( 0 );
211}
212
213typedef struct
214{
215 unsigned char *buf;
216 size_t length;
218
230static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len )
231{
232 rnd_buf_info *info = (rnd_buf_info *) rng_state;
233 size_t use_len;
234
235 if( rng_state == NULL )
236 return( rnd_std_rand( NULL, output, len ) );
237
238 use_len = len;
239 if( len > info->length )
240 use_len = info->length;
241
242 if( use_len )
243 {
244 memcpy( output, info->buf, use_len );
245 info->buf += use_len;
246 info->length -= use_len;
247 }
248
249 if( len - use_len > 0 )
250 return( rnd_std_rand( NULL, output + use_len, len - use_len ) );
251
252 return( 0 );
253}
254
262typedef struct
263{
264 uint32_t key[16];
265 uint32_t v0, v1;
267
276static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len )
277{
278 rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state;
279 uint32_t i, *k, sum, delta=0x9E3779B9;
280 unsigned char result[4], *out = output;
281
282 if( rng_state == NULL )
283 return( rnd_std_rand( NULL, output, len ) );
284
285 k = info->key;
286
287 while( len > 0 )
288 {
289 size_t use_len = ( len > 4 ) ? 4 : len;
290 sum = 0;
291
292 for( i = 0; i < 32; i++ )
293 {
294 info->v0 += (((info->v1 << 4) ^ (info->v1 >> 5)) + info->v1) ^ (sum + k[sum & 3]);
295 sum += delta;
296 info->v1 += (((info->v0 << 4) ^ (info->v0 >> 5)) + info->v0) ^ (sum + k[(sum>>11) & 3]);
297 }
298
299 PUT_UINT32_BE( info->v0, result, 0 );
300 memcpy( out, result, use_len );
301 len -= use_len;
302 out += 4;
303 }
304
305 return( 0 );
306}
307
308
309#include <stdio.h>
310#include <string.h>
311
312#if defined(POLARSSL_PLATFORM_C)
313#include "polarssl/platform.h"
314#else
315#define polarssl_printf printf
316#define polarssl_malloc malloc
317#define polarssl_free free
318#endif
319
320static int test_errors = 0;
321
322#ifdef POLARSSL_PK_WRITE_C
323#ifdef POLARSSL_BIGNUM_C
324#ifdef POLARSSL_FS_IO
325
326#define TEST_SUITE_ACTIVE
327
328static int test_assert( int correct, const char *test )
329{
330 if( correct )
331 return( 0 );
332
333 test_errors++;
334 if( test_errors == 1 )
335 printf( "FAILED\n" );
336 printf( " %s\n", test );
337
338 return( 1 );
339}
340
341#define TEST_ASSERT( TEST ) \
342 do { test_assert( (TEST) ? 1 : 0, #TEST ); \
343 if( test_errors) goto exit; \
344 } while (0)
345
346int verify_string( char **str )
347{
348 if( (*str)[0] != '"' ||
349 (*str)[strlen( *str ) - 1] != '"' )
350 {
351 printf( "Expected string (with \"\") for parameter and got: %s\n", *str );
352 return( -1 );
353 }
354
355 (*str)++;
356 (*str)[strlen( *str ) - 1] = '\0';
357
358 return( 0 );
359}
360
361int verify_int( char *str, int *value )
362{
363 size_t i;
364 int minus = 0;
365 int digits = 1;
366 int hex = 0;
367
368 for( i = 0; i < strlen( str ); i++ )
369 {
370 if( i == 0 && str[i] == '-' )
371 {
372 minus = 1;
373 continue;
374 }
375
376 if( ( ( minus && i == 2 ) || ( !minus && i == 1 ) ) &&
377 str[i - 1] == '0' && str[i] == 'x' )
378 {
379 hex = 1;
380 continue;
381 }
382
383 if( ! ( ( str[i] >= '0' && str[i] <= '9' ) ||
384 ( hex && ( ( str[i] >= 'a' && str[i] <= 'f' ) ||
385 ( str[i] >= 'A' && str[i] <= 'F' ) ) ) ) )
386 {
387 digits = 0;
388 break;
389 }
390 }
391
392 if( digits )
393 {
394 if( hex )
395 *value = strtol( str, NULL, 16 );
396 else
397 *value = strtol( str, NULL, 10 );
398
399 return( 0 );
400 }
401
402
403
404 printf( "Expected integer for parameter and got: %s\n", str );
405 return( -1 );
406}
407
408#ifdef POLARSSL_PEM_WRITE_C
409void test_suite_pk_write_pubkey_check( char *key_file )
410{
411 pk_context key;
412 unsigned char buf[5000];
413 unsigned char check_buf[5000];
414 int ret;
415 FILE *f;
416 size_t ilen;
417
418 memset( buf, 0, sizeof( buf ) );
419 memset( check_buf, 0, sizeof( check_buf ) );
420
421 pk_init( &key );
422 TEST_ASSERT( pk_parse_public_keyfile( &key, key_file ) == 0 );
423
424 ret = pk_write_pubkey_pem( &key, buf, sizeof( buf ) - 1);
425 TEST_ASSERT( ret >= 0 );
426
427 f = fopen( key_file, "r" );
428 TEST_ASSERT( f != NULL );
429 ilen = fread( check_buf, 1, sizeof( check_buf ) - 1, f );
430 fclose( f );
431
432 TEST_ASSERT( ilen == strlen( (char *) buf ) );
433 TEST_ASSERT( strncmp( (char *) buf, (char *) check_buf, sizeof( buf ) ) == 0 );
434
435exit:
436 pk_free( &key );
437}
438#endif /* POLARSSL_PEM_WRITE_C */
439
440#ifdef POLARSSL_PEM_WRITE_C
441void test_suite_pk_write_key_check( char *key_file )
442{
443 pk_context key;
444 unsigned char buf[5000];
445 unsigned char check_buf[5000];
446 int ret;
447 FILE *f;
448 size_t ilen;
449
450 memset( buf, 0, sizeof( buf ) );
451 memset( check_buf, 0, sizeof( check_buf ) );
452
453 pk_init( &key );
454 TEST_ASSERT( pk_parse_keyfile( &key, key_file, NULL ) == 0 );
455
456 ret = pk_write_key_pem( &key, buf, sizeof( buf ) - 1);
457 TEST_ASSERT( ret >= 0 );
458
459 f = fopen( key_file, "r" );
460 TEST_ASSERT( f != NULL );
461 ilen = fread( check_buf, 1, sizeof( check_buf ) - 1, f );
462 fclose( f );
463
464 TEST_ASSERT( ilen == strlen( (char *) buf ) );
465 TEST_ASSERT( strncmp( (char *) buf, (char *) check_buf, sizeof( buf ) ) == 0 );
466
467exit:
468 pk_free( &key );
469}
470#endif /* POLARSSL_PEM_WRITE_C */
471
472
473#endif /* POLARSSL_PK_WRITE_C */
474#endif /* POLARSSL_BIGNUM_C */
475#endif /* POLARSSL_FS_IO */
476
477
478int dep_check( char *str )
479{
480 if( str == NULL )
481 return( 1 );
482
483 if( strcmp( str, "POLARSSL_ECP_C" ) == 0 )
484 {
485#if defined(POLARSSL_ECP_C)
486 return( 0 );
487#else
488 return( 1 );
489#endif
490 }
491 if( strcmp( str, "POLARSSL_ECP_DP_SECP521R1_ENABLED" ) == 0 )
492 {
493#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED)
494 return( 0 );
495#else
496 return( 1 );
497#endif
498 }
499 if( strcmp( str, "POLARSSL_ECP_DP_SECP192R1_ENABLED" ) == 0 )
500 {
501#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED)
502 return( 0 );
503#else
504 return( 1 );
505#endif
506 }
507 if( strcmp( str, "POLARSSL_ECP_DP_BP512R1_ENABLED" ) == 0 )
508 {
509#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED)
510 return( 0 );
511#else
512 return( 1 );
513#endif
514 }
515 if( strcmp( str, "POLARSSL_RSA_C" ) == 0 )
516 {
517#if defined(POLARSSL_RSA_C)
518 return( 0 );
519#else
520 return( 1 );
521#endif
522 }
523 if( strcmp( str, "POLARSSL_BASE64_C" ) == 0 )
524 {
525#if defined(POLARSSL_BASE64_C)
526 return( 0 );
527#else
528 return( 1 );
529#endif
530 }
531
532
533 return( 1 );
534}
535
536int dispatch_test(int cnt, char *params[50])
537{
538 int ret;
539 ((void) cnt);
540 ((void) params);
541
542#if defined(TEST_SUITE_ACTIVE)
543 if( strcmp( params[0], "pk_write_pubkey_check" ) == 0 )
544 {
545 #ifdef POLARSSL_PEM_WRITE_C
546
547 char *param1 = params[1];
548
549 if( cnt != 2 )
550 {
551 fprintf( stderr, "\nIncorrect argument count (%d != %d)\n", cnt, 2 );
552 return( 2 );
553 }
554
555 if( verify_string( &param1 ) != 0 ) return( 2 );
556
557 test_suite_pk_write_pubkey_check( param1 );
558 return ( 0 );
559 #endif /* POLARSSL_PEM_WRITE_C */
560
561 return ( 3 );
562 }
563 else
564 if( strcmp( params[0], "pk_write_key_check" ) == 0 )
565 {
566 #ifdef POLARSSL_PEM_WRITE_C
567
568 char *param1 = params[1];
569
570 if( cnt != 2 )
571 {
572 fprintf( stderr, "\nIncorrect argument count (%d != %d)\n", cnt, 2 );
573 return( 2 );
574 }
575
576 if( verify_string( &param1 ) != 0 ) return( 2 );
577
578 test_suite_pk_write_key_check( param1 );
579 return ( 0 );
580 #endif /* POLARSSL_PEM_WRITE_C */
581
582 return ( 3 );
583 }
584 else
585
586 {
587 fprintf( stdout, "FAILED\nSkipping unknown test function '%s'\n", params[0] );
588 fflush( stdout );
589 return( 1 );
590 }
591#else
592 return( 3 );
593#endif
594 return( ret );
595}
596
597int get_line( FILE *f, char *buf, size_t len )
598{
599 char *ret;
600
601 ret = fgets( buf, len, f );
602 if( ret == NULL )
603 return( -1 );
604
605 if( strlen( buf ) && buf[strlen(buf) - 1] == '\n' )
606 buf[strlen(buf) - 1] = '\0';
607 if( strlen( buf ) && buf[strlen(buf) - 1] == '\r' )
608 buf[strlen(buf) - 1] = '\0';
609
610 return( 0 );
611}
612
613int parse_arguments( char *buf, size_t len, char *params[50] )
614{
615 int cnt = 0, i;
616 char *cur = buf;
617 char *p = buf, *q;
618
619 params[cnt++] = cur;
620
621 while( *p != '\0' && p < buf + len )
622 {
623 if( *p == '\\' )
624 {
625 p++;
626 p++;
627 continue;
628 }
629 if( *p == ':' )
630 {
631 if( p + 1 < buf + len )
632 {
633 cur = p + 1;
634 params[cnt++] = cur;
635 }
636 *p = '\0';
637 }
638
639 p++;
640 }
641
642 // Replace newlines, question marks and colons in strings
643 for( i = 0; i < cnt; i++ )
644 {
645 p = params[i];
646 q = params[i];
647
648 while( *p != '\0' )
649 {
650 if( *p == '\\' && *(p + 1) == 'n' )
651 {
652 p += 2;
653 *(q++) = '\n';
654 }
655 else if( *p == '\\' && *(p + 1) == ':' )
656 {
657 p += 2;
658 *(q++) = ':';
659 }
660 else if( *p == '\\' && *(p + 1) == '?' )
661 {
662 p += 2;
663 *(q++) = '?';
664 }
665 else
666 *(q++) = *(p++);
667 }
668 *q = '\0';
669 }
670
671 return( cnt );
672}
673
674int main()
675{
676 int ret, i, cnt, total_errors = 0, total_tests = 0, total_skipped = 0;
677 const char *filename = "/builddir/build/BUILD/polarssl-1.3.9/tests/suites/test_suite_pkwrite.data";
678 FILE *file;
679 char buf[5000];
680 char *params[50];
681
682#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
683 unsigned char alloc_buf[1000000];
684 memory_buffer_alloc_init( alloc_buf, sizeof(alloc_buf) );
685#endif
686
687 file = fopen( filename, "r" );
688 if( file == NULL )
689 {
690 fprintf( stderr, "Failed to open\n" );
691 return( 1 );
692 }
693
694 while( !feof( file ) )
695 {
696 int skip = 0;
697
698 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
699 break;
700 fprintf( stdout, "%s%.66s", test_errors ? "\n" : "", buf );
701 fprintf( stdout, " " );
702 for( i = strlen( buf ) + 1; i < 67; i++ )
703 fprintf( stdout, "." );
704 fprintf( stdout, " " );
705 fflush( stdout );
706
707 total_tests++;
708
709 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
710 break;
711 cnt = parse_arguments( buf, strlen(buf), params );
712
713 if( strcmp( params[0], "depends_on" ) == 0 )
714 {
715 for( i = 1; i < cnt; i++ )
716 if( dep_check( params[i] ) != 0 )
717 skip = 1;
718
719 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
720 break;
721 cnt = parse_arguments( buf, strlen(buf), params );
722 }
723
724 if( skip == 0 )
725 {
726 test_errors = 0;
727 ret = dispatch_test( cnt, params );
728 }
729
730 if( skip == 1 || ret == 3 )
731 {
732 total_skipped++;
733 fprintf( stdout, "----\n" );
734 fflush( stdout );
735 }
736 else if( ret == 0 && test_errors == 0 )
737 {
738 fprintf( stdout, "PASS\n" );
739 fflush( stdout );
740 }
741 else if( ret == 2 )
742 {
743 fprintf( stderr, "FAILED: FATAL PARSE ERROR\n" );
744 fclose(file);
745 exit( 2 );
746 }
747 else
748 total_errors++;
749
750 if( ( ret = get_line( file, buf, sizeof(buf) ) ) != 0 )
751 break;
752 if( strlen(buf) != 0 )
753 {
754 fprintf( stderr, "Should be empty %d\n", (int) strlen(buf) );
755 return( 1 );
756 }
757 }
758 fclose(file);
759
760 fprintf( stdout, "\n----------------------------------------------------------------------------\n\n");
761 if( total_errors == 0 )
762 fprintf( stdout, "PASSED" );
763 else
764 fprintf( stdout, "FAILED" );
765
766 fprintf( stdout, " (%d / %d tests (%d skipped))\n",
767 total_tests - total_errors, total_tests, total_skipped );
768
769#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C)
770#if defined(POLARSSL_MEMORY_DEBUG)
771 memory_buffer_alloc_status();
772#endif
774#endif
775
776 return( total_errors != 0 );
777}
778
779
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.
Object Identifier (OID) database.
Privacy Enhanced Mail (PEM) decoding.
Public Key abstraction layer.
int pk_parse_keyfile(pk_context *ctx, const char *path, const char *password)
Load and parse a private key.
int pk_write_pubkey_pem(pk_context *ctx, unsigned char *buf, size_t size)
Write a public key to a PEM string.
int pk_write_key_pem(pk_context *ctx, unsigned char *buf, size_t size)
Write a private key to a PKCS#1 or SEC1 PEM string.
void pk_free(pk_context *ctx)
Free a pk_context.
int pk_parse_public_keyfile(pk_context *ctx, const char *path)
Load and parse a public key.
void pk_init(pk_context *ctx)
Initialize a pk_context (as NONE)
PolarSSL Platform abstraction layer.
Public key container.
Definition pk.h:195
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 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.