PKCS #5 v1.5 encrypted key adds, small build fixes

This commit is contained in:
Todd A Ouska
2011-03-22 07:35:18 -07:00
parent b9ff110b2e
commit 680358abe1
11 changed files with 247 additions and 32 deletions

View File

@ -0,0 +1,11 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIBgTAbBgkqhkiG9w0BBQMwDgQIMbn/uK6tvZcCAggABIIBYK9oQl9uOmp/LC3j
VxEoo+imbDLwS+ybpjbvcnfyWja4TRpRdCHCB/PLHRmVGCf/pBMG8UkobxbVbjpg
DE5Mr69rOVOreNVIBkfAt0B8PgmLPRdKXtp6Y8IJ85R9Aic1g1+s5XeBcvEZRUHm
ZvKd+oV4y8OUpnZkAZdN4In/8ZvWEfZf6ZPplGbcmoqM7eoLrCCiJ1zLvTt3CPm5
yi/F8jJxPYM2iNj86y9hlpwk4lS+TvdAwmO/RGQQWverEQmX9MPob23s5ouBdHe5
7TnBldo/Hq6YVtBYHuvOlx99kaMuumhYdhRONRnWbXedqymaMMG0xA4RgCljv0ud
JrWK1YNGB7gl7/ANoqyy4ZODBUoH33qDR0NzkqwGXMIexlUZIjbwMmUPZZ/XBqMB
tEDrOxAnauE12K3DbfviE40Py8uloXiZf94RnPWbttGp874EOpyiEYjUooo3ii6G
jscqox0=
-----END ENCRYPTED PRIVATE KEY-----

View File

@ -69,6 +69,13 @@ openssl rsa -in 1024rsa.priv -pubout -out 1024rsa.pub
openssl pkcs8 -nocrypt -topk8 -in server-key.pem -out server-keyPkcs8.pem
**** To convert to pkcs8 encrypted *******
openssl pkcs8 -topk8 -in server-key.pem -out server-keyPkcs8Enc.pem
passwd: yassl123
**** To convert from pkcs8 to traditional ****
openssl pkcs8 -nocrypt -in server-keyPkcs8.pem -out server-key.pem

View File

@ -77,8 +77,20 @@ enum DN_Tags {
ASN_ORGUNIT_NAME = 0x0b /* OU */
};
enum PBES {
PBE_MD5_DES = 0,
PBE_SHA1_DES = 1
};
enum ENCRYPTION_TYPES {
DES_TYPE = 0
};
enum Misc_ASN {
ASN_NAME_MAX = 256,
ASN_NAME_MAX = 256,
MAX_SALT_SIZE = 64, /* MAX PKCS Salt length */
MAX_KEY_SIZE = 64, /* MAX PKCS Key length */
PKCS5 = 5, /* PKCS oid tag */
SHA_SIZE = 20,
RSA_INTS = 8, /* RSA ints in private key */
MIN_DATE_SIZE = 13,
@ -222,6 +234,7 @@ void FreeSigners(Signer*, void*);
int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32);
int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32);
int ToTraditional(byte* buffer, word32 length);
int ToTraditionalEnc(byte* buffer, word32 length, const char*, int);
#ifndef NO_DH
int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32);

View File

