Compare Revisions

The credentials to download the source code are:
 Username: svnusers
 Password: svnusers

Ignore whitespace Rev 1911 → Rev 1912

/branches/Security/tools/itscertgen/certgen.c
12,6 → 12,7
#include <assert.h>
#include <limits.h>
#include <time.h>
#include <math.h>
 
// #define DEBUG_BOOKMARKS
 
86,7 → 87,7
static int attribute_assurance_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int attribute_aid_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int attribute_ssp_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int attribute_ssp_text (cxml_handler_t* const h, char * const text);
static int attribute_ssp_text (cxml_handler_t* const h, char * const text, int length);
 
static const cxml_taghandler_t h_attribute[] = {
{"public-key", attribute_public_key_tag, NULL, NULL },
131,9 → 132,9
};
static int certificate_version_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int certificate_version_text(cxml_handler_t* const h, char * const text);
static int certificate_version_text(cxml_handler_t* const h, char * const text, int length);
static int certificate_signer_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int certificate_signer_text(cxml_handler_t* const h, char * const text);
static int certificate_signer_text(cxml_handler_t* const h, char * const text, int length);
static int certificate_subject_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int certificate_validity_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
static int certificate_signature_tag (cxml_handler_t* const h, cxml_tag_t * const tag);
154,7 → 155,7
 
static int _Begin_Tag(cxml_handler_t* const h, cxml_tag_t * const tag);
static int _End_Tag(cxml_handler_t* const h, cxml_tag_t * const tag);
static int _Text(cxml_handler_t* const h, char * const text);
static int _Text(cxml_handler_t* const h, char * const text, int length);
 
 
static cxml_handler_class Class = {
192,7 → 193,7
static char *_profileName = NULL;
static const char *_signerName = NULL;
static unsigned int _defaultTime = 0;
static unsigned int _outFormat = 0; // binary by default
static ecc_format _outFormat = 0;
static const char * _outExtensions[] = {
"bin", "hex", "pem"
};
208,7 → 209,6
{
_outFormat = STR2ENUM(_outExtensions, opt->lopt);
if (_outFormat >= 0){
// printf("OutFormat=%s\n", _outExtensions[_outFormat]);
return 0;
}
return -1;
316,58 → 316,20
fclose(f);
}
if (h->verificationKey){
cvstrncpy(end-4, 16, ".v.", _outExtensions[_outFormat], NULL);
switch (_outFormat){
case 2: // PEM format
ecc_api_key_private_save(h->verificationKey, path);
break;
default:
{
FILE * f = fopen(path, "wb");
if (f){
int len = ecc_api_key_private(h->verificationKey, NULL);
char * p = malloc(len);
ecc_api_key_private(h->verificationKey, p);
if (_outFormat == 1){ // hex format
int i;
for (i = 0; i < len; i++){
fprintf(f, "%02X", (unsigned int)p[i]);
}
}
else{
fwrite(p, 1, len, f);
}
free(p);
fclose(f);
}
}}
if (_verificationKey == NULL){
cvstrncpy(end - 4, 16, ".v.prv.", _outExtensions[_outFormat], NULL);
ecc_api_key_private_save(h->verificationKey, path, _outFormat);
cvstrncpy(end - 4, 16, ".v.pub.", _outExtensions[_outFormat], NULL);
ecc_api_key_public_save(h->verificationKey, path, _outFormat);
}
}
if (h->encryptionKey){
cvstrncpy(end-4, 16, ".e.", _outExtensions[_outFormat], NULL);
switch (_outFormat){
case 2: // PEM format
ecc_api_key_private_save(h->encryptionKey, path);
break;
default:
{
FILE * f = fopen(path, "wb");
if (f){
int len = ecc_api_key_private(h->encryptionKey, NULL);
char * p = malloc(len);
ecc_api_key_private(h->encryptionKey, p);
if (_outFormat == 1){ // hex format
int i;
for (i = 0; i < len; i++){
fprintf(f, "%02X", (unsigned int)p[i]);
}
}
else{
fwrite(p, 1, len, f);
}
free(p);
fclose(f);
}
}}
if (_decriptionKey == NULL){
cvstrncpy(end - 4, 16, ".e.prv.", _outExtensions[_outFormat], NULL);
ecc_api_key_private_save(h->encryptionKey, path, _outFormat);
cvstrncpy(end - 4, 16, ".e.pub.", _outExtensions[_outFormat], NULL);
ecc_api_key_public_save(h->encryptionKey, path, _outFormat);
}
}
free(path);
}
392,7 → 354,7
return rc;
}
 
