void asn1show(int depth, struct asn1struct *certificate) { struct asn1struct *token; int i; token = certificate; while (token) { for (i = 0; i < depth; i++) { printf(" "); } if (token->tag_class == ASN1_CLASS_UNIVERSAL) { printf("%s", tag_names[token->tag]); } else if (token->tag_class == ASN1_CLASS_APPLICATION) { printf("application"); } else if (token->tag_class == ASN1_CLASS_SPECIFIC) { printf("context"); } else if (token->tag_class == ASN1_CLASS_PRIVATE) { printf("private"); } printf( " (%d:%d) ", token->tag, token->length ); if (token->tag_class == ASN1_CLASS_UNIVERSAL) { if (token->tag == ASN1_BIT_STRING || \ token->tag == ASN1_OCTET_STRING || \ token->tag == ASN1_OBJECT_IDENTIFIER ) { int i; for (i = 0; i < token->length; i++) { printf("%.02x ", token->data[i]); } } else if (token->tag == ASN1_NUMERIC_STRING || \ token->tag == ASN1_PRINTABLE_STRING || \ token->tag == ASN1_VIDEOTEX_STRING || \ token->tag == ASN1_IA5_STRING || \ token->tag == ASN1_UTC_TIME || \ token->tag == ASN1_GENERALIZED_TIME || \ token->tag == ASN1_GRAPHIC_STRING || \ token->tag == ASN1_VISIBLE_STRING || \ token->tag == ASN1_GENERAL_STRING || \ token->tag == ASN1_UNIVERSAL_STRING || \ token->tag == ASN1_CHARACTER_STRING || \ token->tag == ASN1_BMP_STRING || \ token->tag == ASN1_UTF8_STRING ) { char *str_val = (char*) malloc(token->length + 1); strncpy(str_val, (char *) token->data, token->length); str_val[token->length] = 0; printf(" %s", str_val); free(str_val); } } } printf("\n"); if (token->children) { asn1show(depth + 1, token->children); } token = token->next; }
int main( int argc, char *argv[ ] ) { int certificate_file; struct stat certificate_file_stat; unsigned char *buffer, *bufptr; int buffer_size; int bytes_read; struct asn1struct certificate; if ( argc < 3 ) { fprintf( stderr, "Usage: %s [-der|-pem] <certificate file>\n", argv[ 0 ] ); exit( 0 ); } if ( ( certificate_file = open( argv[ 2 ], O_RDONLY ) ) == -1 ) { perror( "Unable to open certificate file" ); return 1; } // Slurp the whole thing into memory if ( fstat( certificate_file, &certificate_file_stat ) ) { perror( "Unable to stat certificate file" ); return 2; } buffer_size = certificate_file_stat.st_size; buffer = ( char * ) malloc( buffer_size ); if ( !buffer ) { perror( "Not enough memory" ); return 3; } bufptr = buffer; while ( bytes_read = read( certificate_file, ( void * ) buffer, certificate_file_stat.st_size ) ) { bufptr += bytes_read; } if ( !( strcmp( argv[ 1 ], "-pem" ) ) ) { // XXX this overallocates a bit, since it sets aside space for markers, etc. unsigned char *pem_buffer = buffer; buffer = (unsigned char * ) malloc( buffer_size ); buffer_size = pem_decode( pem_buffer, buffer ); free( pem_buffer ); } asn1parse( buffer, buffer_size, &certificate ); asn1show( 0, &certificate ); asn1free( &certificate ); return 0; }