debug.c 7.82 KB
Newer Older
1 2 3
/*
 *  Debugging routines
 *
4
 *  Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakker's avatar
Paul Bakker committed
5 6
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
7
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakker's avatar
Paul Bakker committed
8
 *
9
 *  All rights reserved.
Paul Bakker's avatar
Paul Bakker committed
10
 *
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

26
#include "polarssl/config.h"
27

28
#if defined(POLARSSL_DEBUG_C)
29

30
#include "polarssl/debug.h"
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

#include <stdarg.h>
#include <stdlib.h>

#if defined _MSC_VER && !defined  snprintf
#define  snprintf  _snprintf
#endif

#if defined _MSC_VER && !defined vsnprintf
#define vsnprintf _vsnprintf
#endif

char *debug_fmt( const char *format, ... )
{
    va_list argp;
    static char str[512];
    int maxlen = sizeof( str ) - 1;

    va_start( argp, format );
    vsnprintf( str, maxlen, format, argp );
    va_end( argp );

    str[maxlen] = '\0';
    return( str );
}

57 58
void debug_print_msg( const ssl_context *ssl, int level,
                      const char *file, int line, const char *text )
59 60 61 62 63 64 65 66 67 68 69 70
{
    char str[512];
    int maxlen = sizeof( str ) - 1;

    if( ssl->f_dbg == NULL )
        return;

    snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text );
    str[maxlen] = '\0';
    ssl->f_dbg( ssl->p_dbg, level, str );
}

71 72 73
void debug_print_ret( const ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, int ret )
74 75 76 77 78 79 80 81 82 83 84 85 86 87
{
    char str[512];
    int maxlen = sizeof( str ) - 1;

    if( ssl->f_dbg == NULL )
        return;

    snprintf( str, maxlen, "%s(%04d): %s() returned %d (0x%x)\n",
              file, line, text, ret, ret );

    str[maxlen] = '\0';
    ssl->f_dbg( ssl->p_dbg, level, str );
}

88 89
void debug_print_buf( const ssl_context *ssl, int level,
                      const char *file, int line, const char *text,
90
                      unsigned char *buf, size_t len )
91 92
{
    char str[512];
93
    size_t i, maxlen = sizeof( str ) - 1;
94

95
    if( ssl->f_dbg == NULL )
96 97 98
        return;

    snprintf( str, maxlen, "%s(%04d): dumping '%s' (%d bytes)\n",
99
              file, line, text, (unsigned int) len );
100 101 102 103 104 105 106 107 108 109 110 111 112 113

    str[maxlen] = '\0';
    ssl->f_dbg( ssl->p_dbg, level, str );

    for( i = 0; i < len; i++ )
    {
        if( i >= 4096 )
            break;

        if( i % 16 == 0 )
        {
            if( i > 0 )
                ssl->f_dbg( ssl->p_dbg, level, "\n" );

114 115
            snprintf( str, maxlen, "%s(%04d): %04x: ", file, line,
                      (unsigned int) i );
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

            str[maxlen] = '\0';
            ssl->f_dbg( ssl->p_dbg, level, str );
        }

        snprintf( str, maxlen, " %02x", (unsigned int) buf[i] );

        str[maxlen] = '\0';
        ssl->f_dbg( ssl->p_dbg, level, str );
    }

    if( len > 0 )
        ssl->f_dbg( ssl->p_dbg, level, "\n" );
}

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
#if defined(POLARSSL_ECP_C)
void debug_print_ecp( const ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, const ecp_point *X )
{
    char str[512];
    int maxlen = sizeof( str ) - 1;

    snprintf( str, maxlen, "%s(X)", text );
    str[maxlen] = '\0';
    debug_print_mpi( ssl, level, file, line, str, &X->X );

    snprintf( str, maxlen, "%s(Y)", text );
    str[maxlen] = '\0';
    debug_print_mpi( ssl, level, file, line, str, &X->Y );

    snprintf( str, maxlen, "%s(Z)", text );
    str[maxlen] = '\0';
    debug_print_mpi( ssl, level, file, line, str, &X->Z );
}
#endif /* POLARSSL_ECP_C */

