Merge pull request #302 from libtom/fix/pr/301
re-work PK crypto im- & export
This commit is contained in:
		
						commit
						01a61e64ef
					
				| @ -48,7 +48,6 @@ The following list is a small part of the available, but the most often required | ||||
| | ---- | -------- | | ||||
| | `LTC_NO_TEST` | Remove all algorithm self-tests from the library | | ||||
| | `LTC_NO_FILE` | Remove all API functions requiring a pre-defined `FILE` data-type (mostly useful for embedded targets) | | ||||
| | `MAX_RSA_SIZE` | Per default set to `4096`, if you need support for importing or generating bigger RSA keys, change this at compile-time. | | ||||
| | `GMP_DESC` | enable [gmp](https://gmplib.org/) as MPI provider *\*1* | | ||||
| | `LTM_DESC` | enable [libtommath](http://www.libtom.net/) as MPI provider *\*1* | | ||||
| | `TFM_DESC` | enable [tomsfastmath](http://www.libtom.net/) as MPI provider *\*1* *\*2* | | ||||
|  | ||||
| @ -150,7 +150,7 @@ if SHOW_SELECTED_CONSTANTS: | ||||
|         b'ENDIAN_LITTLE', | ||||
|         b'ENDIAN_64BITWORD', | ||||
|         b'PK_PUBLIC', | ||||
|         b'MAX_RSA_SIZE', | ||||
|         b'LTC_MILLER_RABIN_REPS', | ||||
|         b'CTR_COUNTER_BIG_ENDIAN', | ||||
|     ] | ||||
|     for name in names: | ||||
|  | ||||
| @ -76,6 +76,7 @@ endif | ||||
| LTC_CFLAGS += -Wno-type-limits | ||||
| 
 | ||||
| ifdef LTC_DEBUG | ||||
| $(info Debug build) | ||||
| # compile for DEBUGGING (required for ccmalloc checking!!!)
 | ||||
| LTC_CFLAGS += -g3 -DLTC_NO_ASM | ||||
| ifneq (,$(strip $(LTC_DEBUG))) | ||||
|  | ||||
| @ -425,30 +425,6 @@ | ||||
| #define LTC_ECC_TIMING_RESISTANT | ||||
| #endif | ||||
| 
 | ||||
| /* define these PK sizes out of LTC_NO_PK
 | ||||
|  * to have them always defined | ||||
|  */ | ||||
| #if defined(LTC_MRSA) | ||||
| /* Min and Max RSA key sizes (in bits) */ | ||||
| #ifndef MIN_RSA_SIZE | ||||
| #define MIN_RSA_SIZE 1024 | ||||
| #endif | ||||
| #ifndef MAX_RSA_SIZE | ||||
| #define MAX_RSA_SIZE 4096 | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| /* in cases where you want ASN.1/DER functionality, but no
 | ||||
|  * RSA, you can define this externally if 1024 is not enough | ||||
|  */ | ||||
| #if defined(LTC_MRSA) | ||||
| #define LTC_DER_MAX_PUBKEY_SIZE MAX_RSA_SIZE | ||||
| #elif !defined(LTC_DER_MAX_PUBKEY_SIZE) | ||||
| /* this includes DSA */ | ||||
| #define LTC_DER_MAX_PUBKEY_SIZE 1024 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /* PKCS #1 (RSA) and #5 (Password Handling) stuff */ | ||||
| #ifndef LTC_NO_PKCS | ||||
| 
 | ||||
|  | ||||
| @ -399,9 +399,6 @@ const char *crypt_build_settings = | ||||
| #if defined(LTC_DER) | ||||
|     " DER " | ||||
| #endif | ||||
| #if defined(LTC_DER_MAX_PUBKEY_SIZE) | ||||
|     " " NAME_VALUE(LTC_DER_MAX_PUBKEY_SIZE) " " | ||||
| #endif | ||||
| #if defined(LTC_PKCS_1) | ||||
|     " PKCS#1 " | ||||
| #endif | ||||
|  | ||||
| @ -77,8 +77,6 @@ static const crypt_constant _crypt_constants[] = { | ||||
| 
 | ||||
| #ifdef LTC_MRSA | ||||
|     {"LTC_MRSA", 1}, | ||||
|     _C_STRINGIFY(MIN_RSA_SIZE), | ||||
|     _C_STRINGIFY(MAX_RSA_SIZE), | ||||
| #else | ||||
|     {"LTC_MRSA", 0}, | ||||
| #endif | ||||
| @ -107,9 +105,6 @@ static const crypt_constant _crypt_constants[] = { | ||||
|     {"LTC_MDSA", 0}, | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LTC_DER_MAX_PUBKEY_SIZE | ||||
|     _C_STRINGIFY(LTC_DER_MAX_PUBKEY_SIZE), | ||||
| #endif | ||||
| #ifdef LTC_MILLER_RABIN_REPS | ||||
|     _C_STRINGIFY(LTC_MILLER_RABIN_REPS), | ||||
| #endif | ||||
|  | ||||
| @ -17,6 +17,7 @@ | ||||
| #ifdef LTC_DER | ||||
| 
 | ||||
| #define SETBIT(v, n)    (v=((unsigned char)(v) | (1U << (unsigned char)(n)))) | ||||
| #define CLRBIT(v, n)    (v=((unsigned char)(v) & ~(1U << (unsigned char)(n)))) | ||||
| 
 | ||||
| /**
 | ||||
|   Store a BIT STRING | ||||
| @ -84,12 +85,14 @@ int der_decode_raw_bit_string(const unsigned char *in,  unsigned long inlen, | ||||
| 
 | ||||
|    /* decode/store the bits */ | ||||
|    for (y = 0; y < blen; y++) { | ||||
|        if (in[x] & (1 << (7 - (y & 7)))) { | ||||
|           SETBIT(out[y/8], 7-(y%8)); | ||||
|        } | ||||
|        if ((y & 7) == 7) { | ||||
|           ++x; | ||||
|        } | ||||
|       if (in[x] & (1 << (7 - (y & 7)))) { | ||||
|          SETBIT(out[y/8], 7-(y%8)); | ||||
|       } else { | ||||
|          CLRBIT(out[y/8], 7-(y%8)); | ||||
|       } | ||||
|       if ((y & 7) == 7) { | ||||
|          ++x; | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    /* we done */ | ||||
|  | ||||
| @ -21,7 +21,7 @@ | ||||
| /**
 | ||||
|   Store a BIT STRING | ||||
|   @param in       The array of bits to store (8 per char) | ||||
|   @param inlen    The number of bits tostore | ||||
|   @param inlen    The number of bits to store | ||||
|   @param out      [out] The destination for the DER encoded BIT STRING | ||||
|   @param outlen   [in/out] The max size and resulting size of the DER BIT STRING | ||||
|   @return CRYPT_OK if successful | ||||
| @ -68,11 +68,11 @@ int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen, | ||||
| 
 | ||||
|    /* store the bits in big endian format */ | ||||
|    for (y = buf = 0; y < inlen; y++) { | ||||
|         buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7)); | ||||
|        if ((y & 7) == 7) { | ||||
|           out[x++] = buf; | ||||
|           buf      = 0; | ||||
|        } | ||||
|       buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7)); | ||||
|       if ((y & 7) == 7) { | ||||
|          out[x++] = buf; | ||||
|          buf      = 0; | ||||
|       } | ||||
|    } | ||||
|    /* store last byte */ | ||||
|    if (inlen & 7) { | ||||
|  | ||||
| @ -58,7 +58,7 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in | ||||
|    } | ||||
| 
 | ||||
|    /* see if the OpenSSL DER format RSA public key will work */ | ||||
|    tmpbuf = XCALLOC(1, LTC_DER_MAX_PUBKEY_SIZE*8); | ||||
|    tmpbuf = XCALLOC(1, inlen); | ||||
|    if (tmpbuf == NULL) { | ||||
|        err = CRYPT_MEM; | ||||
|        goto LBL_ERR; | ||||
| @ -72,7 +72,7 @@ int der_decode_subject_public_key_info(const unsigned char *in, unsigned long in | ||||
|     * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet | ||||
|     */ | ||||
|    LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); | ||||
|    LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, LTC_DER_MAX_PUBKEY_SIZE*8); | ||||
|    LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U); | ||||
| 
 | ||||
|    err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); | ||||
|    if (err != CRYPT_OK) { | ||||
|  | ||||
| @ -58,7 +58,7 @@ int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen | ||||
| 
 | ||||
|    return der_encode_sequence_multi(out, outlen, | ||||
|         LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, | ||||
|         LTC_ASN1_RAW_BIT_STRING, (unsigned long)(public_key_len*8), public_key, | ||||
|         LTC_ASN1_RAW_BIT_STRING, public_key_len*8U, public_key, | ||||
|         LTC_ASN1_EOL,     0UL, NULL); | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -90,7 +90,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) | ||||
|        key->type = PK_PRIVATE; | ||||
|    } else { /* public */ | ||||
|       ltc_asn1_list params[3]; | ||||
|       unsigned long tmpbuf_len = LTC_DER_MAX_PUBKEY_SIZE*8; | ||||
|       unsigned long tmpbuf_len = inlen; | ||||
| 
 | ||||
|       LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL); | ||||
|       LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL); | ||||
|  | ||||
| @ -40,7 +40,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) | ||||
|    } | ||||
| 
 | ||||
