def get_backup_auth_from_node(self, base_url, auth_token, hive_did):
        rt, status_code, err = self.post(base_url + '/api/v1/did/backup_auth',
                                         {"jwt": auth_token})
        if err != None:
            return None, "Post backup_auth error: " + err

        token = rt["backup_token"]
        if token is None:
            return None, "Token is none."

        jws = lib.DefaultJWSParser_Parse(token.encode())
        if not jws:
            return None, "Backup token DefaultJWSParser_Parse error: " + ffi.string(
                lib.DIDError_GetLastErrorMessage()).decode()

        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if aud != self.get_did_string():
            lib.JWT_Destroy(jws)
            return None, "Audience is error."

        issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        if issuer is None:
            return None, "Issuer is none."

        if issuer != hive_did:
            return None, "Issuer is error."

        return token, None
Exemple #2
0
    def backup_client_auth(self, host_url, challenge_response,
                           backup_service_instance_did):
        """
        for vault /backup & /restore
        :return backup access token
        """
        body = self.http.post(host_url + URL_DID_BACKUP_AUTH, None,
                              {"challenge_response": challenge_response})
        if 'token' not in body or not body["token"]:
            raise InvalidParameterException(
                msg='backup_auth: failed to backup auth to backup node.')

        jws = lib.DefaultJWSParser_Parse(body["token"].encode())
        if not jws:
            raise InvalidParameterException(
                msg=
                f'backup_auth: failed to parse token with error {self.get_error_message()}.'
            )

        audience = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if audience != self.get_did_string():
            lib.JWT_Destroy(jws)
            raise InvalidParameterException(
                msg=f'backup_auth: failed to get the audience of the challenge.'
            )

        issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        if issuer != backup_service_instance_did:
            raise InvalidParameterException(
                msg=f'backup_auth: failed to get the issuer of the challenge.')

        return body["token"]
Exemple #3
0
    def backup_client_sign_in(self, host_url, credential, subject):
        """
        for vault /backup & /restore
        :return challenge_response, backup_service_instance_did
        """
        vc = lib.Credential_FromJson(credential.encode(), ffi.NULL)
        if not vc:
            raise InvalidParameterException(
                msg='backup_sign_in: invalid credential.')

        doc_str = ffi.string(
            lib.DIDDocument_ToJson(lib.DIDStore_LoadDID(self.store, self.did),
                                   True)).decode()
        doc = json.loads(doc_str)
        body = self.http.post(host_url + URL_DID_SIGN_IN, None, {"id": doc})
        if 'challenge' not in body or not body["challenge"]:
            raise InvalidParameterException(
                msg='backup_sign_in: failed to sign in to backup node.')

        jws = lib.DefaultJWSParser_Parse(body["challenge"].encode())
        if not jws:
            raise InvalidParameterException(
                msg=
                f'backup_sign_in: failed to parse challenge with error {self.get_error_message()}.'
            )

        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if aud != self.get_did_string():
            lib.JWT_Destroy(jws)
            raise InvalidParameterException(
                msg=
                f'backup_sign_in: failed to get the audience of the challenge.'
            )

        nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
        if nonce is None:
            lib.JWT_Destroy(jws)
            raise InvalidParameterException(
                msg=f'backup_sign_in: failed to get the nonce of the challenge.'
            )

        issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        if issuer is None:
            raise InvalidParameterException(
                msg=
                f'backup_sign_in: failed to get the issuer of the challenge.')

        vp_json = self.create_presentation(vc, nonce, issuer)
        if vp_json is None:
            raise InvalidParameterException(
                msg=f'backup_sign_in: failed to create presentation.')
        challenge_response = self.create_vp_token(
            vp_json, subject, issuer, hive_setting.AUTH_CHALLENGE_EXPIRED)
        if challenge_response is None:
            raise InvalidParameterException(
                msg=f'backup_sign_in: failed to create the challenge response.'
            )
        return challenge_response, issuer
    def get_auth_token_by_sign_in(self, base_url, vc_str, subject):
        vc = lib.Credential_FromJson(vc_str.encode(), ffi.NULL)
        if not vc:
            return None, None, "The credential string is error, unable to rebuild to a credential object."

        #sign_in
        doc = lib.DIDStore_LoadDID(self.store, self.did)
        doc_str = ffi.string(lib.DIDDocument_ToJson(doc, True)).decode()
        doc = json.loads(doc_str)

        rt, status_code, err = self.post(base_url + '/api/v1/did/sign_in',
                                         {"document": doc})

        if err != None:
            return None, None, "Post sign_in error: " + err

        jwt = rt["challenge"]
        if jwt is None:
            return None, None, "Challenge is none."

        # print(jwt)
        jws = lib.DefaultJWSParser_Parse(jwt.encode())
        if not jws:
            return None, None, "Challenge DefaultJWSParser_Parse error: " + ffi.string(
                lib.DIDError_GetLastErrorMessage()).decode()

        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if aud != self.get_did_string():
            lib.JWT_Destroy(jws)
            return None, None, "Audience is error."

        nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
        if nonce is None:
            lib.JWT_Destroy(jws)
            return None, None, "Nonce is none."

        hive_did = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        if hive_did is None:
            return None, None, "Issuer is none."

        #auth_token
        vp_json = self.create_presentation(vc, nonce, hive_did)
        if vp_json is None:
            return None, None, "create_presentation error."
        auth_token = self.create_vp_token(vp_json, subject, hive_did,
                                          hive_setting.AUTH_CHALLENGE_EXPIRED)
        if auth_token is None:
            return None, None, "create_vp_token error."
        return auth_token, hive_did, None