@ -29,6 +29,8 @@
#include "ctc_sha.h"
#include "ctc_md5.h"
#include "error.h"
#include "pwdbased.h"
#include "des3.h"
#ifdef HAVE_NTRU
#include "crypto_ntru.h"
@ -67,7 +69,7 @@ enum {
#define NO_TIME_H
/* since Micrium not defining XTIME or XGMTIME, CERT_GEN not available */
#elif defined(USER_TIME)
/* no <time.h> strucutres used */
/* no <time.h> structures used */
#define NO_TIME_H
/* user time, and gmtime compatible functions, there is a gmtime
implementation here that WINCE uses, so really just need some ticks
@ -342,6 +344,31 @@ int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
}
/* Get small count integer, 32 bits or less */
int GetShortInt(const byte* input, word32* inOutIdx, int* number)
{
word32 idx = *inOutIdx;
word32 len;
*number = 0;
if (input[idx++] != ASN_INTEGER)
return ASN_PARSE_E;
len = input[idx++];
if (len > 4)
return ASN_PARSE_E;
while (len--) {
*number = *number << 8 | input[idx++];
}
*inOutIdx = idx;
return *number;
}
/* May not have one, not an error */
int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
{
@ -489,6 +516,138 @@ int ToTraditional(byte* input, word32 sz)
}
/* Check To see if PKCS version algo is supported, set id if it is return 0
< 0 on error */
static int CheckAlgo(int version, int algo, int* id)
{
if (version != PKCS5)
return ASN_INPUT_E; /* VERSION ERROR */
switch (algo) {
case 3: /* see RFC 2898 for ids */
*id = PBE_MD5_DES;
return 0;
case 10:
*id = PBE_SHA1_DES;
return 0;
default:
return -1;
}
}
/* Decrypt intput in place from parameters based on id */
static int DecryptKey(const char* password, int passwordSz, byte* salt,
int saltSz, int iterations, int id, byte* input, int length)
{
byte key[MAX_KEY_SIZE];
int hashType;
int derivedLen;
int decryptionType;
switch (id) {
case PBE_MD5_DES:
hashType = MD5;
derivedLen = 16;
decryptionType = DES_TYPE;
break;
case PBE_SHA1_DES:
hashType = SHA;
derivedLen = 16;
decryptionType = DES_TYPE;
break;
default:
return -1; /* unknown algo id */
}
PBKDF1(key, (byte*)password, passwordSz, salt, saltSz, iterations,
derivedLen, hashType);
switch (decryptionType) {
case DES_TYPE:
{
Des dec;
Des_SetKey(&dec, key, key + 8, DES_DECRYPTION);
Des_CbcDecrypt(&dec, input, input, length);
break;
}
default:
return -1; /* unknown algo id */
}
return 0;
}
/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning
of input */
int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz)
{
word32 inOutIdx = 0, oid;
int type, algo, version, length, iterations, saltSz, id;
byte salt[MAX_SALT_SIZE];
if (GetSequence(input, &inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (sz - inOutIdx))
return ASN_INPUT_E;
if (GetAlgoId(input, &inOutIdx, &oid) < 0)
return ASN_PARSE_E;
version = input[inOutIdx - 2]; /* PKCS version alwyas 2nd to last byte */
algo = input[inOutIdx - 1]; /* version.algo, algo id last byte */
if (CheckAlgo(version, algo, &id) < 0)
return ASN_INPUT_E; /* Algo ID error */
if (GetSequence(input, &inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (sz - inOutIdx))
return ASN_INPUT_E;
if (input[inOutIdx++] != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(input, &inOutIdx, &saltSz) < 0)
return ASN_PARSE_E;
if (saltSz > MAX_SALT_SIZE)
return ASN_PARSE_E;
if ((word32)length > (sz - inOutIdx))
return ASN_INPUT_E;
XMEMCPY(salt, &input[inOutIdx], saltSz);
inOutIdx += saltSz;
if (GetShortInt(input, &inOutIdx, &iterations) < 0)
return ASN_PARSE_E;
if (input[inOutIdx++] != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(input, &inOutIdx, &length) < 0)
return ASN_PARSE_E;
if ((word32)length > (sz - inOutIdx))
return ASN_INPUT_E;
if (DecryptKey(password, passwordSz, salt, saltSz, iterations, id,
input + inOutIdx, length) < 0)
return ASN_INPUT_E; /* decrypt failure */
XMEMMOVE(input, input + inOutIdx, length);
return ToTraditional(input, length);
}
int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
@ -823,7 +982,7 @@ static int GetKey(DecodedCert* cert)
DYNAMIC_TYPE_PUBLIC_KEY);
if (cert->publicKey == NULL)
return MEMORY_E;
memcpy(cert->publicKey, keyBlob, keyLen);
XMEMCPY(cert->publicKey, keyBlob, keyLen);
cert->pubKeyStored = 1;
cert->pubKeySize = keyLen;
}
@ -861,7 +1020,7 @@ static int GetKey(DecodedCert* cert)
DYNAMIC_TYPE_PUBLIC_KEY);
if (cert->publicKey == NULL)
return MEMORY_E;
memcpy(cert->publicKey, &cert->source[cert->srcIdx], length - 1);
XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length - 1);
cert->pubKeyStored = 1;
cert->pubKeySize = length - 1;

1
ctaocrypt/src/ecc.c Normal file
View File

@ -0,0 +1 @@
/* dummy ecc.c for dist */

1
ctaocrypt/src/ecc_fp.c Normal file
View File

@ -0,0 +1 @@
/* dummy ecc_fp.c for dist */

View File

