x509 fixes and plugins
This commit is contained in:
parent
0693403358
commit
362ca96f38
|
@ -189,7 +189,7 @@ class BaseWizard(object):
|
||||||
except:
|
except:
|
||||||
devmgr.print_error("error", name)
|
devmgr.print_error("error", name)
|
||||||
continue
|
continue
|
||||||
devices += map(lambda x: (name, x), u)
|
devices += list(map(lambda x: (name, x), u))
|
||||||
if not devices:
|
if not devices:
|
||||||
msg = ''.join([
|
msg = ''.join([
|
||||||
_('No hardware device detected.') + '\n',
|
_('No hardware device detected.') + '\n',
|
||||||
|
@ -235,7 +235,7 @@ class BaseWizard(object):
|
||||||
self.line_dialog(run_next=f, title=_('Derivation'), message=message, default=default, test=bitcoin.is_bip32_derivation)
|
self.line_dialog(run_next=f, title=_('Derivation'), message=message, default=default, test=bitcoin.is_bip32_derivation)
|
||||||
|
|
||||||
def on_hw_derivation(self, name, device_info, derivation):
|
def on_hw_derivation(self, name, device_info, derivation):
|
||||||
from keystore import hardware_keystore
|
from .keystore import hardware_keystore
|
||||||
xpub = self.plugin.get_xpub(device_info.device.id_, derivation, self)
|
xpub = self.plugin.get_xpub(device_info.device.id_, derivation, self)
|
||||||
if xpub is None:
|
if xpub is None:
|
||||||
self.show_error('Cannot read xpub from device')
|
self.show_error('Cannot read xpub from device')
|
||||||
|
@ -286,7 +286,7 @@ class BaseWizard(object):
|
||||||
self.load_2fa()
|
self.load_2fa()
|
||||||
self.run('on_restore_seed', seed, is_ext)
|
self.run('on_restore_seed', seed, is_ext)
|
||||||
else:
|
else:
|
||||||
raise BaseException('Unknown seed type', seed_type)
|
raise BaseException('Unknown seed type', self.seed_type)
|
||||||
|
|
||||||
def on_restore_bip39(self, seed, passphrase):
|
def on_restore_bip39(self, seed, passphrase):
|
||||||
f = lambda x: self.run('on_bip44', seed, passphrase, str(x))
|
f = lambda x: self.run('on_bip44', seed, passphrase, str(x))
|
||||||
|
@ -334,7 +334,8 @@ class BaseWizard(object):
|
||||||
k.update_password(None, password)
|
k.update_password(None, password)
|
||||||
if self.wallet_type == 'standard':
|
if self.wallet_type == 'standard':
|
||||||
self.storage.put('seed_type', self.seed_type)
|
self.storage.put('seed_type', self.seed_type)
|
||||||
self.storage.put('keystore', k.dump())
|
keys = self.keystores[0].dump()
|
||||||
|
self.storage.put('keystore', keys)
|
||||||
self.wallet = Standard_Wallet(self.storage)
|
self.wallet = Standard_Wallet(self.storage)
|
||||||
self.run('create_addresses')
|
self.run('create_addresses')
|
||||||
elif self.wallet_type == 'multisig':
|
elif self.wallet_type == 'multisig':
|
||||||
|
@ -355,7 +356,7 @@ class BaseWizard(object):
|
||||||
self.on_keystore(k)
|
self.on_keystore(k)
|
||||||
|
|
||||||
def create_seed(self):
|
def create_seed(self):
|
||||||
import mnemonic
|
from . import mnemonic
|
||||||
self.seed_type = 'segwit' if bitcoin.TESTNET and self.config.get('segwit') else 'standard'
|
self.seed_type = 'segwit' if bitcoin.TESTNET and self.config.get('segwit') else 'standard'
|
||||||
seed = mnemonic.Mnemonic('en').make_seed(self.seed_type)
|
seed = mnemonic.Mnemonic('en').make_seed(self.seed_type)
|
||||||
self.opt_bip39 = False
|
self.opt_bip39 = False
|
||||||
|
|
|
@ -29,7 +29,7 @@ import re
|
||||||
import hmac
|
import hmac
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from lib.util import bfh, bh2u
|
from lib.util import bfh, bh2u, to_string
|
||||||
from . import version
|
from . import version
|
||||||
from .util import print_error, InvalidPassword, assert_bytes, to_bytes
|
from .util import print_error, InvalidPassword, assert_bytes, to_bytes
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ def DecodeAES(secret, e):
|
||||||
def pw_encode(s, password):
|
def pw_encode(s, password):
|
||||||
if password:
|
if password:
|
||||||
secret = Hash(password)
|
secret = Hash(password)
|
||||||
return EncodeAES(secret, s.encode("utf8"))
|
return EncodeAES(secret, to_bytes(s, "utf8"))
|
||||||
else:
|
else:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ def pw_decode(s, password):
|
||||||
if password is not None:
|
if password is not None:
|
||||||
secret = Hash(password)
|
secret = Hash(password)
|
||||||
try:
|
try:
|
||||||
d = DecodeAES(secret, s).decode("utf8")
|
d = to_string(DecodeAES(secret, s), "utf8")
|
||||||
except Exception:
|
except Exception:
|
||||||
raise InvalidPassword()
|
raise InvalidPassword()
|
||||||
return d
|
return d
|
||||||
|
@ -213,7 +213,7 @@ def Hash(x):
|
||||||
|
|
||||||
hash_encode = lambda x: bh2u(x[::-1])
|
hash_encode = lambda x: bh2u(x[::-1])
|
||||||
hash_decode = lambda x: bfh(x)[::-1]
|
hash_decode = lambda x: bfh(x)[::-1]
|
||||||
hmac_sha_512 = lambda x, y: _bytes(hmac.new(x, y, hashlib.sha512).digest())
|
hmac_sha_512 = lambda x, y: hmac.new(x, y, hashlib.sha512).digest()
|
||||||
|
|
||||||
|
|
||||||
def is_new_seed(x, prefix=version.SEED_PREFIX):
|
def is_new_seed(x, prefix=version.SEED_PREFIX):
|
||||||
|
|
|
@ -34,8 +34,8 @@ import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
# from jsonrpc import JSONRPCResponseManager
|
# from jsonrpc import JSONRPCResponseManager
|
||||||
import jsonrpclib
|
# import jsonrpclib
|
||||||
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer, SimpleJSONRPCRequestHandler
|
# from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer, SimpleJSONRPCRequestHandler
|
||||||
|
|
||||||
from .version import ELECTRUM_VERSION
|
from .version import ELECTRUM_VERSION
|
||||||
from .network import Network
|
from .network import Network
|
||||||
|
@ -96,17 +96,17 @@ def get_server(config):
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
|
|
||||||
class RequestHandler(SimpleJSONRPCRequestHandler):
|
# class RequestHandler(SimpleJSONRPCRequestHandler):
|
||||||
|
#
|
||||||
def do_OPTIONS(self):
|
# def do_OPTIONS(self):
|
||||||
self.send_response(200)
|
# self.send_response(200)
|
||||||
self.end_headers()
|
# self.end_headers()
|
||||||
|
#
|
||||||
def end_headers(self):
|
# def end_headers(self):
|
||||||
self.send_header("Access-Control-Allow-Headers",
|
# self.send_header("Access-Control-Allow-Headers",
|
||||||
"Origin, X-Requested-With, Content-Type, Accept")
|
# "Origin, X-Requested-With, Content-Type, Accept")
|
||||||
self.send_header("Access-Control-Allow-Origin", "*")
|
# self.send_header("Access-Control-Allow-Origin", "*")
|
||||||
SimpleJSONRPCRequestHandler.end_headers(self)
|
# SimpleJSONRPCRequestHandler.end_headers(self)
|
||||||
|
|
||||||
|
|
||||||
class Daemon(DaemonThread):
|
class Daemon(DaemonThread):
|
||||||
|
@ -132,24 +132,24 @@ class Daemon(DaemonThread):
|
||||||
def init_server(self, config, fd):
|
def init_server(self, config, fd):
|
||||||
host = config.get('rpchost', '127.0.0.1')
|
host = config.get('rpchost', '127.0.0.1')
|
||||||
port = config.get('rpcport', 0)
|
port = config.get('rpcport', 0)
|
||||||
try:
|
# try:
|
||||||
server = SimpleJSONRPCServer((host, port), logRequests=False,
|
# server = SimpleJSONRPCServer((host, port), logRequests=False, requestHandler=RequestHandler)
|
||||||
requestHandler=RequestHandler)
|
# except Exception as e:
|
||||||
except Exception as e:
|
# self.print_error('Warning: cannot initialize RPC server on host', host, e)
|
||||||
self.print_error('Warning: cannot initialize RPC server on host', host, e)
|
# self.server = None
|
||||||
self.server = None
|
# os.close(fd)
|
||||||
os.close(fd)
|
# return
|
||||||
return
|
# os.write(fd, bytes(repr((server.socket.getsockname(), time.time())), 'utf8'))
|
||||||
os.write(fd, bytes(repr((server.socket.getsockname(), time.time())), 'utf8'))
|
# os.close(fd)
|
||||||
os.close(fd)
|
# server.timeout = 0.1
|
||||||
server.timeout = 0.1
|
# for cmdname in known_commands:
|
||||||
for cmdname in known_commands:
|
# server.register_function(getattr(self.cmd_runner, cmdname), cmdname)
|
||||||
server.register_function(getattr(self.cmd_runner, cmdname), cmdname)
|
# server.register_function(self.run_cmdline, 'run_cmdline')
|
||||||
server.register_function(self.run_cmdline, 'run_cmdline')
|
# server.register_function(self.ping, 'ping')
|
||||||
server.register_function(self.ping, 'ping')
|
# server.register_function(self.run_daemon, 'daemon')
|
||||||
server.register_function(self.run_daemon, 'daemon')
|
# server.register_function(self.run_gui, 'gui')
|
||||||
server.register_function(self.run_gui, 'gui')
|
# self.server = server
|
||||||
self.server = server
|
self.server = None
|
||||||
|
|
||||||
def ping(self):
|
def ping(self):
|
||||||
return True
|
return True
|
||||||
|
@ -260,9 +260,9 @@ class Daemon(DaemonThread):
|
||||||
# arguments passed to function
|
# arguments passed to function
|
||||||
args = map(lambda x: config.get(x), cmd.params)
|
args = map(lambda x: config.get(x), cmd.params)
|
||||||
# decode json arguments
|
# decode json arguments
|
||||||
args = map(json_decode, args)
|
args = [json_decode(i) for i in args]
|
||||||
# options
|
# options
|
||||||
args += map(lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options)
|
args += list(map(lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options))
|
||||||
cmd_runner = Commands(config, wallet, self.network)
|
cmd_runner = Commands(config, wallet, self.network)
|
||||||
func = getattr(cmd_runner, cmd.name)
|
func = getattr(cmd_runner, cmd.name)
|
||||||
result = func(*args)
|
result = func(*args)
|
||||||
|
|
|
@ -149,7 +149,7 @@ class Imported_KeyStore(Software_KeyStore):
|
||||||
except Exception:
|
except Exception:
|
||||||
raise BaseException('Invalid private key')
|
raise BaseException('Invalid private key')
|
||||||
# allow overwrite
|
# allow overwrite
|
||||||
self.keypairs[pubkey] = pw_encode(sec, password)
|
self.keypairs[pubkey] = pw_encode(sec, password).decode('ascii')
|
||||||
return pubkey
|
return pubkey
|
||||||
|
|
||||||
def delete_imported_key(self, key):
|
def delete_imported_key(self, key):
|
||||||
|
@ -179,7 +179,7 @@ class Imported_KeyStore(Software_KeyStore):
|
||||||
new_password = None
|
new_password = None
|
||||||
for k, v in self.keypairs.items():
|
for k, v in self.keypairs.items():
|
||||||
b = pw_decode(v, old_password)
|
b = pw_decode(v, old_password)
|
||||||
c = pw_encode(b, new_password)
|
c = pw_encode(b, new_password).decode('ascii')
|
||||||
self.keypairs[k] = c
|
self.keypairs[k] = c
|
||||||
|
|
||||||
|
|
||||||
|
@ -309,13 +309,13 @@ class BIP32_KeyStore(Deterministic_KeyStore, Xpub):
|
||||||
new_password = None
|
new_password = None
|
||||||
if self.has_seed():
|
if self.has_seed():
|
||||||
decoded = self.get_seed(old_password)
|
decoded = self.get_seed(old_password)
|
||||||
self.seed = pw_encode(decoded, new_password)
|
self.seed = pw_encode(decoded, new_password).decode('ascii')
|
||||||
if self.passphrase:
|
if self.passphrase:
|
||||||
decoded = self.get_passphrase(old_password)
|
decoded = self.get_passphrase(old_password)
|
||||||
self.passphrase = pw_encode(decoded, new_password)
|
self.passphrase = pw_encode(decoded, new_password).decode('ascii')
|
||||||
if self.xprv is not None:
|
if self.xprv is not None:
|
||||||
b = pw_decode(self.xprv, old_password)
|
b = pw_decode(self.xprv, old_password)
|
||||||
self.xprv = pw_encode(b, new_password)
|
self.xprv = pw_encode(b, new_password).decode('ascii')
|
||||||
|
|
||||||
def is_watching_only(self):
|
def is_watching_only(self):
|
||||||
return self.xprv is None
|
return self.xprv is None
|
||||||
|
@ -478,7 +478,7 @@ class Old_KeyStore(Deterministic_KeyStore):
|
||||||
new_password = None
|
new_password = None
|
||||||
if self.has_seed():
|
if self.has_seed():
|
||||||
decoded = self.get_hex_seed(old_password)
|
decoded = self.get_hex_seed(old_password)
|
||||||
self.seed = pw_encode(decoded, new_password)
|
self.seed = pw_encode(decoded, new_password).decode('ascii')
|
||||||
|
|
||||||
|
|
||||||
class Hardware_KeyStore(KeyStore, Xpub):
|
class Hardware_KeyStore(KeyStore, Xpub):
|
||||||
|
|
|
@ -173,7 +173,7 @@ class Mnemonic(object):
|
||||||
return i % custom_entropy == 0
|
return i % custom_entropy == 0
|
||||||
|
|
||||||
def make_seed(self, seed_type='standard', num_bits=132, custom_entropy=1):
|
def make_seed(self, seed_type='standard', num_bits=132, custom_entropy=1):
|
||||||
import version
|
from . import version
|
||||||
prefix = version.seed_prefix(seed_type)
|
prefix = version.seed_prefix(seed_type)
|
||||||
# increase num_bits in order to obtain a uniform distibution for the last word
|
# increase num_bits in order to obtain a uniform distibution for the last word
|
||||||
bpw = math.log(len(self.wordlist), 2)
|
bpw = math.log(len(self.wordlist), 2)
|
||||||
|
|
|
@ -345,7 +345,6 @@ def sign_request_with_alias(pr, alias, alias_privkey):
|
||||||
pr.signature = ec_key.sign_message(message, compressed, address)
|
pr.signature = ec_key.sign_message(message, compressed, address)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def verify_cert_chain(chain):
|
def verify_cert_chain(chain):
|
||||||
""" Verify a chain of certificates. The last certificate is the CA"""
|
""" Verify a chain of certificates. The last certificate is the CA"""
|
||||||
load_ca_list()
|
load_ca_list()
|
||||||
|
|
14
lib/pem.py
14
lib/pem.py
|
@ -127,12 +127,12 @@ def pem(b, name):
|
||||||
-----END CERTIFICATE-----
|
-----END CERTIFICATE-----
|
||||||
"""
|
"""
|
||||||
s1 = b2a_base64(b)[:-1] # remove terminating \n
|
s1 = b2a_base64(b)[:-1] # remove terminating \n
|
||||||
s2 = ""
|
s2 = b""
|
||||||
while s1:
|
while s1:
|
||||||
s2 += s1[:64] + "\n"
|
s2 += s1[:64] + b"\n"
|
||||||
s1 = s1[64:]
|
s1 = s1[64:]
|
||||||
s = ("-----BEGIN %s-----\n" % name) + s2 + \
|
s = ("-----BEGIN %s-----\n" % name).encode('ascii') + s2 + \
|
||||||
("-----END %s-----\n" % name)
|
("-----END %s-----\n" % name).encode('ascii')
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def pemSniff(inStr, name):
|
def pemSniff(inStr, name):
|
||||||
|
@ -152,8 +152,8 @@ def parse_private_key(s):
|
||||||
raise SyntaxError("Not a PEM private key file")
|
raise SyntaxError("Not a PEM private key file")
|
||||||
|
|
||||||
|
|
||||||
def _parsePKCS8(bytes):
|
def _parsePKCS8(_bytes):
|
||||||
s = ASN1_Node(str(bytes))
|
s = ASN1_Node(_bytes)
|
||||||
root = s.root()
|
root = s.root()
|
||||||
version_node = s.first_child(root)
|
version_node = s.first_child(root)
|
||||||
version = bytestr_to_int(s.get_value_of_type(version_node, 'INTEGER'))
|
version = bytestr_to_int(s.get_value_of_type(version_node, 'INTEGER'))
|
||||||
|
@ -192,5 +192,5 @@ def _parseASN1PrivateKey(s):
|
||||||
dP = s.next_node(q)
|
dP = s.next_node(q)
|
||||||
dQ = s.next_node(dP)
|
dQ = s.next_node(dP)
|
||||||
qInv = s.next_node(dQ)
|
qInv = s.next_node(dQ)
|
||||||
return map(lambda x: bytesToNumber(s.get_value_of_type(x, 'INTEGER')), [n, e, d, p, q, dP, dQ, qInv])
|
return list(map(lambda x: bytesToNumber(s.get_value_of_type(x, 'INTEGER')), [n, e, d, p, q, dP, dQ, qInv]))
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,6 @@
|
||||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import division
|
|
||||||
from __future__ import print_function
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import six
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
@ -192,7 +186,7 @@ class Plugins(DaemonThread):
|
||||||
|
|
||||||
|
|
||||||
def hook(func):
|
def hook(func):
|
||||||
hook_names.add(func.func_name)
|
hook_names.add(func.__name__)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
def run_hook(name, *args):
|
def run_hook(name, *args):
|
||||||
|
|
|
@ -22,12 +22,6 @@
|
||||||
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
from __future__ import absolute_import
|
|
||||||
from __future__ import division
|
|
||||||
from __future__ import print_function
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import six
|
|
||||||
import os
|
import os
|
||||||
import ast
|
import ast
|
||||||
import threading
|
import threading
|
||||||
|
|
|
@ -586,7 +586,8 @@ def parse_URI(uri, on_pr=None):
|
||||||
request = pr.PaymentRequest(s)
|
request = pr.PaymentRequest(s)
|
||||||
else:
|
else:
|
||||||
request = pr.get_payment_request(r)
|
request = pr.get_payment_request(r)
|
||||||
on_pr(request)
|
if on_pr:
|
||||||
|
on_pr(request)
|
||||||
t = threading.Thread(target=get_payment_request_thread)
|
t = threading.Thread(target=get_payment_request_thread)
|
||||||
t.setDaemon(True)
|
t.setDaemon(True)
|
||||||
t.start()
|
t.start()
|
||||||
|
@ -698,7 +699,6 @@ class SocketPipe:
|
||||||
self._send(out)
|
self._send(out)
|
||||||
|
|
||||||
def send_all(self, requests):
|
def send_all(self, requests):
|
||||||
print(requests)
|
|
||||||
out = b''.join(map(lambda x: (json.dumps(x) + '\n').encode('utf8'), requests))
|
out = b''.join(map(lambda x: (json.dumps(x) + '\n').encode('utf8'), requests))
|
||||||
self._send(out)
|
self._send(out)
|
||||||
|
|
||||||
|
|
|
@ -1537,8 +1537,6 @@ class Deterministic_Wallet(Abstract_Wallet):
|
||||||
return self.get_master_public_key()
|
return self.get_master_public_key()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Simple_Wallet(Abstract_Wallet):
|
class Simple_Wallet(Abstract_Wallet):
|
||||||
|
|
||||||
""" Wallet with a single pubkey per address """
|
""" Wallet with a single pubkey per address """
|
||||||
|
|
53
lib/x509.py
53
lib/x509.py
|
@ -63,6 +63,7 @@ ASN1_TYPES = {
|
||||||
'PrintableString' : 0x13,
|
'PrintableString' : 0x13,
|
||||||
'IA5String' : 0x16,
|
'IA5String' : 0x16,
|
||||||
'UTCTime' : 0x17,
|
'UTCTime' : 0x17,
|
||||||
|
'GeneralizedTime' : 0x18,
|
||||||
'ENUMERATED' : 0x0A,
|
'ENUMERATED' : 0x0A,
|
||||||
'UTF8String' : 0x0C,
|
'UTF8String' : 0x0C,
|
||||||
}
|
}
|
||||||
|
@ -75,7 +76,7 @@ class CertificateError(Exception):
|
||||||
# helper functions
|
# helper functions
|
||||||
def bitstr_to_bytestr(s):
|
def bitstr_to_bytestr(s):
|
||||||
if s[0] != 0x00:
|
if s[0] != 0x00:
|
||||||
raise BaseException('no padding')
|
raise TypeError('no padding')
|
||||||
return s[1:]
|
return s[1:]
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ class ASN1_Node(bytes):
|
||||||
def get_node(self, ix):
|
def get_node(self, ix):
|
||||||
# return index of first byte, first content byte and last byte.
|
# return index of first byte, first content byte and last byte.
|
||||||
first = self[ix + 1]
|
first = self[ix + 1]
|
||||||
if (self[ix + 1] & 0x80) == 0:
|
if (first & 0x80) == 0:
|
||||||
length = first
|
length = first
|
||||||
ixf = ix + 2
|
ixf = ix + 2
|
||||||
ixl = ixf + length - 1
|
ixl = ixf + length - 1
|
||||||
|
@ -138,7 +139,7 @@ class ASN1_Node(bytes):
|
||||||
def first_child(self, node):
|
def first_child(self, node):
|
||||||
ixs, ixf, ixl = node
|
ixs, ixf, ixl = node
|
||||||
if self[ixs] & 0x20 != 0x20:
|
if self[ixs] & 0x20 != 0x20:
|
||||||
raise BaseException('Can only open constructed types.', hex(self[ixs]))
|
raise TypeError('Can only open constructed types.', hex(self[ixs]))
|
||||||
return self.get_node(ixf)
|
return self.get_node(ixf)
|
||||||
|
|
||||||
def is_child_of(node1, node2):
|
def is_child_of(node1, node2):
|
||||||
|
@ -155,7 +156,7 @@ class ASN1_Node(bytes):
|
||||||
# verify type byte and return content
|
# verify type byte and return content
|
||||||
ixs, ixf, ixl = node
|
ixs, ixf, ixl = node
|
||||||
if ASN1_TYPES[asn1_type] != self[ixs]:
|
if ASN1_TYPES[asn1_type] != self[ixs]:
|
||||||
raise BaseException('Wrong type:', hex(self[ixs]), hex(ASN1_TYPES[asn1_type]))
|
raise TypeError('Wrong type:', hex(self[ixs]), hex(ASN1_TYPES[asn1_type]))
|
||||||
return self[ixf:ixl + 1]
|
return self[ixf:ixl + 1]
|
||||||
|
|
||||||
def get_value(self, node):
|
def get_value(self, node):
|
||||||
|
@ -217,9 +218,15 @@ class X509(object):
|
||||||
# validity
|
# validity
|
||||||
validity = der.next_node(issuer)
|
validity = der.next_node(issuer)
|
||||||
ii = der.first_child(validity)
|
ii = der.first_child(validity)
|
||||||
self.notBefore = der.get_value_of_type(ii, 'UTCTime')
|
try:
|
||||||
|
self.notBefore = der.get_value_of_type(ii, 'UTCTime')
|
||||||
|
except TypeError:
|
||||||
|
self.notBefore = der.get_value_of_type(ii, 'GeneralizedTime')[2:] # strip year
|
||||||
ii = der.next_node(ii)
|
ii = der.next_node(ii)
|
||||||
self.notAfter = der.get_value_of_type(ii, 'UTCTime')
|
try:
|
||||||
|
self.notAfter = der.get_value_of_type(ii, 'UTCTime')
|
||||||
|
except TypeError:
|
||||||
|
self.notAfter = der.get_value_of_type(ii, 'GeneralizedTime')[2:] # strip year
|
||||||
|
|
||||||
# subject
|
# subject
|
||||||
subject = der.next_node(validity)
|
subject = der.next_node(validity)
|
||||||
|
@ -229,17 +236,22 @@ class X509(object):
|
||||||
ii = der.first_child(public_key_algo)
|
ii = der.first_child(public_key_algo)
|
||||||
self.public_key_algo = decode_OID(der.get_value_of_type(ii, 'OBJECT IDENTIFIER'))
|
self.public_key_algo = decode_OID(der.get_value_of_type(ii, 'OBJECT IDENTIFIER'))
|
||||||
|
|
||||||
# pubkey modulus and exponent
|
if self.public_key_algo != '1.2.840.10045.2.1': # for non EC public key
|
||||||
subject_public_key = der.next_node(public_key_algo)
|
# pubkey modulus and exponent
|
||||||
spk = der.get_value_of_type(subject_public_key, 'BIT STRING')
|
subject_public_key = der.next_node(public_key_algo)
|
||||||
spk = ASN1_Node(bitstr_to_bytestr(spk))
|
spk = der.get_value_of_type(subject_public_key, 'BIT STRING')
|
||||||
r = spk.root()
|
spk = ASN1_Node(bitstr_to_bytestr(spk))
|
||||||
modulus = spk.first_child(r)
|
r = spk.root()
|
||||||
exponent = spk.next_node(modulus)
|
modulus = spk.first_child(r)
|
||||||
rsa_n = spk.get_value_of_type(modulus, 'INTEGER')
|
exponent = spk.next_node(modulus)
|
||||||
rsa_e = spk.get_value_of_type(exponent, 'INTEGER')
|
rsa_n = spk.get_value_of_type(modulus, 'INTEGER')
|
||||||
self.modulus = ecdsa.util.string_to_number(rsa_n)
|
rsa_e = spk.get_value_of_type(exponent, 'INTEGER')
|
||||||
self.exponent = ecdsa.util.string_to_number(rsa_e)
|
self.modulus = ecdsa.util.string_to_number(rsa_n)
|
||||||
|
self.exponent = ecdsa.util.string_to_number(rsa_e)
|
||||||
|
else:
|
||||||
|
subject_public_key = der.next_node(public_key_algo)
|
||||||
|
spk = der.get_value_of_type(subject_public_key, 'BIT STRING')
|
||||||
|
self.ec_public_key = spk
|
||||||
|
|
||||||
# extensions
|
# extensions
|
||||||
self.CA = False
|
self.CA = False
|
||||||
|
@ -308,14 +320,17 @@ def load_certificates(ca_path):
|
||||||
from . import pem
|
from . import pem
|
||||||
ca_list = {}
|
ca_list = {}
|
||||||
ca_keyID = {}
|
ca_keyID = {}
|
||||||
with open(ca_path, 'rb') as f:
|
# ca_path = '/tmp/tmp.txt'
|
||||||
s = f.read().decode('ascii')
|
with open(ca_path, 'r') as f:
|
||||||
|
s = f.read()
|
||||||
bList = pem.dePemList(s, "CERTIFICATE")
|
bList = pem.dePemList(s, "CERTIFICATE")
|
||||||
for b in bList:
|
for b in bList:
|
||||||
try:
|
try:
|
||||||
x = X509(b)
|
x = X509(b)
|
||||||
x.check_date()
|
x.check_date()
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
|
# with open('/tmp/tmp.txt', 'w') as f:
|
||||||
|
# f.write(pem.pem(b, 'CERTIFICATE').decode('ascii'))
|
||||||
util.print_error("cert error:", e)
|
util.print_error("cert error:", e)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
import socket
|
import socket
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import xmlrpclib
|
from xmlrpc.client import ServerProxy
|
||||||
|
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
|
@ -45,7 +45,7 @@ import traceback
|
||||||
|
|
||||||
PORT = 12344
|
PORT = 12344
|
||||||
HOST = 'cosigner.electrum.org'
|
HOST = 'cosigner.electrum.org'
|
||||||
server = xmlrpclib.ServerProxy('http://%s:%d'%(HOST,PORT), allow_none=True)
|
server = ServerProxy('http://%s:%d'%(HOST,PORT), allow_none=True)
|
||||||
|
|
||||||
|
|
||||||
class Listener(util.DaemonThread):
|
class Listener(util.DaemonThread):
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
|
|
||||||
from __future__ import absolute_import
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import base64
|
import base64
|
||||||
|
@ -33,9 +31,9 @@ from functools import partial
|
||||||
import smtplib
|
import smtplib
|
||||||
import imaplib
|
import imaplib
|
||||||
import email
|
import email
|
||||||
from email.MIMEMultipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.MIMEBase import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
from email import Encoders
|
from email.encoders import encode_base64
|
||||||
|
|
||||||
from PyQt4.QtGui import *
|
from PyQt4.QtGui import *
|
||||||
from PyQt4.QtCore import *
|
from PyQt4.QtCore import *
|
||||||
|
@ -49,7 +47,6 @@ from electrum_gui.qt.util import EnterButton, Buttons, CloseButton
|
||||||
from electrum_gui.qt.util import OkButton, WindowModalDialog
|
from electrum_gui.qt.util import OkButton, WindowModalDialog
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Processor(threading.Thread):
|
class Processor(threading.Thread):
|
||||||
polling_interval = 5*60
|
polling_interval = 5*60
|
||||||
|
|
||||||
|
@ -96,7 +93,7 @@ class Processor(threading.Thread):
|
||||||
msg['From'] = self.username
|
msg['From'] = self.username
|
||||||
part = MIMEBase('application', "bitcoin-paymentrequest")
|
part = MIMEBase('application', "bitcoin-paymentrequest")
|
||||||
part.set_payload(payment_request)
|
part.set_payload(payment_request)
|
||||||
Encoders.encode_base64(part)
|
encode_base64(part)
|
||||||
part.add_header('Content-Disposition', 'attachment; filename="payreq.btc"')
|
part.add_header('Content-Disposition', 'attachment; filename="payreq.btc"')
|
||||||
msg.attach(part)
|
msg.attach(part)
|
||||||
s = smtplib.SMTP_SSL(self.imap_server, timeout=2)
|
s = smtplib.SMTP_SSL(self.imap_server, timeout=2)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
from plugin import HW_PluginBase
|
from .plugin import HW_PluginBase
|
||||||
|
|
|
@ -12,8 +12,6 @@ from electrum.plugins import BasePlugin, hook
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LabelsPlugin(BasePlugin):
|
class LabelsPlugin(BasePlugin):
|
||||||
|
|
||||||
def __init__(self, parent, config, name):
|
def __init__(self, parent, config, name):
|
||||||
|
@ -83,7 +81,7 @@ class LabelsPlugin(BasePlugin):
|
||||||
bundle = {"labels": [],
|
bundle = {"labels": [],
|
||||||
"walletId": wallet_id,
|
"walletId": wallet_id,
|
||||||
"walletNonce": self.get_nonce(wallet)}
|
"walletNonce": self.get_nonce(wallet)}
|
||||||
for key, value in wallet.labels.iteritems():
|
for key, value in wallet.labels.items():
|
||||||
try:
|
try:
|
||||||
encoded_key = self.encode(wallet, key)
|
encoded_key = self.encode(wallet, key)
|
||||||
encoded_value = self.encode(wallet, value)
|
encoded_value = self.encode(wallet, value)
|
||||||
|
@ -135,12 +133,12 @@ class LabelsPlugin(BasePlugin):
|
||||||
def start_wallet(self, wallet):
|
def start_wallet(self, wallet):
|
||||||
nonce = self.get_nonce(wallet)
|
nonce = self.get_nonce(wallet)
|
||||||
self.print_error("wallet", wallet.basename(), "nonce is", nonce)
|
self.print_error("wallet", wallet.basename(), "nonce is", nonce)
|
||||||
mpk = wallet.get_fingerprint()
|
mpk = wallet.get_fingerprint().encode('ascii')
|
||||||
if not mpk:
|
if not mpk:
|
||||||
return
|
return
|
||||||
password = hashlib.sha1(mpk).digest().encode('hex')[:32]
|
password = hashlib.sha1(mpk).hexdigest()[:32].encode('ascii')
|
||||||
iv = hashlib.sha256(password).digest()[:16]
|
iv = hashlib.sha256(password).digest()[:16]
|
||||||
wallet_id = hashlib.sha256(mpk).digest().encode('hex')
|
wallet_id = hashlib.sha256(mpk).hexdigest()
|
||||||
self.wallets[wallet] = (password, iv, wallet_id)
|
self.wallets[wallet] = (password, iv, wallet_id)
|
||||||
# If there is an auth token we can try to actually start syncing
|
# If there is an auth token we can try to actually start syncing
|
||||||
t = threading.Thread(target=self.pull_thread, args=(wallet, False))
|
t = threading.Thread(target=self.pull_thread, args=(wallet, False))
|
||||||
|
|
|
@ -9,7 +9,7 @@ from electrum_gui.qt import EnterButton
|
||||||
from electrum_gui.qt.util import ThreadedButton, Buttons
|
from electrum_gui.qt.util import ThreadedButton, Buttons
|
||||||
from electrum_gui.qt.util import WindowModalDialog, OkButton
|
from electrum_gui.qt.util import WindowModalDialog, OkButton
|
||||||
|
|
||||||
from labels import LabelsPlugin
|
from .labels import LabelsPlugin
|
||||||
|
|
||||||
|
|
||||||
class Plugin(LabelsPlugin):
|
class Plugin(LabelsPlugin):
|
||||||
|
|
|
@ -3,8 +3,8 @@ from electrum.plugins import BasePlugin, hook
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
import random
|
import random
|
||||||
|
|
||||||
class Plugin(BasePlugin):
|
|
||||||
|
|
||||||
|
class Plugin(BasePlugin):
|
||||||
vkb = None
|
vkb = None
|
||||||
vkb_index = 0
|
vkb_index = 0
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class Plugin(BasePlugin):
|
||||||
self.vkb_index += 1
|
self.vkb_index += 1
|
||||||
|
|
||||||
def virtual_keyboard(self, i, pw):
|
def virtual_keyboard(self, i, pw):
|
||||||
i = i%3
|
i = i % 3
|
||||||
if i == 0:
|
if i == 0:
|
||||||
chars = 'abcdefghijklmnopqrstuvwxyz '
|
chars = 'abcdefghijklmnopqrstuvwxyz '
|
||||||
elif i == 1:
|
elif i == 1:
|
||||||
|
@ -35,9 +35,9 @@ class Plugin(BasePlugin):
|
||||||
|
|
||||||
n = len(chars)
|
n = len(chars)
|
||||||
s = []
|
s = []
|
||||||
for i in xrange(n):
|
for i in range(n):
|
||||||
while True:
|
while True:
|
||||||
k = random.randint(0,n-1)
|
k = random.randint(0, n - 1)
|
||||||
if k not in s:
|
if k not in s:
|
||||||
s.append(k)
|
s.append(k)
|
||||||
break
|
break
|
||||||
|
@ -53,7 +53,7 @@ class Plugin(BasePlugin):
|
||||||
l_button.setFixedWidth(25)
|
l_button.setFixedWidth(25)
|
||||||
l_button.setFixedHeight(25)
|
l_button.setFixedHeight(25)
|
||||||
l_button.clicked.connect(add_target(chars[s[i]]))
|
l_button.clicked.connect(add_target(chars[s[i]]))
|
||||||
grid.addWidget(l_button, i/6, i%6)
|
grid.addWidget(l_button, i // 6, i % 6)
|
||||||
|
|
||||||
vbox.addLayout(grid)
|
vbox.addLayout(grid)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue