/*
- Copyright 2015 IoT.bzh
+ Copyright 2015, 2016 IoT.bzh
+
+ author: José Bollo <jose.bollo@iot.bzh>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
*/
-#include <syslog.h>
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <xmlsec/io.h>
-#include "wgtpkg.h"
+#include "verbose.h"
+#include "wgtpkg-files.h"
+#include "wgtpkg-workdir.h"
+#include "wgtpkg-xmlsec.h"
static int initstatus;
static int initdone;
static xmlSecKeysMngrPtr keymgr;
-#ifndef CA_ROOT_DIRECTORY
-#define CA_ROOT_DIRECTORY "./ca-certificates"
-#endif
+static const char trusted_certificates_directory[] = WGTPKG_TRUSTED_CERT_DIR;
/* checks if a file match uri (should not be a distributor signature) */
static int file_match_cb(const char *uri)
fdesc = file_of_name(file);
if (fdesc == NULL) {
- syslog(LOG_ERR, "shouldn't open uri %s", file);
+ ERROR("shouldn't open uri %s", file);
return NULL;
}
fd = openat(workdirfd, file, O_RDONLY);
f = fd < 0 ? NULL : fdopen(fd, "r");
if (f == NULL) {
- syslog(LOG_ERR, "can't open file %s for reading", file);
+ ERROR("can't open file %s for reading", file);
if (fd >= 0)
close(fd);
} else
/* read the opened file */
static int file_read_cb(void *context, char *buffer, int len)
{
- size_t r = fread(buffer, 1, len, (FILE*)context);
+ size_t r = fread(buffer, 1, (unsigned)len, (FILE*)context);
return r ? (int)r : feof((FILE*)context) ? 0 : - 1;
}
/* echo an error message */
static void errors_cb(const char *file, int line, const char *func, const char *errorObject, const char *errorSubject, int reason, const char *msg)
{
- syslog(LOG_ERR, "xmlSec error %3d: %s (subject=\"%s\", object=\"%s\")", reason, msg, errorSubject ? errorSubject : "?", errorObject ? errorObject : "?");
+ ERROR("xmlSec error %3d: %s (subject=\"%s\", object=\"%s\")", reason, msg, errorSubject ? errorSubject : "?", errorObject ? errorObject : "?");
}
/* fills database with trusted keys */
{
int err = xmlSecCryptoAppKeysMngrCertLoad(keymgr, file, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted);
if (err < 0) {
- syslog(LOG_ERR, "xmlSecCryptoAppKeysMngrCertLoadMemory failed for %s", file);
+ ERROR("xmlSecCryptoAppKeysMngrCertLoadMemory failed for %s", file);
return -1;
}
return 0;
e = stpcpy(path, directory);
dir = opendir(path);
if (!dir) {
- syslog(LOG_ERR, "opendir %s failed in fill_trusted_keys_dir", path);
+ ERROR("opendir %s failed in fill_trusted_keys_dir", path);
return -1;
}
initstatus = -1;
if(xmlSecInit() < 0) {
- syslog(LOG_ERR, "xmlSecInit failed.");
+ ERROR("xmlSecInit failed.");
goto end;
}
#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
if(xmlSecCryptoDLLoadLibrary(XMLSEC_CRYPTO) < 0) {
- syslog(LOG_ERR, "xmlSecCryptoDLLoadLibrary %s failed.", XMLSEC_CRYPTO);
+ ERROR("xmlSecCryptoDLLoadLibrary %s failed.", XMLSEC_CRYPTO);
goto end;
}
#endif
if(xmlSecCryptoAppInit(NULL) < 0) {
- syslog(LOG_ERR, "xmlSecCryptoAppInit failed.");
+ ERROR("xmlSecCryptoAppInit failed.");
goto end;
}
if(xmlSecCryptoInit() < 0) {
- syslog(LOG_ERR, "xmlSecCryptoInit failed.");
+ ERROR("xmlSecCryptoInit failed.");
goto end;
}
xmlSecIOCleanupCallbacks();
if (xmlSecIORegisterCallbacks(file_match_cb,
file_open_cb, file_read_cb, file_close_cb)) {
- syslog(LOG_ERR, "xmlSecIORegisterCallbacks failed.");
+ ERROR("xmlSecIORegisterCallbacks failed.");
goto end;
}
keymgr = xmlSecKeysMngrCreate();
if (keymgr == NULL) {
- syslog(LOG_ERR, "xmlSecKeysMngrCreate failed.");
+ ERROR("xmlSecKeysMngrCreate failed.");
goto end;
}
if(xmlSecCryptoAppDefaultKeysMngrInit(keymgr) < 0) {
- syslog(LOG_ERR, "xmlSecCryptoAppDefaultKeysMngrInit failed.");
+ ERROR("xmlSecCryptoAppDefaultKeysMngrInit failed.");
goto end;
}
- fill_trusted_keys_dir(CA_ROOT_DIRECTORY);
+ fill_trusted_keys_dir(trusted_certificates_directory);
initstatus = 0;
end:
dsigctx = xmlSecDSigCtxCreate(keymgr);
if (dsigctx == NULL) {
- syslog(LOG_ERR, "xmlSecDSigCtxCreate failed.");
+ ERROR("xmlSecDSigCtxCreate failed.");
rc = -1;
} else {
rc = xmlSecDSigCtxVerify(dsigctx, node);
if (rc)
- syslog(LOG_ERR, "xmlSecDSigCtxVerify failed.");
+ ERROR("xmlSecDSigCtxVerify failed.");
else if (dsigctx->status != xmlSecDSigStatusSucceeded) {
- syslog(LOG_ERR, "invalid signature.");
+ ERROR("invalid signature.");
rc = -1;
}
xmlSecDSigCtxDestroy(dsigctx);
/* create a signature of 'index' (0 for author, other values for distributors)
using the private 'key' (filename) and the certificates 'certs' (filenames)
as trusted chain */
-xmlDocPtr xmlsec_create(int index, const char *key, const char **certs)
+xmlDocPtr xmlsec_create(unsigned int index, const char *key, const char **certs)
{
unsigned int i, fc, mask;
struct filedesc *fdesc;
/* create the document */
doc = xmlNewDoc("1.0");
if (doc == NULL) {
- syslog(LOG_ERR, "xmlNewDoc failed");
+ ERROR("xmlNewDoc failed");
goto error;
}
/* create the root signature node */
sign = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14N11Id, xmlSecTransformRsaSha256Id, properties[!!index].id);
if (sign == NULL) {
- syslog(LOG_ERR, "xmlSecTmplSignatureCreate failed");
+ ERROR("xmlSecTmplSignatureCreate failed");
goto error2;
}
xmlDocSetRootElement(doc, sign);
/* create the object and its reference */
obj = xmlSecTmplSignatureAddObject(sign, "prop", NULL, NULL);
if (obj == NULL) {
- syslog(LOG_ERR, "xmlSecTmplSignatureAddObject failed");
+ ERROR("xmlSecTmplSignatureAddObject failed");
goto error2;
}
rc = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, properties[!!index].xml, &props);
if (rc) {
- syslog(LOG_ERR, "xmlParseBalancedChunkMemory failed");
+ ERROR("xmlParseBalancedChunkMemory failed");
goto error2;
}
if (NULL == xmlAddChild(obj, props)) {
- syslog(LOG_ERR, "filling object node failed");
+ ERROR("filling object node failed");
xmlFreeNode(obj);
goto error2;
}
if (fdesc->type == type_file && (fdesc->flags & mask) == 0) {
ref = xmlSecTmplSignatureAddReference(sign, xmlSecTransformSha256Id, NULL, fdesc->name, NULL);
if (ref == NULL) {
- syslog(LOG_ERR, "creation of reference to %s failed", fdesc->name);
+ ERROR("creation of reference to %s failed", fdesc->name);
goto error2;
}
}
/* create reference to object having properties */
ref = xmlSecTmplSignatureAddReference(sign, xmlSecTransformSha256Id, NULL, "#prop", NULL);
if (ref == NULL) {
- syslog(LOG_ERR, "creation of reference to #prop failed");
+ ERROR("creation of reference to #prop failed");
goto error2;
}
if (NULL == xmlSecTmplReferenceAddTransform(ref, xmlSecTransformInclC14N11Id)) {
- syslog(LOG_ERR, "setting transform reference to #prop failed");
+ ERROR("setting transform reference to #prop failed");
goto error2;
}
/* adds the X509 data */
kinfo = xmlSecTmplSignatureEnsureKeyInfo(sign, NULL);
if (kinfo == NULL) {
- syslog(LOG_ERR, "xmlSecTmplSignatureEnsureKeyInfo failed");
+ ERROR("xmlSecTmplSignatureEnsureKeyInfo failed");
goto error2;
}
if (NULL == xmlSecTmplKeyInfoAddX509Data(kinfo)) {
- syslog(LOG_ERR, "xmlSecTmplKeyInfoAddX509Data failed");
+ ERROR("xmlSecTmplKeyInfoAddX509Data failed");
goto error2;
}
/* sign now */
dsigctx = xmlSecDSigCtxCreate(keymgr);
if (dsigctx == NULL) {
- syslog(LOG_ERR, "xmlSecDSigCtxCreate failed.");
+ ERROR("xmlSecDSigCtxCreate failed.");
goto error3;
}
dsigctx->signKey = xmlSecCryptoAppKeyLoad(key, xmlSecKeyDataFormatPem, NULL, NULL, NULL);
if (dsigctx->signKey == NULL) {
- syslog(LOG_ERR, "loading key %s failed.", key);
+ ERROR("loading key %s failed.", key);
goto error3;
}
while (*certs) {
if(xmlSecCryptoAppKeyCertLoad(dsigctx->signKey, *certs, xmlSecKeyDataFormatPem) < 0) {
- syslog(LOG_ERR, "loading certificate %s failed.", *certs);
+ ERROR("loading certificate %s failed.", *certs);
goto error3;
}
certs++;
}
if(xmlSecDSigCtxSign(dsigctx, sign) < 0) {
- syslog(LOG_ERR, "signing the document failed.");
+ ERROR("signing the document failed.");
goto error3;
}
xmlSecDSigCtxDestroy(dsigctx);