/** * Recurse through the given node and free all of the memory that was allocated * by asn1parse. Don't free the "data" pointers, since that points to memory that * was not allocated by asn1parse. */ void asn1free(struct asn1struct *node) { if (!node) { return; } asn1free(node->children); free(node->children); asn1free(node->next); free(node->next); }
/** * Parse the modulus and private exponent from the buffer, which * should contain a DER-encoded RSA private key file. There's a * lot more information in the private key file format, but this * app isn't set up to use any of it. * This, according to PKCS #1 (note that this is not in pkcs #8 format), is: * Version * modulus (n) * public exponent (e) * private exponent (d) * prime1 (p) * prime2 (q) * exponent1 (d mod p-1) * exponent2 (d mod q-1) * coefficient (inverse of q % p) * Here, all we care about is n & d. */ int parse_private_key( rsa_key *privkey, const unsigned char *buffer, int buffer_length ) { struct asn1struct private_key; struct asn1struct *version; struct asn1struct *modulus; struct asn1struct *public_exponent; struct asn1struct *private_exponent; asn1parse( buffer, buffer_length, &private_key ); version = ( struct asn1struct * ) private_key.children; modulus = ( struct asn1struct * ) version->next; // Just read this to skip over it public_exponent = ( struct asn1struct * ) modulus->next; private_exponent = ( struct asn1struct * ) public_exponent->next; privkey->modulus = malloc( sizeof( huge ) ); privkey->exponent = malloc( sizeof( huge ) ); load_huge( privkey->modulus, modulus->data, modulus->length ); load_huge( privkey->exponent, private_exponent->data, private_exponent->length ); asn1free( &private_key ); return 0; }
int parse_pkcs8_private_key( rsa_key *privkey, const unsigned char *buffer, int buffer_length, const unsigned char *passphrase ) { struct asn1struct pkcs8_key; struct asn1struct private_key; struct asn1struct *encryptionId; struct asn1struct *salt; struct asn1struct *iteration_count; struct asn1struct *encrypted_key; struct asn1struct *key_type_oid; struct asn1struct *priv_key_data; digest_ctx initial_hash; int counter; unsigned char passphrase_hash_in[ MD5_RESULT_SIZE * sizeof( int ) ]; unsigned char passphrase_hash_out[ MD5_RESULT_SIZE * sizeof( int ) ]; unsigned char *decrypted_key; asn1parse( buffer, buffer_length, &pkcs8_key ); encryptionId = pkcs8_key.children->children; if ( memcmp( OID_pbeWithMD5andDES_CBC, encryptionId->data, encryptionId->length ) ) { fprintf( stderr, "Unsupported key encryption algorithm\n" ); asn1free( &pkcs8_key ); return 1; } // TODO support more algorithms salt = encryptionId->next->children; iteration_count = salt->next; encrypted_key = pkcs8_key.children->next; // ugly typecasting counter = ntohs( *iteration_count->data ); new_md5_digest( &initial_hash ); update_digest( &initial_hash, passphrase, strlen( passphrase ) ); update_digest( &initial_hash, salt->data, salt->length ); finalize_digest( &initial_hash ); memcpy( passphrase_hash_out, initial_hash.hash, initial_hash.hash_len * sizeof( int ) ); while ( --counter ) { memcpy( passphrase_hash_in, passphrase_hash_out, sizeof( int ) * MD5_RESULT_SIZE ); md5_hash( passphrase_hash_in, sizeof( int ) * MD5_RESULT_SIZE, ( unsigned int * ) passphrase_hash_out ); } decrypted_key = ( unsigned char * ) malloc( encrypted_key->length ); des_decrypt( encrypted_key->data, encrypted_key->length, decrypted_key, ( unsigned char * ) passphrase_hash_out + DES_KEY_SIZE, ( unsigned char * ) passphrase_hash_out ); // sanity check if ( decrypted_key[ encrypted_key->length - 1 ] > 8 ) { fprintf( stderr, "Decryption error, bad padding\n"); asn1free( &pkcs8_key ); free( decrypted_key ); return 1; } asn1parse( decrypted_key, encrypted_key->length - decrypted_key[ encrypted_key->length - 1 ], &private_key ); free( decrypted_key ); key_type_oid = private_key.children->next->children; if ( memcmp( OID_RSAPrivateKey, key_type_oid->data, key_type_oid->length ) ) { fprintf( stderr, "Unsupported private key type" ); asn1free( &pkcs8_key ); asn1free( &private_key ); } priv_key_data = private_key.children->next->next; parse_pkcs8_private_key( privkey, priv_key_data->data, priv_key_data->length, "password" ); asn1free( &pkcs8_key ); asn1free( &private_key ); return 0; }
void CRSADlg::OnBnClickedBtnGenrsakey() { // TODO: Add your control notification handler code here rsa_key key; unsigned char outRSA[4096]; unsigned long outlenRSA = 4096; padding = LTC_PKCS_1_V1_5; switch(g_AsyAlgList_Index) { case eASYMKEY_ALG_1024: rsa_byte_len = 1024 / 8; break; case eASYMKEY_ALG_2048: rsa_byte_len = 2048 / 8; break; case eASYMKEY_ALG_4096: rsa_byte_len = 4096 / 8; break; default: break; } /* make an RSA-1024 key */ if ((err = rsa_make_key(NULL, /* PRNG state */ prng_idx, /* PRNG idx */ rsa_byte_len, /*key byte length*/ 65537, /* we like e=65537 */ &key) /* where to store the key */ ) != CRYPT_OK) { printf("rsa_make_key %s", error_to_string(err)); } if ((err = rsa_export((unsigned char*)outRSA, &outlenRSA, PK_PRIVATE, &key)) != CRYPT_OK) { printf("Export error: %s", error_to_string(err)); outlenRSA = 0; } //unsigned char *tmp; //int len = 0; //len = mp_unsigned_bin_size((mp_int *)key.N); //tmp = (unsigned char *) malloc(len); //mp_to_unsigned_bin((mp_int *)key.N, tmp); // unsigned char *msg; //// N // msg = (unsigned char *) malloc(2*len+1); // *(msg+(2*len)) = '\0'; // StdCharsToHexChars(tmp, msg, len); // SetDlgItemText(IDC_EDIT_N, (LPCTSTR)msg); // if(msg != NULL) //{ // free(msg); // msg = NULL; //} struct asn1struct certificate; struct RsaKeyBlob ExportKey; memset(&ExportKey, 0, sizeof(RsaKeyBlob)); asn1parse(outRSA, outlenRSA, &certificate); ExportKey.m_IndexCount = 0; ans1GetKey(0, &certificate, &ExportKey); asn1free( &certificate ); unsigned long len = ExportKey.m_ulKeyBits; unsigned char *msg; // N msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_N, msg, len); SetDlgItemText(IDC_EDIT_N, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } //D len = ExportKey.m_ulKeyBits; msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_D, msg, len); SetDlgItemText(IDC_EDIT_D, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } //P len = ExportKey.m_ulKeyBits / 2; msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_p, msg, len); SetDlgItemText(IDC_EDIT_P, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } // Q len = ExportKey.m_ulKeyBits / 2; msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_q, msg, len); SetDlgItemText(IDC_EDIT_Q, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } // DP len = ExportKey.m_ulKeyBits / 2; msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_dp, msg, len); SetDlgItemText(IDC_EDIT_DP, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } // DQ len = ExportKey.m_ulKeyBits / 2; msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_dq, msg, len); SetDlgItemText(IDC_EDIT_DQ, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } // Qinv len = ExportKey.m_ulKeyBits / 2; msg = (unsigned char *) malloc(2*len+1); *(msg+(2*len)) = '\0'; StdCharsToHexChars(ExportKey.m_qinv, msg, len); SetDlgItemText(IDC_EDIT_Qinv, (LPCTSTR)msg); if(msg != NULL) { free(msg); msg = NULL; } }
int main( int argc, char *argv[ ] ) { int certificate_file; struct stat certificate_file_stat; unsigned char *buffer, *bufptr; int buffer_size; int bytes_read; struct asn1struct certificate; if ( argc < 3 ) { fprintf( stderr, "Usage: %s [-der|-pem] <certificate file>\n", argv[ 0 ] ); exit( 0 ); } if ( ( certificate_file = open( argv[ 2 ], O_RDONLY ) ) == -1 ) { perror( "Unable to open certificate file" ); return 1; } // Slurp the whole thing into memory if ( fstat( certificate_file, &certificate_file_stat ) ) { perror( "Unable to stat certificate file" ); return 2; } buffer_size = certificate_file_stat.st_size; buffer = ( char * ) malloc( buffer_size ); if ( !buffer ) { perror( "Not enough memory" ); return 3; } bufptr = buffer; while ( bytes_read = read( certificate_file, ( void * ) buffer, certificate_file_stat.st_size ) ) { bufptr += bytes_read; } if ( !( strcmp( argv[ 1 ], "-pem" ) ) ) { // XXX this overallocates a bit, since it sets aside space for markers, etc. unsigned char *pem_buffer = buffer; buffer = (unsigned char * ) malloc( buffer_size ); buffer_size = pem_decode( pem_buffer, buffer ); free( pem_buffer ); } asn1parse( buffer, buffer_size, &certificate ); asn1show( 0, &certificate ); asn1free( &certificate ); return 0; }