add ecdsa cert signing

This commit is contained in:
toddouska
2013-11-14 15:00:22 -08:00
parent 7a1fb428d1
commit a7bcca84c3
6 changed files with 243 additions and 72 deletions

2
.gitignore vendored
View File

@ -46,6 +46,8 @@ testsuite/*.pem
testsuite/*.raw testsuite/*.raw
cert.der cert.der
cert.pem cert.pem
certecc.der
certecc.pem
othercert.der othercert.der
othercert.pem othercert.pem
key.der key.der

View File

@ -2241,7 +2241,7 @@ static word32 SetAlgoID(int algoOID, byte* output, int type)
static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x02, 0x02, 0x05, 0x00}; 0x02, 0x02, 0x05, 0x00};
/* sigTypes */ /* RSA sigTypes */
#ifndef NO_RSA #ifndef NO_RSA
static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x04, 0x05, 0x00}; 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00};
@ -2255,12 +2255,29 @@ static word32 SetAlgoID(int algoOID, byte* output, int type)
0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00}; 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00};
#endif /* NO_RSA */ #endif /* NO_RSA */
/* keyTypes */ /* ECDSA sigTypes */
#ifdef HAVE_ECC
static const byte shawECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
0x04, 0x01, 0x05, 0x00};
static const byte sha256wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
0x04, 0x03, 0x02, 0x05, 0x00};
static const byte sha384wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
0x04, 0x03, 0x03, 0x05, 0x00};
static const byte sha512wECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE,0x3d,
0x04, 0x03, 0x04, 0x05, 0x00};
#endif /* HAVE_ECC */
/* RSA keyType */
#ifndef NO_RSA #ifndef NO_RSA
static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00}; 0x01, 0x01, 0x01, 0x05, 0x00};
#endif /* NO_RSA */ #endif /* NO_RSA */
#ifdef HAVE_ECC
static const byte ECDSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0xCE, 0x3d,
0x04, 0x02, 0x05, 0x00};
#endif /* HAVE_ECC */
int algoSz = 0; int algoSz = 0;
word32 idSz, seqSz; word32 idSz, seqSz;
const byte* algoName = 0; const byte* algoName = 0;
@ -2332,6 +2349,27 @@ static word32 SetAlgoID(int algoOID, byte* output, int type)
algoName = sha512wRSA_AlgoID; algoName = sha512wRSA_AlgoID;
break; break;
#endif /* NO_RSA */ #endif /* NO_RSA */
#ifdef HAVE_ECC
case CTC_SHAwECDSA:
algoSz = sizeof(shawECDSA_AlgoID);
algoName = shawECDSA_AlgoID;
break;
case CTC_SHA256wECDSA:
algoSz = sizeof(sha256wECDSA_AlgoID);
algoName = sha256wECDSA_AlgoID;
break;
case CTC_SHA384wECDSA:
algoSz = sizeof(sha384wECDSA_AlgoID);
algoName = sha384wECDSA_AlgoID;
break;
case CTC_SHA512wECDSA:
algoSz = sizeof(sha512wECDSA_AlgoID);
algoName = sha512wECDSA_AlgoID;
break;
#endif /* HAVE_ECC */
default: default:
CYASSL_MSG("Unknown Signature Algo"); CYASSL_MSG("Unknown Signature Algo");
return 0; return 0;
@ -2345,6 +2383,12 @@ static word32 SetAlgoID(int algoOID, byte* output, int type)
algoName = RSA_AlgoID; algoName = RSA_AlgoID;
break; break;
#endif /* NO_RSA */ #endif /* NO_RSA */
#ifdef HAVE_ECC
case ECDSAk:
algoSz = sizeof(ECDSA_AlgoID);
algoName = ECDSA_AlgoID;
break;
#endif /* HAVE_ECC */
default: default:
CYASSL_MSG("Unknown Key Algo"); CYASSL_MSG("Unknown Key Algo");
return 0; return 0;
@ -3995,13 +4039,8 @@ static int SetName(byte* output, CertName* name)
} }
/* encode info from cert into DER enocder format */ /* encode info from cert into DER enocder format */
static int EncodeCert( static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng,
Cert* cert, const byte* ntruKey, word16 ntruSz)
DerCert* der,
RsaKey* rsaKey,
RNG* rng,
const byte* ntruKey,
word16 ntruSz)
{ {
(void)ntruKey; (void)ntruKey;
(void)ntruSz; (void)ntruSz;
@ -4153,12 +4192,15 @@ static int WriteCertBody(DerCert* der, byte* buffer)
/* Make RSA signature from buffer (sz), write to sig (sigSz) */ /* Make RSA signature from buffer (sz), write to sig (sigSz) */
static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
RsaKey* key, RNG* rng, int sigAlgoType) RsaKey* rsaKey, ecc_key* eccKey, RNG* rng,
int sigAlgoType)
{ {
byte digest[SHA256_DIGEST_SIZE]; /* max size */ byte digest[SHA256_DIGEST_SIZE]; /* max size */
byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
int encSigSz, digestSz, typeH; int encSigSz, digestSz, typeH;
(void)eccKey;
if (sigAlgoType == CTC_MD5wRSA) { if (sigAlgoType == CTC_MD5wRSA) {
Md5 md5; Md5 md5;
InitMd5(&md5); InitMd5(&md5);
@ -4167,7 +4209,7 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
digestSz = MD5_DIGEST_SIZE; digestSz = MD5_DIGEST_SIZE;
typeH = MD5h; typeH = MD5h;
} }
else if (sigAlgoType == CTC_SHAwRSA) { else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) {
Sha sha; Sha sha;
InitSha(&sha); InitSha(&sha);
ShaUpdate(&sha, buffer, sz); ShaUpdate(&sha, buffer, sz);
@ -4175,7 +4217,7 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
digestSz = SHA_DIGEST_SIZE; digestSz = SHA_DIGEST_SIZE;
typeH = SHAh; typeH = SHAh;
} }
else if (sigAlgoType == CTC_SHA256wRSA) { else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) {
Sha256 sha256; Sha256 sha256;
InitSha256(&sha256); InitSha256(&sha256);
Sha256Update(&sha256, buffer, sz); Sha256Update(&sha256, buffer, sz);
@ -4186,9 +4228,23 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
else else
return ALGO_ID_E; return ALGO_ID_E;
if (rsaKey) {
/* signature */ /* signature */
encSigSz = EncodeSignature(encSig, digest, digestSz, typeH); encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng); return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, rsaKey, rng);
}
#ifdef HAVE_ECC
else if (eccKey) {
word32 outSz = sigSz;
int ret = ecc_sign_hash(digest, digestSz, sig, &outSz, rng, eccKey);
if (ret != 0)
return ret;
return outSz;
}
#endif /* HAVE_ECC */
return ALGO_ID_E;
} }
@ -4257,7 +4313,8 @@ int MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
#endif /* HAVE_NTRU */ #endif /* HAVE_NTRU */
int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng) int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* rsaKey,
ecc_key* eccKey, RNG* rng)
{ {
byte sig[MAX_ENCODED_SIG_SZ]; byte sig[MAX_ENCODED_SIG_SZ];
int sigSz; int sigSz;
@ -4266,8 +4323,8 @@ int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
if (bodySz < 0) if (bodySz < 0)
return bodySz; return bodySz;
sigSz = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng, sigSz = MakeSignature(buffer, bodySz, sig, sizeof(sig), rsaKey, eccKey,
cert->sigType); rng, cert->sigType);
if (sigSz < 0) if (sigSz < 0)
return sigSz; return sigSz;
@ -4285,7 +4342,7 @@ int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
if (ret < 0) if (ret < 0)
return ret; return ret;
return SignCert(cert, buffer, buffSz, key, rng); return SignCert(cert, buffer, buffSz, key, NULL, rng);
} }

