Commit 3a46c91d authored by Robert David Graham's avatar Robert David Graham
Browse files

ssl base64 fix

parent 644e6419
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -18,6 +18,12 @@ struct Banner1
    struct ProtocolParserStream *tcp_payloads[65536];
};

struct BanBase64
{
    unsigned state:2;
    unsigned temp:24;
};

struct SSL_SERVER_HELLO {
    unsigned state;
    unsigned remaining;
@@ -32,8 +38,7 @@ struct SSL_SERVER_CERT {
    unsigned remaining;
    struct {
        unsigned remaining;
        unsigned state;
        unsigned b64x;
        struct BanBase64 base64;
    } sub;
    struct CertDecode x509;
};
+167 −19
Original line number Diff line number Diff line
@@ -188,10 +188,110 @@ banout_append(struct BannerOutput *banout, unsigned proto, const void *px, size_
    p->length = (unsigned)(p->length + length);
}

/***************************************************************************
 ***************************************************************************/
/*****************************************************************************
 *****************************************************************************/
static const char *b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"+/";


/*****************************************************************************
 *****************************************************************************/
void
banout_init_base64(struct BanBase64 *base64)
{
    base64->state = 0;
    base64->temp = 0;
}

/*****************************************************************************
 *****************************************************************************/
void
banout_append_base64(struct BannerOutput *banout, unsigned proto,
                     const void *vpx, size_t length,
                     struct BanBase64 *base64)
{
    const unsigned char *px = (const unsigned char *)vpx;
    size_t i;
    unsigned x = base64->temp;
    unsigned state = base64->state;
    
    for (i=0; i<length; i++) {
        switch (state) {
            case 0:
                x = px[i]<<16;
                state++;
                break;
            case 1:
                x |= px[i]<<8;
                state++;
                break;
            case 2:
                x |= px[i];
                state = 0;
                banout_append_char(banout, proto, b64[(x>>18)&0x3F]);
                banout_append_char(banout, proto, b64[(x>>12)&0x3F]);
                banout_append_char(banout, proto, b64[(x>> 6)&0x3F]);
                banout_append_char(banout, proto, b64[(x>> 0)&0x3F]);
        }
    }
    
