def setUp(self): layer = serial.loads( 'cereal1\n2\ndict\nCrypto.PublicKey.RSA._RSAobj\n6\nl65537L' '\ns1\nel572396271319355377302563592532289659494057533229597' '51710497474978922545181152759845508370178512234195180734902' '12419530396241354979963274248658624171029071725537151731993' '42933079891189457563201701117839696266295625152139367640601' '66443728541654900932569585341275738092423626919561311239635' '547176809158404659713L\ns1\ndl12728397948376965717385352254' '27139909550150941750411661187185470172925774815828047636767' '79872053348685177789877867582370921033415215069592981250085' '60556879090635468400999031563232300384449880853932718970353' '29805338834524020288467900702919724732303093984109904938853' '65647029509787184463935331239873911603698563L\ns1\nnl125577' '19737462719423110792947834292566930717591137982174999804751' '57426272766733316753566802241203955973889242142431112011040' '3860412744740476425917223401771L\ns1\nql1013591497061769252' '04895782750537719326038384264015503840615434274912532862261' '49765674778971387525351166395571997688812581139239675783599' '201065332383615753L\ns1\npl97225030816482359917484417766934' '30964287586773695586071056462460373031449533752987373837199' '72700016650629608621663588495627267552627999501333835100675' '9420L\ns1\nur0\nr1\n' ) layer._randfunc = os.urandom self.layers = [('keyid', layer)] _ESCROW_KEYS_CACHE['keyid'] = layer self.sign_key = serial.loads( 'cereal1\n2\ndict\nCrypto.PublicKey.RSA._RSAobj\n6\nl65537L' '\ns1\nel488998731920803595820925672497412329981375135192610' '84857389376383295791619483445264680079462203305484701008340' '57980910145198252592264933868738967927974809918625147286702' '92149399952343077067798254508626729649869563459616085824789' '31737856189011389458886653057704339590120539561170419572137' '549729675692397744513L\ns1\ndl13662819702376238599640179825' '40199175903367250815063829424764478185562881721558045835325' '02034209499980851380611211585482684966695148050379841211519' '90777846717237250189829960261537886730596610705749175213240' '29345221905361630262971841665103104788484983174076861127496' '93363485578857292553118398596402906394535309L\ns1\nnl125153' '92213883511393234180326019375584559651650302222103156776465' '77673640645230891483338041681039093600136032724891701279815' '4161197516362175629467657595419L\ns1\nql1091681304819186470' '75257045239424491842722017497241906220305724398464847269465' '01870670684745169890379365398342306412289577240231138208678' '788024638742440311L\ns1\npl43686597982280522901322472960701' '29738889210109581129368500126135091705488019320241792983277' '84798183272094286556009959784668608746730102217136755267929' '8862L\ns1\nur0\nr1\n' ) self.sign_key._randfunc = os.urandom
def setUp(self): layer = serial.loads( 'cereal1\n2\ndict\nCrypto.PublicKey.RSA._RSAobj\n6\nl65537L' '\ns1\nel572396271319355377302563592532289659494057533229597' '51710497474978922545181152759845508370178512234195180734902' '12419530396241354979963274248658624171029071725537151731993' '42933079891189457563201701117839696266295625152139367640601' '66443728541654900932569585341275738092423626919561311239635' '547176809158404659713L\ns1\ndl12728397948376965717385352254' '27139909550150941750411661187185470172925774815828047636767' '79872053348685177789877867582370921033415215069592981250085' '60556879090635468400999031563232300384449880853932718970353' '29805338834524020288467900702919724732303093984109904938853' '65647029509787184463935331239873911603698563L\ns1\nnl125577' '19737462719423110792947834292566930717591137982174999804751' '57426272766733316753566802241203955973889242142431112011040' '3860412744740476425917223401771L\ns1\nql1013591497061769252' '04895782750537719326038384264015503840615434274912532862261' '49765674778971387525351166395571997688812581139239675783599' '201065332383615753L\ns1\npl97225030816482359917484417766934' '30964287586773695586071056462460373031449533752987373837199' '72700016650629608621663588495627267552627999501333835100675' '9420L\ns1\nur0\nr1\n') layer._randfunc = os.urandom self.layers = [('keyid', layer)] _ESCROW_KEYS_CACHE['keyid'] = layer self.sign_key = serial.loads( 'cereal1\n2\ndict\nCrypto.PublicKey.RSA._RSAobj\n6\nl65537L' '\ns1\nel488998731920803595820925672497412329981375135192610' '84857389376383295791619483445264680079462203305484701008340' '57980910145198252592264933868738967927974809918625147286702' '92149399952343077067798254508626729649869563459616085824789' '31737856189011389458886653057704339590120539561170419572137' '549729675692397744513L\ns1\ndl13662819702376238599640179825' '40199175903367250815063829424764478185562881721558045835325' '02034209499980851380611211585482684966695148050379841211519' '90777846717237250189829960261537886730596610705749175213240' '29345221905361630262971841665103104788484983174076861127496' '93363485578857292553118398596402906394535309L\ns1\nnl125153' '92213883511393234180326019375584559651650302222103156776465' '77673640645230891483338041681039093600136032724891701279815' '4161197516362175629467657595419L\ns1\nql1091681304819186470' '75257045239424491842722017497241906220305724398464847269465' '01870670684745169890379365398342306412289577240231138208678' '788024638742440311L\ns1\npl43686597982280522901322472960701' '29738889210109581129368500126135091705488019320241792983277' '84798183272094286556009959784668608746730102217136755267929' '8862L\ns1\nur0\nr1\n') self.sign_key._randfunc = os.urandom
def login(self, brand, username, password, verify=True): self.log.info('logging in with brand %r, username %r', brand, username) self.brand = brand self.username = username self.password = password self.log.debug('requesting challenge') r = requests.get(self.url + 'authsession', params={ 'brand_id': self.brand, 'username': self.username, }) data = r.json() self.log.debug('received challenge') self.layers = serial.loads(b64decode(data['layer_data'])) self.challenge_b64 = data['challenge'] self.challenge = b64decode(self.challenge_b64) # TODO: should also get a session token of some kind. probably a cookie # http://docs.python-requests.org/en/latest/user/quickstart/#cookies if not verify: self.log.debug('login verification not requested') return self.log.debug('verifying login') r = requests.get(self.url + 'auth', params=self.get_auth_params()) assert r.content == 'OK' self.log.debug('login verified')
def test_that_sign_key_has_no_priv_key(self, gen): gen.return_value = self.sign_key client = self._get_client_with_dummy_credentials() params = client.get_auth_params() sign_key = serial.loads(params['sign_key']) self.assertFalse(sign_key.has_private()) with self.assertRaises(TypeError): sign_key.sign('x' * 32, 'x' * 32)
def read_data(environ, start_response): log = logging.getLogger("read_data") log.debug("start") try: brand_identifier = environ['query_data']['brand_id'][0] escrowed_data = environ['post_data']['escrow_data'][0] serial_sign_key = environ['post_data']['sign_key'][0] except KeyError: log.warn("KeyError at start") return BadRequest()(environ, start_response) try: layer_count = int(environ['post_data'].get('layer_count', [])[0]) except IndexError: layer_count = None sign_key = serial.loads(serial_sign_key) log.debug("Being sent:") log.debug("brand_identifier: %r" % brand_identifier) log.debug("layer_count: %r" % layer_count) try: if layer_count is None: plaintext_data = server.read_escrow_data(brand_identifier, escrowed_data, sign_key=sign_key) else: plaintext_data = server.read_escrow_data(brand_identifier, escrowed_data, layer_count=layer_count, sign_key=sign_key) except ValueError: log.warn("ValueError at reading escrow data") return BadRequest()(environ, start_response) except KeyError: log.warn("KeyError at reading escrow data") return NotFound()(environ, start_response) except Exception: log.exception('500 error in reading escrow data') return ServerError()( environ, start_response, ) log.info("Read data for brand %s" % (brand_identifier, )) return SuperSimple(plaintext_data, ctype="application/octet-stream")(environ, start_response)
def read_data(environ, start_response): log = logging.getLogger("read_data") log.debug("start") try: brand_identifier = environ['query_data']['brand_id'][0] escrowed_data = environ['post_data']['escrow_data'][0] serial_sign_key = environ['post_data']['sign_key'][0] except KeyError: log.warn("KeyError at start") return BadRequest()(environ, start_response) try: layer_count = int(environ['post_data'].get('layer_count', [])[0]) except IndexError: layer_count = None sign_key = serial.loads(serial_sign_key) log.debug("Being sent:") log.debug("brand_identifier: %r" % brand_identifier) log.debug("layer_count: %r" % layer_count) try: if layer_count is None: plaintext_data = server.read_escrow_data(brand_identifier, escrowed_data, sign_key=sign_key) else: plaintext_data = server.read_escrow_data(brand_identifier, escrowed_data, layer_count=layer_count, sign_key=sign_key) except ValueError: log.warn("ValueError at reading escrow data") return BadRequest()(environ, start_response) except KeyError: log.warn("KeyError at reading escrow data") return NotFound()(environ, start_response) except Exception: log.exception('500 error in reading escrow data') return ServerError()(environ, start_response,) log.info("Read data for brand %s" % (brand_identifier,)) return SuperSimple(plaintext_data, ctype="application/octet-stream")(environ, start_response)
def fingerprint(request, api, account_info, config, username): brand_identifier = api.info()['brand_identifier'] layers = serial.loads(server.get_escrow_layers(brand_identifier)) # Generate fingerprint h = sha256() for key_id, key in layers: s = '{0}{1}'.format(key_id, key.publickey().exportKey('DER')) h.update(s) fingerprint = enumerate(key_to_english(h.digest()).split(' ')) fingerprint = ' '.join([word for x, word in fingerprint if x % 2 == 0]) return render_to_response( 'fingerprint.html', dict( user=request.user, username=username, account_info=account_info, fingerprint=fingerprint, ), RequestContext(request))
def fingerprint(request, api, account_info, config, username): brand_identifier = api.info()['brand_identifier'] layers = serial.loads(server.get_escrow_layers(brand_identifier)) # Generate fingerprint h = sha256() for key_id, key in layers: s = '{0}{1}'.format(key_id, key.publickey().exportKey('DER')) h.update(s) fingerprint = enumerate(key_to_english(h.digest()).split(' ')) fingerprint = ' '.join([word for x, word in fingerprint \ if x % 2 == 0]) return render_to_response('fingerprint.html', dict( user=request.user, username=username, account_info=account_info, fingerprint=fingerprint, ), RequestContext(request))
def encrypt_with_layers(escrow_data, sign_key, brand_identifier): escrow_key_layers = loads(server.get_escrow_layers(brand_identifier)) return escrow_binary(escrow_key_layers, escrow_data, sign_key)
def decorator(request): log = logging.getLogger('login_required') log.debug("start") if valid_auth_session(request): return fun(request) else: try: brand_identifier = request.POST['brand_id'] username = request.POST['username'] auth = a2b_base64(request.POST['auth']) serial_sign_key = request.POST['sign_key'] layer_count = int(request.POST['layer_count']) except KeyError: log.error("Got bad request.") return HttpResponseBadRequest() try: sign_key = serial.loads(serial_sign_key) except (serial.EndOfFile, serial.NotSerializerFileError, serial.NotSerializableObjectError): log.error("Got bad request. Unable to load sign key") return HttpResponseBadRequest() decoded_user = urllib.unquote(username) try: data = server.read_escrow_data( brand_identifier, auth, sign_key=sign_key, layer_count=layer_count, ) plaintext_auth = json.loads(data) if ('challenge' not in plaintext_auth or 'password' not in plaintext_auth): log.warn("missing auth key %s" % (brand_identifier, )) return HttpResponseBadRequest() except KeyError: log.warn("missing identifier %s" % (brand_identifier, )) return HttpResponseNotFound() except ValueError: log.warn("bad values for authenticating user %s" % (decoded_user, )) return HttpResponseBadRequest() except Exception: log.exception( "server.read_escrow_data failed for user %s brand %s" % ( decoded_user, brand_identifier, )) return HttpResponseServerError() challenge = valid_challenge(request, plaintext_auth['challenge']) authenticated = authenticator(read_config_file(), decoded_user, plaintext_auth['password']) if not challenge or not authenticated: log.info("Auth failed for %s" % (decoded_user, )) return HttpResponseForbidden() session_challenge = get_challenge(request) secret_box, nonce = create_secret_box(plaintext_auth['password'], session_challenge[0]) request.session['auth'] = { 'secret_box': secret_box, 'nonce': nonce, 'time': session_challenge[1], 'brand_identifier': brand_identifier, 'sign_key': sign_key, 'layer_count': layer_count, } log.info("Auth OK for brand %s with user %s" % ( brand_identifier, decoded_user, )) return fun(request)
def decorator(request): log = logging.getLogger('login_required') log.debug("start") if valid_auth_session(request): return fun(request) else: try: brand_identifier = request.POST['brand_id'] username = request.POST['username'] auth = a2b_base64(request.POST['auth']) serial_sign_key = request.POST['sign_key'] layer_count = int(request.POST['layer_count']) except KeyError: log.error("Got bad request.") return HttpResponseBadRequest() try: sign_key = serial.loads(serial_sign_key) except (serial.EndOfFile, serial.NotSerializerFileError, serial.NotSerializableObjectError): log.error("Got bad request. Unable to load sign key") return HttpResponseBadRequest() decoded_user = urllib.unquote(username) try: data = server.read_escrow_data( brand_identifier, auth, sign_key=sign_key, layer_count=layer_count, ) plaintext_auth = json.loads(data) if ('challenge' not in plaintext_auth or 'password' not in plaintext_auth): log.warn("missing auth key %s" % (brand_identifier,)) return HttpResponseBadRequest() except KeyError: log.warn("missing identifier %s" % (brand_identifier,)) return HttpResponseNotFound() except ValueError: log.warn("bad values for authenticating user %s" % (decoded_user,)) return HttpResponseBadRequest() except Exception: log.exception("server.read_escrow_data failed for user %s brand %s" % (decoded_user, brand_identifier,)) return HttpResponseServerError() challenge = valid_challenge(request, plaintext_auth['challenge']) authenticated = authenticator(get_config(), decoded_user, plaintext_auth['password']) if not challenge or not authenticated: log.info("Auth failed for %s" % (decoded_user,)) return HttpResponseForbidden() session_challenge = get_challenge(request) secret_box, nonce = create_secret_box(plaintext_auth['password'], session_challenge[0]) request.session['auth'] = { 'secret_box': secret_box, 'nonce': nonce, 'time': session_challenge[1], 'brand_identifier': brand_identifier, 'sign_key': sign_key, 'layer_count': layer_count, } log.info("Auth OK for brand %s with user %s" % (brand_identifier, decoded_user, )) return fun(request)