Back to index

lightning-sunbird  0.9+nobinonly
ssltrace.c
Go to the documentation of this file.
00001 /*
00002  * Functions to trace SSL protocol behavior in DEBUG builds.
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is the Netscape security libraries.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 /* $Id: ssltrace.c,v 1.3 2004/04/27 23:04:39 gerv%gerv.net Exp $ */
00040 #include <stdarg.h>
00041 #include "cert.h"
00042 #include "ssl.h"
00043 #include "sslimpl.h"
00044 #include "sslproto.h"
00045 #include "prprf.h"
00046 
00047 #if defined(DEBUG) || defined(TRACE)
00048 static const char *hex = "0123456789abcdef";
00049 
00050 static const char printable[257] = {
00051        "................"   /* 0x */
00052        "................"   /* 1x */
00053        " !\"#$%&'()*+,-./"  /* 2x */
00054        "0123456789:;<=>?"   /* 3x */
00055        "@ABCDEFGHIJKLMNO"   /* 4x */
00056        "PQRSTUVWXYZ[\\]^_"  /* 5x */
00057        "`abcdefghijklmno"   /* 6x */
00058        "pqrstuvwxyz{|}~."   /* 7x */
00059        "................"   /* 8x */
00060        "................"   /* 9x */
00061        "................"   /* ax */
00062        "................"   /* bx */
00063        "................"   /* cx */
00064        "................"   /* dx */
00065        "................"   /* ex */
00066        "................"   /* fx */
00067 };
00068 
00069 void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *vp, int len)
00070 {
00071     const unsigned char *cp = (const unsigned char *)vp;
00072     char buf[80];
00073     char *bp;
00074     char *ap;
00075 
00076     if (ss) {
00077        SSL_TRACE(("%d: SSL[%d]: %s [Len: %d]", SSL_GETPID(), ss->fd,
00078                  msg, len));
00079     } else {
00080        SSL_TRACE(("%d: SSL: %s [Len: %d]", SSL_GETPID(), msg, len));
00081     }
00082     memset(buf, ' ', sizeof buf);
00083     bp = buf;
00084     ap = buf + 50;
00085     while (--len >= 0) {
00086        unsigned char ch = *cp++;
00087        *bp++ = hex[(ch >> 4) & 0xf];
00088        *bp++ = hex[ch & 0xf];
00089        *bp++ = ' ';
00090        *ap++ = printable[ch];
00091        if (ap - buf >= 66) {
00092            *ap = 0;
00093            SSL_TRACE(("   %s", buf));
00094            memset(buf, ' ', sizeof buf);
00095            bp = buf;
00096            ap = buf + 50;
00097        }
00098     }
00099     if (bp > buf) {
00100        *ap = 0;
00101        SSL_TRACE(("   %s", buf));
00102     }
00103 }
00104 
00105 #define LEN(cp)             (((cp)[0] << 8) | ((cp)[1]))
00106 
00107 static void PrintType(sslSocket *ss, char *msg)
00108 {
00109     if (ss) {
00110        SSL_TRACE(("%d: SSL[%d]: dump-msg: %s", SSL_GETPID(), ss->fd,
00111                  msg));
00112     } else {
00113        SSL_TRACE(("%d: SSL: dump-msg: %s", SSL_GETPID(), msg));
00114     }
00115 }
00116 
00117 static void PrintInt(sslSocket *ss, char *msg, unsigned v)
00118 {
00119     if (ss) {
00120        SSL_TRACE(("%d: SSL[%d]:           %s=%u", SSL_GETPID(), ss->fd,
00121                  msg, v));
00122     } else {
00123        SSL_TRACE(("%d: SSL:           %s=%u", SSL_GETPID(), msg, v));
00124     }
00125 }
00126 
00127 /* PrintBuf is just like ssl_PrintBuf above, except that:
00128  * a) It prefixes each line of the buffer with "XX: SSL[xxx]           "
00129  * b) It dumps only hex, not ASCII.
00130  */
00131 static void PrintBuf(sslSocket *ss, char *msg, unsigned char *cp, int len)
00132 {
00133     char buf[80];
00134     char *bp;
00135 
00136     if (ss) {
00137        SSL_TRACE(("%d: SSL[%d]:           %s [Len: %d]", 
00138                  SSL_GETPID(), ss->fd, msg, len));
00139     } else {
00140        SSL_TRACE(("%d: SSL:           %s [Len: %d]", 
00141                  SSL_GETPID(), msg, len));
00142     }
00143     bp = buf;
00144     while (--len >= 0) {
00145        unsigned char ch = *cp++;
00146        *bp++ = hex[(ch >> 4) & 0xf];
00147        *bp++ = hex[ch & 0xf];
00148        *bp++ = ' ';
00149        if (bp + 4 > buf + 50) {
00150            *bp = 0;
00151            if (ss) {
00152               SSL_TRACE(("%d: SSL[%d]:             %s",
00153                         SSL_GETPID(), ss->fd, buf));
00154            } else {
00155               SSL_TRACE(("%d: SSL:             %s", SSL_GETPID(), buf));
00156            }
00157            bp = buf;
00158        }
00159     }
00160     if (bp > buf) {
00161        *bp = 0;
00162        if (ss) {
00163            SSL_TRACE(("%d: SSL[%d]:             %s",
00164                      SSL_GETPID(), ss->fd, buf));
00165        } else {
00166            SSL_TRACE(("%d: SSL:             %s", SSL_GETPID(), buf));
00167        }
00168     }
00169 }
00170 
00171 void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len)
00172 {
00173     switch (bp[0]) {
00174       case SSL_MT_ERROR:
00175        PrintType(ss, "Error");
00176        PrintInt(ss, "error", LEN(bp+1));
00177        break;
00178 
00179       case SSL_MT_CLIENT_HELLO:
00180        {
00181            unsigned lcs = LEN(bp+3);
00182            unsigned ls  = LEN(bp+5);
00183            unsigned lc  = LEN(bp+7);
00184 
00185            PrintType(ss, "Client-Hello");
00186 
00187            PrintInt(ss, "version (Major)",                   bp[1]);
00188            PrintInt(ss, "version (minor)",                   bp[2]);
00189 
00190            PrintBuf(ss, "cipher-specs",         bp+9,        lcs);
00191            PrintBuf(ss, "session-id",           bp+9+lcs,    ls);
00192            PrintBuf(ss, "challenge",            bp+9+lcs+ls, lc);
00193        }
00194        break;
00195       case SSL_MT_CLIENT_MASTER_KEY:
00196        {
00197            unsigned lck = LEN(bp+4);
00198            unsigned lek = LEN(bp+6);
00199            unsigned lka = LEN(bp+8);
00200 
00201            PrintType(ss, "Client-Master-Key");
00202 
00203            PrintInt(ss, "cipher-choice",                       bp[1]);
00204            PrintInt(ss, "key-length",                          LEN(bp+2));
00205 
00206            PrintBuf(ss, "clear-key",            bp+10,         lck);
00207            PrintBuf(ss, "encrypted-key",        bp+10+lck,     lek);
00208            PrintBuf(ss, "key-arg",              bp+10+lck+lek, lka);
00209        }
00210        break;
00211       case SSL_MT_CLIENT_FINISHED:
00212        PrintType(ss, "Client-Finished");
00213        PrintBuf(ss, "connection-id",            bp+1,          len-1);
00214        break;
00215       case SSL_MT_SERVER_HELLO:
00216        {
00217            unsigned lc = LEN(bp+5);
00218            unsigned lcs = LEN(bp+7);
00219            unsigned lci = LEN(bp+9);
00220 
00221            PrintType(ss, "Server-Hello");
00222 
00223            PrintInt(ss, "session-id-hit",                     bp[1]);
00224            PrintInt(ss, "certificate-type",                   bp[2]);
00225            PrintInt(ss, "version (Major)",                    bp[3]);
00226            PrintInt(ss, "version (minor)",                    bp[3]);
00227            PrintBuf(ss, "certificate",          bp+11,        lc);
00228            PrintBuf(ss, "cipher-specs",         bp+11+lc,     lcs);
00229            PrintBuf(ss, "connection-id",        bp+11+lc+lcs, lci);
00230        }
00231        break;
00232       case SSL_MT_SERVER_VERIFY:
00233        PrintType(ss, "Server-Verify");
00234        PrintBuf(ss, "challenge",                bp+1,         len-1);
00235        break;
00236       case SSL_MT_SERVER_FINISHED:
00237        PrintType(ss, "Server-Finished");
00238        PrintBuf(ss, "session-id",               bp+1,         len-1);
00239        break;
00240       case SSL_MT_REQUEST_CERTIFICATE:
00241        PrintType(ss, "Request-Certificate");
00242        PrintInt(ss, "authentication-type",                    bp[1]);
00243        PrintBuf(ss, "certificate-challenge",    bp+2,         len-2);
00244        break;
00245       case SSL_MT_CLIENT_CERTIFICATE:
00246        {
00247            unsigned lc = LEN(bp+2);
00248            unsigned lr = LEN(bp+4);
00249            PrintType(ss, "Client-Certificate");
00250            PrintInt(ss, "certificate-type",                   bp[1]);
00251            PrintBuf(ss, "certificate",          bp+6,         lc);
00252            PrintBuf(ss, "response",             bp+6+lc,      lr);
00253        }
00254        break;
00255       default:
00256        ssl_PrintBuf(ss, "sending *unknown* message type", bp, len);
00257        return;
00258     }
00259 }
00260 
00261 void
00262 ssl_Trace(const char *format, ... )
00263 {
00264     char buf[2000]; 
00265 
00266     va_list args;
00267     va_start(args, format);
00268     PR_vsnprintf(buf, sizeof(buf), format, args);
00269     va_end(args);
00270     puts(buf);
00271 }
00272 #endif