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
cert.der
cert.pem
certecc.der
certecc.pem
othercert.der
othercert.pem
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,
0x02, 0x02, 0x05, 0x00};
/* sigTypes */
/* RSA sigTypes */
#ifndef NO_RSA
static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
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};
#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
static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00};
#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;
word32 idSz, seqSz;
const byte* algoName = 0;
@ -2332,6 +2349,27 @@ static word32 SetAlgoID(int algoOID, byte* output, int type)
algoName = sha512wRSA_AlgoID;
break;
#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:
CYASSL_MSG("Unknown Signature Algo");
return 0;
@ -2345,6 +2383,12 @@ static word32 SetAlgoID(int algoOID, byte* output, int type)
algoName = RSA_AlgoID;
break;
#endif /* NO_RSA */
#ifdef HAVE_ECC
case ECDSAk:
algoSz = sizeof(ECDSA_AlgoID);
algoName = ECDSA_AlgoID;
break;
#endif /* HAVE_ECC */
default:
CYASSL_MSG("Unknown Key Algo");
return 0;
@ -3995,13 +4039,8 @@ static int SetName(byte* output, CertName* name)
}
/* encode info from cert into DER enocder format */
static int EncodeCert(
Cert* cert,
DerCert* der,
RsaKey* rsaKey,
RNG* rng,
const byte* ntruKey,
word16 ntruSz)
static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, RNG* rng,
const byte* ntruKey, word16 ntruSz)
{
(void)ntruKey;
(void)ntruSz;
@ -4153,12 +4192,15 @@ static int WriteCertBody(DerCert* der, byte* buffer)
/* Make RSA signature from buffer (sz), write to sig (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 encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ];
int encSigSz, digestSz, typeH;
(void)eccKey;
if (sigAlgoType == CTC_MD5wRSA) {
Md5 md5;
InitMd5(&md5);
@ -4167,7 +4209,7 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
digestSz = MD5_DIGEST_SIZE;
typeH = MD5h;
}
else if (sigAlgoType == CTC_SHAwRSA) {
else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) {
Sha sha;
InitSha(&sha);
ShaUpdate(&sha, buffer, sz);
@ -4175,7 +4217,7 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
digestSz = SHA_DIGEST_SIZE;
typeH = SHAh;
}
else if (sigAlgoType == CTC_SHA256wRSA) {
else if (sigAlgoType == CTC_SHA256wRSA || sigAlgoType == CTC_SHA256wECDSA) {
Sha256 sha256;
InitSha256(&sha256);
Sha256Update(&sha256, buffer, sz);
@ -4186,9 +4228,23 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz,
else
return ALGO_ID_E;
/* signature */
encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
return RsaSSL_Sign(encSig, encSigSz, sig, sigSz, key, rng);
if (rsaKey) {
/* signature */
encSigSz = EncodeSignature(encSig, digest, digestSz, typeH);
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 */
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];
int sigSz;
@ -4266,8 +4323,8 @@ int SignCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
if (bodySz < 0)
return bodySz;
sigSz = MakeSignature(buffer, bodySz, sig, sizeof(sig), key, rng,
cert->sigType);
sigSz = MakeSignature(buffer, bodySz, sig, sizeof(sig), rsaKey, eccKey,
rng, cert->sigType);
if (sigSz < 0)
return sigSz;
@ -4285,7 +4342,7 @@ int MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, RsaKey* key, RNG* rng)
if (ret < 0)
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
static const char* caKeyFile = "a:\\certs\\ca-key.der";
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
#elif defined(CYASSL_MKD_SHELL)
static char* clientKey = "certs/client-key.der";
static char* clientCert = "certs/client-cert.der";
void set_clientKey(char *key) { clientKey = key ; } /* set by shell command */
void set_clientCert(char *cert) { clientCert = cert ; } /* set by shell command */
void set_clientKey(char *key) { clientKey = key ; }
void set_clientCert(char *cert) { clientCert = cert ; }
#ifdef CYASSL_CERT_GEN
static char* caKeyFile = "certs/ca-key.der";
static char* caCertFile = "certs/ca-cert.pem";
void set_caKeyFile (char * key) { caKeyFile = key ; } /* set by shell command */
void set_caCertFile(char * cert) { caCertFile = cert ; } /* set by shell command */
void set_caKeyFile (char * key) { caKeyFile = key ; }
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
#else
static const char* clientKey = "./certs/client-key.der";
@ -2505,6 +2515,10 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
#ifdef CYASSL_CERT_GEN
static const char* caKeyFile = "./certs/ca-key.der";
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
@ -2788,7 +2802,7 @@ int rsa_test(void)
if (certSz < 0)
return -407;
certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, &rng);
certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, NULL, &rng);
if (certSz < 0)
return -408;
@ -2820,6 +2834,94 @@ int rsa_test(void)
free(derCert);
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
{
RsaKey caKey;
@ -2900,7 +3002,7 @@ int rsa_test(void)
if (certSz < 0)
return -456;
certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, &rng);
certSz = SignCert(&myCert, derCert, FOURK_BUF, &caKey, NULL, &rng);
if (certSz < 0)
return -457;

View File

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

View File

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