Exemple #5
0
    def verify_order_proof(self, proof, user_did, order_id):
        # INFO:DefaultJWSParser_Parse will validate the sign information.
        jws = lib.DefaultJWSParser_Parse(proof.encode())
        if not jws:
            raise BadRequestException(
                msg=self.get_error_message('parse the proof error'))

        issuer = lib.JWT_GetIssuer(jws)
        if not issuer:
            lib.JWT_Destroy(jws)
            raise BadRequestException(
                msg=self.get_error_message('the issue of the proof error'))
        if self.did_str != ffi.string(issuer).decode():
            lib.JWT_Destroy(jws)
            raise BadRequestException(
                msg=
                f'the issue of the proof not match: {ffi.string(issuer).decode()}'
            )

        audience = lib.JWT_GetAudience(jws)
        if not audience:
            lib.JWT_Destroy(jws)
            raise BadRequestException(
                msg=self.get_error_message('the audience of the proof error'))
        if user_did != ffi.string(audience).decode():
            lib.JWT_Destroy(jws)
            raise BadRequestException(
                msg=
                f'the audience of the proof not match: {ffi.string(audience).decode()}'
            )

        props = lib.JWT_GetClaim(jws, "props".encode())
        if not props:
            lib.JWT_Destroy(jws)
            raise BadRequestException(
                msg=self.get_error_message('the claim of the proof error'))
        props_json = json.loads(ffi.string(props).decode())
        if props_json.get('order_id') != order_id:
            lib.JWT_Destroy(jws)
            raise BadRequestException(
                msg=
                f'the order_id of the proof not match: {props_json.get("order_id")}'
            )

        if hive_setting.PAYMENT_CHECK_EXPIRED:
            expired = lib.JWT_GetExpiration(jws)
            now = int(datetime.now().timestamp())
            if now > expired:
                lib.JWT_Destroy(jws)
                raise BadRequestException(
                    msg=f'the proof is expired (valid for 7 days)')

        lib.JWT_Destroy(jws)
Exemple #6
0
    def get_node_did(self):
        node_did = self.test_config.get_node_did(self.http_client.base_url)
        if node_did:
            return node_did

        # get from the result of sign_in()
        challenge = self.sign_in()
        jws = lib.DefaultJWSParser_Parse(challenge.encode())
        assert jws, f'Cannot get challenge for node did: {ffi.string(lib.DIDError_GetLastErrorMessage()).decode()}'
        node_did = self.__get_issuer_by_challenge2(jws)
        lib.JWT_Destroy(jws)
        return node_did
Exemple #7
0
    def __get_auth_token_by_challenge(self, challenge, did: DIDApp):
        jws = lib.DefaultJWSParser_Parse(challenge.encode())
        assert jws, f'Cannot get challenge: {ffi.string(lib.DIDError_GetLastErrorMessage()).decode()}'
        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        assert aud == self.app_did.get_did_string()
        nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
        hive_did = self.__get_issuer_by_challenge2(jws)
        lib.JWT_Destroy(jws)

        # auth
        vc = did.issue_auth(self.app_did)
        vp_json = self.app_did.create_presentation(vc, nonce, hive_did)
        return self.app_did.create_vp_token(vp_json, "DIDAuthResponse", hive_did, 60)