153
#if defined(POLARSSL_BIGNUM_C)
154 155 156
void debug_print_mpi( const ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, const mpi *X )
157 158
{
    char str[512];
159 160
    int j, k, maxlen = sizeof( str ) - 1, zeros = 1;
    size_t i, n;
161 162 163 164

    if( ssl->f_dbg == NULL || X == NULL )
        return;

165
    for( n = X->n - 1; n > 0; n-- )
166 167 168
        if( X->p[n] != 0 )
            break;

169
    for( j = ( sizeof(t_uint) << 3 ) - 1; j >= 0; j-- )
170 171 172
        if( ( ( X->p[n] >> j ) & 1 ) != 0 )
            break;

173
    snprintf( str, maxlen, "%s(%04d): value of '%s' (%d bits) is:\n",
174
              file, line, text, 
175
              (int) ( ( n * ( sizeof(t_uint) << 3 ) ) + j + 1 ) );
176 177 178 179

    str[maxlen] = '\0';
    ssl->f_dbg( ssl->p_dbg, level, str );

180
    for( i = n + 1, j = 0; i > 0; i-- )
181
    {
182
        if( zeros && X->p[i - 1] == 0 )
183 184
            continue;

185
        for( k = sizeof( t_uint ) - 1; k >= 0; k-- )
186
        {
187
            if( zeros && ( ( X->p[i - 1] >> (k << 3) ) & 0xFF ) == 0 )
188 189 190
                continue;
            else
                zeros = 0;
191

192 193 194 195
            if( j % 16 == 0 )
            {
                if( j > 0 )
                    ssl->f_dbg( ssl->p_dbg, level, "\n" );
196

197 198 199 200 201
                snprintf( str, maxlen, "%s(%04d): ", file, line );

                str[maxlen] = '\0';
                ssl->f_dbg( ssl->p_dbg, level, str );
            }
202 203

            snprintf( str, maxlen, " %02x", (unsigned int)
204
                      ( X->p[i - 1] >> (k << 3) ) & 0xFF );
205 206 207

            str[maxlen] = '\0';
            ssl->f_dbg( ssl->p_dbg, level, str );
208 209

            j++;
210
        }
211 212 213 214 215 216 217 218 219 220

    }

    if( zeros == 1 )
    {
        snprintf( str, maxlen, "%s(%04d): ", file, line );

        str[maxlen] = '\0';
        ssl->f_dbg( ssl->p_dbg, level, str );
        ssl->f_dbg( ssl->p_dbg, level, " 00" );
221 222 223 224
    }

    ssl->f_dbg( ssl->p_dbg, level, "\n" );
}
225
#endif /* POLARSSL_BIGNUM_C */
226

227
#if defined(POLARSSL_X509_PARSE_C)
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
static void debug_print_pk( const ssl_context *ssl, int level,
                            const char *file, int line,
                            const char *text, const pk_context *pk )
{
    size_t i;
    pk_debug_item items[POLARSSL_PK_DEBUG_MAX_ITEMS];
    char name[16];

    memset( items, 0, sizeof( items ) );

    if( pk_debug( pk, items ) != 0 )
    {
        debug_print_msg( ssl, level, file, line, "invalid PK context" );
        return;
    }

    for( i = 0; i < sizeof( items ); i++ )
    {
        if( items[i].type == POLARSSL_PK_DEBUG_NONE )
            return;

        snprintf( name, sizeof( name ), "%s%s", text, items[i].name );
        name[sizeof( name ) - 1] = '\0';

        if( items[i].type == POLARSSL_PK_DEBUG_MPI )
            debug_print_mpi( ssl, level, file, line, name, items[i].value );
        else if( items[i].type == POLARSSL_PK_DEBUG_ECP )
            debug_print_ecp( ssl, level, file, line, name, items[i].value );
        else
            debug_print_msg( ssl, level, file, line, "should not happen" );
    }
}

261 262 263
void debug_print_crt( const ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, const x509_cert *crt )
264
{
265
    char str[1024], prefix[64];
266 267 268 269 270 271 272 273 274
    int i = 0, maxlen = sizeof( prefix ) - 1;

    if( ssl->f_dbg == NULL || crt == NULL )
        return;

    snprintf( prefix, maxlen, "%s(%04d): ", file, line );
    prefix[maxlen] = '\0';
    maxlen = sizeof( str ) - 1;

Paul Bakker's avatar
Paul Bakker committed
275
    while( crt != NULL )
276
    {
277 278
        char buf[1024];
        x509parse_cert_info( buf, sizeof( buf ) - 1, prefix, crt );
279 280

        snprintf( str, maxlen, "%s(%04d): %s #%d:\n%s",
281
                  file, line, text, ++i, buf );
282 283 284 285

        str[maxlen] = '\0';
        ssl->f_dbg( ssl->p_dbg, level, str );

286
        debug_print_pk( ssl, level, file, line, "crt->", &crt->pk );
287 288 289 290

        crt = crt->next;
    }
}
291
#endif /* POLARSSL_X509_PARSE_C */
292 293

#endif