/* print a JSON object to the FILE stream */ static void pobj(FILE *fp, mj_t *obj, int depth) { unsigned i; char *s; if (obj == NULL) { (void) fprintf(stderr, "No object found\n"); return; } for (i = 0 ; i < (unsigned)depth ; i++) { p(fp, " ", NULL); } switch(obj->type) { case MJ_NULL: case MJ_FALSE: case MJ_TRUE: p(fp, (obj->type == MJ_NULL) ? "null" : (obj->type == MJ_FALSE) ? "false" : "true", NULL); break; case MJ_NUMBER: p(fp, obj->value.s, NULL); break; case MJ_STRING: if ((i = mj_asprint(&s, obj, MJ_HUMAN)) > 2) { (void) fprintf(fp, "%.*s", (int)i - 2, &s[1]); free(s); } break; case MJ_ARRAY: for (i = 0 ; i < obj->c ; i++) { pobj(fp, &obj->value.v[i], depth + 1); if (i < obj->c - 1) { (void) fprintf(fp, ", "); } } (void) fprintf(fp, "\n"); break; case MJ_OBJECT: for (i = 0 ; i < obj->c ; i += 2) { pobj(fp, &obj->value.v[i], depth + 1); p(fp, ": ", NULL); pobj(fp, &obj->value.v[i + 1], 0); if (i < obj->c - 1) { p(fp, ", ", NULL); } } p(fp, "\n", NULL); break; default: break; } }
int __ops_keyring_json(__ops_io_t *io, const __ops_keyring_t *keyring, mj_t *obj, const int psigs) { __ops_key_t *key; unsigned n; (void) memset(obj, 0x0, sizeof(*obj)); mj_create(obj, "array"); obj->size = keyring->keyvsize; if (__ops_get_debug_level(__FILE__)) { (void) fprintf(io->errs, "__ops_keyring_json: vsize %u\n", obj->size); } if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) { (void) fprintf(io->errs, "calloc failure\n"); return 0; } for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) { if (__ops_is_key_secret(key)) { __ops_sprint_mj(io, keyring, key, &obj->value.v[obj->c], "sec", &key->key.seckey.pubkey, psigs); } else { __ops_sprint_mj(io, keyring, key, &obj->value.v[obj->c], "signature ", &key->key.pubkey, psigs); } if (obj->value.v[obj->c].type != 0) { obj->c += 1; } } if (__ops_get_debug_level(__FILE__)) { char *s; mj_asprint(&s, obj); (void) fprintf(stderr, "__ops_keyring_json: '%s'\n", s); free(s); } return 1; }
/* format a JSON object */ static void format_json_key(FILE *fp, mj_t *obj, const int psigs) { int64_t birthtime; int64_t duration; time_t now; char tbuf[32]; char *s; mj_t *sub; int i; if (pgp_get_debug_level(__FILE__)) { mj_asprint(&s, obj, MJ_HUMAN); (void) fprintf(stderr, "formatobj: json is '%s'\n", s); free(s); } if (obj->c == 2 && obj->value.v[1].type == MJ_STRING && strcmp(obj->value.v[1].value.s, "[REVOKED]") == 0) { /* whole key has been rovoked - just return */ return; } pobj(fp, &obj->value.v[mj_object_find(obj, "header", 0, 2) + 1], 0); p(fp, " ", NULL); pobj(fp, &obj->value.v[mj_object_find(obj, "key bits", 0, 2) + 1], 0); p(fp, "/", NULL); pobj(fp, &obj->value.v[mj_object_find(obj, "pka", 0, 2) + 1], 0); p(fp, " ", NULL); pobj(fp, &obj->value.v[mj_object_find(obj, "key id", 0, 2) + 1], 0); birthtime = (int64_t)strtoll(obj->value.v[mj_object_find(obj, "birthtime", 0, 2) + 1].value.s, NULL, 10); p(fp, " ", ptimestr(tbuf, sizeof(tbuf), birthtime), NULL); duration = (int64_t)strtoll(obj->value.v[mj_object_find(obj, "duration", 0, 2) + 1].value.s, NULL, 10); if (duration > 0) { now = time(NULL); p(fp, " ", (birthtime + duration < now) ? "[EXPIRED " : "[EXPIRES ", ptimestr(tbuf, sizeof(tbuf), birthtime + duration), "]", NULL); } p(fp, "\n", "Key fingerprint: ", NULL); pobj(fp, &obj->value.v[mj_object_find(obj, "fingerprint", 0, 2) + 1], 0); p(fp, "\n", NULL); /* go to field after \"duration\" */ for (i = mj_object_find(obj, "duration", 0, 2) + 2; i < mj_arraycount(obj) ; i += 2) { if (strcmp(obj->value.v[i].value.s, "uid") == 0) { sub = &obj->value.v[i + 1]; p(fp, "uid", NULL); pobj(fp, &sub->value.v[0], (psigs) ? 4 : 14); /* human name */ pobj(fp, &sub->value.v[1], 1); /* any revocation */ p(fp, "\n", NULL); } else if (strcmp(obj->value.v[i].value.s, "encryption") == 0) { sub = &obj->value.v[i + 1]; p(fp, "encryption", NULL); pobj(fp, &sub->value.v[0], 1); /* size */ p(fp, "/", NULL); pobj(fp, &sub->value.v[1], 0); /* alg */ p(fp, " ", NULL); pobj(fp, &sub->value.v[2], 0); /* id */ p(fp, " ", ptimestr(tbuf, sizeof(tbuf), (time_t)strtoll(sub->value.v[3].value.s, NULL, 10)), "\n", NULL); } else if (strcmp(obj->value.v[i].value.s, "sig") == 0) { sub = &obj->value.v[i + 1]; p(fp, "sig", NULL); pobj(fp, &sub->value.v[0], 8); /* size */ p(fp, " ", ptimestr(tbuf, sizeof(tbuf), (time_t)strtoll(sub->value.v[1].value.s, NULL, 10)), " ", NULL); /* time */ pobj(fp, &sub->value.v[2], 0); /* human name */ p(fp, "\n", NULL); } else { fprintf(stderr, "weird '%s'\n", obj->value.v[i].value.s); pobj(fp, &obj->value.v[i], 0); /* human name */ } } p(fp, "\n", NULL); }