static int certificate_version_text(cxml_handler_t* const _h, char * const text)
static int certificate_version_text(cxml_handler_t* const _h, char * const text, int length)
{
cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h;
if(text){
477,7 → 439,7
return rc;
}
 
static int certificate_signer_text(cxml_handler_t* const h, char * const text)
static int certificate_signer_text(cxml_handler_t* const h, char * const text, int length)
{ return 0;}
 
static const char * _subject_type [] = {
555,12 → 517,30
}else{
switch(h->sa_type){
case 0: // verification_key
h->verificationKey = h->key;
h->key = NULL;
if (_verificationKey){
h->verificationKey = ecc_api_key_public_load(_verificationKey);
if (h->verificationKey == NULL){
fprintf(stderr, "%s: Can't load verification pulic key\n", _verificationKey);
return -1;
}
}
else{
h->verificationKey = h->key;
h->key = NULL;
}
break;
case 1: // encryption_key
h->encryptionKey = h->key;
h->key = NULL;
if (_decriptionKey){
h->encryptionKey = ecc_api_key_public_load(_decriptionKey);
if (h->encryptionKey == NULL){
fprintf(stderr, "%s: Can't load decription pulic key\n", _decriptionKey);
return -1;
}
}
else{
h->encryptionKey = h->key;
h->key = NULL;
}
break;
case 32: //its_aid_list
case 33: //its_aid_ssp_list
744,13 → 724,13
}
return rc;
}
static int attribute_ssp_text (cxml_handler_t* const _h, char * const text)
 
static int attribute_ssp_text(cxml_handler_t* const _h, char * const text, int length)
{
int rc=0;
int len = cstrlen(text);
if(len){
if(text && length){
cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h;
rc = cbuf_write(text, len, &h->ptr, h->end, NULL);
rc = cbuf_write(text, length, &h->ptr, h->end, NULL);
}
return rc;
}
966,6 → 946,7
int rc = 0;
if (cxml_tag_is_open(tag)){
int32_t lat, lon;
long double d;
cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h;
const char * v = cxml_tag_attr_value(tag, "latitude");
if(v == NULL){
972,7 → 953,9
fprintf(stderr, "ERROR: Latitude shall be specified for location.\n");
return -1;
}
lat = strtol(v, NULL, 0);
d = strtold(v, NULL);
if (d <= 90.0 && d >= -90.0) d *= 10000000.0; // degree
lat = (int32_t)floorl(d);
 
v = cxml_tag_attr_value(tag, "longitude");
if(v == NULL){
979,8 → 962,10
fprintf(stderr, "ERROR: Longitude shall be specified for location.\n");
return -1;
}
lon = strtol(v, NULL, 0);
d = strtold(v, NULL);
if (d <= 180.0 && d >= -180.0) d *= 10000000.0; // degree
lon = (int32_t)floorl(d);
 
cint32_write(lat, &h->ptr, h->end, &rc);
cint32_write(lon, &h->ptr, h->end, &rc);
}
1065,44 → 1050,40
return -1;
}
}else{
const char * v = cxml_tag_attr_value(tag, "algorithm");
if (v){
alg = STR2ENUM(_signature_algorithms, v);
if (alg < 0){
fprintf(stderr, "%s: Unknown signature algorithm\n", v);
return -1;
}
}
 
if (h->signer == NULL){
fprintf(stderr, "ERROR: Signer certificate name shall be provided\n");
return -1;
}
 
// load signer certificate
char * binkey;
int plen = strlen(_searchPath) + strlen(h->signer);
char * path = malloc(plen + 16);
 
cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".v.bin", NULL);
if (cstraload(&binkey, path)){
key = ecc_api_key_init(ecdsa_nistp256_with_sha256, aes_128_ccm, binkey);
cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".v.prv.pem", NULL);
key = ecc_api_key_private_load(path);
if (key == NULL){
cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".v.prv.bin", NULL);
key = ecc_api_key_private_load(path);
if (key == NULL){
fprintf(stderr, "%s: Could not load issuing private key from binary file\n", path);
free(path);
free(binkey);
return -1;
cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".v.prv.hex", NULL);
key = ecc_api_key_private_load(path);
if (key == NULL){
fprintf(stderr, "%s: Could not load issuing private key\n", path);
free(path);
return -1;
}
}
}
else {
cvstrncpy(path, plen + 16, _searchPath, "/", h->signer, ".v.pem", NULL);
key = ecc_api_key_private_load(path);
if (!key){
fprintf(stderr, "%s: Could not load issuing private key from file\n", path);
free(path);
return -1;
}
}
}
const char * v = cxml_tag_attr_value(tag, "algorithm");
if(v){
alg = STR2ENUM(_signature_algorithms, v);
if(alg < 0){
fprintf(stderr, "%s: Unknown signature algorithm\n", v);
return -1;
}
}
cint8_write(alg, &h->ptr, h->end, &rc);
rc = ecc_sign(key, h->buf, h->ptr-h->buf-1, &h->ptr, h->end-h->ptr);
}
1119,5 → 1100,5
{
return 0;
}
static int _Text(cxml_handler_t* const h, char * const text)
static int _Text(cxml_handler_t* const h, char * const text, int length)
{return 0;}
/branches/Security/tools/itscertgen/cxml/cxml.c
243,7 → 243,7
*e = 0;
ret = cxml_text_decode(h, b, e-b);
if(0 <= ret ){
ret = h->Class->text(h, b);
ret = h->Class->text(h, b, ret);
}
*e = ch;
}
/branches/Security/tools/itscertgen/cxml/cxml.h
47,7 → 47,7
 
