Beispiel #1
0
def verify_sig(sig):
    '''The base function for verifying an ASCII-armored signature.'''
    sig_info = parse_sig(sig)
    if sig_info:
        message = strip_armor(sig)
        valid = bitcoinecdsa.verify(sig_info['signature_address'], message,
                                    sig_info['signature'])
    else:
        valid = False
    return {'valid': valid, 'info': sig_info}
Beispiel #2
0
def verify_sig(sig):
    '''The base function for verifying an ASCII-armored signature.'''
    sig_info = parse_sig(sig)
    if sig_info:
        message = strip_armor(sig)
        valid = bitcoinecdsa.verify(
            sig_info['signature_address'],
            message,
            sig_info['signature']
        )
    else:
        valid = False
    return {'valid': valid, 'info': sig_info}
Beispiel #3
0
def sign_and_store_document(rein,
                            doc_type,
                            document,
                            signature_address=None,
                            signature_key=None,
                            store=True):
    """
    Save document if no signature key provided. Otherwise sign document, then validate and store it.
    """
    validated = False
    if signature_key is None:  # signing will happen outside app
        f = open(doc_type + '.txt', 'w')
        f.write(document)
        f.close()
        click.echo("\n%s\n" % document)
        done = False
        while not done:
            filename = click.prompt("File containing signed document",
                                    type=str,
                                    default=doc_type + '.sig.txt')
            if os.path.isfile(filename):
                done = True
        f = open(filename, 'r')
        signed = f.read()
        res = validate_enrollment(signed)
        if res:
            validated = True
    else:  # sign with stored delegate key
        signature = sign(signature_key, document)
        validated = verify(signature_address, document, signature)

    if validated:
        # insert signed document into documents table
        b = "-----BEGIN BITCOIN SIGNED MESSAGE-----"
        c = "-----BEGIN SIGNATURE-----"
        d = "-----END BITCOIN SIGNED MESSAGE-----"
        signed = "%s\n%s\n%s\n%s\n%s\n%s" % (b, document, c, signature_address,
                                             signature, d)
        click.echo('\n' + signed + '\n')
        if store:
            d = Document(rein,
                         doc_type,
                         signed,
                         sig_verified=True,
                         testnet=rein.testnet)
            rein.session.add(d)
            rein.session.commit()
        return d
    return validated
Beispiel #4
0
def delete():
    '''Delete a key-value pair.'''
    # Validate JSON body w/ API params
    try:
        body = request.data.decode('utf-8')
        in_obj = json.loads(body)
    except:
        return ("JSON Decode failed", 400, {'Content-Type': 'text/plain'})

    k = in_obj['key']
    d = in_obj['address']
    n = in_obj['nonce']
    s = in_obj['signature']

    # check signature
    owner = Owner.query.filter_by(delegate=d).first()
    if owner.nonce not in n or verify(o, k + o + n, s):
        body = json.dumps({'error': 'Incorrect signature.'})
        code = 401
    else:
        # check if key already exists and is owned by the same owner
        kv = db.session.query(Kv).filter_by(key=k).filter_by(owner=o).first()
        if kv is None:
            body = json.dumps(
                {'error': 'Key not found or not owned by caller.'})
            code = 404
        else:
            # free up storage quota and remove kv
            size = len(kv.value)
            sale_id = kv.sale
            s = db.session.query(Sale).get(sale_id)
            s.bytes_used = s.bytes_used - size
            db.session.delete(kv)
            db.session.commit()
            body = json.dumps({'result': 'success'})
            code = 200

    return (body, code, {
        'Content-length': len(body),
        'Content-type': 'application/json',
    })
Beispiel #5
0
def get_deposit_address():
    '''Return new or unused deposit address for on-chain funding.'''
    # check if user exists
    o = db.session.query(Owner).get(request.args.get('address'))
    if o is None:
        return abort(500)

    address = request.args.get('address')
    message = request.args.get('contact') + "," + address
    signature = request.args.get('signature')

    print(len(signature))
    if len(signature) == 88 and verify(address, message, signature):
        body = json.dumps({'address': 'hereyago'})
    else:
        body = json.dumps({'error': 'Invalid signature'})

    return (body, 200, {
        'Content-length': len(body),
        'Content-type': 'application/json',
    })
