static int cipher_des_ede3_cbc_code(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) { int ret = DES3_CBCUpdate(data(ctx), out, (unsigned char *)in, inl); switch (ret) { case RE_LEN: RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_LENGTH_NOT_BLOCK_ALIGNED); break; case 0: break; default: RSAREFerr(RSAREF_F_CIPHER_DES_CBC_CODE,RSAREF_R_UNKNOWN_FAULT); } return !ret; }
int read_priv_key (FILE * privring, PRIVATE_KEY * privkey, unsigned char *newID) { unsigned char line[1024]; int i, err, len, length; unsigned char iv[20]; unsigned char *temp, *temp2; byte digest[16], *byteptr; byte des3key[24]; BUFFER *buff; #ifdef USE_RSAREF R_DIGEST_CTX digest_context; DES3_CBC_CTX context; #else B_ALGORITHM_OBJ digest_obj; B_ALGORITHM_OBJ des_obj; B_KEY_OBJ key_obj; A_PKCS_RSA_PRIVATE_KEY keyinfo; #endif buff = new_buffer (); /* read in the length */ if ((temp = getline (line, sizeof (line), privring)) == NULL) return -1; sscanf (line, "%d", &length); /* Read in iv */ if (((temp = getline (line, sizeof (line), privring)) == NULL) || (decode_block (iv, &len, line, strlen (line)))) return -1; if ((temp = getline (line, sizeof (line), privring)) == NULL) return -1; while (temp != NULL && !streq (line, end_key)) { add_to_buffer (buff, line, strlen (line)); temp = getline (line, sizeof (line), privring); } temp = malloc (buff->length); temp2 = malloc (buff->length); if (decode_block (temp, &len, buff->message, buff->length) != 0) return -1; if (len < length) { fprintf (errlog, "Error: recovered key is too small!\n"); return (-2); } /* decrypt key */ #ifdef USE_RSAREF R_DigestInit (&digest_context, DA_MD5); R_DigestUpdate (&digest_context, PASSPHRASE, strlen (PASSPHRASE)); R_DigestFinal (&digest_context, digest, &i); memcpy (des3key, digest, 16); /* set first 2 keys */ memcpy (des3key + 16, digest, 8); /* third key = first key */ DES3_CBCInit (&context, des3key, iv, 0); while (len % 8 != 0) len++; /* align on block boundry */ err = DES3_CBCUpdate (&context, temp2, temp, len); #else B_CreateAlgorithmObject (&digest_obj); B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL); B_DigestInit (digest_obj, NULL, CHOOSER, NULL); B_DigestUpdate (digest_obj, PASSPHRASE, strlen (PASSPHRASE), NULL); B_DigestFinal (digest_obj, digest, &i, 16, NULL); B_DestroyAlgorithmObject (&digest_obj); memcpy (des3key, digest, 16); /* set first 2 keys */ memcpy (des3key + 16, digest, 8); /* third key = first key */ B_CreateAlgorithmObject (&des_obj); B_SetAlgorithmInfo (des_obj, AI_DES_EDE3_CBC_IV8, iv); B_CreateKeyObject (&key_obj); err = B_SetKeyInfo (key_obj, KI_DES24Strong, des3key); B_DecryptInit (des_obj, key_obj, CHOOSER, NULL); err = B_DecryptUpdate (des_obj, temp2, &i, len, temp, len, random_obj, NULL); B_DecryptFinal (des_obj, temp2 + i, &i, len - i, random_obj, NULL); B_DestroyKeyObject (&key_obj); B_DestroyAlgorithmObject (&des_obj); #endif if (err) { printf ("Error: Problem decrypting key %x\n", err); return (-1); } memset ((void *) digest, 0, 16); /* zero password */ free (temp); /* Rebuild privkey */ byteptr = temp2; i = *byteptr++; i += (*byteptr++ * 256); #ifdef USE_RSAREF (*privkey).bits = i; for (i = 0; i < MAX_RSA_MODULUS_LEN; i++) (*privkey).modulus[i] = *byteptr++; for (i = 0; i < MAX_RSA_MODULUS_LEN; i++) (*privkey).publicExponent[i] = *byteptr++; for (i = 0; i < MAX_RSA_MODULUS_LEN; i++) (*privkey).exponent[i] = *byteptr++; for (i = 0; i < MAX_RSA_PRIME_LEN; i++) (*privkey).prime[0][i] = *byteptr++; for (i = 0; i < MAX_RSA_PRIME_LEN; i++) (*privkey).prime[1][i] = *byteptr++; for (i = 0; i < MAX_RSA_PRIME_LEN; i++) (*privkey).primeExponent[0][i] = *byteptr++; for (i = 0; i < MAX_RSA_PRIME_LEN; i++) (*privkey).primeExponent[1][i] = *byteptr++; for (i = 0; i < MAX_RSA_PRIME_LEN; i++) (*privkey).coefficient[i] = *byteptr++; free (temp2); /* Make Key ID */ R_DigestInit (&digest_context, DA_MD5); R_DigestUpdate (&digest_context, privkey->modulus, MAX_RSA_MODULUS_LEN); R_DigestUpdate (&digest_context, privkey->publicExponent, MAX_RSA_MODULUS_LEN); R_DigestFinal (&digest_context, newID, &i); #else i = (i + 7) / 8; if (i < MAX_RSA_MODULUS_LEN) i = MAX_RSA_MODULUS_LEN; keyinfo.modulus.len = i; keyinfo.publicExponent.len = i; keyinfo.privateExponent.len = i; keyinfo.prime[0].len = (i + 1) / 2; keyinfo.prime[1].len = (i + 1) / 2; keyinfo.primeExponent[0].len = (i + 1) / 2; keyinfo.primeExponent[1].len = (i + 1) / 2; keyinfo.coefficient.len = (i + 1) / 2; keyinfo.modulus.data = malloc (keyinfo.modulus.len); memcpy (keyinfo.modulus.data, byteptr, keyinfo.modulus.len); byteptr += keyinfo.modulus.len; keyinfo.publicExponent.data = malloc (keyinfo.publicExponent.len); memcpy (keyinfo.publicExponent.data, byteptr, keyinfo.publicExponent.len); byteptr += keyinfo.publicExponent.len; keyinfo.privateExponent.data = malloc (keyinfo.privateExponent.len); memcpy (keyinfo.privateExponent.data, byteptr, keyinfo.privateExponent.len); byteptr += keyinfo.privateExponent.len; keyinfo.prime[0].data = malloc (keyinfo.prime[0].len); memcpy (keyinfo.prime[0].data, byteptr, keyinfo.prime[0].len); byteptr += keyinfo.prime[0].len; keyinfo.prime[1].data = malloc (keyinfo.prime[1].len); memcpy (keyinfo.prime[1].data, byteptr, keyinfo.prime[1].len); byteptr += keyinfo.prime[1].len; keyinfo.primeExponent[0].data = malloc (keyinfo.primeExponent[0].len); memcpy (keyinfo.primeExponent[0].data, byteptr, keyinfo.primeExponent[0].len); byteptr += keyinfo.primeExponent[0].len; keyinfo.primeExponent[1].data = malloc (keyinfo.primeExponent[1].len); memcpy (keyinfo.primeExponent[1].data, byteptr, keyinfo.primeExponent[1].len); byteptr += keyinfo.primeExponent[1].len; keyinfo.coefficient.data = malloc (keyinfo.coefficient.len); memcpy (keyinfo.coefficient.data, byteptr, keyinfo.coefficient.len); B_CreateKeyObject (privkey); B_SetKeyInfo (*privkey, KI_PKCS_RSAPrivate, (POINTER) & keyinfo); /* Make Key ID */ B_CreateAlgorithmObject (&digest_obj); B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL); B_DigestInit (digest_obj, NULL, CHOOSER, NULL); B_DigestUpdate (digest_obj, keyinfo.modulus.data, keyinfo.modulus.len, NULL); B_DigestUpdate (digest_obj, keyinfo.publicExponent.data, keyinfo.publicExponent.len, NULL); B_DigestFinal (digest_obj, newID, &i, 16, NULL); B_DestroyAlgorithmObject (&digest_obj); free (keyinfo.modulus.data); free (keyinfo.publicExponent.data); free (keyinfo.privateExponent.data); free (keyinfo.prime[0].data); free (keyinfo.prime[1].data); free (keyinfo.primeExponent[0].data); free (keyinfo.primeExponent[1].data); free (keyinfo.coefficient.data); free (temp2); #endif return 0; }
int generate_key (const char *header) { PUBLIC_KEY pubkey; PRIVATE_KEY privkey; unsigned char line[1024]; int i, err, len; unsigned char iv[8]; byte digest[16], ID[16], tmpbyte; byte des3key[24]; BUFFER *b1, *encrypted_key; FILE *privring, *privlock; #ifdef USE_RSAREF R_DIGEST_CTX digest_context; DES3_CBC_CTX context; R_RSA_PROTO_KEY protokey; #else B_ALGORITHM_OBJ digest_obj; B_ALGORITHM_OBJ des_obj; B_ALGORITHM_OBJ gen_obj; B_KEY_OBJ key_obj; A_RSA_KEY_GEN_PARAMS keypar; A_PKCS_RSA_PRIVATE_KEY *keyinfo; unsigned char pubexpt[] = {1, 0, 1}; #endif #ifdef DEBUG printf ("Generating key:\n%s", header); #endif /* Generate a 1024 bit key with pub exponent = 65537 */ #ifdef USE_RSAREF protokey.bits = MIX_RSA_MOD; protokey.useFermat4 = 1; err = R_GeneratePEMKeys (&pubkey, &privkey, &protokey, &random_obj); #else B_CreateAlgorithmObject (&gen_obj); /* Generate a 1024 bit key with pub exponent = 65537 */ keypar.modulusBits = 1024; keypar.publicExponent.data = pubexpt; keypar.publicExponent.len = sizeof (pubexpt); B_SetAlgorithmInfo (gen_obj, AI_RSAKeyGen, (POINTER) & keypar); B_GenerateInit (gen_obj, CHOOSER, NULL); B_CreateKeyObject (&pubkey); B_CreateKeyObject (&privkey); err = (B_GenerateKeypair (gen_obj, pubkey, privkey, random_obj, NULL)); #endif if (err != 0) { fprintf (errlog, "Key generation error.\n"); return (-1); } #ifdef DEBUG printf ("Done.\n"); #endif /* put private key in a buffer */ b1 = new_buffer (); #ifdef USE_RSAREF /* Convert privkey.bits to two bytes */ i = privkey.bits; #else B_GetKeyInfo ((POINTER *) & keyinfo, privkey, KI_PKCS_RSAPrivate); i = keyinfo->modulus.len * 8; #endif tmpbyte = i & 0xFF; add_to_buffer (b1, &tmpbyte, 1); /* low byte of bits */ tmpbyte = (i / 256) & 0xFF; add_to_buffer (b1, &tmpbyte, 1); /* high byte of bits */ #ifdef USE_RSAREF add_to_buffer (b1, privkey.modulus, MAX_RSA_MODULUS_LEN); add_to_buffer (b1, privkey.publicExponent, MAX_RSA_MODULUS_LEN); /* Make Key ID */ R_DigestInit (&digest_context, DA_MD5); R_DigestUpdate (&digest_context, pubkey.modulus, MAX_RSA_MODULUS_LEN); R_DigestUpdate (&digest_context, pubkey.exponent, MAX_RSA_MODULUS_LEN); R_DigestFinal (&digest_context, ID, &i); add_to_buffer (b1, privkey.exponent, MAX_RSA_MODULUS_LEN); add_to_buffer (b1, privkey.prime[0], MAX_RSA_PRIME_LEN); add_to_buffer (b1, privkey.prime[1], MAX_RSA_PRIME_LEN); add_to_buffer (b1, privkey.primeExponent[0], MAX_RSA_PRIME_LEN); add_to_buffer (b1, privkey.primeExponent[1], MAX_RSA_PRIME_LEN); add_to_buffer (b1, privkey.coefficient, MAX_RSA_PRIME_LEN); #else i = (i + 7) / 8; /* Make Key ID */ B_CreateAlgorithmObject (&digest_obj); B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL); B_DigestInit (digest_obj, NULL, CHOOSER, NULL); add_to_buffer (b1, keyinfo->modulus.data, i); if (keyinfo->publicExponent.len < i) add_to_buffer (b1, NULL, i - keyinfo->publicExponent.len); add_to_buffer (b1, keyinfo->publicExponent.data, keyinfo->publicExponent.len); B_DigestUpdate (digest_obj, b1->message + 2, 2 * i, NULL); B_DigestFinal (digest_obj, ID, &i, 16, NULL); B_DestroyAlgorithmObject (&digest_obj); if (keyinfo->privateExponent.len < i) add_to_buffer (b1, NULL, i - keyinfo->privateExponent.len); add_to_buffer (b1, keyinfo->privateExponent.data, keyinfo->privateExponent.len); i = (i + 1) / 2; if (keyinfo->prime[0].len < i) add_to_buffer (b1, NULL, i - keyinfo->prime[0].len); add_to_buffer (b1, keyinfo->prime[0].data, keyinfo->prime[0].len); if (keyinfo->prime[1].len < i) add_to_buffer (b1, NULL, i - keyinfo->prime[1].len); add_to_buffer (b1, keyinfo->prime[1].data, keyinfo->prime[1].len); if (keyinfo->primeExponent[0].len < i) add_to_buffer (b1, NULL, i - keyinfo->primeExponent[0].len); add_to_buffer (b1, keyinfo->primeExponent[0].data, keyinfo->primeExponent[0].len); if (keyinfo->primeExponent[1].len < i) add_to_buffer (b1, NULL, i - keyinfo->primeExponent[1].len); add_to_buffer (b1, keyinfo->primeExponent[1].data, keyinfo->primeExponent[1].len); if (keyinfo->coefficient.len < i) add_to_buffer (b1, NULL, i - keyinfo->coefficient.len); add_to_buffer (b1, keyinfo->coefficient.data, keyinfo->coefficient.len); #endif /* Encrypt the secret key */ encrypted_key = new_buffer (); len = b1->length; if (len % 8 != 0) /* ensure length is mult of 8 */ len += 8 - len % 8; add_to_buffer (encrypted_key, malloc (len), len); our_randombytes (iv, 8); #ifdef USE_RSAREF R_DigestInit (&digest_context, DA_MD5); R_DigestUpdate (&digest_context, PASSPHRASE, strlen (PASSPHRASE)); R_DigestFinal (&digest_context, digest, &i); memcpy (des3key, digest, 16); /* set first 2 keys */ memcpy (des3key + 16, digest, 8); /* third key = first key */ DES3_CBCInit (&context, des3key, iv, 1); if (DES3_CBCUpdate (&context, encrypted_key->message, b1->message, encrypted_key->length)) { printf ("Error: Problem encrypting key\n"); return (-1); } #else B_CreateAlgorithmObject (&digest_obj); B_SetAlgorithmInfo (digest_obj, AI_MD5, NULL); B_DigestInit (digest_obj, NULL, CHOOSER, NULL); B_DigestUpdate (digest_obj, PASSPHRASE, strlen (PASSPHRASE), NULL); B_DigestFinal (digest_obj, digest, &i, 16, NULL); B_DestroyAlgorithmObject (&digest_obj); memcpy (des3key, digest, 16); /* set first 2 keys */ memcpy (des3key + 16, digest, 8); /* third key = first key */ B_CreateAlgorithmObject (&des_obj); B_SetAlgorithmInfo (des_obj, AI_DES_EDE3_CBC_IV8, iv); B_CreateKeyObject (&key_obj); B_SetKeyInfo (key_obj, KI_DES24Strong, des3key); B_EncryptInit (des_obj, key_obj, CHOOSER, NULL); B_EncryptUpdate (des_obj, encrypted_key->message, &len, encrypted_key->length, b1->message, b1->length, random_obj, NULL); B_EncryptFinal (des_obj, encrypted_key->message + len, &len, encrypted_key->length - len, random_obj, NULL); /* err? XXX */ #endif memset ((void *) digest, 0, 16); /* zero password */ mix_lock ("secring", &privlock); if ((privring = open_mix_file (SECRING, "a+")) == NULL) { mix_unlock ("secring", privlock); return (-1); } fprintf (privring, "%s\n", begin_key); if (strlen (header) > 0) { fprintf (privring, KEY_VERSION "%s\n", VERSION); fprintf (privring, "%s", header); } print_ID (privring, ID); fprintf (privring, "%d\n", len); encode_block (line, &i, iv, 8); fwrite (line, 1, i, privring); fprintf (privring, "\n"); /* Armor privkey */ armor (encrypted_key); write_buffer (encrypted_key, privring); free_buffer (encrypted_key); fprintf (privring, "%s\n", end_key); fclose (privring); mix_unlock ("secring", privlock); return 0; }