typedef int (cxml_doc_f)(cxml_handler_t* const h, int rc);
typedef int (cxml_tag_f)(cxml_handler_t* const h, cxml_tag_t * const tag);
typedef int (cxml_text_f)(cxml_handler_t* const h, char * const text);
typedef int (cxml_text_f)(cxml_handler_t* const h, char * const text, int length);
 
typedef void * (cxml_alloc_f)(unsigned int);
typedef void (cxml_free_f)(void *);
/branches/Security/tools/itscertgen/ecc_api.h
18,13 → 18,21
aes_128_ccm
}ecc_sym_algorithm;
 
typedef enum {
ecc_bin,
ecc_hex,
ecc_pem
}ecc_format;
 
void * ecc_api_key_gen (ecc_pk_algorithm pk_alg, ecc_sym_algorithm sym_alg);
void * ecc_api_key_init(ecc_pk_algorithm pk_alg, ecc_sym_algorithm sym_alg, const char* pkey);
void ecc_api_key_free(void*);
int ecc_api_key_private(void*, char* buf);
int ecc_api_key_public(void*, char* x, char* y);
int ecc_api_key_private_save(void*, const char* path);
int ecc_api_key_private_save(void*, const char* path, ecc_format format);
void * ecc_api_key_private_load(const char* path);
int ecc_api_key_public_save(void*, const char* path, ecc_format format);
void * ecc_api_key_public_load(const char* path);
 
#define sha256_hash_size 32
int sha256_calculate(char* hash, const char * ptr, int len);
/branches/Security/tools/itscertgen/ecc_openssl.c
1,74 → 1,75
#include "ecc_api.h"
 
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/ecdsa.h>
 
static const int _NIDS[] = {
NID_secp256k1,
NID_secp256k1
};
 
static EVP_PKEY_CTX *pctx[sizeof(_NIDS) / sizeof(_NIDS[0])] = { NULL };
static EVP_PKEY_CTX *kctx[sizeof(_NIDS) / sizeof(_NIDS[0])] = { NULL };
static EVP_PKEY *params[sizeof(_NIDS) / sizeof(_NIDS[0])] = { NULL };
 
