X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/2f1c4d4cc07565389135d9ecaa8390b46d043d86..67932e542eb65f681779f5d49974afe8369a9b9a:/src/src/pdkim/rsa.c diff --git a/src/src/pdkim/rsa.c b/src/src/pdkim/rsa.c index 992a396aa..91524ac9e 100644 --- a/src/src/pdkim/rsa.c +++ b/src/src/pdkim/rsa.c @@ -1,9 +1,10 @@ /* * The RSA public-key cryptosystem * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * Copyright (C) 2006-2009, Paul Bakker + * All rights reserved. * - * Copyright (C) 2009 Paul Bakker + * Joined copyright on original XySSL code with: Christophe Devine * * 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 @@ -26,7 +27,7 @@ * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf */ -/* $Cambridge: exim/src/src/pdkim/rsa.c,v 1.2 2009/06/10 07:34:05 tom Exp $ */ +/* $Cambridge: exim/src/src/pdkim/rsa.c,v 1.3 2009/12/07 13:05:07 tom Exp $ */ #include "rsa.h" #include "base64.h" @@ -36,6 +37,7 @@ #include +/* *************** begin copy from x509parse.c ********************/ /* * ASN.1 DER decoding routines */ @@ -133,6 +135,8 @@ static int asn1_get_mpi( unsigned char **p, return( ret ); } +/* *************** end copy from x509parse.c ********************/ + /* @@ -159,6 +163,9 @@ void rsa_init( rsa_context *ctx, */ int rsa_check_pubkey( rsa_context *ctx ) { + if( !ctx->N.p || !ctx->E.p ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + if( ( ctx->N.p[0] & 1 ) == 0 || ( ctx->E.p[0] & 1 ) == 0 ) return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); @@ -185,6 +192,9 @@ int rsa_check_privkey( rsa_context *ctx ) if( ( ret = rsa_check_pubkey( ctx ) ) != 0 ) return( ret ); + if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, NULL ); MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); @@ -355,11 +365,11 @@ int rsa_pkcs1_decrypt( rsa_context *ctx, int mode, int *olen, unsigned char *input, unsigned char *output, - int output_max_len) + int output_max_len) { int ret, ilen; unsigned char *p; - unsigned char buf[512]; + unsigned char buf[1024]; ilen = ctx->len; @@ -397,7 +407,7 @@ int rsa_pkcs1_decrypt( rsa_context *ctx, } if (ilen - (int)(p - buf) > output_max_len) - return( POLARSSL_ERR_RSA_OUTPUT_TO_LARGE ); + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); *olen = ilen - (int)(p - buf); memcpy( output, p, *olen ); @@ -426,24 +436,37 @@ int rsa_pkcs1_sign( rsa_context *ctx, switch( hash_id ) { - case RSA_RAW: + case SIG_RSA_RAW: nb_pad = olen - 3 - hashlen; break; - case RSA_MD2: - case RSA_MD4: - case RSA_MD5: - nb_pad = olen - 3 - 16 - 18; + case SIG_RSA_MD2: + case SIG_RSA_MD4: + case SIG_RSA_MD5: + nb_pad = olen - 3 - 34; break; - case RSA_SHA1: - nb_pad = olen - 3 - 20 - 15; + case SIG_RSA_SHA1: + nb_pad = olen - 3 - 35; break; - case RSA_SHA256: - nb_pad = olen - 3 - 32 - 19; + case SIG_RSA_SHA224: + nb_pad = olen - 3 - 47; break; + case SIG_RSA_SHA256: + nb_pad = olen - 3 - 51; + break; + + case SIG_RSA_SHA384: + nb_pad = olen - 3 - 67; + break; + + case SIG_RSA_SHA512: + nb_pad = olen - 3 - 83; + break; + + default: return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); } @@ -465,34 +488,49 @@ int rsa_pkcs1_sign( rsa_context *ctx, switch( hash_id ) { - case RSA_RAW: + case SIG_RSA_RAW: memcpy( p, hash, hashlen ); break; - case RSA_MD2: + case SIG_RSA_MD2: memcpy( p, ASN1_HASH_MDX, 18 ); memcpy( p + 18, hash, 16 ); p[13] = 2; break; - case RSA_MD4: + case SIG_RSA_MD4: memcpy( p, ASN1_HASH_MDX, 18 ); memcpy( p + 18, hash, 16 ); p[13] = 4; break; - case RSA_MD5: + case SIG_RSA_MD5: memcpy( p, ASN1_HASH_MDX, 18 ); memcpy( p + 18, hash, 16 ); p[13] = 5; break; - case RSA_SHA1: + case SIG_RSA_SHA1: memcpy( p, ASN1_HASH_SHA1, 15 ); memcpy( p + 15, hash, 20 ); break; - case RSA_SHA256: - memcpy( p, ASN1_HASH_SHA256, 19 ); + case SIG_RSA_SHA224: + memcpy( p, ASN1_HASH_SHA2X, 19 ); + memcpy( p + 19, hash, 28 ); + p[1] += 28; p[14] = 4; p[18] += 28; break; + + case SIG_RSA_SHA256: + memcpy( p, ASN1_HASH_SHA2X, 19 ); memcpy( p + 19, hash, 32 ); - break; + p[1] += 32; p[14] = 1; p[18] += 32; break; + + case SIG_RSA_SHA384: + memcpy( p, ASN1_HASH_SHA2X, 19 ); + memcpy( p + 19, hash, 48 ); + p[1] += 48; p[14] = 2; p[18] += 48; break; + + case SIG_RSA_SHA512: + memcpy( p, ASN1_HASH_SHA2X, 19 ); + memcpy( p + 19, hash, 64 ); + p[1] += 64; p[14] = 3; p[18] += 64; break; default: return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); @@ -515,7 +553,7 @@ int rsa_pkcs1_verify( rsa_context *ctx, { int ret, len, siglen; unsigned char *p, c; - unsigned char buf[512]; + unsigned char buf[1024]; siglen = ctx->len; @@ -562,9 +600,9 @@ int rsa_pkcs1_verify( rsa_context *ctx, if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 ) return( POLARSSL_ERR_RSA_VERIFY_FAILED ); - if( ( c == 2 && hash_id == RSA_MD2 ) || - ( c == 4 && hash_id == RSA_MD4 ) || - ( c == 5 && hash_id == RSA_MD5 ) ) + if( ( c == 2 && hash_id == SIG_RSA_MD2 ) || + ( c == 4 && hash_id == SIG_RSA_MD4 ) || + ( c == 5 && hash_id == SIG_RSA_MD5 ) ) { if( memcmp( p + 18, hash, 16 ) == 0 ) return( 0 ); @@ -573,7 +611,7 @@ int rsa_pkcs1_verify( rsa_context *ctx, } } - if( len == 35 && hash_id == RSA_SHA1 ) + if( len == 35 && hash_id == SIG_RSA_SHA1 ) { if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 && memcmp( p + 15, hash, 20 ) == 0 ) @@ -581,17 +619,24 @@ int rsa_pkcs1_verify( rsa_context *ctx, else return( POLARSSL_ERR_RSA_VERIFY_FAILED ); } - - if( len == 51 && hash_id == RSA_SHA256 ) + if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) || + ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) || + ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) || + ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) ) { - if( memcmp( p, ASN1_HASH_SHA256, 19 ) == 0 && - memcmp( p + 19, hash, 32 ) == 0 ) + c = p[1] - 17; + p[1] = 17; + p[14] = 0; + + if( p[18] == c && + memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 && + memcmp( p + 19, hash, c ) == 0 ) return( 0 ); else return( POLARSSL_ERR_RSA_VERIFY_FAILED ); } - if( len == hashlen && hash_id == RSA_RAW ) + if( len == hashlen && hash_id == SIG_RSA_RAW ) { if( memcmp( p, hash, hashlen ) == 0 ) return( 0 ); @@ -613,7 +658,6 @@ void rsa_free( rsa_context *ctx ) &ctx->E, &ctx->N, NULL ); } - /* * Parse a public RSA key