int rsa_calc_str(const char* n, const char* e, const unsigned char* data, unsigned char* output) { int ret = 0; mpi N = {0,0,0}; mpi E = {0,0,0}; mpi V = {0,0,0}; mpi RN = {0,0,0}; size_t l = 128; int j; MPI_CHK(mpi_read_string(&N,16,n)); for(j=N.n;j>=0;j--){ if(N.p[j-1])break; } l = j * sizeof(t_uint); MPI_CHK(mpi_read_string(&E,16,e)); MPI_CHK(mpi_read_binary(&V,data, l)); if( mpi_cmp_mpi( &V, &N ) >= 0 ){ ret = POLARSSL_ERR_RSA_BAD_INPUT_DATA; goto cleanup; } printf("===========================>>>>>>>\n"); MPI_CHK(mpi_exp_mod( &V, &V, &E, &N, &RN )); printf("<<<<<<<===========================\n"); MPI_CHK(mpi_write_binary( &V, output, l )); cleanup: mpi_free( &N ); mpi_free( &E ); mpi_free( &RN ); mpi_free( &V ); return ret; }
int chiffrer_rsa(char* data, char* sortie, int taille_data ) { FILE *f; int ret; size_t i; rsa_context rsa; entropy_context entropy; ctr_drbg_context ctr_drbg; char *pers = "rsa_encrypt"; printf( "[i] Seeding the random number generator\n" ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (unsigned char *) pers, strlen( pers ) ) ) != 0 ) { printf( "[-] ctr_drbg_init returned %d\n", ret ); goto exit; } printf( "[i] Reading private key\n" ); rsa_init( &rsa, RSA_PKCS_V15, 0 ); if( ( ret = mpi_read_string( &rsa.N, RSA_N_BASE, RSA_N ) ) != 0 || ( ret = mpi_read_string( &rsa.D, RSA_D_BASE, RSA_D ) ) != 0 ) { printf( "[-] mpi_read_file returned %d\n", ret ); goto exit; } rsa.len = ( mpi_msb( &rsa.N ) + 7 ) >> 3; /* * Calculate the RSA encryption of the hash. */ printf( "[i] Generating the RSA encrypted value (%d/%d)\n", rsa.len, taille_data ); fflush( stdout ); if( ( ret = rsa_pkcs1_encrypt( &rsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, taille_data, data, sortie ) ) != 0 ) { printf( "[-] rsa_pkcs1_encrypt returned %d\n\n", ret ); goto exit; } printf( "[i] Cryptogramme copie\n"); exit: return( ret ); }
/* initialise de DHM context according to requested algorithm */ bctbx_DHMContext_t *bctbx_CreateDHMContext(uint8_t DHMAlgo, uint8_t secretLength) { dhm_context *polarsslDhmContext; /* create the context */ bctbx_DHMContext_t *context = (bctbx_DHMContext_t *)malloc(sizeof(bctbx_DHMContext_t)); memset (context, 0, sizeof(bctbx_DHMContext_t)); /* create the polarssl context for DHM */ polarsslDhmContext=(dhm_context *)malloc(sizeof(dhm_context)); memset(polarsslDhmContext, 0, sizeof(dhm_context)); context->cryptoModuleData=(void *)polarsslDhmContext; /* initialise pointer to NULL to ensure safe call to free() when destroying context */ context->secret = NULL; context->self = NULL; context->key = NULL; context->peer = NULL; /* set parameters in the context */ context->algo=DHMAlgo; context->secretLength = secretLength; switch (DHMAlgo) { case BCTBX_DHM_2048: /* set P and G in the polarssl context */ if ((mpi_read_string(&(polarsslDhmContext->P), 16, POLARSSL_DHM_RFC3526_MODP_2048_P) != 0) || (mpi_read_string(&(polarsslDhmContext->G), 16, POLARSSL_DHM_RFC3526_MODP_2048_G) != 0)) { return NULL; } context->primeLength=256; polarsslDhmContext->len=256; break; case BCTBX_DHM_3072: /* set P and G in the polarssl context */ if ((mpi_read_string(&(polarsslDhmContext->P), 16, POLARSSL_DHM_RFC3526_MODP_3072_P) != 0) || (mpi_read_string(&(polarsslDhmContext->G), 16, POLARSSL_DHM_RFC3526_MODP_3072_G) != 0)) { return NULL; } context->primeLength=384; polarsslDhmContext->len=384; break; default: free(context); return NULL; break; } return context; }
int main( void ) { mpi E, P, Q, N, H, D, X, Y, Z; mpi_init( &E, &P, &Q, &N, &H, &D, &X, &Y, &Z, NULL ); mpi_read_string( &P, 10, "2789" ); mpi_read_string( &Q, 10, "3203" ); mpi_read_string( &E, 10, "257" ); mpi_mul_mpi( &N, &P, &Q ); printf( "\n Public key:\n\n" ); mpi_write_file( " N = ", &N, 10, NULL ); mpi_write_file( " E = ", &E, 10, NULL ); printf( "\n Private key:\n\n" ); mpi_write_file( " P = ", &P, 10, NULL ); mpi_write_file( " Q = ", &Q, 10, NULL ); mpi_sub_int( &P, &P, 1 ); mpi_sub_int( &Q, &Q, 1 ); mpi_mul_mpi( &H, &P, &Q ); mpi_inv_mod( &D, &E, &H ); mpi_write_file( " D = E^-1 mod (P-1)*(Q-1) = ", &D, 10, NULL ); mpi_read_string( &X, 10, "55555" ); mpi_exp_mod( &Y, &X, &E, &N, NULL ); mpi_exp_mod( &Z, &Y, &D, &N, NULL ); printf( "\n RSA operation:\n\n" ); mpi_write_file( " X (plaintext) = ", &X, 10, NULL ); mpi_write_file( " Y (ciphertext) = X^E mod N = ", &Y, 10, NULL ); mpi_write_file( " Z (decrypted) = Y^D mod N = ", &Z, 10, NULL ); printf( "\n" ); mpi_free( &Z, &Y, &X, &D, &H, &N, &Q, &P, &E, NULL ); #ifdef WIN32 printf( " Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( 0 ); }
void init_rsa_context_with_public_key(rsa_context *rsa, const unsigned char *pubkey) { rsa_init(rsa, RSA_PKCS_V15, RSA_RAW, NULL, NULL); rsa->len = 256; mpi_read_binary(&rsa->N, pubkey + 33, 256); mpi_read_string(&rsa->E, 16, "10001"); }
static mpi *Bget(lua_State *L, int i) { switch (lua_type(L,i)) { case LUA_TNUMBER: case LUA_TSTRING: { mpi *x=Bnew(L); const char *s=lua_tostring(L,i); if(s[0]=='X' || s[0]=='x') mpi_read_string(x, 16, s+1); else mpi_read_string(x,10,s); lua_replace(L,i); return x; } default: return *((mpi**)luaL_checkudata(L,i,MYTYPE)); } return NULL; }
int mpi_get_field(lua_State*L, int index, const char *fieldname, mpi *X, int radix) { char *buff; int res = -1; if(lua_istable(L, index)) { lua_getfield(L, index, fieldname); buff = (char*)lua_tostring(L, -1); res = mpi_read_string(X, radix, buff); } return res; }
void init_rsa_context_with_public_key(rsa_context *rsa, const unsigned char *pubkey) { #ifdef USE_MBEDTLS mbedtls_rsa_init(rsa, MBEDTLS_RSA_PKCS_V15, 0); #else rsa_init(rsa, RSA_PKCS_V15, RSA_RAW, NULL, NULL); #endif #if !defined(USE_MBEDTLS) && (PLATFORM_ID == 6 || PLATFORM_ID == 8) rsa->length = 256; #else rsa->len = 256; #endif mpi_read_binary(&rsa->N, pubkey + 33, 256); mpi_read_string(&rsa->E, 16, "10001"); }
int main(void) { int ret; mpi A, E, N, X, Y, U, V; mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL ); MPI_CHK( mpi_read_string( &A, 16, "EFE021C2645FD1DC586E69184AF4A31E" \ "D5F53E93B5F123FA41680867BA110131" \ "944FE7952E2517337780CB0DB80E61AA" \ "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); MPI_CHK( mpi_read_string( &E, 16, "B2E7EFD37075B9F03FF989C7C5051C20" \ "34D2A323810251127E7BF8625A4F49A5" \ "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ "5B5C25763222FEFCCFC38B832366C29E" ) ); MPI_CHK( mpi_read_string( &N, 16, "0066A198186C18C10B2F5ED9B522752A" \ "9830B69916E535C8F047518A889A43A5" \ "94B6BED27A168D31D4A52F88925AA8F5" ) ); MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); MPI_CHK( mpi_read_string( &U, 16, "602AB7ECA597A3D6B56FF9829A5E8B85" \ "9E857EA95A03512E2BAE7391688D264A" \ "A5663B0341DB9CCFD2C4C5F421FEC814" \ "8001B72E848A38CAE1C65F78E56ABDEF" \ "E12D3C039B8A02D6BE593F0BBBDA56F1" \ "ECF677152EF804370C1A305CAF3B5BF1" \ "30879B56C61DE584A0F53A2447A51E" ) ); if( verbose != 0 ) printf( " MPI test #1 (mul_mpi): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); MPI_CHK( mpi_read_string( &U, 16, "256567336059E52CAE22925474705F39A94" ) ); MPI_CHK( mpi_read_string( &V, 16, "6613F26162223DF488E9CD48CC132C7A" \ "0AC93C701B001B092E4E5B9F73BCD27B" \ "9EE50D0657C77F374E903CDFA4C642" ) ); if( verbose != 0 ) printf( " MPI test #2 (div_mpi): " ); if( mpi_cmp_mpi( &X, &U ) != 0 || mpi_cmp_mpi( &Y, &V ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); MPI_CHK( mpi_read_string( &U, 16, "36E139AEA55215609D2816998ED020BB" \ "BD96C37890F65171D948E9BC7CBAA4D9" \ "325D24D6A3C12710F10A09FA08AB87" ) ); if( verbose != 0 ) printf( " MPI test #3 (exp_mod): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); MPI_CHK( mpi_read_string( &U, 16, "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ "C3DBA76456363A10869622EAC2DD84EC" \ "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); if( verbose != 0 ) printf( " MPI test #4 (inv_mod): " ); if( mpi_cmp_mpi( &X, &U ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n" ); cleanup: if( ret != 0 && verbose != 0 ) printf( "Unexpected error, return code = %08X\n", ret ); mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL ); if( verbose != 0 ) printf( "\n" ); return( ret ); }
/* * Checkup routine */ int rsa_self_test( int verbose ) { int len; rsa_context rsa; unsigned char sha1sum[20]; unsigned char rsa_plaintext[PT_LEN]; unsigned char rsa_decrypted[PT_LEN]; unsigned char rsa_ciphertext[KEY_LEN]; memset( &rsa, 0, sizeof( rsa_context ) ); rsa.len = KEY_LEN; mpi_read_string( &rsa.N , 16, RSA_N ); mpi_read_string( &rsa.E , 16, RSA_E ); mpi_read_string( &rsa.D , 16, RSA_D ); mpi_read_string( &rsa.P , 16, RSA_P ); mpi_read_string( &rsa.Q , 16, RSA_Q ); mpi_read_string( &rsa.DP, 16, RSA_DP ); mpi_read_string( &rsa.DQ, 16, RSA_DQ ); mpi_read_string( &rsa.QP, 16, RSA_QP ); if( verbose != 0 ) printf( " RSA key validation: " ); if( rsa_check_pubkey( &rsa ) != 0 || rsa_check_privkey( &rsa ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 encryption : " ); memcpy( rsa_plaintext, RSA_PT, PT_LEN ); if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN, rsa_plaintext, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 decryption : " ); if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len, rsa_ciphertext, rsa_decrypted, sizeof(rsa_decrypted) ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 data sign : " ); sha1( rsa_plaintext, PT_LEN, sha1sum ); if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, SIG_RSA_SHA1, 20, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) printf( "passed\n\n" ); rsa_free( &rsa ); return( 0 ); }
int main( int argc, char *argv[] ) { int ret = 0; x509_crt issuer_crt; pk_context loaded_issuer_key, loaded_subject_key; pk_context *issuer_key = &loaded_issuer_key, *subject_key = &loaded_subject_key; char buf[1024]; char issuer_name[128]; int i, j, n; char *p, *q, *r; #if defined(POLARSSL_X509_CSR_PARSE_C) char subject_name[128]; x509_csr csr; #endif x509write_cert crt; mpi serial; entropy_context entropy; ctr_drbg_context ctr_drbg; const char *pers = "crt example app"; /* * Set to sane values */ x509write_crt_init( &crt ); x509write_crt_set_md_alg( &crt, POLARSSL_MD_SHA1 ); pk_init( &loaded_issuer_key ); pk_init( &loaded_subject_key ); mpi_init( &serial ); #if defined(POLARSSL_X509_CSR_PARSE_C) x509_csr_init( &csr ); #endif x509_crt_init( &issuer_crt ); memset( buf, 0, 1024 ); if( argc == 0 ) { usage: printf( USAGE ); ret = 1; goto exit; } opt.issuer_crt = DFL_ISSUER_CRT; opt.request_file = DFL_REQUEST_FILE; opt.request_file = DFL_REQUEST_FILE; opt.subject_key = DFL_SUBJECT_KEY; opt.issuer_key = DFL_ISSUER_KEY; opt.subject_pwd = DFL_SUBJECT_PWD; opt.issuer_pwd = DFL_ISSUER_PWD; opt.output_file = DFL_OUTPUT_FILENAME; opt.subject_name = DFL_SUBJECT_NAME; opt.issuer_name = DFL_ISSUER_NAME; opt.not_before = DFL_NOT_BEFORE; opt.not_after = DFL_NOT_AFTER; opt.serial = DFL_SERIAL; opt.selfsign = DFL_SELFSIGN; opt.is_ca = DFL_IS_CA; opt.max_pathlen = DFL_MAX_PATHLEN; opt.key_usage = DFL_KEY_USAGE; opt.ns_cert_type = DFL_NS_CERT_TYPE; for( i = 1; i < argc; i++ ) { p = argv[i]; if( ( q = strchr( p, '=' ) ) == NULL ) goto usage; *q++ = '\0'; n = strlen( p ); for( j = 0; j < n; j++ ) { if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' ) argv[i][j] |= 0x20; } if( strcmp( p, "request_file" ) == 0 ) opt.request_file = q; else if( strcmp( p, "subject_key" ) == 0 ) opt.subject_key = q; else if( strcmp( p, "issuer_key" ) == 0 ) opt.issuer_key = q; else if( strcmp( p, "subject_pwd" ) == 0 ) opt.subject_pwd = q; else if( strcmp( p, "issuer_pwd" ) == 0 ) opt.issuer_pwd = q; else if( strcmp( p, "issuer_crt" ) == 0 ) opt.issuer_crt = q; else if( strcmp( p, "output_file" ) == 0 ) opt.output_file = q; else if( strcmp( p, "subject_name" ) == 0 ) { opt.subject_name = q; } else if( strcmp( p, "issuer_name" ) == 0 ) { opt.issuer_name = q; } else if( strcmp( p, "not_before" ) == 0 ) { opt.not_before = q; } else if( strcmp( p, "not_after" ) == 0 ) { opt.not_after = q; } else if( strcmp( p, "serial" ) == 0 ) { opt.serial = q; } else if( strcmp( p, "selfsign" ) == 0 ) { opt.selfsign = atoi( q ); if( opt.selfsign < 0 || opt.selfsign > 1 ) goto usage; } else if( strcmp( p, "is_ca" ) == 0 ) { opt.is_ca = atoi( q ); if( opt.is_ca < 0 || opt.is_ca > 1 ) goto usage; } else if( strcmp( p, "max_pathlen" ) == 0 ) { opt.max_pathlen = atoi( q ); if( opt.max_pathlen < -1 || opt.max_pathlen > 127 ) goto usage; } else if( strcmp( p, "key_usage" ) == 0 ) { while( q != NULL ) { if( ( r = strchr( q, ',' ) ) != NULL ) *r++ = '\0'; if( strcmp( q, "digital_signature" ) == 0 ) opt.key_usage |= KU_DIGITAL_SIGNATURE; else if( strcmp( q, "non_repudiation" ) == 0 ) opt.key_usage |= KU_NON_REPUDIATION; else if( strcmp( q, "key_encipherment" ) == 0 ) opt.key_usage |= KU_KEY_ENCIPHERMENT; else if( strcmp( q, "data_encipherment" ) == 0 ) opt.key_usage |= KU_DATA_ENCIPHERMENT; else if( strcmp( q, "key_agreement" ) == 0 ) opt.key_usage |= KU_KEY_AGREEMENT; else if( strcmp( q, "key_cert_sign" ) == 0 ) opt.key_usage |= KU_KEY_CERT_SIGN; else if( strcmp( q, "crl_sign" ) == 0 ) opt.key_usage |= KU_CRL_SIGN; else goto usage; q = r; } } else if( strcmp( p, "ns_cert_type" ) == 0 ) { while( q != NULL ) { if( ( r = strchr( q, ',' ) ) != NULL ) *r++ = '\0'; if( strcmp( q, "ssl_client" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_SSL_CLIENT; else if( strcmp( q, "ssl_server" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_SSL_SERVER; else if( strcmp( q, "email" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_EMAIL; else if( strcmp( q, "object_signing" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_OBJECT_SIGNING; else if( strcmp( q, "ssl_ca" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_SSL_CA; else if( strcmp( q, "email_ca" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_EMAIL_CA; else if( strcmp( q, "object_signing_ca" ) == 0 ) opt.ns_cert_type |= NS_CERT_TYPE_OBJECT_SIGNING_CA; else goto usage; q = r; } } else goto usage; } printf("\n"); /* * 0. Seed the PRNG */ printf( " . Seeding the random number generator..." ); fflush( stdout ); entropy_init( &entropy ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! ctr_drbg_init returned %d - %s\n", ret, buf ); goto exit; } printf( " ok\n" ); // Parse serial to MPI // printf( " . Reading serial number..." ); fflush( stdout ); if( ( ret = mpi_read_string( &serial, 10, opt.serial ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! mpi_read_string returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); // Parse issuer certificate if present // if( !opt.selfsign && strlen( opt.issuer_crt ) ) { /* * 1.0.a. Load the certificates */ printf( " . Loading the issuer certificate ..." ); fflush( stdout ); if( ( ret = x509_crt_parse_file( &issuer_crt, opt.issuer_crt ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509_crt_parse_file returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } ret = x509_dn_gets( issuer_name, sizeof(issuer_name), &issuer_crt.issuer ); if( ret < 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509_dn_gets returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } opt.issuer_name = issuer_name; printf( " ok\n" ); } #if defined(POLARSSL_X509_CSR_PARSE_C) // Parse certificate request if present // if( !opt.selfsign && strlen( opt.request_file ) ) { /* * 1.0.b. Load the CSR */ printf( " . Loading the certificate request ..." ); fflush( stdout ); if( ( ret = x509_csr_parse_file( &csr, opt.request_file ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509_csr_parse_file returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } ret = x509_dn_gets( subject_name, sizeof(subject_name), &csr.subject ); if( ret < 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509_dn_gets returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } opt.subject_name = subject_name; subject_key = &csr.pk; printf( " ok\n" ); } #endif /* POLARSSL_X509_CSR_PARSE_C */ /* * 1.1. Load the keys */ if( !opt.selfsign && !strlen( opt.request_file ) ) { printf( " . Loading the subject key ..." ); fflush( stdout ); ret = pk_parse_keyfile( &loaded_subject_key, opt.subject_key, opt.subject_pwd ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! pk_parse_keyfile returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); } printf( " . Loading the issuer key ..." ); fflush( stdout ); ret = pk_parse_keyfile( &loaded_issuer_key, opt.issuer_key, opt.issuer_pwd ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! pk_parse_keyfile returned -x%02x - %s\n\n", -ret, buf ); goto exit; } // Check if key and issuer certificate match // if( strlen( opt.issuer_crt ) ) { if( !pk_can_do( &issuer_crt.pk, POLARSSL_PK_RSA ) || mpi_cmp_mpi( &pk_rsa( issuer_crt.pk )->N, &pk_rsa( *issuer_key )->N ) != 0 || mpi_cmp_mpi( &pk_rsa( issuer_crt.pk )->E, &pk_rsa( *issuer_key )->E ) != 0 ) { printf( " failed\n ! issuer_key does not match issuer certificate\n\n" ); ret = -1; goto exit; } } printf( " ok\n" ); if( opt.selfsign ) { opt.subject_name = opt.issuer_name; subject_key = issuer_key; } x509write_crt_set_subject_key( &crt, subject_key ); x509write_crt_set_issuer_key( &crt, issuer_key ); /* * 1.0. Check the names for validity */ if( ( ret = x509write_crt_set_subject_name( &crt, opt.subject_name ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_subject_name returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } if( ( ret = x509write_crt_set_issuer_name( &crt, opt.issuer_name ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_issuer_name returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " . Setting certificate values ..." ); fflush( stdout ); ret = x509write_crt_set_serial( &crt, &serial ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_serial returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } ret = x509write_crt_set_validity( &crt, opt.not_before, opt.not_after ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_validity returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); printf( " . Adding the Basic Constraints extension ..." ); fflush( stdout ); ret = x509write_crt_set_basic_constraints( &crt, opt.is_ca, opt.max_pathlen ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_basic_contraints returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); #if defined(POLARSSL_SHA1_C) printf( " . Adding the Subject Key Identifier ..." ); fflush( stdout ); ret = x509write_crt_set_subject_key_identifier( &crt ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_subject_key_identifier returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); printf( " . Adding the Authority Key Identifier ..." ); fflush( stdout ); ret = x509write_crt_set_authority_key_identifier( &crt ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_authority_key_identifier returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); #endif /* POLARSSL_SHA1_C */ if( opt.key_usage ) { printf( " . Adding the Key Usage extension ..." ); fflush( stdout ); ret = x509write_crt_set_key_usage( &crt, opt.key_usage ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_key_usage returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); } if( opt.ns_cert_type ) { printf( " . Adding the NS Cert Type extension ..." ); fflush( stdout ); ret = x509write_crt_set_ns_cert_type( &crt, opt.ns_cert_type ); if( ret != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! x509write_crt_set_ns_cert_type returned -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); } /* * 1.2. Writing the request */ printf( " . Writing the certificate..." ); fflush( stdout ); if( ( ret = write_certificate( &crt, opt.output_file, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { error_strerror( ret, buf, 1024 ); printf( " failed\n ! write_certifcate -0x%02x - %s\n\n", -ret, buf ); goto exit; } printf( " ok\n" ); exit: x509write_crt_free( &crt ); pk_free( &loaded_subject_key ); pk_free( &loaded_issuer_key ); mpi_free( &serial ); entropy_free( &entropy ); #if defined(_WIN32) printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
result_t X509Req::sign(const char *issuer, PKey_base *key, v8::Local<v8::Object> opts, obj_ptr<X509Cert_base> &retVal, exlib::AsyncEvent *ac) { result_t hr; bool priv; hr = key->isPrivate(priv); if (hr < 0) return hr; if (!priv) return CHECK_ERROR(CALL_E_INVALIDARG); int ret; std::string subject; pk_context *pk; int32_t hash; std::string buf; obj_ptr<X509Cert> cert; if (!ac) { mpi serial; v8::Local<v8::Value> v; x509write_crt_init(&m_crt); hr = GetConfigValue(opts, "hash", hash); if (hr == CALL_E_PARAMNOTOPTIONAL) hash = m_csr.sig_md; else if (hr < 0) goto exit; if (hash < POLARSSL_MD_MD2 || hash > POLARSSL_MD_RIPEMD160) { hr = CALL_E_INVALIDARG; goto exit; } x509write_crt_set_md_alg(&m_crt, POLARSSL_MD_SHA1); v = opts->Get(v8::String::NewFromUtf8(isolate, "serial", v8::String::kNormalString, 6)); if (!IsEmpty(v)) { v8::String::Utf8Value str(v); if (!*str) { hr = CHECK_ERROR(_ssl::setError(POLARSSL_ERR_MPI_BAD_INPUT_DATA)); goto exit; } mpi_init(&serial); ret = mpi_read_string(&serial, 10, *str); if (ret != 0) { mpi_free(&serial); hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } } else { mpi_init(&serial); mpi_lset(&serial, 1); } ret = x509write_crt_set_serial(&m_crt, &serial); if (ret != 0) { mpi_free(&serial); hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } mpi_free(&serial); date_t d1, d2; std::string s1, s2; hr = GetConfigValue(opts, "notBefore", d1); if (hr == CALL_E_PARAMNOTOPTIONAL) d1.now(); else if (hr < 0) goto exit; d1.toX509String(s1); hr = GetConfigValue(opts, "notAfter", d2); if (hr == CALL_E_PARAMNOTOPTIONAL) { d2 = d1; d2.add(1, date_t::_YEAR); } else if (hr < 0) goto exit; d2.toX509String(s2); ret = x509write_crt_set_validity(&m_crt, s1.c_str(), s2.c_str()); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } bool is_ca = false; hr = GetConfigValue(opts, "ca", is_ca); if (hr < 0 && hr != CALL_E_PARAMNOTOPTIONAL) goto exit; int32_t pathlen = -1; hr = GetConfigValue(opts, "pathlen", pathlen); if (hr < 0 && hr != CALL_E_PARAMNOTOPTIONAL) goto exit; if (pathlen < -1 || pathlen > 127) { hr = CALL_E_INVALIDARG; goto exit; } ret = x509write_crt_set_basic_constraints(&m_crt, is_ca ? 1 : 0, pathlen); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } int key_usage = parseString(opts->Get(v8::String::NewFromUtf8(isolate, "usage", v8::String::kNormalString, 5)), X509Cert::g_usages); if (key_usage < 0) { hr = key_usage; goto exit; } else if (key_usage) { ret = x509write_crt_set_key_usage(&m_crt, key_usage); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } } int cert_type = parseString(opts->Get(v8::String::NewFromUtf8(isolate, "type", v8::String::kNormalString, 4)), X509Cert::g_types); if (cert_type < 0) { hr = cert_type; goto exit; } else if (cert_type) { ret = x509write_crt_set_ns_cert_type(&m_crt, cert_type); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } } return CHECK_ERROR(CALL_E_NOSYNC); } pk = &((PKey *)key)->m_key; x509write_crt_set_subject_key(&m_crt, &m_csr.pk); x509write_crt_set_issuer_key(&m_crt, pk); hr = X509Req::get_subject(subject); if (hr < 0) goto exit; ret = x509write_crt_set_subject_name(&m_crt, subject.c_str()); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } ret = x509write_crt_set_issuer_name(&m_crt, issuer); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } ret = x509write_crt_set_subject_key_identifier(&m_crt); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } ret = x509write_crt_set_authority_key_identifier(&m_crt); if (ret != 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } buf.resize(pk_get_size(pk) * 8 + 128); ret = x509write_crt_pem(&m_crt, (unsigned char *)&buf[0], buf.length(), ctr_drbg_random, &g_ssl.ctr_drbg); if (ret < 0) { hr = CHECK_ERROR(_ssl::setError(ret)); goto exit; } cert = new X509Cert(); hr = cert->load(buf.c_str()); if (hr < 0) goto exit; retVal = cert; exit: x509write_crt_free(&m_crt); return hr; }
int main( int argc, char *argv[] ) { int ret = 1; mpi G, P, Q; entropy_context entropy; ctr_drbg_context ctr_drbg; const char *pers = "dh_genprime"; FILE *fout; ((void) argc); ((void) argv); mpi_init( &G ); mpi_init( &P ); mpi_init( &Q ); entropy_init( &entropy ); if( ( ret = mpi_read_string( &G, 10, GENERATOR ) ) != 0 ) { polarssl_printf( " failed\n ! mpi_read_string returned %d\n", ret ); goto exit; } polarssl_printf( "\nWARNING: You should not generate and use your own DHM primes\n" ); polarssl_printf( " unless you are very certain of what you are doing!\n" ); polarssl_printf( " Failing to follow this instruction may result in\n" ); polarssl_printf( " weak security for your connections! Use the\n" ); polarssl_printf( " predefined DHM parameters from dhm.h instead!\n\n" ); polarssl_printf( "============================================================\n\n" ); polarssl_printf( " ! Generating large primes may take minutes!\n" ); polarssl_printf( "\n . Seeding the random number generator..." ); fflush( stdout ); if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { polarssl_printf( " failed\n ! ctr_drbg_init returned %d\n", ret ); goto exit; } polarssl_printf( " ok\n . Generating the modulus, please wait..." ); fflush( stdout ); /* * This can take a long time... */ if( ( ret = mpi_gen_prime( &P, DH_P_SIZE, 1, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! mpi_gen_prime returned %d\n\n", ret ); goto exit; } polarssl_printf( " ok\n . Verifying that Q = (P-1)/2 is prime..." ); fflush( stdout ); if( ( ret = mpi_sub_int( &Q, &P, 1 ) ) != 0 ) { polarssl_printf( " failed\n ! mpi_sub_int returned %d\n\n", ret ); goto exit; } if( ( ret = mpi_div_int( &Q, NULL, &Q, 2 ) ) != 0 ) { polarssl_printf( " failed\n ! mpi_div_int returned %d\n\n", ret ); goto exit; } if( ( ret = mpi_is_prime( &Q, ctr_drbg_random, &ctr_drbg ) ) != 0 ) { polarssl_printf( " failed\n ! mpi_is_prime returned %d\n\n", ret ); goto exit; } polarssl_printf( " ok\n . Exporting the value in dh_prime.txt..." ); fflush( stdout ); if( ( fout = fopen( "dh_prime.txt", "wb+" ) ) == NULL ) { ret = 1; polarssl_printf( " failed\n ! Could not create dh_prime.txt\n\n" ); goto exit; } if( ( ret = mpi_write_file( "P = ", &P, 16, fout ) != 0 ) || ( ret = mpi_write_file( "G = ", &G, 16, fout ) != 0 ) ) { polarssl_printf( " failed\n ! mpi_write_file returned %d\n\n", ret ); goto exit; } polarssl_printf( " ok\n\n" ); fclose( fout ); exit: mpi_free( &G ); mpi_free( &P ); mpi_free( &Q ); ctr_drbg_free( &ctr_drbg ); entropy_free( &entropy ); #if defined(_WIN32) polarssl_printf( " Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
/* Very simple ASN.1 parsing. * Mainly needed because, even though all the RSA big integers * are always a specific number of bytes, the key generation * and encoding process sometimes pads each number with a * leading zero byte. */ void init_rsa_context_with_private_key(rsa_context *rsa, const unsigned char *private_key) { #ifdef USE_MBEDTLS mbedtls_rsa_init(rsa, MBEDTLS_RSA_PKCS_V15, 0); #else rsa_init(rsa, RSA_PKCS_V15, RSA_RAW, NULL, NULL); #endif #if !defined(USE_MBEDTLS) && (PLATFORM_ID == 6 || PLATFORM_ID == 8) rsa->length = 128; #else rsa->len = 128; #endif int i = 9; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->N, private_key + i, 128); mpi_read_string(&rsa->E, 16, "10001"); i = i + 135; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->D, private_key + i, 128); i = i + 129; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->P, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->Q, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->DP, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->DQ, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->QP, private_key + i, 64); }
int main( void ) { int ret = 1; #if defined(XYSSL_GENPRIME) mpi G, P, Q; havege_state hs; FILE *fout; mpi_init( &G, &P, &Q, NULL ); mpi_read_string( &G, 10, GENERATOR ); printf( "\n . Seeding the random number generator..." ); fflush( stdout ); havege_init( &hs ); printf( " ok\n . Generating the modulus, please wait..." ); fflush( stdout ); /* * This can take a long time... */ if( ( ret = mpi_gen_prime( &P, DH_P_SIZE, 1, havege_rand, &hs ) ) != 0 ) { printf( " failed\n ! mpi_gen_prime returned %d\n\n", ret ); goto exit; } printf( " ok\n . Verifying that Q = (P-1)/2 is prime..." ); fflush( stdout ); if( ( ret = mpi_sub_int( &Q, &P, 1 ) ) != 0 ) { printf( " failed\n ! mpi_sub_int returned %d\n\n", ret ); goto exit; } if( ( ret = mpi_div_int( &Q, NULL, &Q, 2 ) ) != 0 ) { printf( " failed\n ! mpi_div_int returned %d\n\n", ret ); goto exit; } if( ( ret = mpi_is_prime( &Q, havege_rand, &hs ) ) != 0 ) { printf( " failed\n ! mpi_is_prime returned %d\n\n", ret ); goto exit; } printf( " ok\n . Exporting the value in dh_prime.txt..." ); fflush( stdout ); if( ( fout = fopen( "dh_prime.txt", "wb+" ) ) == NULL ) { ret = 1; printf( " failed\n ! Could not create dh_prime.txt\n\n" ); goto exit; } if( ( ret = mpi_write_file( "P = ", &P, 16, fout ) != 0 ) || ( ret = mpi_write_file( "G = ", &G, 16, fout ) != 0 ) ) { printf( " failed\n ! mpi_write_file returned %d\n\n", ret ); goto exit; } printf( " ok\n\n" ); fclose( fout ); exit: mpi_free( &Q, &P, &G, NULL ); #else printf( "\n ! Prime-number generation is not available.\n\n" ); #endif #ifdef WIN32 printf( " Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
/* * Checkup routine */ int rsa_self_test( int verbose ) { int ret = 0; #if defined(POLARSSL_PKCS1_V15) size_t len; rsa_context rsa; unsigned char rsa_plaintext[PT_LEN]; unsigned char rsa_decrypted[PT_LEN]; unsigned char rsa_ciphertext[KEY_LEN]; #if defined(POLARSSL_SHA1_C) unsigned char sha1sum[20]; #endif rsa_init( &rsa, RSA_PKCS_V15, 0 ); rsa.len = KEY_LEN; MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) ); MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) ); MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) ); MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) ); MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) ); MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) ); MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) ); if( verbose != 0 ) polarssl_printf( " RSA key validation: " ); if( rsa_check_pubkey( &rsa ) != 0 || rsa_check_privkey( &rsa ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 encryption : " ); memcpy( rsa_plaintext, RSA_PT, PT_LEN ); if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN, rsa_plaintext, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 decryption : " ); if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len, rsa_ciphertext, rsa_decrypted, sizeof(rsa_decrypted) ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } #if defined(POLARSSL_SHA1_C) if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 data sign : " ); sha1( rsa_plaintext, PT_LEN, sha1sum ); if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n PKCS#1 sig. verify: " ); if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0, sha1sum, rsa_ciphertext ) != 0 ) { if( verbose != 0 ) polarssl_printf( "failed\n" ); return( 1 ); } if( verbose != 0 ) polarssl_printf( "passed\n\n" ); #endif /* POLARSSL_SHA1_C */ cleanup: rsa_free( &rsa ); #else /* POLARSSL_PKCS1_V15 */ ((void) verbose); #endif /* POLARSSL_PKCS1_V15 */ return( ret ); }
int main( void ) { int ret; mpi E, P, Q, N, H, D, X, Y, Z; mpi_init( &E ); mpi_init( &P ); mpi_init( &Q ); mpi_init( &N ); mpi_init( &H ); mpi_init( &D ); mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); MPI_CHK( mpi_read_string( &P, 10, "2789" ) ); MPI_CHK( mpi_read_string( &Q, 10, "3203" ) ); MPI_CHK( mpi_read_string( &E, 10, "257" ) ); MPI_CHK( mpi_mul_mpi( &N, &P, &Q ) ); polarssl_printf( "\n Public key:\n\n" ); MPI_CHK( mpi_write_file( " N = ", &N, 10, NULL ) ); MPI_CHK( mpi_write_file( " E = ", &E, 10, NULL ) ); polarssl_printf( "\n Private key:\n\n" ); MPI_CHK( mpi_write_file( " P = ", &P, 10, NULL ) ); MPI_CHK( mpi_write_file( " Q = ", &Q, 10, NULL ) ); #if defined(POLARSSL_GENPRIME) MPI_CHK( mpi_sub_int( &P, &P, 1 ) ); MPI_CHK( mpi_sub_int( &Q, &Q, 1 ) ); MPI_CHK( mpi_mul_mpi( &H, &P, &Q ) ); MPI_CHK( mpi_inv_mod( &D, &E, &H ) ); mpi_write_file( " D = E^-1 mod (P-1)*(Q-1) = ", &D, 10, NULL ); #else polarssl_printf("\nTest skipped (POLARSSL_GENPRIME not defined).\n\n"); #endif MPI_CHK( mpi_read_string( &X, 10, "55555" ) ); MPI_CHK( mpi_exp_mod( &Y, &X, &E, &N, NULL ) ); MPI_CHK( mpi_exp_mod( &Z, &Y, &D, &N, NULL ) ); polarssl_printf( "\n RSA operation:\n\n" ); MPI_CHK( mpi_write_file( " X (plaintext) = ", &X, 10, NULL ) ); MPI_CHK( mpi_write_file( " Y (ciphertext) = X^E mod N = ", &Y, 10, NULL ) ); MPI_CHK( mpi_write_file( " Z (decrypted) = Y^D mod N = ", &Z, 10, NULL ) ); polarssl_printf( "\n" ); cleanup: mpi_free( &E ); mpi_free( &P ); mpi_free( &Q ); mpi_free( &N ); mpi_free( &H ); mpi_free( &D ); mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); if( ret != 0 ) { polarssl_printf( "\nAn error occurred.\n" ); ret = 1; } #if defined(_WIN32) polarssl_printf( " Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
/* Very simple ASN.1 parsing. * Mainly needed because, even though all the RSA big integers * are always a specific number of bytes, the key generation * and encoding process sometimes pads each number with a * leading zero byte. */ void init_rsa_context_with_private_key(rsa_context *rsa, const unsigned char *private_key) { rsa_init(rsa, RSA_PKCS_V15, RSA_RAW, NULL, NULL); rsa->len = 128; int i = 9; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->N, private_key + i, 128); mpi_read_string(&rsa->E, 16, "10001"); i = i + 135; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->D, private_key + i, 128); i = i + 129; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->P, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->Q, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->DP, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->DQ, private_key + i, 64); i = i + 65; if (private_key[i] & 1) { // key contains an extra zero byte ++i; } ++i; mpi_read_binary(&rsa->QP, private_key + i, 64); }