int pki_privkey_build_rsa(ssh_key key, ssh_string n, ssh_string e, ssh_string d, ssh_string iqmp, ssh_string p, ssh_string q) { mbedtls_rsa_context *rsa = NULL; const mbedtls_pk_info_t *pk_info = NULL; int rc; key->rsa = malloc(sizeof(mbedtls_pk_context)); if (key->rsa == NULL) { return SSH_ERROR; } mbedtls_pk_init(key->rsa); pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_RSA); mbedtls_pk_setup(key->rsa, pk_info); rc = mbedtls_pk_can_do(key->rsa, MBEDTLS_PK_RSA); if (rc == 0) { goto fail; } rsa = mbedtls_pk_rsa(*key->rsa); rc = mbedtls_rsa_import_raw(rsa, ssh_string_data(n), ssh_string_len(n), ssh_string_data(p), ssh_string_len(p), ssh_string_data(q), ssh_string_len(q), ssh_string_data(d), ssh_string_len(d), ssh_string_data(e), ssh_string_len(e)); if (rc != 0) { SSH_LOG(SSH_LOG_WARN, "Failed to import private RSA key"); goto fail; } rc = mbedtls_rsa_complete(rsa); if (rc != 0) { SSH_LOG(SSH_LOG_WARN, "Failed to complete private RSA key"); goto fail; } rc = mbedtls_rsa_check_privkey(rsa); if (rc != 0) { SSH_LOG(SSH_LOG_WARN, "Inconsistent private RSA key"); goto fail; } return SSH_OK; fail: mbedtls_pk_free(key->rsa); SAFE_FREE(key->rsa); return SSH_ERROR; }
/* * Check if contexts holding a public and private key match */ int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ) { if( mbedtls_rsa_check_pubkey( pub ) != 0 || mbedtls_rsa_check_privkey( prv ) != 0 ) { return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); } if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 || mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 ) { return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); } return( 0 ); }
result_t PKey::isPrivate(bool &retVal) { mbedtls_pk_type_t type = mbedtls_pk_get_type(&m_key); if (type == MBEDTLS_PK_RSA) { retVal = mbedtls_rsa_check_privkey(mbedtls_pk_rsa(m_key)) == 0; return 0; } if (type == MBEDTLS_PK_ECKEY) { mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(m_key); retVal = mbedtls_ecp_check_privkey(&ecp->grp, &ecp->d) == 0; return 0; } return CHECK_ERROR(CALL_E_INVALID_CALL); }
/* * Parse a PKCS#1 encoded private RSA key */ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, const unsigned char *key, size_t keylen ) { int ret; size_t len; unsigned char *p, *end; p = (unsigned char *) key; end = p + keylen; /* * This function parses the RSAPrivateKey (PKCS#1) * * RSAPrivateKey ::= SEQUENCE { * version Version, * modulus INTEGER, -- n * publicExponent INTEGER, -- e * privateExponent INTEGER, -- d * prime1 INTEGER, -- p * prime2 INTEGER, -- q * exponent1 INTEGER, -- d mod (p-1) * exponent2 INTEGER, -- d mod (q-1) * coefficient INTEGER, -- (inverse of q) mod p * otherPrimeInfos OtherPrimeInfos OPTIONAL * } */ if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } end = p + len; if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } if( rsa->ver != 0 ) { return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); } if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) { mbedtls_rsa_free( rsa ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); } rsa->len = mbedtls_mpi_size( &rsa->N ); if( p != end ) { mbedtls_rsa_free( rsa ); return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); } if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 ) { mbedtls_rsa_free( rsa ); return( ret ); } return( 0 ); }
int main( void ) { int ret, i; mbedtls_x509_crt cacert; mbedtls_x509_crl crl; char buf[10240]; mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crl_init( &crl ); /* * 1.1. Load the trusted CA */ mbedtls_printf( "\n . Loading the CA root certificate ..." ); fflush( stdout ); /* * Alternatively, you may load the CA certificates from a .pem or * .crt file by calling mbedtls_x509_crt_parse_file( &cacert, "myca.crt" ). */ ret = mbedtls_x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_x509_crt_info( buf, 1024, "CRT: ", &cacert ); mbedtls_printf("%s\n", buf ); /* * 1.2. Load the CRL */ mbedtls_printf( " . Loading the CRL ..." ); fflush( stdout ); ret = mbedtls_x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crl_parse_file returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_x509_crl_info( buf, 1024, "CRL: ", &crl ); mbedtls_printf("%s\n", buf ); for( i = 0; i < MAX_CLIENT_CERTS; i++ ) { /* * 1.3. Load own certificate */ char name[512]; uint32_t flags; mbedtls_x509_crt clicert; mbedtls_pk_context pk; mbedtls_x509_crt_init( &clicert ); mbedtls_pk_init( &pk ); mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]); mbedtls_printf( " . Loading the client certificate %s...", name ); fflush( stdout ); ret = mbedtls_x509_crt_parse_file( &clicert, name ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_x509_crt_parse_file returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.4. Verify certificate validity with CA certificate */ mbedtls_printf( " . Verify the client certificate with CA certificate..." ); fflush( stdout ); ret = mbedtls_x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL, NULL ); if( ret != 0 ) { if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) { char vrfy_buf[512]; mbedtls_printf( " failed\n" ); mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), " ! ", flags ); mbedtls_printf( "%s\n", vrfy_buf ); } else { mbedtls_printf( " failed\n ! mbedtls_x509_crt_verify returned %d\n\n", ret ); goto exit; } } mbedtls_printf( " ok\n" ); /* * 1.5. Load own private key */ mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]); mbedtls_printf( " . Loading the client private key %s...", name ); fflush( stdout ); ret = mbedtls_pk_parse_keyfile( &pk, name, NULL ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_pk_parse_keyfile returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * 1.6. Verify certificate validity with private key */ mbedtls_printf( " . Verify the client certificate with private key..." ); fflush( stdout ); /* EC NOT IMPLEMENTED YET */ if( ! mbedtls_pk_can_do( &clicert.pk, MBEDTLS_PK_RSA ) ) { mbedtls_printf( " failed\n ! certificate's key is not RSA\n\n" ); ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; goto exit; } ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->N, &mbedtls_pk_rsa( clicert.pk )->N); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_cmp_mpi for N returned %d\n\n", ret ); goto exit; } ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->E, &mbedtls_pk_rsa( clicert.pk )->E); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_cmp_mpi for E returned %d\n\n", ret ); goto exit; } ret = mbedtls_rsa_check_privkey( mbedtls_pk_rsa( pk ) ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_check_privkey returned %d\n\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); mbedtls_x509_crt_free( &clicert ); mbedtls_pk_free( &pk ); } exit: mbedtls_x509_crt_free( &cacert ); mbedtls_x509_crl_free( &crl ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
int main( int argc, char *argv[] ) { FILE *f; int ret = 1; int exit_code = MBEDTLS_EXIT_FAILURE; size_t i; mbedtls_rsa_context rsa; unsigned char hash[32]; unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; char filename[512]; mbedtls_mpi N, P, Q, D, E, DP, DQ, QP; mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP ); if( argc != 2 ) { mbedtls_printf( "usage: rsa_sign <filename>\n" ); #if defined(_WIN32) mbedtls_printf( "\n" ); #endif goto exit; } mbedtls_printf( "\n . Reading private key from rsa_priv.txt" ); fflush( stdout ); if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL ) { mbedtls_printf( " failed\n ! Could not open rsa_priv.txt\n" \ " ! Please run rsa_genkey first\n\n" ); goto exit; } if( ( ret = mbedtls_mpi_read_file( &N , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &E , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &D , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &P , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &Q , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &DP , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &DQ , 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &QP , 16, f ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret ); fclose( f ); goto exit; } fclose( f ); if( ( ret = mbedtls_rsa_import( &rsa, &N, &P, &Q, &D, &E ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_import returned %d\n\n", ret ); goto exit; } if( ( ret = mbedtls_rsa_complete( &rsa ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_complete returned %d\n\n", ret ); goto exit; } mbedtls_printf( "\n . Checking the private key" ); fflush( stdout ); if( ( ret = mbedtls_rsa_check_privkey( &rsa ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_check_privkey failed with -0x%0x\n", -ret ); goto exit; } /* * Compute the SHA-256 hash of the input file, * then calculate the RSA signature of the hash. */ mbedtls_printf( "\n . Generating the RSA/SHA-256 signature" ); fflush( stdout ); if( ( ret = mbedtls_md_file( mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), argv[1], hash ) ) != 0 ) { mbedtls_printf( " failed\n ! Could not open or read %s\n\n", argv[1] ); goto exit; } if( ( ret = mbedtls_rsa_pkcs1_sign( &rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, 20, hash, buf ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_pkcs1_sign returned -0x%0x\n\n", -ret ); goto exit; } /* * Write the signature into <filename>.sig */ mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[1] ); if( ( f = fopen( filename, "wb+" ) ) == NULL ) { mbedtls_printf( " failed\n ! Could not create %s\n\n", argv[1] ); goto exit; } for( i = 0; i < rsa.len; i++ ) mbedtls_fprintf( f, "%02X%s", buf[i], ( i + 1 ) % 16 == 0 ? "\r\n" : " " ); fclose( f ); mbedtls_printf( "\n . Done (created \"%s\")\n\n", filename ); exit_code = MBEDTLS_EXIT_SUCCESS; exit: mbedtls_rsa_free( &rsa ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( exit_code ); }