int ecc_api_init()
{
int i;
int rc = -1;
for (i = 0; i < sizeof(_NIDS) / sizeof(_NIDS[0]); i++){
/* Create the context for generating the parameters */
pctx[i] = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
if (pctx[i]){
if (EVP_PKEY_paramgen_init(pctx[i])){
/* Set the paramgen parameters according to the type */
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx[i], _NIDS[i])){
/* Generate parameters */
if (EVP_PKEY_paramgen(pctx[i], &params[i])) {
/* Create context for the key generation */
kctx[i] = EVP_PKEY_CTX_new(params[i], NULL);
if (kctx[i]){
if (EVP_PKEY_keygen_init(kctx[i])){
rc = 0;
continue;
}
}
}
}
}
}
ERR_print_errors_fp(stderr);
if (kctx[i])EVP_PKEY_CTX_free(kctx[i]); kctx[i] = NULL;
if (params[i])EVP_PKEY_free(params[i]); params[i] = NULL;
if (pctx[i])EVP_PKEY_CTX_free(pctx[i]); pctx[i] = NULL;
}
return rc;
}
 
int ecc_api_done()
{
int i;
for (i = 0; i < sizeof(_NIDS) / sizeof(_NIDS[0]); i++){
if (kctx[i])EVP_PKEY_CTX_free(kctx[i]); kctx[i] = NULL;
if (params[i])EVP_PKEY_free(params[i]); params[i] = NULL;
if (pctx[i])EVP_PKEY_CTX_free(pctx[i]); pctx[i] = NULL;
}
return 0;
}
 
void * ecc_api_key_gen(ecc_pk_algorithm pk_alg, ecc_sym_algorithm sym_alg)
{
EVP_PKEY * key = NULL;
if (!EVP_PKEY_keygen(kctx[pk_alg], &key)){
ERR_print_errors_fp(stderr);
}
return (void*)key;
}
#include "ecc_api.h"
 
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/ec.h>
#include <openssl/pem.h>
#include <openssl/sha.h>
#include <openssl/ecdsa.h>
#include <string.h>
 
static const int _NIDS[] = {
NID_secp256k1,
NID_secp256k1
};
 
static EVP_PKEY_CTX *pctx[sizeof(_NIDS) / sizeof(_NIDS[0])] = { NULL };
static EVP_PKEY_CTX *kctx[sizeof(_NIDS) / sizeof(_NIDS[0])] = { NULL };
static EVP_PKEY *params[sizeof(_NIDS) / sizeof(_NIDS[0])] = { NULL };
 
int ecc_api_init()
{
int i;
int rc = -1;
for (i = 0; i < sizeof(_NIDS) / sizeof(_NIDS[0]); i++){
/* Create the context for generating the parameters */
pctx[i] = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
if (pctx[i]){
if (EVP_PKEY_paramgen_init(pctx[i])){
/* Set the paramgen parameters according to the type */
if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx[i], _NIDS[i])){
/* Generate parameters */
if (EVP_PKEY_paramgen(pctx[i], &params[i])) {
/* Create context for the key generation */
kctx[i] = EVP_PKEY_CTX_new(params[i], NULL);
if (kctx[i]){
if (EVP_PKEY_keygen_init(kctx[i])){
rc = 0;
continue;
}
}
}
}
}
}
ERR_print_errors_fp(stderr);
if (kctx[i])EVP_PKEY_CTX_free(kctx[i]); kctx[i] = NULL;
if (params[i])EVP_PKEY_free(params[i]); params[i] = NULL;
if (pctx[i])EVP_PKEY_CTX_free(pctx[i]); pctx[i] = NULL;
}
return rc;
}
 
int ecc_api_done()
{
int i;
for (i = 0; i < sizeof(_NIDS) / sizeof(_NIDS[0]); i++){
if (kctx[i])EVP_PKEY_CTX_free(kctx[i]); kctx[i] = NULL;
if (params[i])EVP_PKEY_free(params[i]); params[i] = NULL;
if (pctx[i])EVP_PKEY_CTX_free(pctx[i]); pctx[i] = NULL;
}
return 0;
}
 
void * ecc_api_key_gen(ecc_pk_algorithm pk_alg, ecc_sym_algorithm sym_alg)
{
EVP_PKEY * key = NULL;
if (!EVP_PKEY_keygen(kctx[pk_alg], &key)){
ERR_print_errors_fp(stderr);
}
return (void*)key;
}
 
