Add signing key to restful keyring API

This commit is contained in:
Jeremy Lakeman 2016-06-28 14:22:16 +09:30
parent dbded493c1
commit df6688c496
8 changed files with 92 additions and 109 deletions

View File

@ -21,48 +21,37 @@
package org.servalproject.servaldna;
import org.servalproject.codec.Base64;
import org.servalproject.servaldna.meshms.MeshMSConversationList;
import org.servalproject.servaldna.meshms.MeshMSException;
import org.servalproject.servaldna.meshms.MeshMSMessageList;
import java.lang.Iterable;
import java.util.Vector;
import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import org.servalproject.codec.Base64;
import org.servalproject.servaldna.SubscriberId;
import org.servalproject.servaldna.BundleId;
import org.servalproject.servaldna.BundleSecret;
import org.servalproject.servaldna.ServalDCommand;
import org.servalproject.servaldna.ServalDInterfaceException;
import org.servalproject.servaldna.keyring.KeyringCommon;
import org.servalproject.servaldna.keyring.KeyringIdentity;
import org.servalproject.servaldna.keyring.KeyringIdentityList;
import org.servalproject.servaldna.rhizome.RhizomeCommon;
import org.servalproject.servaldna.rhizome.RhizomeIncompleteManifest;
import org.servalproject.servaldna.rhizome.RhizomeBundleList;
import org.servalproject.servaldna.rhizome.RhizomeManifestBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadRawBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadBundle;
import org.servalproject.servaldna.rhizome.RhizomeInsertBundle;
import org.servalproject.servaldna.rhizome.RhizomeInvalidManifestException;
import org.servalproject.servaldna.rhizome.RhizomeFakeManifestException;
import org.servalproject.servaldna.rhizome.RhizomeInconsistencyException;
import org.servalproject.servaldna.rhizome.RhizomeEncryptionException;
import org.servalproject.servaldna.rhizome.RhizomeReadOnlyException;
import org.servalproject.servaldna.rhizome.RhizomeDecryptionException;
import org.servalproject.servaldna.meshms.MeshMSCommon;
import org.servalproject.servaldna.meshms.MeshMSConversationList;
import org.servalproject.servaldna.meshms.MeshMSMessageList;
import org.servalproject.servaldna.meshms.MeshMSException;
import org.servalproject.servaldna.meshms.MeshMSMessageList;
import org.servalproject.servaldna.meshms.MeshMSStatus;
import org.servalproject.servaldna.rhizome.RhizomeBundleList;
import org.servalproject.servaldna.rhizome.RhizomeCommon;
import org.servalproject.servaldna.rhizome.RhizomeDecryptionException;
import org.servalproject.servaldna.rhizome.RhizomeEncryptionException;
import org.servalproject.servaldna.rhizome.RhizomeFakeManifestException;
import org.servalproject.servaldna.rhizome.RhizomeIncompleteManifest;
import org.servalproject.servaldna.rhizome.RhizomeInconsistencyException;
import org.servalproject.servaldna.rhizome.RhizomeInsertBundle;
import org.servalproject.servaldna.rhizome.RhizomeInvalidManifestException;
import org.servalproject.servaldna.rhizome.RhizomeManifestBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadBundle;
import org.servalproject.servaldna.rhizome.RhizomePayloadRawBundle;
import org.servalproject.servaldna.rhizome.RhizomeReadOnlyException;
public class ServalDClient implements ServalDHttpConnectionFactory
{
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Vector;
public class ServalDClient implements ServalDHttpConnectionFactory {
private final int httpPort;
private final String restfulUsername;
private final String restfulPassword;
@ -79,13 +68,17 @@ public class ServalDClient implements ServalDHttpConnectionFactory
this.restfulPassword = restfulPassword;
}
public KeyringIdentityList keyringListIdentities(String pin) throws ServalDInterfaceException, IOException
{
public KeyringIdentityList keyringListIdentities(String pin) throws ServalDInterfaceException, IOException {
KeyringIdentityList list = new KeyringIdentityList(this);
list.connect(pin);
return list;
}
public KeyringIdentity keyringSetDidName(Subscriber subscriber, String did, String name, String pin) throws ServalDInterfaceException, IOException
{
return this.keyringSetDidName(subscriber.sid, did, name, pin);
}
public KeyringIdentity keyringSetDidName(SubscriberId sid, String did, String name, String pin) throws ServalDInterfaceException, IOException
{
return KeyringCommon.setDidName(this, sid, did, name, pin);

View File

@ -20,28 +20,23 @@
package org.servalproject.servaldna.keyring;
import java.lang.StringBuilder;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.List;
import java.util.Vector;
import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.HttpURLConnection;
import org.servalproject.json.JSONTokeniser;
import org.servalproject.json.JSONInputException;
import org.servalproject.servaldna.SubscriberId;
import org.servalproject.json.JSONTokeniser;
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
import org.servalproject.servaldna.ServalDInterfaceException;
import org.servalproject.servaldna.ServalDFailureException;
import org.servalproject.servaldna.ServalDNotImplementedException;
import org.servalproject.servaldna.SigningKey;
import org.servalproject.servaldna.Subscriber;
import org.servalproject.servaldna.SubscriberId;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import java.util.Vector;
public class KeyringCommon
{
@ -62,7 +57,7 @@ public class KeyringCommon
if (status.identity == null) {
out.println("identity=null");
} else {
out.println("identity.sid=" + status.identity.sid);
out.println("identity.subscriber=" + status.identity.subscriber);
out.println("identity.did=" + status.identity.did);
out.println("identity.name=" + status.identity.name);
}
@ -146,8 +141,11 @@ public class KeyringCommon
json.consume(JSONTokeniser.Token.START_OBJECT);
json.consume("sid");
json.consume(JSONTokeniser.Token.COLON);
String sid_hex = json.consume(String.class);
SubscriberId sid = new SubscriberId(sid_hex);
SubscriberId sid = new SubscriberId(json.consume(String.class));
json.consume(JSONTokeniser.Token.COMMA);
json.consume("sign");
json.consume(JSONTokeniser.Token.COLON);
SigningKey sas = new SigningKey(json.consume(String.class));
String did = null;
String name = null;
tok = json.nextToken();
@ -165,7 +163,7 @@ public class KeyringCommon
}
json.match(tok, JSONTokeniser.Token.END_OBJECT);
tok = json.nextToken();
status.identity = new KeyringIdentity(0, sid, did, name);
status.identity = new KeyringIdentity(0, new Subscriber(sid, sas, true), did, name);
}
json.match(tok, JSONTokeniser.Token.END_OBJECT);
json.consume(JSONTokeniser.Token.EOF);

View File

@ -20,22 +20,26 @@
package org.servalproject.servaldna.keyring;
import org.servalproject.servaldna.Subscriber;
import org.servalproject.servaldna.SubscriberId;
public class KeyringIdentity {
public final int rowNumber;
public final Subscriber subscriber;
@Deprecated
public final SubscriberId sid;
public final String did;
public final String name;
protected KeyringIdentity(int rowNumber,
SubscriberId sid,
Subscriber subscriber,
String did,
String name)
{
this.rowNumber = rowNumber;
this.sid = sid;
this.subscriber = subscriber;
this.sid = subscriber.sid;
this.did = did;
this.name = name;
}

View File

@ -25,6 +25,8 @@ import org.servalproject.json.JSONTableScanner;
import org.servalproject.json.JSONTokeniser;
import org.servalproject.servaldna.ServalDHttpConnectionFactory;
import org.servalproject.servaldna.ServalDInterfaceException;
import org.servalproject.servaldna.SigningKey;
import org.servalproject.servaldna.Subscriber;
import org.servalproject.servaldna.SubscriberId;
import java.io.IOException;
@ -47,6 +49,7 @@ public class KeyringIdentityList {
this.httpConnector = connector;
this.table = new JSONTableScanner()
.addColumn("sid", SubscriberId.class)
.addColumn("sign", SigningKey.class)
.addColumn("did", String.class, JSONTokeniser.Narrow.ALLOW_NULL)
.addColumn("name", String.class, JSONTokeniser.Narrow.ALLOW_NULL);
}
@ -91,7 +94,7 @@ public class KeyringIdentityList {
sid[0]=(byte)i;
ret.add(new KeyringIdentity(
i,
new SubscriberId(sid),
new Subscriber(new SubscriberId(sid), new SigningKey(sid), true),
"555000" + i,
"Agent " + i));
}
@ -117,7 +120,9 @@ public class KeyringIdentityList {
Map<String,Object> row = table.consumeRowArray(json);
return new KeyringIdentity(
rowCount++,
(SubscriberId)row.get("sid"),
new Subscriber((SubscriberId)row.get("sid"),
(SigningKey) row.get("sign"),
true),
(String)row.get("did"),
(String)row.get("name")
);

View File

@ -1973,27 +1973,17 @@ int keyring_send_sas_request(struct subscriber *subscriber){
return ret;
}
void keyring_identity_extract(const keyring_identity *id, const sid_t **sidp, const char **didp, const char **namep)
void keyring_identity_extract(const keyring_identity *id, const char **didp, const char **namep)
{
keypair *kp=id->keypairs;
while(kp){
switch (kp->type) {
case KEYTYPE_CRYPTOBOX:
if (sidp)
*sidp = (const sid_t *)kp->public_key;
break;
case KEYTYPE_DID:
if (didp)
*didp = (const char *) kp->private_key;
if (namep)
*namep = (const char *) kp->public_key;
break;
case KEYTYPE_CRYPTOCOMBINED:
if (sidp){
struct combined_pk *pk = (struct combined_pk *)kp->public_key;
*sidp = &pk->box_key;
}
break;
return;
}
kp=kp->next;
}

View File

@ -124,7 +124,7 @@ int keyring_send_sas_request(struct subscriber *subscriber);
int keyring_commit(keyring_file *k);
keyring_identity *keyring_create_identity(keyring_file *k, const char *pin);
int keyring_seed(keyring_file *k);
void keyring_identity_extract(const keyring_identity *id, const sid_t **sidp, const char **didp, const char **namep);
void keyring_identity_extract(const keyring_identity *id, const char **didp, const char **namep);
int keyring_load_from_dump(keyring_file *k, unsigned entry_pinc, const char **entry_pinv, FILE *input);
int keyring_dump(keyring_file *k, XPRINTF xpf, int include_secret);

View File

@ -133,16 +133,13 @@ static int app_keyring_list(const struct cli_parsed *parsed, struct cli_context
keyring_iterator_start(k, &it);
const keyring_identity *id;
while((id = keyring_next_identity(&it))){
const sid_t *sidp = NULL;
const char *did = NULL;
const char *name = NULL;
keyring_identity_extract(id, &sidp, &did, &name);
if (sidp || did) {
cli_put_string(context, alloca_tohex_sid_t(*sidp), ":");
cli_put_string(context, did, ":");
cli_put_string(context, name, "\n");
rowcount++;
}
keyring_identity_extract(id, &did, &name);
cli_put_string(context, alloca_tohex_sid_t(*id->box_pk), ":");
cli_put_string(context, did, ":");
cli_put_string(context, name, "\n");
rowcount++;
}
keyring_free(k);
cli_row_count(context, rowcount);
@ -242,14 +239,6 @@ static int app_keyring_add(const struct cli_parsed *parsed, struct cli_context *
keyring_free(k);
return WHY("Could not create new identity");
}
const sid_t *sidp = NULL;
const char *did = "";
const char *name = "";
keyring_identity_extract(id, &sidp, &did, &name);
if (!sidp) {
keyring_free(k);
return WHY("New identity has no SID");
}
if (keyring_commit(k) == -1) {
keyring_free(k);
return WHY("Could not write new identity");

View File

@ -81,24 +81,28 @@ static int http_request_keyring_response(struct httpd_request *r, uint16_t resul
static int http_request_keyring_response_identity(struct httpd_request *r, uint16_t result, const char *message, const keyring_identity *id)
{
const sid_t *sidp = NULL;
const char *did = NULL;
const char *name = NULL;
keyring_identity_extract(id, &sidp, &did, &name);
if (!sidp)
return http_request_keyring_response(r, 500, "Identity has no SID");
keyring_identity_extract(id, &did, &name);
struct json_atom json_id;
struct json_key_value json_id_kv[3];
struct json_key_value json_id_kv[4];
struct json_atom json_sid;
struct json_atom json_sas;
struct json_atom json_did;
struct json_atom json_name;
json_id.type = JSON_OBJECT;
json_id.u.object.itemc = 1;
json_id.u.object.itemc = 2;
json_id.u.object.itemv = json_id_kv;
json_id_kv[0].key = "sid";
json_id_kv[0].value = &json_sid;
json_sid.type = JSON_STRING_NULTERM;
json_sid.u.string.content = alloca_tohex_sid_t(*sidp);
json_sid.u.string.content = alloca_tohex_sid_t(*id->box_pk);
json_id_kv[1].key = "sign";
json_id_kv[1].value = &json_sas;
json_sas.type = JSON_STRING_NULTERM;
json_sas.u.string.content = alloca_tohex_sas(id->sign_pk);
if (did) {
json_id_kv[json_id.u.object.itemc].key = "did";
json_id_kv[json_id.u.object.itemc].value = &json_did;
@ -148,6 +152,7 @@ static int restful_keyring_identitylist_json_content_chunk(struct http_request *
// identities.
const char *headers[] = {
"sid",
"sign",
"did",
"name"
};
@ -172,19 +177,18 @@ static int restful_keyring_identitylist_json_content_chunk(struct http_request *
strbuf_putc(b, ',');
case LIST_FIRST:
r->u.sidlist.phase = LIST_ROWS;
const sid_t *sidp = NULL;
const char *did = NULL;
const char *name = NULL;
keyring_identity_extract(r->u.sidlist.it.identity, &sidp, &did, &name);
if (sidp || did) {
strbuf_puts(b, "\n[");
strbuf_json_string(b, alloca_tohex_sid_t(*sidp));
strbuf_puts(b, ",");
strbuf_json_string(b, did);
strbuf_puts(b, ",");
strbuf_json_string(b, name);
strbuf_puts(b, "]");
}
keyring_identity_extract(r->u.sidlist.it.identity, &did, &name);
strbuf_puts(b, "\n[");
strbuf_json_string(b, alloca_tohex_sid_t(*r->u.sidlist.it.identity->box_pk));
strbuf_puts(b, ",");
strbuf_json_string(b, alloca_tohex_sas(r->u.sidlist.it.identity->sign_pk));
strbuf_puts(b, ",");
strbuf_json_string(b, did);
strbuf_puts(b, ",");
strbuf_json_string(b, name);
strbuf_puts(b, "]");
if (!strbuf_overrun(b)) {
if (!keyring_next_identity(&r->u.sidlist.it))