Beispiel #6
0
def get_deposit_address():
    '''Return new or unused deposit address for on-chain funding.'''
    # check if user exists
    o = db.session.query(Owner).get(request.args.get('address'))
    if o is None:
        return abort(500)

    address = request.args.get('address')
    message = request.args.get('contact') + "," + address
    signature = request.args.get('signature')

    print(len(signature))
    if len(signature) == 88 and verify(address, message, signature):
        body = json.dumps({'address': 'hereyago'})
    else:
        body = json.dumps({'error': 'Invalid signature'})

    return (body, 200, {'Content-length': len(body),
                        'Content-type': 'application/json',
                       }
           )
Beispiel #7
0
def delete():
    '''Delete a key-value pair.'''
    # Validate JSON body w/ API params
    try:
        body = request.data.decode('utf-8')
        in_obj = json.loads(body)
    except:
        return ("JSON Decode failed", 400, {'Content-Type':'text/plain'})

    k = in_obj['key']
    d = in_obj['address']
    n = in_obj['nonce']
    s = in_obj['signature']

    # check signature
    owner = Owner.query.filter_by(delegate=d).first()
    if owner.nonce not in n or verify(o, k + o + n, s):
        body = json.dumps({'error': 'Incorrect signature.'})
        code = 401
    else:
        # check if key already exists and is owned by the same owner
        kv = db.session.query(Kv).filter_by(key=k).filter_by(owner=o).first()
        if kv is None:
            body = json.dumps({'error': 'Key not found or not owned by caller.'})
            code = 404
        else:
            # free up storage quota and remove kv
            size = len(kv.value)
            sale_id = kv.sale
            s = db.session.query(Sale).get(sale_id)
            s.bytes_used = s.bytes_used - size
            db.session.delete(kv)
            db.session.commit()
            body = json.dumps({'result': 'success'})
            code = 200
    
    return (body, code, {'Content-length': len(body),
                         'Content-type': 'application/json',
                        }
           )
Beispiel #8
0
def sign_and_store_document(rein, doc_type, document, signature_address=None, signature_key=None, store=True):
    """
    Save document if no signature key provided. Otherwise sign document, then validate and store it.
    """
    validated = False
    if signature_key is None:  # signing will happen outside app
        f = open(doc_type + '.txt', 'w')
        f.write(document)
        f.close()
        click.echo("\n%s\n" % document)
        done = False
        while not done:
            filename = click.prompt("File containing signed document", type=str, default=doc_type + '.sig.txt')
            if os.path.isfile(filename):
                done = True
        f = open(filename, 'r')
        signed = f.read()
        res = validate_enrollment(signed)
        if res:
            validated = True
    else:                       # sign with stored delegate key
        signature = sign(signature_key, document)
        validated = verify(signature_address, document, signature)

    if validated:
        # insert signed document into documents table
        b = "-----BEGIN BITCOIN SIGNED MESSAGE-----"
        c = "-----BEGIN SIGNATURE-----"
        d = "-----END BITCOIN SIGNED MESSAGE-----"
        signed = "%s\n%s\n%s\n%s\n%s\n%s" % (b, document, c, signature_address, signature, d)
        click.echo('\n' + signed + '\n')
        if store:
            d = Document(rein, doc_type, signed, sig_verified=True, testnet=rein.testnet)
            rein.session.add(d)
            rein.session.commit()
        return d
    return validated