|    /* see if the OpenSSL DER format RSA public key will work */ | ||||
|    tmpbuf_len = MAX_RSA_SIZE * 8; | ||||
|    tmpbuf_len = inlen; | ||||
|    tmpbuf = XCALLOC(1, tmpbuf_len); | ||||
|    if (tmpbuf == NULL) { | ||||
|        err = CRYPT_MEM; | ||||
|  | ||||
| @ -39,7 +39,7 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key) | ||||
|       return err; | ||||
|    } | ||||
| 
 | ||||
|    tmpbuf_len = MAX_RSA_SIZE * 8; | ||||
|    tmpbuf_len = inlen; | ||||
|    tmpbuf = XCALLOC(1, tmpbuf_len); | ||||
|    if (tmpbuf == NULL) { | ||||
|        err = CRYPT_MEM; | ||||
|  | ||||
| @ -31,10 +31,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) | ||||
| 
 | ||||
|    LTC_ARGCHK(ltc_mp.name != NULL); | ||||
|    LTC_ARGCHK(key         != NULL); | ||||
| 
 | ||||
|    if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { | ||||
|       return CRYPT_INVALID_KEYSIZE; | ||||
|    } | ||||
|    LTC_ARGCHK(size        > 0); | ||||
| 
 | ||||
|    if ((e < 3) || ((e & 1) == 0)) { | ||||
|       return CRYPT_INVALID_ARG; | ||||
|  | ||||
| @ -239,8 +239,8 @@ SEQUENCE(3 elem) | ||||
| static void _der_tests_print_flexi(ltc_asn1_list* l, unsigned int level) | ||||
| { | ||||
|   char buf[1024]; | ||||
|   char* name = NULL; | ||||
|   char* text = NULL; | ||||
|   const char* name = NULL; | ||||
|   const char* text = NULL; | ||||
|   ltc_asn1_list* ostring = NULL; | ||||
|   unsigned int n; | ||||
| 
 | ||||
|  | ||||
| @ -285,6 +285,64 @@ static int rsa_compat_test(void) | ||||
|    return 0; | ||||
| } | ||||
| 
 | ||||
| static int _rsa_key_cmp(const int should_type, const rsa_key *should, const rsa_key *is) | ||||
| { | ||||
|    if(should_type != is->type) | ||||
|       return CRYPT_ERROR; | ||||
|    if(should_type == PK_PRIVATE) { | ||||
|       if(mp_cmp(should->q, is->q) != LTC_MP_EQ) | ||||
|          return CRYPT_ERROR; | ||||
|       if(mp_cmp(should->p, is->p) != LTC_MP_EQ) | ||||
|          return CRYPT_ERROR; | ||||
|       if(mp_cmp(should->qP, is->qP) != LTC_MP_EQ) | ||||
|          return CRYPT_ERROR; | ||||
|       if(mp_cmp(should->dP, is->dP) != LTC_MP_EQ) | ||||
|          return CRYPT_ERROR; | ||||
|       if(mp_cmp(should->dQ, is->dQ) != LTC_MP_EQ) | ||||
|          return CRYPT_ERROR; | ||||
|       if(mp_cmp(should->d, is->d) != LTC_MP_EQ) | ||||
|          return CRYPT_ERROR; | ||||
|    } | ||||
|    if(mp_cmp(should->N, is->N) != LTC_MP_EQ) | ||||
|       return CRYPT_ERROR; | ||||
|    if(mp_cmp(should->e, is->e) != LTC_MP_EQ) | ||||
|       return CRYPT_ERROR; | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| static int _rsa_issue_301(int prng_idx) | ||||
| { | ||||
|    rsa_key       key, key_in; | ||||
|    unsigned char buf[4096]; | ||||
|    unsigned long len; | ||||
| 
 | ||||
|    DO(rsa_make_key(&yarrow_prng, prng_idx, sizeof(buf)/8, 65537, &key)); | ||||
| 
 | ||||
|    len = sizeof(buf); | ||||
|    DO(rsa_export(buf, &len, PK_PRIVATE, &key)); | ||||
|    DO(rsa_import(buf, len, &key_in)); | ||||
| 
 | ||||
|    DO(_rsa_key_cmp(PK_PRIVATE, &key, &key_in)); | ||||
|    rsa_free(&key_in); | ||||
| 
 | ||||
|    len = sizeof(buf); | ||||
|    DO(rsa_export(buf, &len, PK_PUBLIC, &key)); | ||||
|    DO(rsa_import(buf, len, &key_in)); | ||||
| 
 | ||||
|    DO(_rsa_key_cmp(PK_PUBLIC, &key, &key_in)); | ||||
|    rsa_free(&key_in); | ||||
| 
 | ||||
|    len = sizeof(buf); | ||||
|    DO(rsa_export(buf, &len, PK_PUBLIC | PK_STD, &key)); | ||||
|    DO(rsa_import(buf, len, &key_in)); | ||||
| 
 | ||||
|    DO(_rsa_key_cmp(PK_PUBLIC, &key, &key_in)); | ||||
|    rsa_free(&key_in); | ||||
| 
 | ||||
|    rsa_free(&key); | ||||
|    return CRYPT_OK; | ||||
| } | ||||
| 
 | ||||
| int rsa_test(void) | ||||
| { | ||||
|    unsigned char in[1024], out[1024], tmp[3072]; | ||||
| @ -308,6 +366,8 @@ int rsa_test(void) | ||||
|       return 1; | ||||
|    } | ||||
| 
 | ||||
|    DO(_rsa_issue_301(prng_idx)); | ||||
| 
 | ||||
|    /* make 10 random key */ | ||||
|    for (cnt = 0; cnt < 10; cnt++) { | ||||
|       DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key)); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user