    base64->temp = x;
    base64->state = state;
}

/*****************************************************************************
 *****************************************************************************/
void
banout_finalize_base64(struct BannerOutput *banout, unsigned proto,
                       struct BanBase64 *base64)
{
    unsigned x = base64->temp;
    switch (base64->state) {
        case 0:
            break;
        case 1:
            banout_append_char(banout, proto, b64[(x>>18)&0x3F]);
            banout_append_char(banout, proto, b64[(x>>12)&0x3F]);
            banout_append_char(banout, proto, '=');
            banout_append_char(banout, proto, '=');
            break;
        case 2:
            banout_append_char(banout, proto, b64[(x>>18)&0x3F]);
            banout_append_char(banout, proto, b64[(x>>12)&0x3F]);
            banout_append_char(banout, proto, b64[(x>>6)&0x3F]);
            banout_append_char(banout, proto, '=');
            break;
    }
}



/*****************************************************************************
 *****************************************************************************/
static int
banout_string_equals(struct BannerOutput *banout, unsigned proto,
                     const char *rhs)
{
    const unsigned char *lhs = banout_string(banout, proto);
    size_t lhs_length = banout_string_length(banout, proto);
    size_t rhs_length = strlen(rhs);
    
    if (lhs_length != rhs_length)
        return 0;
    return memcmp(lhs, rhs, rhs_length) == 0;
}

/*****************************************************************************
 *****************************************************************************/
int
banout_selftest(void)
{
    /*
     * Basic test
     */
    {
        struct BannerOutput banout[1];
        unsigned i;
@@ -213,6 +313,54 @@ banout_selftest(void)
        banout_release(banout);
        if (banout->next != 0)
            return 1;
    }
    
    /*
     * Test BASE64 encoding. We are going to do strings of various lengths
     * in order to test the boundary condition of finalizing various strings
     * properly
     */
    {
        struct BannerOutput banout[1];
        struct BanBase64 base64[1];
    
        banout_init(banout);

        banout_init_base64(base64);
        banout_append_base64(banout, 1, "x", 1, base64);
        banout_finalize_base64(banout, 1, base64);
        
        banout_init_base64(base64);
        banout_append_base64(banout, 2, "bc", 2, base64);
        banout_finalize_base64(banout, 2, base64);
        
        banout_init_base64(base64);
        banout_append_base64(banout, 3, "mno", 3, base64);
        banout_finalize_base64(banout, 3, base64);
        
        banout_init_base64(base64);
        banout_append_base64(banout, 4, "stuv", 4, base64);
        banout_finalize_base64(banout, 4, base64);
        
        banout_init_base64(base64);
        banout_append_base64(banout, 5, "fghij", 5, base64);
        banout_finalize_base64(banout, 5, base64);
        
        
        if (!banout_string_equals(banout, 1, "eA=="))
            return 1;
        if (!banout_string_equals(banout, 2, "YmM="))
            return 1;
        if (!banout_string_equals(banout, 3, "bW5v"))
            return 1;
        if (!banout_string_equals(banout, 4, "c3R1dg=="))
            return 1;
        if (!banout_string_equals(banout, 5, "ZmdoaWo="))
            return 1;

        banout_release(banout);
    }
    
    
    return 0;
}
+28 −0
Original line number Diff line number Diff line
#ifndef PROTO_BANOUT_H
#define PROTO_BANOUT_H
struct BanBase64;

/**
 * A structure for tracking one or more banners from a target.
@@ -75,6 +76,33 @@ banout_string(const struct BannerOutput *banout, unsigned proto);
unsigned
banout_string_length(const struct BannerOutput *banout, unsigned proto);


/**
 * Prepare to start calling banout_append_base64()
 */
void
banout_init_base64(struct BanBase64 *base64);

/**
 * Converts the string to BASE64 and appends it to the banner.
 * Since this can be called iteratively as new input arrives,
 * a call to banout_init_base64() must be called before the first fragment,
 * and a call to banout_finalize_base64() must be called after the last
 * fragment
 */
void
banout_append_base64(struct BannerOutput *banout, unsigned proto,
                     const void *px, size_t length,
                     struct BanBase64 *base64);

/**
 * Finish encoding the BASE64 string, appending the '==' things on the
 * end if necessary
 */
void
banout_finalize_base64(struct BannerOutput *banout, unsigned proto,
                       struct BanBase64 *base64);

/**
 * Do the typical unit/regression test, for this module.
 */
+6 −59
Original line number Diff line number Diff line
@@ -180,24 +180,6 @@ enum {
};


/***************************************************************************
 ***************************************************************************/
static const char *b64 =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789"
    "+/";

/***************************************************************************
 ***************************************************************************/
static void
out_b64(unsigned x, struct BannerOutput *banout, unsigned proto)
{
    banout_append_char(banout, proto, b64[(x>>18)&0x3F]);
    banout_append_char(banout, proto, b64[(x>>12)&0x3F]);
    banout_append_char(banout, proto, b64[(x>> 6)&0x3F]);
    banout_append_char(banout, proto, b64[(x>> 0)&0x3F]);
}

/***************************************************************************
 ***************************************************************************/
@@ -208,16 +190,13 @@ server_cert_copy( struct SSL_SERVER_CERT *data,
                    struct BannerOutput *banout
                    )
{
    unsigned state = data->sub.state;
    unsigned b64x = data->sub.b64x;
    unsigned i;

    /*
     * Initialize
     */
    if (px == 0 && length == CERT_COPY_START) {
        data->sub.state = 0;
        data->sub.b64x = 0;
        banout_init_base64(&data->sub.base64);
        banout_append(  banout, PROTO_X509_CERT,
                        "cert:", 5);
        return;
@@ -227,52 +206,20 @@ server_cert_copy( struct SSL_SERVER_CERT *data,
     * Convert to base64
     */
    if (px)
    for (i=0; i<length; i++)
    switch (state) {
    case 0:
        b64x = px[i];
        DROPDOWN(i,length,state);
    case 1:
        b64x = b64x * 256 + px[i];
        DROPDOWN(i,length,state);
    case 2:
        b64x = b64x * 256 + px[i];
        state = 0;
        out_b64(b64x, banout, PROTO_X509_CERT);
    }
        banout_append_base64(banout, 
                             PROTO_X509_CERT, 
                             px, length,
                             &data->sub.base64);

    /*
     * Finalize: we need to put the final touches on the
     * base64 encoding
     */
    if (px == 0) {
        switch (state) {
        case 0:
            out_b64(b64x, banout, PROTO_X509_CERT);
            break;
        case 1:
            b64x *= 256;
            banout_append_char(banout, PROTO_X509_CERT, b64[(b64x>>18)&0x3F]);
            banout_append_char(banout, PROTO_X509_CERT, b64[(b64x>>12)&0x3F]);
            banout_append_char(banout, PROTO_X509_CERT, '=');
            banout_append_char(banout, PROTO_X509_CERT, '=');
            break;
        case 2:
            b64x *= 256;
            b64x *= 256;
            banout_append_char(banout, PROTO_X509_CERT, b64[(b64x>>18)&0x3F]);
            banout_append_char(banout, PROTO_X509_CERT, b64[(b64x>>12)&0x3F]);
            banout_append_char(banout, PROTO_X509_CERT, b64[(b64x>>6)&0x3F]);
            banout_append_char(banout, PROTO_X509_CERT, '=');
            break;
        }

        banout_finalize_base64(banout, PROTO_X509_CERT, &data->sub.base64);        
        banout_end(banout, PROTO_X509_CERT);

    }

    data->sub.state = state;
    data->sub.b64x = b64x;
}

/***************************************************************************
+12 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@
		11B22ED618641DCC00DA5438 /* proto-ssl-test.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED218641DCC00DA5438 /* proto-ssl-test.c */; };
		11B22ED718641DCC00DA5438 /* proto-x509.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B22ED318641DCC00DA5438 /* proto-x509.c */; };
		11B2DD9E17DE4DD8007FC363 /* templ-payloads.c in Sources */ = {isa = PBXBuildFile; fileRef = 11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */; };
		11BA296218902CEE0064A759 /* out-grepable.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA295F18902CEE0064A759 /* out-grepable.c */; };
		11BA296318902CEE0064A759 /* proto-tcp-telnet.c in Sources */ = {isa = PBXBuildFile; fileRef = 11BA296018902CEE0064A759 /* proto-tcp-telnet.c */; };
		11E76DB41889BC5200061F45 /* pixie-backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 11E76DB21889BC5200061F45 /* pixie-backtrace.c */; };