void * ecc_api_key_init(ecc_pk_algorithm pk_alg, ecc_sym_algorithm sym_alg, const char* pkey)
{
EVP_PKEY * key = NULL;
78,7 → 79,7
if (eckey){
if (EC_KEY_set_private_key(eckey, bn)){
EC_POINT * point;
EC_GROUP * group;
const EC_GROUP * group;
group = EC_KEY_get0_group(eckey);
point = EC_POINT_new(group);
if (EC_POINT_mul(group, point, bn, NULL, NULL, NULL)){
97,139 → 98,303
BN_free(bn);
return (void*)key;
}
 
void ecc_api_key_free(void* key)
{
EVP_PKEY_free((EVP_PKEY*)key);
}
 
int ecc_api_key_private(void* key, char* buf)
{
int len = -1;
const EC_KEY * eckey;
eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY*)key);
if(eckey){
const BIGNUM * ecbn;
ecbn = EC_KEY_get0_private_key(eckey);
if(ecbn){
len = BN_num_bytes(ecbn);
if(buf){
BN_bn2bin(ecbn, (unsigned char*)buf);
}
}
}
return len;
}
int ecc_api_key_public(void* key, char * px, char * py)
{
const EC_KEY * eckey;
const EC_GROUP * ecgroup;
const EC_POINT * ecpoint;
BIGNUM x, y;
int bcount = -1;
eckey = EVP_PKEY_get1_EC_KEY(key);
ecgroup = EC_KEY_get0_group(eckey);
ecpoint = EC_KEY_get0_public_key(eckey);
 
//fill public key data
BN_init(&x); BN_init(&y);
if(EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint, &x, &y, NULL)){
bcount = BN_num_bytes(&x);
if(px){
BN_bn2bin(&x, (unsigned char*)px);
}
 
bcount = BN_num_bytes(&y);
if(py){
BN_bn2bin(&x, (unsigned char*)py);
}
}
BN_clear_free(&x); BN_clear_free(&y);
return bcount;
}
 
static int _pass_cb(char *buf, int size, int rwflag, void *u)
{
fprintf(stderr, "Ask for a pass phrase");
return 0;
}
int ecc_api_key_private_save(void* key, const char* path)
{
int rc = -1;
FILE * f = fopen(path, "wb");
if(f){
rc = PEM_write_PKCS8PrivateKey(f, key, NULL, NULL, 0, _pass_cb, NULL);
fclose(f);
if(!rc){
ERR_print_errors_fp(stderr);
remove(path);
rc = -1;
}
}else{
perror(path);
}
return rc;
}
 
void * ecc_api_key_private_load(const char* path)
{
EVP_PKEY * key = NULL;
FILE * f = fopen(path, "rb");
if(f){
key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
fclose(f);
}
return key;
}
 
int sha256_calculate(char* hash, const char * ptr, int len)
{
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, ptr, len);
SHA256_Final((unsigned char*)hash, &ctx);
return 0;
}
 
int ecc_sign(void * key, const char * data, int length, char ** psig, int maxsize)
{
EC_KEY * eckey;
unsigned char *sig = (unsigned char *)*psig;
 
if (65 <= maxsize){
eckey = EC_KEY_dup(EVP_PKEY_get1_EC_KEY(key));
if(eckey){
unsigned char hash[32];
ECDSA_SIG * ecdsa;
SHA256_CTX ctx;
BIGNUM *kinv = NULL;
BIGNUM *rp = NULL;
 
SHA256_Init(&ctx);
SHA256_Update(&ctx, data, length);
SHA256_Final(hash, &ctx);
 
if (ECDSA_sign_setup(eckey, NULL, &kinv, &rp)){
ecdsa = ECDSA_do_sign_ex(hash, 32, kinv, rp, eckey);
EC_KEY_free(eckey);
BN_clear_free(kinv);
BN_clear_free(rp);
if (ecdsa){
int bcount;
*(sig++) = 0; // x_coordinate_only
bcount = BN_num_bytes(ecdsa->r);
BN_bn2bin(ecdsa->r, sig);
sig += bcount;
bcount = BN_num_bytes(ecdsa->s);
BN_bn2bin(ecdsa->s, sig);
sig += bcount;
ECDSA_SIG_free(ecdsa);
*psig = (char*)sig;
return 0;
}
}
}
}
return -1;
}
 
void ecc_api_key_free(void* key)
{
EVP_PKEY_free((EVP_PKEY*)key);
}
 