Beispiel #9
0
def put():
    '''Store a key-value pair.'''
    # get size of file sent
    # Validate JSON body w/ API params
    try:
        body = request.data.decode('utf-8')
        in_obj = json.loads(body)
    except:
        return ("JSON Decode failed", 400, {'Content-Type': 'text/plain'})

    k = in_obj['key']
    v = in_obj['value']
    o = in_obj['owner']
    n = in_obj['nonce']
    s = in_obj['signature']
    d = in_obj['signature_address']
    if 'testnet' in in_obj:
        testnet = in_obj['testnet']
    else:
        testnet = False

    owner = Owner.query.filter_by(address=o).first()
    if owner is None:
        body = json.dumps({'error': 'User not found'})
        code = 403
    elif owner.nonce != n:
        body = json.dumps({'error': 'Bad nonce'})
        code = 401
    elif not verify(d, k + v + d + n, s):
        body = json.dumps({'error': 'Incorrect signature'})
        code = 401
    else:
        size = len(k) + len(v)

        # need to also check that we have an enrollment that makes this a delegate of this owner

        # check if owner has enough free storage
        # get free space from each of owner's buckets
        result = db.engine.execute(
            'select * from sale where julianday("now") - \
                    julianday(sale.created) < sale.term order by sale.created desc'
        )
        # choose newest bucket that has enough space
        sale_id = None
        for row in result:
            if (row[7] + size) < (1024 * 1024):
                sale_id = row[0]

        if sale_id is None:  # we couldn't find enough free space
            body = json.dumps({'error': 'Insufficient storage space.'})
            code = 403
        else:
            # check if key already exists and is owned by the same owner
            kv = db.session.query(Kv).filter(and_(Kv.key == k,
                                                  Kv.owner == o)).first()
            if kv is None:
                kv = Kv(k, v, o, sale_id, testnet)
                db.session.add(kv)
                db.session.commit()
            else:
                kv.value = v
                db.session.commit()

            s = db.session.query(Sale).get(sale_id)
            s.bytes_used = s.bytes_used + size
            db.session.commit()
            body = json.dumps({'result': 'success'})
            code = 201

    return (body, code, {
        'Content-length': len(body),
        'Content-type': 'application/json',
    })
Beispiel #10
0
def put():
    '''Store a key-value pair.'''
    # get size of file sent
    # Validate JSON body w/ API params
    try:
        body = request.data.decode('utf-8')
        in_obj = json.loads(body)
    except:
        return ("JSON Decode failed", 400, {'Content-Type':'text/plain'})

    k = in_obj['key']
    v = in_obj['value']
    o = in_obj['owner']
    n = in_obj['nonce']
    s = in_obj['signature']
    d = in_obj['signature_address']
    if 'testnet' in in_obj:
        testnet = in_obj['testnet']
    else:
        testnet = False

    owner = Owner.query.filter_by(address=o).first()
    if owner is None:
        body = json.dumps({'error': 'User not found'})
        code = 403
    elif owner.nonce != n:
        body = json.dumps({'error': 'Bad nonce'})
        code = 401
    elif not verify(d, k + v + d + n, s) :
        body = json.dumps({'error': 'Incorrect signature'})
        code = 401
    else:
        size = len(k) + len(v)

        # need to also check that we have an enrollment that makes this a delegate of this owner

        # check if owner has enough free storage
        # get free space from each of owner's buckets
        result = db.engine.execute('select * from sale where julianday("now") - \
                    julianday(sale.created) < sale.term order by sale.created desc')
        # choose newest bucket that has enough space
        sale_id = None
        for row in result:
            if (row[7] + size) < (1024 * 1024):
                sale_id = row[0]
    
        if sale_id is None:     # we couldn't find enough free space
            body = json.dumps({'error': 'Insufficient storage space.'})
            code = 403 
        else:
            # check if key already exists and is owned by the same owner
            kv = db.session.query(Kv).filter(and_(Kv.key == k, Kv.owner == o)).first()
            if kv is None:
                kv = Kv(k, v, o, sale_id, testnet)
                db.session.add(kv)
                db.session.commit()
            else:
                kv.value = v
                db.session.commit()
    
            s = db.session.query(Sale).get(sale_id)
            s.bytes_used = s.bytes_used + size
            db.session.commit()
            body = json.dumps({'result': 'success'})
            code = 201
    
    return (body, code, {'Content-length': len(body),
                        'Content-type': 'application/json',
                        }
           )