View File

@ -2487,17 +2487,27 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
#ifdef CYASSL_CERT_GEN #ifdef CYASSL_CERT_GEN
static const char* caKeyFile = "a:\\certs\\ca-key.der"; static const char* caKeyFile = "a:\\certs\\ca-key.der";
static const char* caCertFile = "a:\\certs\\ca-cert.pem"; static const char* caCertFile = "a:\\certs\\ca-cert.pem";
#ifdef HAVE_ECC
static const char* eccCaKeyFile = "a:\\certs\\ecc-key.der";
static const char* eccCaCertFile = "a:\\certs\\server-ecc.pem";
#endif
#endif #endif
#elif defined(CYASSL_MKD_SHELL) #elif defined(CYASSL_MKD_SHELL)
static char* clientKey = "certs/client-key.der"; static char* clientKey = "certs/client-key.der";
static char* clientCert = "certs/client-cert.der"; static char* clientCert = "certs/client-cert.der";
void set_clientKey(char *key) { clientKey = key ; } /* set by shell command */ void set_clientKey(char *key) { clientKey = key ; }
void set_clientCert(char *cert) { clientCert = cert ; } /* set by shell command */ void set_clientCert(char *cert) { clientCert = cert ; }
#ifdef CYASSL_CERT_GEN #ifdef CYASSL_CERT_GEN
static char* caKeyFile = "certs/ca-key.der"; static char* caKeyFile = "certs/ca-key.der";
static char* caCertFile = "certs/ca-cert.pem"; static char* caCertFile = "certs/ca-cert.pem";
void set_caKeyFile (char * key) { caKeyFile = key ; } /* set by shell command */ void set_caKeyFile (char * key) { caKeyFile = key ; }
void set_caCertFile(char * cert) { caCertFile = cert ; } /* set by shell command */ void set_caCertFile(char * cert) { caCertFile = cert ; }
#ifdef HAVE_ECC
static const char* eccCaKeyFile = "certs/ecc-key.der";
static const char* eccCaCertFile = "certs/server-ecc.pem";
void set_eccCaKeyFile (char * key) { eccCaKeyFile = key ; }
void set_eccCaCertFile(char * cert) { eccCaCertFile = cert ; }
#endif
#endif #endif
#else #else
static const char* clientKey = "./certs/client-key.der"; static const char* clientKey = "./certs/client-key.der";
@ -2505,6 +2515,10 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
#ifdef CYASSL_CERT_GEN #ifdef CYASSL_CERT_GEN
static const char* caKeyFile = "./certs/ca-key.der"; static const char* caKeyFile = "./certs/ca-key.der";
static const char* caCertFile = "./certs/ca-cert.pem"; static const char* caCertFile = "./certs/ca-cert.pem";
#ifdef HAVE_ECC
static const char* eccCaKeyFile = "./certs/ecc-key.der";
static const char* eccCaCertFile = "./certs/server-ecc.pem";
#endif
#endif #endif
#endif #endif
#endif #endif
@ -2788,7 +2802,7 @@ int rsa_test(void)
if (certSz < 0) if (certSz < 0)
return -407; return -407;
certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, &rng); certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, NULL, &rng);
if (certSz < 0) if (certSz < 0)
return -408; return -408;
@ -2820,6 +2834,94 @@ int rsa_test(void)
free(derCert); free(derCert);
FreeRsaKey(&caKey); FreeRsaKey(&caKey);
} }
#ifdef HAVE_ECC
/* ECC CA style */
{
ecc_key caKey;
Cert myCert;
byte* derCert;
byte* pem;
FILE* derFile;
FILE* pemFile;
int certSz;
int pemSz;
size_t bytes3;
word32 idx3 = 0;
FILE* file3 ;
#ifdef CYASSL_TEST_CERT
DecodedCert decode;
#endif
derCert = (byte*)malloc(FOURK_BUF);
if (derCert == NULL)
return -5311;
pem = (byte*)malloc(FOURK_BUF);
if (pem == NULL)
return -5312;
file3 = fopen(eccCaKeyFile, "rb");
if (!file3)
return -5412;
bytes3 = fread(tmp, 1, FOURK_BUF, file3);
fclose(file3);
ecc_init(&caKey);
ret = EccPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3);
if (ret != 0) return -5413;
InitCert(&myCert);
myCert.sigType = CTC_SHA256wECDSA;
strncpy(myCert.subject.country, "US", CTC_NAME_SIZE);
strncpy(myCert.subject.state, "OR", CTC_NAME_SIZE);
strncpy(myCert.subject.locality, "Portland", CTC_NAME_SIZE);
strncpy(myCert.subject.org, "wolfSSL", CTC_NAME_SIZE);
strncpy(myCert.subject.unit, "Development", CTC_NAME_SIZE);
strncpy(myCert.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(myCert.subject.email, "info@wolfssl.com", CTC_NAME_SIZE);
ret = SetIssuer(&myCert, eccCaCertFile);
if (ret < 0)
return -5405;
certSz = MakeCert(&myCert, derCert, FOURK_BUF, &key, &rng);
if (certSz < 0)
return -5407;
certSz = SignCert(&myCert, derCert, FOURK_BUF, NULL, &caKey, &rng);
if (certSz < 0)
return -5408;
#ifdef CYASSL_TEST_CERT
InitDecodedCert(&decode, derCert, certSz, 0);
ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0);
if (ret != 0)
return -5409;
FreeDecodedCert(&decode);
#endif
derFile = fopen("./certecc.der", "wb");
if (!derFile)
return -5410;
ret = (int)fwrite(derCert, certSz, 1, derFile);
fclose(derFile);
pemSz = DerToPem(derCert, certSz, pem, FOURK_BUF, CERT_TYPE);
if (pemSz < 0)
return -5411;
pemFile = fopen("./certecc.pem", "wb");
if (!pemFile)
return -5412;
ret = (int)fwrite(pem, pemSz, 1, pemFile);
fclose(pemFile);
free(pem);
free(derCert);
ecc_free(&caKey);
}
#endif /* HAVE_ECC */
#ifdef HAVE_NTRU #ifdef HAVE_NTRU
{ {
RsaKey caKey; RsaKey caKey;
@ -2900,7 +3002,7 @@ int rsa_test(void)
if (certSz < 0) if (certSz < 0)
return -456; return -456;
certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, &rng); certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, NULL, &rng);
if (certSz < 0) if (certSz < 0)
return -457; return -457;

