00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "RSA.h"
00019 #include "CODEX_Exceptions/BignumExceptions.h"
00020
00021 using namespace CODEX_Ciphers;
00022 using namespace CODEX_Exceptions;
00023 using CODEX_ASN1::BigNumber;
00024 using CODEX_ASN1::SecureBigNumber;
00025
00026 void
00027 RSAKeyPairGenerator::operator()( RSAPublicKey*& pubKey,
00028 RSAPrivateKey*& privKey )
00029 {
00030 BN_CTX * ctx = NULL;
00031 BIGNUM * p = NULL;
00032 BIGNUM * q = NULL;
00033 BIGNUM * n = NULL;
00034 BIGNUM * e = NULL;
00035 BIGNUM * p1 = NULL;
00036 BIGNUM * q1 = NULL;
00037 BIGNUM * phi = NULL;
00038 BIGNUM * d = NULL;
00039
00040 try
00041 {
00042 ctx = BN_CTX_new();
00043 if ( NULL == ctx )
00044 {
00045 throw BignumContextException( __FILE__ , __LINE__ );
00046 }
00047
00048
00049 p = BN_new();
00050 if ( NULL == p )
00051 {
00052 throw BignumNullException( __FILE__ , __LINE__ );
00053 }
00054 if ( NULL == BN_generate_prime( p, m_numBits, 1,
00055 NULL, NULL, NULL, NULL ) )
00056 {
00057 throw BignumGeneratePrimeException( __FILE__ , __LINE__ );
00058 }
00059
00060
00061 q = BN_new();
00062 if ( NULL == q )
00063 {
00064 throw BignumNullException( __FILE__ , __LINE__ );
00065 }
00066 if ( NULL == BN_generate_prime( q, m_numBits, 1,
00067 NULL, NULL, NULL, NULL ) )
00068 {
00069 throw BignumGeneratePrimeException( __FILE__ , __LINE__ );
00070 }
00071
00072 n = BN_new();
00073 if ( NULL == n )
00074 {
00075 throw BignumNullException( __FILE__ , __LINE__ );
00076 }
00077 if ( ! BN_mul( n, p, q, ctx ) )
00078 {
00079 throw BignumMulException( __FILE__ , __LINE__ );
00080 }
00081
00082 p1 = BN_new();
00083 if ( NULL == p1 )
00084 {
00085 throw BignumNullException( __FILE__ , __LINE__ );
00086 }
00087 if ( ! BN_sub( p1, p, BN_value_one() ) )
00088 {
00089 throw BignumSubException( __FILE__ , __LINE__ );
00090 }
00091
00092 q1 = BN_new();
00093 if ( NULL == q1 )
00094 {
00095 throw BignumNullException( __FILE__ , __LINE__ );
00096 }
00097 if ( ! BN_sub( q1, q, BN_value_one() ) )
00098 {
00099 throw BignumSubException( __FILE__ , __LINE__ );
00100 }
00101
00102 phi = BN_new();
00103 if ( NULL == phi )
00104 {
00105 throw BignumNullException( __FILE__ , __LINE__ );
00106 }
00107 if ( ! BN_mul( phi, p1, q1, ctx ) )
00108 {
00109 throw BignumMulException( __FILE__ , __LINE__ );
00110 }
00111
00112 e = BN_new();
00113 if ( NULL == e )
00114 {
00115 throw BignumNullException( __FILE__ , __LINE__ );
00116 }
00117 if ( ! BN_set_word( e, 65537 ) )
00118 {
00119 throw BignumSetWordException( __FILE__ , __LINE__ );
00120 }
00121
00122 d = BN_new();
00123 if ( NULL == d )
00124 {
00125 throw BignumNullException( __FILE__ , __LINE__ );
00126 }
00127 if ( ! BN_mod_inverse( d, e, phi, ctx ) )
00128 {
00129 throw BignumModInverseException( __FILE__ , __LINE__ );
00130 }
00131
00132
00133 pubKey = new RSAPublicKey( BN_dup(n), e );
00134 privKey = new RSAPrivateKey( p, q, d, n, phi );
00135
00136 if ( NULL != ctx ) BN_CTX_free( ctx );
00137 if ( NULL != p1 ) BN_clear_free( p1 );
00138 if ( NULL != q1 ) BN_clear_free( q1 );
00139 }
00140 catch ( ... )
00141 {
00142 if ( NULL != ctx ) BN_CTX_free( ctx );
00143 if ( NULL != p ) BN_clear_free( p );
00144 if ( NULL != q ) BN_clear_free( q );
00145 if ( NULL != n ) BN_free( n );
00146 if ( NULL != e ) BN_free( e );
00147 if ( NULL != p1 ) BN_clear_free( p1 );
00148 if ( NULL != q1 ) BN_clear_free( q1 );
00149 if ( NULL != phi ) BN_clear_free( phi );
00150 if ( NULL != d ) BN_clear_free( d );
00151 throw;
00152 }
00153 }