/* End PBXBuildFile section */

@@ -202,6 +204,10 @@
		11B22ED418641DCC00DA5438 /* proto-x509.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "proto-x509.h"; sourceTree = "<group>"; };
		11B2DD9C17DE4DD8007FC363 /* templ-payloads.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "templ-payloads.c"; sourceTree = "<group>"; };
		11B2DD9D17DE4DD8007FC363 /* templ-payloads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "templ-payloads.h"; sourceTree = "<group>"; };
		11BA295E18902CEE0064A759 /* masscan-version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "masscan-version.h"; sourceTree = "<group>"; };
		11BA295F18902CEE0064A759 /* out-grepable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "out-grepable.c"; sourceTree = "<group>"; };
		11BA296018902CEE0064A759 /* proto-tcp-telnet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "proto-tcp-telnet.c"; sourceTree = "<group>"; };
		11BA296118902CEE0064A759 /* proto-tcp-telnet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "proto-tcp-telnet.h"; sourceTree = "<group>"; };
		11E76DB21889BC5200061F45 /* pixie-backtrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "pixie-backtrace.c"; sourceTree = "<group>"; };
		11E76DB31889BC5200061F45 /* pixie-backtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "pixie-backtrace.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -237,6 +243,10 @@
		11A9219217DBCC7E00DDFD32 /* src */ = {
			isa = PBXGroup;
			children = (
				11BA295E18902CEE0064A759 /* masscan-version.h */,
				11BA295F18902CEE0064A759 /* out-grepable.c */,
				11BA296018902CEE0064A759 /* proto-tcp-telnet.c */,
				11BA296118902CEE0064A759 /* proto-tcp-telnet.h */,
				11AC2F99188CE34A008CB623 /* proto-sctp.c */,
				11AC2F9A188CE34A008CB623 /* proto-sctp.h */,
				11E76DB21889BC5200061F45 /* pixie-backtrace.c */,
@@ -472,6 +482,8 @@
				11A773EB1881BFC700B135DE /* crypto-base64.c in Sources */,
				11E76DB41889BC5200061F45 /* pixie-backtrace.c in Sources */,
				11AC2F9B188CE34A008CB623 /* proto-sctp.c in Sources */,
				11BA296218902CEE0064A759 /* out-grepable.c in Sources */,
				11BA296318902CEE0064A759 /* proto-tcp-telnet.c in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
+1 −1

File changed.

Contains only whitespace changes.

Loading