Add private key parameter for nimbus_start() + additional checks

This commit is contained in:
kdeme 2019-11-04 16:34:02 +01:00 committed by zah
parent 7ac8b98ce9
commit 9e7e51b5b4
5 changed files with 69 additions and 19 deletions

View File

@ -56,11 +56,13 @@ typedef void (*received_msg_handler)(received_message* msg, void* udata);
*/ */
void NimMain(); void NimMain();
/** Start Ethereum node with Whisper capability, optionally start discovery and /** Start Ethereum node with Whisper capability and connect to Status fleet.
* connect to Status fleet. * Optionally start discovery and listen for incoming connections.
* The minPow value is the minimum required PoW that this node will allow.
* When privkey is null, a new keypair will be generated.
*/ */
void nimbus_start(uint16_t port, bool startListening, bool enableDiscovery, bool nimbus_start(uint16_t port, bool startListening, bool enableDiscovery,
double minPow); double minPow, uint8_t* privkey);
/** Add peers to connect to - must be called after nimbus_start */ /** Add peers to connect to - must be called after nimbus_start */
void nimbus_add_peer(const char* nodeId); void nimbus_add_peer(const char* nodeId);

View File

@ -110,13 +110,22 @@ proc subscribeChannel(
# notice "no luck parsing", message=getCurrentExceptionMsg() # notice "no luck parsing", message=getCurrentExceptionMsg()
proc nimbus_start(port: uint16, startListening: bool, enableDiscovery: bool, proc nimbus_start(port: uint16, startListening: bool, enableDiscovery: bool,
minPow: float64) minPow: float64, privateKey: ptr byte): bool {.exportc.} =
{.exportc.} =
let address = Address( let address = Address(
udpPort: port.Port, tcpPort: port.Port, ip: parseIpAddress("0.0.0.0")) udpPort: port.Port, tcpPort: port.Port, ip: parseIpAddress("0.0.0.0"))
let keys = newKeyPair() var keypair: KeyPair
node = newEthereumNode(keys, address, 1, nil, addAllCapabilities = false) if privateKey.isNil:
keypair = newKeyPair()
else:
try:
let privKey = initPrivateKey(makeOpenArray(privateKey, 32))
keypair = KeyPair(seckey: privKey, pubkey: privKey.getPublicKey())
except EthKeysException:
error "Passed an invalid privateKey"
return false
node = newEthereumNode(keypair, address, 1, nil, addAllCapabilities = false)
node.addCapability Whisper node.addCapability Whisper
node.protocolState(Whisper).config.powRequirement = minPow node.protocolState(Whisper).config.powRequirement = minPow
@ -139,6 +148,8 @@ proc nimbus_start(port: uint16, startListening: bool, enableDiscovery: bool,
traceAsyncErrors node.peerPool.connectToNode(whisperNode) traceAsyncErrors node.peerPool.connectToNode(whisperNode)
result = true
proc nimbus_poll() {.exportc.} = proc nimbus_poll() {.exportc.} =
poll() poll()
@ -209,15 +220,23 @@ proc nimbus_new_keypair(): cstring {.exportc.} =
result = generateRandomID() result = generateRandomID()
whisperKeys.asymKeys.add($result, newKeyPair()) whisperKeys.asymKeys.add($result, newKeyPair())
proc nimbus_add_keypair(key: ptr PrivateKey): proc nimbus_add_keypair(privateKey: ptr byte):
cstring {.exportc.} = cstring {.exportc.} =
## It is important that the caller makes a copy of the returned cstring before ## It is important that the caller makes a copy of the returned cstring before
## doing any other API calls. This might not hold for all types of GC. ## doing any other API calls. This might not hold for all types of GC.
result = generateRandomID() doAssert(not privateKey.isNil, "Passed a null pointer as privateKey")
var privKey: PrivateKey
try:
privKey = initPrivateKey(makeOpenArray(privateKey, 32))
except EthKeysException:
error "Passed an invalid privateKey"
return ""
result = generateRandomID()
# Creating a KeyPair here does a copy of the key and so does the add # Creating a KeyPair here does a copy of the key and so does the add
whisperKeys.asymKeys.add($result, KeyPair(seckey: key[], whisperKeys.asymKeys.add($result, KeyPair(seckey: privKey,
pubkey: key[].getPublicKey())) pubkey: privKey.getPublicKey()))
proc nimbus_delete_keypair(id: cstring): bool {.exportc.} = proc nimbus_delete_keypair(id: cstring): bool {.exportc.} =
var unneeded: KeyPair var unneeded: KeyPair
@ -225,21 +244,26 @@ proc nimbus_delete_keypair(id: cstring): bool {.exportc.} =
proc nimbus_get_private_key(id: cstring, privateKey: ptr PrivateKey): proc nimbus_get_private_key(id: cstring, privateKey: ptr PrivateKey):
bool {.exportc.} = bool {.exportc.} =
doAssert(not privateKey.isNil, "Passed a null pointer as privateKey")
try: try:
privateKey[] = whisperKeys.asymkeys[$id].seckey privateKey[] = whisperKeys.asymkeys[$id].seckey
result = true result = true
except KeyError: except KeyError:
error "Private key not found"
result = false result = false
# Symmetric Keys API # Symmetric Keys API
proc nimbus_add_symkey(key: ptr SymKey): cstring {.exportc.} = proc nimbus_add_symkey(symKey: ptr SymKey): cstring {.exportc.} =
## It is important that the caller makes a copy of the returned cstring before ## It is important that the caller makes a copy of the returned cstring before
## doing any other API calls. This might not hold for all types of GC. ## doing any other API calls. This might not hold for all types of GC.
doAssert(not symKey.isNil, "Passed a null pointer as symKey")
result = generateRandomID().cstring result = generateRandomID().cstring
# Copy of key happens at add # Copy of key happens at add
whisperKeys.symKeys.add($result, key[]) whisperKeys.symKeys.add($result, symKey[])
proc nimbus_add_symkey_from_password(password: cstring): proc nimbus_add_symkey_from_password(password: cstring):
cstring {.exportc.} = cstring {.exportc.} =
@ -260,6 +284,8 @@ proc nimbus_delete_symkey(id: cstring): bool {.exportc.} =
proc nimbus_get_symkey(id: cstring, symKey: ptr SymKey): proc nimbus_get_symkey(id: cstring, symKey: ptr SymKey):
bool {.exportc.} = bool {.exportc.} =
doAssert(not symKey.isNil, "Passed a null pointer as symKey")
try: try:
symKey[] = whisperKeys.symkeys[$id] symKey[] = whisperKeys.symkeys[$id]
result = true result = true
@ -270,7 +296,7 @@ proc nimbus_get_symkey(id: cstring, symKey: ptr SymKey):
proc nimbus_post(message: ptr CPostMessage): bool {.exportc.} = proc nimbus_post(message: ptr CPostMessage): bool {.exportc.} =
## Encryption is mandatory. ## Encryption is mandatory.
## A symmetric key or an asymmetric key can be provided. Both is not allowed. ## A symmetric key or an asymmetric key must be provided. Both is not allowed.
## Providing a payload is mandatory, it cannot be nil, but can be of length 0. ## Providing a payload is mandatory, it cannot be nil, but can be of length 0.
var var
sigPrivKey: Option[PrivateKey] sigPrivKey: Option[PrivateKey]
@ -323,6 +349,8 @@ proc nimbus_post(message: ptr CPostMessage): bool {.exportc.} =
proc nimbus_subscribe_filter(options: ptr CFilterOptions, proc nimbus_subscribe_filter(options: ptr CFilterOptions,
handler: proc (msg: ptr CReceivedMessage, udata: pointer) {.gcsafe, cdecl.}, handler: proc (msg: ptr CReceivedMessage, udata: pointer) {.gcsafe, cdecl.},
udata: pointer = nil): cstring {.exportc.} = udata: pointer = nil): cstring {.exportc.} =
## Encryption is mandatory.
## A symmetric key or an asymmetric key must be provided. Both is not allowed.
## In case of a passed handler, the received msg needs to be copied before the ## In case of a passed handler, the received msg needs to be copied before the
## handler ends. ## handler ends.
var var
@ -330,6 +358,14 @@ proc nimbus_subscribe_filter(options: ptr CFilterOptions,
symKey: Option[SymKey] symKey: Option[SymKey]
privateKey: Option[PrivateKey] privateKey: Option[PrivateKey]
if not options.privateKeyID.isNil() and not options.symKeyID.isNil():
warn "Both symmetric and asymmetric keys are provided, choose one."
return ""
if options.privateKeyID.isNil() and options.symKeyID.isNil():
warn "Both symmetric and asymmetric keys are nil, provide one."
return ""
if not options.source.isNil(): if not options.source.isNil():
src = some(options.source[]) src = some(options.source[])
@ -339,7 +375,7 @@ proc nimbus_subscribe_filter(options: ptr CFilterOptions,
if not options.privateKeyID.isNil(): if not options.privateKeyID.isNil():
privateKey = some(whisperKeys.asymKeys[$options.privateKeyID].seckey) privateKey = some(whisperKeys.asymKeys[$options.privateKeyID].seckey)
except KeyError: except KeyError:
return nil return ""
let filter = newFilter(src, privateKey, symKey, @[options.topic], let filter = newFilter(src, privateKey, symKey, @[options.topic],
options.minPow, options.allowP2P) options.minPow, options.allowP2P)

View File

@ -22,7 +22,7 @@ int main(int argc, char* argv[]) {
time_t lastmsg; time_t lastmsg;
NimMain(); NimMain();
nimbus_start(30303, false, false, 0.002); nimbus_start(30303, true, false, 0.002, NULL);
nimbus_join_public_chat(channel, print_msg); nimbus_join_public_chat(channel, print_msg);

View File

@ -39,7 +39,7 @@ func receiveHandler(msg *C.received_message) {
func Start() { func Start() {
C.NimMain() C.NimMain()
fmt.Println("[nim-status] Start Nimbus") fmt.Println("[nim-status] Start Nimbus")
C.nimbus_start(30306, false, false, 0.002) C.nimbus_start(30306, true, false, 0.002, nil)
peer1 := "enode://2d3e27d7846564f9b964308038dfadd4076e4373ac938e020708ad8819fd4fd90e5eb8314140768f782db704cb313b60707b968f8b61108a6fecd705b041746d@192.168.0.33:30303" peer1 := "enode://2d3e27d7846564f9b964308038dfadd4076e4373ac938e020708ad8819fd4fd90e5eb8314140768f782db704cb313b60707b968f8b61108a6fecd705b041746d@192.168.0.33:30303"
peer2 := "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@206.189.243.178:443" peer2 := "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@206.189.243.178:443"

View File

@ -5,6 +5,7 @@ import (
"runtime" "runtime"
"time" "time"
"unsafe" "unsafe"
"encoding/hex"
) )
/* /*
@ -45,7 +46,18 @@ func receiveHandler(msg *C.received_message, udata unsafe.Pointer) {
func Start() { func Start() {
C.NimMain() C.NimMain()
fmt.Println("[nim-status] Start Nimbus") fmt.Println("[nim-status] Start Nimbus")
C.nimbus_start(30306, false, false, 0.002)
privKeyHex := "a2b50376a79b1a8c8a3296485572bdfbf54708bb46d3c25d73d2723aaaf6a617"
data, err := hex.DecodeString(privKeyHex)
if err != nil {
panic(err)
}
privKey := (*C.uint8_t)(C.CBytes(data))
defer C.free(unsafe.Pointer(privKey))
if C.nimbus_start(30306, true, false, 0.002, privKey) == false {
panic("Can't start nimbus")
}
} }
func StatusListenAndPost(channel string) { func StatusListenAndPost(channel string) {