forked from wolfSSL/wolfssl
PKCS #5 v1.5 encrypted key adds, small build fixes
This commit is contained in:
11
certs/server-keyPkcs8Enc.pem
Normal file
11
certs/server-keyPkcs8Enc.pem
Normal 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-----
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
1
ctaocrypt/src/ecc.c
Normal file
@ -0,0 +1 @@
|
||||
/* dummy ecc.c for dist */
|
1
ctaocrypt/src/ecc_fp.c
Normal file
1
ctaocrypt/src/ecc_fp.c
Normal file
@ -0,0 +1 @@
|
||||
/* dummy ecc_fp.c for dist */
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
49
src/ssl.c
49
src/ssl.c
@ -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)
|
||||
|
Reference in New Issue
Block a user