View File

@ -391,9 +391,6 @@ CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
mp_int* s); mp_int* s);
CYASSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen, CYASSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,
mp_int* r, mp_int* s); mp_int* r, mp_int* s);
/* private key helpers */
CYASSL_API int EccPrivateKeyDecode(const byte* input,word32* inOutIdx,
ecc_key*,word32);
#endif #endif
#ifdef CYASSL_CERT_GEN #ifdef CYASSL_CERT_GEN

View File

@ -24,6 +24,7 @@
#define CTAO_CRYPT_ASN_PUBLIC_H #define CTAO_CRYPT_ASN_PUBLIC_H
#include <cyassl/ctaocrypt/types.h> #include <cyassl/ctaocrypt/types.h>
#include <cyassl/ctaocrypt/ecc.h>
#ifdef CYASSL_CERT_GEN #ifdef CYASSL_CERT_GEN
#include <cyassl/ctaocrypt/rsa.h> #include <cyassl/ctaocrypt/rsa.h>
#endif #endif
@ -63,6 +64,10 @@ enum Ctc_SigType {
#ifdef CYASSL_CERT_GEN #ifdef CYASSL_CERT_GEN
#ifndef HAVE_ECC
typedef struct ecc_key ecc_key;
#endif
enum Ctc_Misc { enum Ctc_Misc {
CTC_NAME_SIZE = 64, CTC_NAME_SIZE = 64,
CTC_DATE_SIZE = 32, CTC_DATE_SIZE = 32,
@ -121,7 +126,8 @@ typedef struct Cert {
*/ */
CYASSL_API void InitCert(Cert*); CYASSL_API void InitCert(Cert*);
CYASSL_API int MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*); CYASSL_API int MakeCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*);
CYASSL_API int SignCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, RNG*); CYASSL_API int SignCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
ecc_key*, RNG*);
CYASSL_API int MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*, CYASSL_API int MakeSelfCert(Cert*, byte* derBuffer, word32 derSz, RsaKey*,
RNG*); RNG*);
CYASSL_API int SetIssuer(Cert*, const char*); CYASSL_API int SetIssuer(Cert*, const char*);
@ -147,6 +153,12 @@ CYASSL_API int SetDatesBuffer(Cert*, const byte*, int);
word32 outputSz, int type); word32 outputSz, int type);
#endif #endif
#ifdef HAVE_ECC
/* private key helpers */
CYASSL_API int EccPrivateKeyDecode(const byte* input,word32* inOutIdx,
ecc_key*,word32);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@ -1045,6 +1045,50 @@ int CyaSSL_CertManagerUnloadCAs(CYASSL_CERT_MANAGER* cm)
} }
/* Return bytes written to buff or < 0 for error */
int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
int buffSz, const char* pass)
{
EncryptedInfo info;
int eccKey = 0;
int ret;
buffer der;
(void)pass;
CYASSL_ENTER("CyaSSL_KeyPemToDer");
if (pem == NULL || buff == NULL || buffSz <= 0) {
CYASSL_MSG("Bad pem der args");
return BAD_FUNC_ARG;
}
info.set = 0;
info.ctx = NULL;
info.consumed = 0;
der.buffer = NULL;
ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, &info, &eccKey);
if (ret < 0) {
CYASSL_MSG("Bad Pem To Der");
}
else {
if (der.length <= (word32)buffSz) {
XMEMCPY(buff, der.buffer, der.length);
ret = der.length;
}
else {
CYASSL_MSG("Bad der length");
ret = BAD_FUNC_ARG;
}
}
XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
return ret;
}
#endif /* !NO_CERTS */ #endif /* !NO_CERTS */
@ -10430,49 +10474,6 @@ static int initGlobalRNG = 0;
/* Return bytes written to buff or < 0 for error */
int CyaSSL_KeyPemToDer(const unsigned char* pem, int pemSz, unsigned char* buff,
int buffSz, const char* pass)
{
EncryptedInfo info;
int eccKey = 0;
int ret;
buffer der;
(void)pass;
CYASSL_ENTER("CyaSSL_KeyPemToDer");
if (pem == NULL || buff == NULL || buffSz <= 0) {
CYASSL_MSG("Bad pem der args");
return BAD_FUNC_ARG;
}
info.set = 0;
info.ctx = NULL;
info.consumed = 0;
der.buffer = NULL;
ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, &info, &eccKey);
if (ret < 0) {
CYASSL_MSG("Bad Pem To Der");
}
else {
if (der.length <= (word32)buffSz) {
XMEMCPY(buff, der.buffer, der.length);
ret = der.length;
}
else {
CYASSL_MSG("Bad der length");
ret = BAD_FUNC_ARG;
}
}
XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
return ret;
}
/* Load RSA from Der, SSL_SUCCESS on success < 0 on error */ /* Load RSA from Der, SSL_SUCCESS on success < 0 on error */
int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der, int derSz) int CyaSSL_RSA_LoadDer(CYASSL_RSA* rsa, const unsigned char* der, int derSz)