json_t *(*pref2json)(struct ROAIPAddress *))
{
json_t *root;
- json_t *family, *addresses;
+ json_t *addrs;
int i;
root = json_object();
if (root == NULL)
return NULL;
- family = json_string(ipname);
- if (family == NULL)
+ if (json_object_set_new(root, "addressFamily", json_string(ipname)) < 0)
goto fail;
- if (json_object_set_new(root, "addressFamily", family) < 0)
- goto fail;
-
- addresses = json_array();
- if (addresses == NULL)
- goto fail;
- if (json_object_set_new(root, "addresses", addresses) < 0)
+ if (json_object_set_new(root, "addresses", addrs = json_array()) < 0)
goto fail;
for (i = 0; i < riaf->addresses.list.count; i++) {
json_t *prefix, *maxlen;
prefix = pref2json(src);
- if (prefix == NULL)
- goto fail;
- if (json_array_append_new(addresses, prefix))
+ if (json_array_append_new(addrs, prefix))
goto fail;
maxlen = asn_DEF_INTEGER.op->json_encoder(&asn_DEF_INTEGER, src->maxLength);
- if (maxlen == NULL)
- goto fail;
if (json_object_set_new(prefix, "maxLength", maxlen))
goto fail;
}
#include "asn1/content_info.h"
#include "asn1/asn1c/Certificate.h"
#include "asn1/asn1c/CRL.h"
+#include "types/bio_seq.h"
#define HDRSIZE 32
ssize_t len_len;
len_len = ber_fetch_length(0, cursor, HDRSIZE - (cursor - buf), &len);
- if (len_len <= 0) {
- pr_op_debug("aoe");
+ if (len_len <= 0)
return NULL;
- }
cursor += len_len + len;
return (cursor <= (buf + HDRSIZE)) ? cursor : NULL;
}
static int
-guess_file_type(FILE *file)
+guess_file_type(BIO **bio, unsigned char *hdrbuf)
{
- unsigned char buf[HDRSIZE];
unsigned char *ptr;
+ size_t consumed;
if (config_get_file_type() != FT_UNK)
return config_get_file_type();
- if (fread(buf, 1, HDRSIZE, file) != HDRSIZE) {
- pr_op_debug("File is too small or generic IO error.");
- return FT_UNK;
- }
- rewind(file);
+ if (!BIO_read_ex(*bio, hdrbuf, HDRSIZE, &consumed))
+ return op_crypto_err("Cannot guess file type; IO error.");
+
+ *bio = BIO_new_seq(BIO_new_mem_buf(hdrbuf, consumed), *bio);
+ if ((*bio) == NULL)
+ return op_crypto_err("BIO_new_seq() returned NULL.");
- if (buf[0] != 0x30) {
+ if (hdrbuf[0] != 0x30) {
pr_op_debug("File doesn't start with a SEQUENCE.");
return FT_UNK;
}
- ptr = skip_sequence(buf, buf + 1);
+ ptr = skip_sequence(hdrbuf, hdrbuf + 1);
if (ptr == NULL) {
pr_op_debug("Cannot skip first sequence length.");
return FT_UNK;
return FT_UNK;
}
- ptr = skip_sequence(buf, ptr + 1);
+ ptr = skip_sequence(hdrbuf, ptr + 1);
if (ptr == NULL) {
pr_op_debug("Cannot skip second sequence length.");
return FT_UNK;
}
- ptr = skip_integer(buf, ptr + 1);
+ ptr = skip_integer(hdrbuf, ptr + 1);
if (ptr == NULL) {
pr_op_debug("Cannot skip version number.");
return FT_UNK;
}
static struct ContentInfo *
-file2ci(FILE *file)
+bio2ci(BIO *bio)
{
-#define BUFFER_SIZE 1024
+#define BUFFER_SIZE 4096
struct ContentInfo *ci = NULL;
unsigned char buffer[BUFFER_SIZE];
size_t consumed;
- bool eof;
+// bool eof;
asn_dec_rval_t res;
- eof = false;
+// eof = false;
do {
- consumed = fread(buffer, 1, BUFFER_SIZE, file);
- if (consumed < BUFFER_SIZE) {
- if (feof(file)) {
- eof = true;
- } else if (ferror(file)) {
- pr_op_err("ferror.");
- return NULL;
- } else {
- pr_op_err("?");
- return NULL;
- }
+ if (!BIO_read_ex(bio, buffer, BUFFER_SIZE, &consumed)) {
+ op_crypto_err("IO error.");
+ return NULL;
}
- res = ber_decode(NULL, &asn_DEF_ContentInfo, (void **)&ci, buffer, consumed);
+ res = ber_decode(NULL, &asn_DEF_ContentInfo, (void **)&ci,
+ buffer, consumed);
pr_op_debug("Consumed: %zu", res.consumed);
switch (res.code) {
case RC_OK:
- if (!eof)
- pr_op_warn("File has trailing bytes.");
+// if (!buf->eof)
+// pr_op_warn("File has trailing bytes.");
return ci;
case RC_WMORE:
- if (eof) {
- pr_op_err("File ended prematurely.");
- return NULL;
- }
+// if (buf->eof) {
+// pr_op_err("File ended prematurely.");
+// return NULL;
+// }
break;
case RC_FAIL:
}
static json_t *
-asn1c2json(FILE *file)
+asn1c2json(BIO *bio)
{
struct ContentInfo *ci;
json_t *json;
- ci = file2ci(file);
+ ci = bio2ci(bio);
if (ci == NULL)
return NULL;
return json;
}
-int
-print_file(void)
+static int
+__print_file(void)
{
- char const *filename = config_get_payload();
- FILE *file;
+ char const *filename;
+ BIO *bio;
+ unsigned char hdrbuf[HDRSIZE];
json_t *json = NULL;
- int error = 0;
+ int error;
- if (filename == NULL || strcmp(filename, "-") == 0) {
- file = stdin;
- } else {
- file = fopen(filename, "rb");
- if (file == NULL)
- return pr_op_err("Cannot open file: %s", strerror(errno));
- }
+ filename = config_get_payload();
+ bio = (filename == NULL || strcmp(filename, "-") == 0)
+ ? BIO_new_fp(stdin, BIO_NOCLOSE)
+ : BIO_new_file(filename, "rb");
+ if (bio == NULL)
+ return pr_op_err("BIO_new_*() returned NULL.");
- switch (guess_file_type(file)) {
+ switch (guess_file_type(&bio, hdrbuf)) {
case FT_UNK:
- error = pr_op_err("Unrecognized file type.");
- break;
+ BIO_free_all(bio);
+ return pr_op_err("Unrecognized file type.");
+
case FT_ROA:
case FT_MFT:
case FT_GBR:
- json = asn1c2json(file);
+ json = asn1c2json(bio);
break;
case FT_CER:
- json = Certificate_file2json(file);
+ json = Certificate_bio2json(bio);
break;
case FT_CRL:
- json = CRL_file2json(file);
+ json = CRL_bio2json(bio);
break;
}
- if (file != stdin)
- fclose(file);
- if (error)
- return error;
+ BIO_free_all(bio);
if (json == NULL)
return pr_op_err("Unable to parse.");
pr_op_err("Error writing JSON to file: %s", strerror(error));
else
pr_op_err("Unknown error writing JSON to file.");
- goto end;
+
+ } else {
+ error = 0;
+ printf("\n");
}
- error = 0;
- printf("\n");
-end: json_decref(json);
+ json_decref(json);
+ return error;
+}
+
+int
+print_file(void)
+{
+ int error;
+
+ error = bioseq_setup();
+ if (error)
+ return error;
+
+ error = __print_file();
+
+ bioseq_teardown();
return error;
}
--- /dev/null
+#include "types/bio_seq.h"
+
+#include "log.h"
+#include "alloc.h"
+
+static BIO_METHOD *method;
+
+struct bioseq_priv {
+ BIO *prefix;
+ BIO *suffix;
+};
+
+static int
+bioseq_read_ex(BIO *bio, char *data, size_t len, size_t *consumed)
+{
+ struct bioseq_priv *priv = BIO_get_data(bio);
+ int res;
+
+ if (priv->prefix != NULL) {
+ res = BIO_read_ex(priv->prefix, data, len, consumed);
+ if (res == 1 && BIO_eof(priv->prefix)) {
+ BIO_free_all(priv->prefix);
+ priv->prefix = NULL;
+ }
+ return res;
+ }
+
+ return BIO_read_ex(priv->suffix, data, len, consumed);
+}
+
+static int
+bioseq_destroy(BIO *bio)
+{
+ struct bioseq_priv *priv;
+
+ if (bio == NULL)
+ return 0;
+
+ priv = BIO_get_data(bio);
+ BIO_free(priv->prefix);
+ BIO_free(priv->suffix);
+ free(priv);
+
+ BIO_set_data(bio, NULL);
+ BIO_set_init(bio, 0);
+
+ return 1;
+}
+
+int
+bioseq_setup(void)
+{
+ int type;
+
+ type = BIO_get_new_index();
+ if (type == -1)
+ return op_crypto_err("BIO_get_new_index() returned -1.");
+
+ method = BIO_meth_new(type | BIO_TYPE_FILTER, "seq");
+ if (method == NULL)
+ return op_crypto_err("BIO_meth_new() returned NULL.");
+
+ if (!BIO_meth_set_read_ex(method, bioseq_read_ex) ||
+ !BIO_meth_set_destroy(method, bioseq_destroy)) {
+ BIO_meth_free(method);
+ method = NULL;
+ return op_crypto_err("BIO_meth_set_*() returned 0.");
+ }
+
+ return 0;
+}
+
+void
+bioseq_teardown(void)
+{
+ BIO_meth_free(method);
+}
+
+BIO *
+BIO_new_seq(BIO *prefix, BIO *suffix)
+{
+ BIO *bio;
+ struct bioseq_priv *priv;
+
+ if (prefix == NULL || suffix == NULL)
+ return NULL;
+
+ bio = BIO_new(method);
+ if (bio == NULL)
+ return NULL;
+
+ priv = pmalloc(sizeof(struct bioseq_priv));
+ priv->prefix = prefix;
+ priv->suffix = suffix;
+
+ BIO_set_data(bio, priv);
+ BIO_set_init(bio, 1);
+ return bio;
+}