@ -255,10 +255,10 @@ enum Misc {
SIZEOF_SENDER = 4, /* clnt or srvr */
FINISHED_SZ = MD5_DIGEST_SIZE + SHA_DIGEST_SIZE,
MAX_RECORD_SIZE = 16384, /* 2^14, max size by standard */
MAX_UDP_SIZE = 1400, /* don't exceed MTU */
MAX_MSG_EXTRA = 68, /* max added to msg, mac + pad */
MAX_COMP_EXTRA = 1024, /* max compression extra */
MAX_MTU = 1500, /* max expected MTU */
MAX_UDP_SIZE = MAX_MTU - 100, /* don't exceed MTU w/ 100 byte header */
MAX_DH_SZ = 612, /* 2240 p, pub, g + 2 byte size for each */
MAX_STR_VERSION = 8, /* string rep of protocol version */
@ -1027,10 +1027,11 @@ enum {
typedef struct EncryptedInfo {
char name[NAME_SZ];
byte iv[IV_SZ];
word32 ivSz;
byte set;
char name[NAME_SZ];
byte iv[IV_SZ];
word32 ivSz;
byte set;
SSL_CTX* ctx;
} EncryptedInfo;

View File

@ -99,7 +99,8 @@
const char* eccCert = "../../certs/server-ecc.pem";
const char* eccKey = "../../certs/ecc-key.pem";
const char* svrCert = "../../certs/server-cert.pem";
const char* svrKey = "../../certs/server-key.pem";
//const char* svrKey = "../../certs/server-key.pem";
const char* svrKey = "../../certs/server-keyPkcs8Enc.pem";
const char* cliCert = "../../certs/client-cert.pem";
const char* cliKey = "../../certs/client-key.pem";
const char* ntruCert = "../../certs/ntru-cert.pem";
@ -109,7 +110,8 @@
static const char* eccCert = "../certs/server-ecc.pem";
static const char* eccKey = "../certs/ecc-key.pem";
static const char* svrCert = "../certs/server-cert.pem";
static const char* svrKey = "../certs/server-key.pem";
//static const char* svrKey = "../certs/server-key.pem";
static const char* svrKey = "../certs/server-keyPkcs8Enc.pem";
static const char* cliCert = "../certs/client-cert.pem";
static const char* cliKey = "../certs/client-key.pem";
static const char* ntruCert = "../certs/ntru-cert.pem";

View File

@ -168,7 +168,7 @@ static INLINE void c32to48(word32 in, byte out[6])
/* convert 16 bit integer to opaque */
static void INLINE c16toa(word16 u16, byte* c)
static INLINE void c16toa(word16 u16, byte* c)
{
c[0] = (u16 >> 8) & 0xff;
c[1] = u16 & 0xff;
@ -1832,8 +1832,6 @@ int DoApplicationData(SSL* ssl, byte* input, word32* inOutIdx)
ssl->hmac(ssl, verify, rawData, rawSz, application_data, 1);
#ifdef HAVE_LIBZ
byte decomp[MAX_RECORD_SIZE + MAX_COMP_EXTRA];
if (ssl->options.usingCompression) {
dataSz = DeCompress(ssl, rawData, dataSz, decomp, sizeof(decomp));
if (dataSz < 0) return dataSz;
@ -1976,7 +1974,9 @@ int ProcessReply(SSL* ssl)
{
int ret, type, readSz;
word32 startIdx = 0;
#ifndef NO_CYASSL_SERVER
byte b0, b1;
#endif
#ifdef CYASSL_DTLS
int used;
#endif
@ -3895,7 +3895,8 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
encSigSz = EncodeSignature(encodedSig,digest,digestSz,hashType);
if (encSigSz != ret || XMEMCMP(out, encodedSig, encSigSz) != 0)
if (encSigSz != (word32)ret || XMEMCMP(out, encodedSig,
encSigSz) != 0)
return VERIFY_SIGN_ERROR;
}
else {
@ -4900,7 +4901,7 @@ int SetCipherList(SSL_CTX* ctx, const char* list)
sigSz = EncodeSignature(encodedSig, digest, digestSz, hashType);
if (outLen == sigSz && XMEMCMP(out, encodedSig, sigSz) == 0)
if (outLen == (int)sigSz && XMEMCMP(out, encodedSig,sigSz) == 0)
ret = 0;
}
else {

View File

@ -29,7 +29,7 @@
/* if user writes own I/O callbacks they can define CYASSL_USER_IO to remove
automatic setting of default I/O functions EmbedSend() and EmbedReceive()
but they'll still nedd SetCallback xxx() at end of file
but they'll still need SetCallback xxx() at end of file
*/
#ifndef CYASSL_USER_IO

View File

@ -210,8 +210,11 @@ int SSL_shutdown(SSL* ssl)
}
int SSL_get_error(SSL* ssl, int dummy)
int SSL_get_error(SSL* ssl, int ret)
{
if (ret > 0)
return SSL_ERROR_NONE;
if (ssl->error == WANT_READ)
return SSL_ERROR_WANT_READ; /* convert to OpenSSL type */
else if (ssl->error == WANT_WRITE)
@ -360,7 +363,8 @@ static int AddCA(SSL_CTX* ctx, buffer der)
char* headerEnd;
char* footerEnd;
long neededSz;
int pkcs8 = 0;
int pkcs8 = 0;
int pkcs8Enc = 0;
int dynamicType;
if (type == CERT_TYPE || type == CA_TYPE) {
@ -383,10 +387,16 @@ static int AddCA(SSL_CTX* ctx, buffer der)
headerEnd = XSTRSTR((char*)buff, header);
if (headerEnd)
pkcs8 = 1;
/*
else
maybe encrypted "-----BEGIN ENCRYPTED PRIVATE KEY-----"
*/
else {
XSTRNCPY(header, "-----BEGIN ENCRYPTED PRIVATE KEY-----",
sizeof(header));
XSTRNCPY(footer, "-----END ENCRYPTED PRIVATE KEY-----",
sizeof(footer));
headerEnd = XSTRSTR((char*)buff, header);
if (headerEnd)
pkcs8Enc = 1;
}
}
if (!headerEnd && type == PRIVATEKEY_TYPE) { /* may be ecc */
XSTRNCPY(header, "-----BEGIN EC PRIVATE KEY-----", sizeof(header));
@ -470,10 +480,17 @@ static int AddCA(SSL_CTX* ctx, buffer der)
if (pkcs8)
return ToTraditional(der->buffer, der->length);
/* not full support yet
if (pkcs8Enc)
return ToTraditionalEnc(der->buffer, der->length);
*/
if (pkcs8Enc) {
int passwordSz;
char password[80];
if (!info->ctx->passwd_cb)
return SSL_BAD_FILE; /* no callback error */
passwordSz = info->ctx->passwd_cb(password, sizeof(password), 0,
info->ctx->userdata);
return ToTraditionalEnc(der->buffer, der->length, password,
passwordSz);
}
return 0;
}
@ -488,6 +505,7 @@ static int AddCA(SSL_CTX* ctx, buffer der)
int eccKey = 0;
info.set = 0;
info.ctx = ctx;
der.buffer = 0;
if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM
@ -502,9 +520,10 @@ static int AddCA(SSL_CTX* ctx, buffer der)
dynamicType = DYNAMIC_TYPE_KEY;
if (format == SSL_FILETYPE_PEM) {
if (PemToDer(buff, sz, type, &der, ctx->heap, &info, &eccKey) < 0) {
int ret = PemToDer(buff, sz, type, &der, ctx->heap, &info, &eccKey);
if (ret < 0) {
XFREE(der.buffer, ctx->heap, dynamicType);
return SSL_BAD_FILE;
return ret;
}
}
else { /* ASN1 (DER) or RAW (NTRU) */
@ -660,7 +679,7 @@ static int ProcessFile(SSL_CTX* ctx, const char* fname, int format, int type)
sz = XFTELL(file);
XREWIND(file);
if (sz > sizeof(staticBuffer)) {
if (sz > (long)sizeof(staticBuffer)) {
buffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
if (buffer == NULL) {
XFCLOSE(file);
@ -744,7 +763,7 @@ int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz)
if (ret == 0) {
if (converted.length < derSz) {
memcpy(derBuf, converted.buffer, converted.length);
XMEMCPY(derBuf, converted.buffer, converted.length);
ret = converted.length;
}
else
@ -1574,7 +1593,7 @@ int CyaSSL_set_compression(SSL* ssl)
for (i = 0; i < iovcnt; i++)
send += iov[i].iov_len;
if (send > sizeof(tmp)) {
if (send > (int)sizeof(tmp)) {
byte* tmp2 = (byte*) XMALLOC(send, ssl->heap,
DYNAMIC_TYPE_WRITEV);
if (!tmp2)