int ecc_api_key_private(void* key, char* buf)
{
int len = -1;
const EC_KEY * eckey;
eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY*)key);
if(eckey){
const BIGNUM * ecbn;
ecbn = EC_KEY_get0_private_key(eckey);
if(ecbn){
len = BN_num_bytes(ecbn);
if(buf){
BN_bn2bin(ecbn, (unsigned char*)buf);
}
}
}
return len;
}
int ecc_api_key_public(void* key, char * px, char * py)
{
const EC_KEY * eckey;
const EC_GROUP * ecgroup;
const EC_POINT * ecpoint;
BIGNUM x, y;
int bcount = -1;
eckey = EVP_PKEY_get1_EC_KEY(key);
ecgroup = EC_KEY_get0_group(eckey);
ecpoint = EC_KEY_get0_public_key(eckey);
 
//fill public key data
BN_init(&x); BN_init(&y);
if(EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint, &x, &y, NULL)){
bcount = BN_num_bytes(&x);
if(px){
BN_bn2bin(&x, (unsigned char*)px);
}
 
bcount = BN_num_bytes(&y);
if(py){
BN_bn2bin(&x, (unsigned char*)py);
}
}
BN_clear_free(&x); BN_clear_free(&y);
return bcount;
}
 
static int _pass_cb(char *buf, int size, int rwflag, void *u)
{
fprintf(stderr, "Ask for a pass phrase");
return 0;
}
int ecc_api_key_private_save(void* key, const char* path, ecc_format format)
{
int rc = -1;
FILE * f = fopen(path, "wb");
if(f){
if (format == ecc_pem){
rc = PEM_write_PKCS8PrivateKey(f, key, NULL, NULL, 0, _pass_cb, NULL) ? 0 : -1;
if (rc < 0){
ERR_print_errors_fp(stderr);
}
}
else{
const EC_KEY * eckey;
eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY*)key);
if (eckey){
const BIGNUM * ecbn;
ecbn = EC_KEY_get0_private_key(eckey);
if (ecbn){
char * buf = NULL;
int len = BN_num_bytes(ecbn);
if (format == ecc_bin){
buf = (char *)OPENSSL_malloc(len);
BN_bn2bin(ecbn, buf);
rc = 0;
}
else if (format == ecc_hex){
buf = BN_bn2hex(ecbn);
len = strlen(buf);
rc = 0;
}
if (buf){
rc = (len == fwrite(buf, 1, len, f)) ? 0 : -1;
OPENSSL_free(buf);
}
}
}
}
fclose(f);
if (rc < 0){
ERR_print_errors_fp(stderr);
remove(path);
rc = -1;
}
}
else{
perror(path);
}
return rc;
}
 
void * ecc_api_key_private_load(const char* path)
{
EVP_PKEY * key = NULL;
FILE * f = fopen(path, "rb");
if (f){
key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
if (key == NULL){
BIGNUM * bn = NULL;
fseek(f, 0, SEEK_END);
int len = ftell(f);
fseek(f, 0, SEEK_SET);
char * buf = OPENSSL_malloc(len + 1);
if (len == fread(buf, 1, len, f)){
buf[len] = 0;
// try hex first
if (len != BN_hex2bn(&bn, buf)){
if (bn){
BN_free(bn); bn = NULL;
}
bn = BN_bin2bn(buf, len, NULL);
}
}
OPENSSL_free(buf);
if (bn){
EC_KEY * eckey = EC_KEY_new_by_curve_name(_NIDS[0]);
if (eckey){
if (EC_KEY_set_private_key(eckey, bn)){
EC_POINT * point;
const EC_GROUP * group;
group = EC_KEY_get0_group(eckey);
point = EC_POINT_new(group);
if (EC_POINT_mul(group, point, bn, NULL, NULL, NULL)){
EC_KEY_set_public_key(eckey, point);
key = EVP_PKEY_new();
EVP_PKEY_assign_EC_KEY(key, eckey);
eckey = NULL;
}
EC_POINT_free(point);
}
if (eckey)EC_KEY_free(eckey);
}
BN_free(bn);
}
}
fclose(f);
}
return key;
}
 
