certgen.c 30.2 KB
Newer Older
		const char * v;

		// region dictionary. use 0 by default
		v = cxml_tag_attr_value(tag, "dictionary");
		if(v == NULL)v = cxml_tag_attr_value(tag, "dict");
		if(v){
			value = STR2ENUM(_id_dictionaries, v);
			if(value<0){
				fprintf(stderr, "%s: Unknown dictionary type\n", v);
				return -1;
			}
		}
		if(cint8_write(value, &h->ptr, h->end, NULL)){
			return -1;
		}
			
		v = cxml_tag_attr_value(tag, "id");
		if(v == NULL){
			fprintf(stderr, "ERROR: Region identifier must be set\n");
			return -1;
		}
		while(isspace(*v))v++;
		uvalue = strtoul(v, NULL, 0);
		if(uvalue > 0xFFFF){
			fprintf(stderr, "%s: Invalid region identifier\n", v);
			return -1;
		}
		if(cint16_write(uvalue, &h->ptr, h->end, NULL)){
			return -1;
		}
			
		uvalue = 0;
		v = cxml_tag_attr_value(tag, "local");
		if(v){
			while(isspace(*v))v++;
			uvalue = strtoul(v, NULL, 0);
			if(!isdigit(*v) || uvalue > 0xFFFF){
				fprintf(stderr, "%s: Invalid region identifier\n", v);
				return -1;
			}
		}
		cintx_write(uvalue, &h->ptr, h->end, &rc);
		if(rc) return -1;
	}
	return rc;
}

static const char * _signature_algorithms[] = {
	"ecdsa_nistp256_with_sha256",
};

static int certificate_signature_tag (cxml_handler_t* const _h, cxml_tag_t * const tag)
{
	int rc = 0;
	cert_cxml_handler_t * h = (cert_cxml_handler_t *)_h;
	if (cxml_tag_is_open(tag)){
		void * key;
		int alg = 0;
		if(h->signer_type == 0){
			// self signed certificate
			key = h->verificationKey;
			if(!key){
				fprintf(stderr, "ERROR: Verification key attribute was not provided for self-signed certificate\n");
				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
			int plen = strlen(_searchPath) + strlen(h->signer);
			char * path = malloc(plen + 16);

			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){
					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;
					}
				}
			}
		}
		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);
	}
	return rc;
}

static int  _Begin_Tag(cxml_handler_t* const h, cxml_tag_t * const tag)
{
	fprintf(stderr, "WARNING: %s: Unknown tag", tag->name);
	return 0;
}

static int  _End_Tag(cxml_handler_t* const h, cxml_tag_t * const tag)
{
	return 0;
}
static int  _Text(cxml_handler_t* const h, char * const text, int length)
{return 0;}