Add asymmetric and symmetric key API for whisper

This commit is contained in:
kdeme 2019-10-25 14:50:14 +02:00 committed by zah
parent e51474f393
commit 24850f8b96
3 changed files with 79 additions and 21 deletions

View File

@ -65,20 +65,33 @@ void nimbus_join_public_chat(const char* channel, received_msg_handler msg);
/* Whisper API */
/* Helper, can be removed */
topic nimbus_string_to_topic(const char* s);
/* Generate asymmetric keypair */
/* Asymmetric Keys API */
const char* nimbus_new_keypair();
/* Generate symmetric key from password */
const char* nimbus_add_keypair(const uint8_t* privkey);
int nimbus_delete_keypair(const char* id);
int nimbus_get_private_key(const char* id, uint8_t* privkey);
/* Symmetric Keys API */
const char* nimbus_add_symkey(const uint8_t* symkey);
const char* nimbus_add_symkey_from_password(const char* password);
int nimbus_delete_symkey(const char* id);
int nimbus_get_symkey(const char* id, uint8_t* symkey);
/* Whisper message posting and receiving API */
/* Subscribe to given filter */
void nimbus_whisper_subscribe(filter_options* filter_options,
void nimbus_subscribe_filter(filter_options* filter_options,
received_msg_handler msg);
/* Post Whisper message */
void nimbus_whisper_post(post_message* msg);
void nimbus_post(post_message* msg);
#ifdef __cplusplus
}
#endif
#endif //__LIBNIMBUS_H__

View File

@ -62,6 +62,11 @@ type
CTopic* = object
topic*: Topic
template foreignThreadGc*(body: untyped) =
setupForeignThreadGc()
`body`
tearDownForeignThreadGc()
proc `$`*(digest: SymKey): string =
for c in digest: result &= hexChar(c.byte)
@ -219,35 +224,74 @@ proc nimbus_string_to_topic(s: cstring): CTopic {.exportc.} =
tearDownForeignThreadGc()
proc nimbus_new_keypair(): cstring {.exportc.} =
setupForeignThreadGc()
# Asymmetric Keys API
proc nimbus_new_keypair(): cstring {.exportc,foreignThreadGc.} =
## It is important that the caller makes a copy of the returned cstring before
## doing any other API calls.
result = generateRandomID()
whisperKeys.asymKeys.add($result, newKeyPair())
tearDownForeignThreadGc()
proc nimbus_add_keypair(key: ptr PrivateKey):
cstring {.exportc,foreignThreadGc.} =
## It is important that the caller makes a copy of the returned cstring before
## doing any other API calls.
result = generateRandomID()
proc nimbus_add_keypair(key: PrivateKey): cstring = discard
proc nimbus_delete_keypair(id: cstring) = discard
proc nimbus_add_symkey(key: SymKey): cstring = discard
# Creating a KeyPair here does a copy of the key and so does the add
whisperKeys.asymKeys.add($result, KeyPair(seckey: key[],
pubkey: key[].getPublicKey()))
proc nimbus_add_symkey_from_password(password: cstring): cstring {.exportc.} =
setupForeignThreadGc()
proc nimbus_delete_keypair(id: cstring): bool {.exportc,foreignThreadGc.} =
var unneeded: KeyPair
result = whisperKeys.asymKeys.take($id, unneeded)
proc nimbus_get_private_key(id: cstring, privateKey: ptr PrivateKey):
bool {.exportc,foreignThreadGc.} =
try:
privateKey[] = whisperKeys.asymkeys[$id].seckey
result = true
except KeyError:
result = false
# Symmetric Keys API
proc nimbus_add_symkey(key: ptr SymKey): cstring {.exportc,foreignThreadGc.} =
## It is important that the caller makes a copy of the returned cstring before
## doing any other API calls.
result = generateRandomID().cstring
# Copy of key happens at add
whisperKeys.symKeys.add($result, key[])
proc nimbus_add_symkey_from_password(password: cstring):
cstring {.exportc,foreignThreadGc.} =
## It is important that the caller makes a copy of the returned cstring before
## doing any other API calls.
var ctx: HMAC[sha256]
var symKey: SymKey
if pbkdf2(ctx, $password, "", 65356, symKey) != sizeof(SymKey):
raise newException(KeyGenerationError, "Failed generating key")
return nil # TODO: Something else than nil? And, can this practically occur?
result = generateRandomID()
whisperKeys.symKeys.add($result, symKey)
tearDownForeignThreadGc()
proc nimbus_delete_symkey(id: cstring): bool {.exportc,foreignThreadGc.} =
var unneeded: SymKey
result = whisperKeys.symKeys.take($id, unneeded)
proc nimbus_delete_symkey(id: cstring) = discard
proc nimbus_get_symkey(id: cstring, symKey: ptr SymKey):
bool {.exportc,foreignThreadGc.} =
try:
symKey[] = whisperKeys.symkeys[$id]
result = true
except KeyError:
result = false
proc nimbus_whisper_post(message: ptr CPostMessage) {.exportc.} =
# Whisper message posting and receiving API
proc nimbus_post(message: ptr CPostMessage) {.exportc.} =
setupForeignThreadGc()
var
@ -293,7 +337,7 @@ proc nimbus_whisper_post(message: ptr CPostMessage) {.exportc.} =
tearDownForeignThreadGc()
proc nimbus_whisper_subscribe(options: ptr CFilterOptions,
proc nimbus_subscribe_filter(options: ptr CFilterOptions,
handler: proc (msg: ptr CReceivedMessage)
{.gcsafe, cdecl.}) {.exportc.} =
setupForeignThreadGc()
@ -335,4 +379,5 @@ proc nimbus_whisper_subscribe(options: ptr CFilterOptions,
tearDownForeignThreadGc()
proc nimbus_whisper_unsubscribe(id: cstring) = discard
proc nimbus_unsubscribe_filter(id: cstring): bool {.exportc.} =
result = node.unsubscribeFilter($id)

View File

@ -54,7 +54,7 @@ func StatusListenAndPost(channel string) {
options := C.filter_options{symKeyID: C.CString(symKeyId),
minPow: 0.002,
topic: C.nimbus_string_to_topic(C.CString(channel)).topic}
C.nimbus_whisper_subscribe(&options,
C.nimbus_subscribe_filter(&options,
(C.received_msg_handler)(unsafe.Pointer(C.receiveHandler_cgo)))
postMessage := C.post_message{symKeyID: C.CString(symKeyId),
@ -74,7 +74,7 @@ func StatusListenAndPost(channel string) {
if i%1000 == 0 {
fmt.Println("[nim-status] posting", message)
postMessage.payload = (C.CString(message))
C.nimbus_whisper_post(&postMessage)
C.nimbus_post(&postMessage)
}
}
}