int ecc_api_key_public_save(void* key , const char* path, ecc_format format)
{
int rc = -1;
FILE * f = fopen(path, "wb");
if (f){
const EC_KEY * eckey;
eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY*)key);
if (eckey){
if (format == ecc_pem){
rc = PEM_write_EC_PUBKEY(f, eckey) ? 0 : -1;
}
else{
size_t len;
char * buf = NULL;
const EC_POINT * point = EC_KEY_get0_public_key(eckey);
const EC_GROUP * group = EC_KEY_get0_group(eckey);
 
if (format == ecc_hex){
buf = EC_POINT_point2hex(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL);
len = strlen(buf);
}
else if (format == ecc_bin){
len = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
if (len > 0){
buf = OPENSSL_malloc(len + 1);
if (len != EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, buf, len, NULL)){
OPENSSL_free(buf); buf = NULL;
}
}
}
if (buf){
if (len == fwrite(buf, 1, len, f)){
rc = 0;
}
OPENSSL_free(buf); buf = NULL;
}
}
}
fclose(f);
if (rc < 0){
ERR_print_errors_fp(stderr);
remove(path);
}
}
else{
perror(path);
}
return rc;
}
 
void * ecc_api_key_public_load(const char* path, ecc_pk_algorithm pk_alg)
{
EVP_PKEY * key = NULL;
FILE * f = fopen(path, "rb");
if (f){
key = PEM_read_PUBKEY(f, &key, NULL, NULL);
if (key == NULL){
fseek(f, 0, SEEK_END);
int len = ftell(f);
fseek(f, 0, SEEK_SET);
char * buf = OPENSSL_malloc(len + 1);
if (len == fread(buf, 1, len, f)){
buf[len] = 0;
 
EC_KEY * eckey = EC_KEY_new_by_curve_name(_NIDS[pk_alg]);
if (eckey){
// try load hex
EC_POINT * point = NULL;
const EC_GROUP * group = EC_KEY_get0_group(eckey);
// try hex first
point = EC_POINT_hex2point(group, buf, NULL, NULL);
if (point == NULL){
// try oct
point = EC_POINT_oct2point(group, NULL, buf, len, NULL);
}
if (point){
EC_KEY_set_public_key(eckey, point);
EC_POINT_free(point);
key = EVP_PKEY_new();
EVP_PKEY_assign_EC_KEY(key, eckey);
eckey = NULL;
}
else{
EC_KEY_free(eckey);
}
}
}
OPENSSL_free(buf);
}
fclose(f);
}
return key;
}
 
int sha256_calculate(char* hash, const char * ptr, int len)
{
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, ptr, len);
SHA256_Final((unsigned char*)hash, &ctx);
return 0;
}
 
int ecc_sign(void * key, const char * data, int length, char ** psig, int maxsize)
{
EC_KEY * eckey;
unsigned char *sig = (unsigned char *)*psig;
 
if (65 <= maxsize){
eckey = EC_KEY_dup(EVP_PKEY_get1_EC_KEY(key));
if(eckey){
unsigned char hash[32];
ECDSA_SIG * ecdsa;
SHA256_CTX ctx;
BIGNUM *kinv = NULL;
BIGNUM *rp = NULL;
 
SHA256_Init(&ctx);
SHA256_Update(&ctx, data, length);
SHA256_Final(hash, &ctx);
 
if (ECDSA_sign_setup(eckey, NULL, &kinv, &rp)){
ecdsa = ECDSA_do_sign_ex(hash, 32, kinv, rp, eckey);
EC_KEY_free(eckey);
BN_clear_free(kinv);
BN_clear_free(rp);
if (ecdsa){
int bcount;
*(sig++) = 0; // x_coordinate_only
bcount = BN_num_bytes(ecdsa->r);
BN_bn2bin(ecdsa->r, sig);
sig += bcount;
bcount = BN_num_bytes(ecdsa->s);
BN_bn2bin(ecdsa->s, sig);
sig += bcount;
ECDSA_SIG_free(ecdsa);
*psig = (char*)sig;
return 0;
}
}
}
}
return -1;
}
/branches/Security/tools/itscertgen/itscertgen.vcxproj
14,6 → 14,9
<ClCompile Include="applink.c" />
<ClCompile Include="certgen.c" />
<ClCompile Include="ecc_openssl.c" />
<ClCompile Include="ecc_openssl_ec.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="mkgmtime.c" />
</ItemGroup>
<ItemGroup>