Exemple #8
0
def get_info_from_token(token):
    if token is None:
        return None, "Then token is none!"

    token_splits = token.split(".")
    if token_splits is None:
        return None, "Then token is invalid!"

    if (len(token_splits) != 3) or token_splits[2] == "":
        return None, "Then token is invalid!"

    jws = lib.DefaultJWSParser_Parse(token.encode())
    if not jws:
        return None, get_error_message("JWS parser")

    issuer = lib.JWT_GetIssuer(jws)
    if not issuer:
        lib.JWT_Destroy(jws)
        return None, get_error_message("JWT getIssuer")

    issuer = ffi.string(issuer).decode()
    if issuer != get_current_node_did_string():
        lib.JWT_Destroy(jws)
        return None, "The issuer is invalid!"

    expired = lib.JWT_GetExpiration(jws)
    now = (int)(datetime.now().timestamp())
    if now > expired:
        lib.JWT_Destroy(jws)
        return None, "Then token is expired!"

    props = lib.JWT_GetClaim(jws, "props".encode())
    if not props:
        lib.JWT_Destroy(jws)
        return None, "Then props is none!"

    props_str = ffi.string(props).decode()
    props_json = json.loads(props_str)

    app_instance_did = ffi.string(lib.JWT_GetAudience(jws)).decode()
    if not app_instance_did:
        lib.JWT_Destroy(jws)
        return None, "Then app instance id is none!"

    props_json[APP_INSTANCE_DID] = app_instance_did

    lib.JWT_Destroy(jws)
    # print(props_json)

    return props_json, None
Exemple #9
0
    def __get_values_from_challenge_response(self, challenge_response):
        challenge_response_cstr = lib.DefaultJWSParser_Parse(
            challenge_response.encode())
        if not challenge_response_cstr:
            raise BadRequestException(msg='Invalid challenge response.')

        presentation_cstr = lib.JWT_GetClaimAsJson(challenge_response_cstr,
                                                   "presentation".encode())
        lib.JWT_Destroy(challenge_response_cstr)
        if not presentation_cstr:
            raise BadRequestException(msg='Can not get presentation cstr.')
        presentation = lib.Presentation_FromJson(presentation_cstr)
        if not presentation or lib.Presentation_IsValid(presentation) != 1:
            raise BadRequestException(msg='The presentation is invalid.')
        if lib.Presentation_GetCredentialCount(presentation) < 1:
            raise BadRequestException(msg='No presentation credential exists.')

        self.__validate_presentation_realm(presentation)
        nonce, nonce_info = self.__get_presentation_nonce(presentation)
        return json.loads(
            ffi.string(presentation_cstr).decode()), nonce, nonce_info
Exemple #10
0
def test_auth_common(self, user_did, app_did):
    # sign_in
    doc = lib.DIDStore_LoadDID(app_did.store, app_did.did)
    doc_str = ffi.string(lib.DIDDocument_ToJson(doc, True)).decode()
    logging.getLogger("test_auth_common").debug(f"\ndoc_str: {doc_str}")
    doc = json.loads(doc_str)
    rt, s = self.parse_response(
        self.test_client.post('/api/v1/did/sign_in',
                              data=json.dumps({
                                  "document": doc,
                              }),
                              headers=self.json_header))
    self.assert200(s)
    self.assertEqual(rt["_status"], "OK")
    jwt = rt["challenge"]
    # print(jwt)
    jws = lib.DefaultJWSParser_Parse(jwt.encode())
    # if not jws:
    #     print(ffi.string(lib.DIDError_GetLastErrorMessage()).decode())
    aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
    self.assertEqual(aud, app_did.get_did_string())
    nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
    hive_did = ffi.string(lib.JWT_GetIssuer(jws)).decode()
    lib.JWT_Destroy(jws)

    # auth
    vc = user_did.issue_auth(app_did)
    vp_json = app_did.create_presentation(vc, nonce, hive_did)
    auth_token = app_did.create_vp_token(vp_json, "DIDAuthResponse", hive_did,
                                         60)
    # print(auth_token)
    logging.getLogger("test_auth_common").debug(f"\nauth_token: {auth_token}")

    rt, s = self.parse_response(
        self.test_client.post('/api/v1/did/auth',
                              data=json.dumps({
                                  "jwt": auth_token,
                              }),
                              headers=self.json_header))
    self.assert200(s)
    self.assertEqual(rt["_status"], "OK")

    token = rt["access_token"]
    jws = lib.DefaultJWSParser_Parse(token.encode())
    aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
    self.assertEqual(aud, app_did.get_did_string())
    issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
    lib.JWT_Destroy(jws)
    # print(token)
    logging.getLogger("test_auth_common").debug(f"\ntoken: {token}")
    app_did.set_access_token(token)

    # auth_check
    # token = test_common.get_auth_token()
    self.json_header = [
        ("Authorization", "token " + token),
        self.content_type,
    ]
    rt, s = self.parse_response(
        self.test_client.post('/api/v1/did/check_token',
                              headers=self.json_header))
    self.assert200(s)
    self.assertEqual(rt["_status"], "OK")
    return token, hive_did