Exemplo n.º 1
0
    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
    def sign_in(self):
        body = request.get_json(force=True, silent=True)
        if body is None:
            return self.response.response_err(UNAUTHORIZED, "parameter is not application/json")
        document = body.get('document', None)
        if document is None:
            return self.response.response_err(BAD_REQUEST, "Thd did document is null")

        doc_str = json.dumps(body.get('document', None))
        doc = lib.DIDDocument_FromJson(doc_str.encode())
        if (not doc) or (not lib.DIDDocument_IsValid(doc)):
            return self.response.response_err(BAD_REQUEST, "Thd did document is vaild")

        did = lib.DIDDocument_GetSubject(doc)
        if not did:
            return self.response.response_err(BAD_REQUEST, "Thd did document is vaild, can't get did.")

        spec_did_str = ffi.string(lib.DID_GetMethodSpecificId(did)).decode()
        f = open(hive_setting.DID_DATA_LOCAL_DIDS+ os.sep + spec_did_str, "w")
        try:
            f.write(doc_str)
        finally:
            f.close()
        did_str = "did:" + ffi.string(lib.DID_GetMethod(did)).decode() + ":" + spec_did_str

        # save to db
        nonce = create_nonce()
        exp = int(datetime.now().timestamp()) + hive_setting.AUTH_CHALLENGE_EXPIRED
        if not self.__save_nonce_to_db(nonce, did_str, exp):
            return self.response.response_err(INTERNAL_SERVER_ERROR, "save to db fail!")

        # response token
        builder = lib.DIDDocument_GetJwtBuilder(self.doc)
        if not builder:
            return self.response.response_err(INTERNAL_SERVER_ERROR, "Can't get jwt builder.")

        lib.JWTBuilder_SetHeader(builder, "type".encode(), "JWT".encode())
        lib.JWTBuilder_SetHeader(builder, "version".encode(), "1.0".encode())

        lib.JWTBuilder_SetSubject(builder, "DIDAuthChallenge".encode())
        lib.JWTBuilder_SetAudience(builder, did_str.encode())
        lib.JWTBuilder_SetClaim(builder, "nonce".encode(), nonce.encode())
        lib.JWTBuilder_SetExpiration(builder, exp)

        lib.JWTBuilder_Sign(builder, ffi.NULL, self.storepass)
        token = lib.JWTBuilder_Compact(builder)
        if not token:
            return self.response.response_err(INTERNAL_SERVER_ERROR, "Compact builder to a token is fail.")

        token = ffi.string(token).decode()
        # print(token)
        lib.JWTBuilder_Destroy(builder)
        data = {
            "challenge": token,
        }
        return self.response.response_ok(data)
Exemplo n.º 3
0
    def get_did_string_from_did(self, did):
        if not did:
            return None

        method = lib.DID_GetMethod(did)
        if not method:
            return None
        method = ffi.string(method).decode()
        sep_did = lib.DID_GetMethodSpecificId(did)
        if not sep_did:
            return None
        sep_did = ffi.string(sep_did).decode()
        return "did:" + method + ":" + sep_did
Exemplo n.º 4
0
    def get_info_from_token(self, 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, self.get_error_message("JWS parser")

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

        issuer = ffi.string(issuer).decode()
        if issuer != self.get_did_string():
            lib.JWT_Destroy(jws)
            return None, "Then 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
Exemplo n.º 5
0
    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
    def did_auth(self, host, 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)

        param = {"document": doc}
        r = requests.post(host + '/api/v1/did/sign_in',
                          json=param,
                          headers=self.json_header())
        self.assert200(r.status_code)
        rt = r.json()

        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}")
        param = {
            "jwt": auth_token,
        }
        r = requests.post(host + '/api/v1/did/auth',
                          json=param,
                          headers=self.json_header())
        self.assert200(r.status_code)
        rt = r.json()

        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()
        r = requests.post(host + '/api/v1/did/check_token',
                          json=param,
                          headers=self.auth_header(token))
        self.assert200(r.status_code)
        return token, hive_did
Exemplo n.º 7
0
def MyDIDLocalResovleHandle(did):
    spec_did_str = ffi.string(lib.DID_GetMethodSpecificId(did)).decode()
    doc = ffi.NULL

    file_path = hive_setting.DID_DATA_LOCAL_DIDS + os.sep + spec_did_str
    is_exist = os.path.exists(file_path)
    if is_exist:
        f = open(file_path, "r")
        try:
            doc_str = f.read()
            doc = lib.DIDDocument_FromJson(doc_str.encode())
        finally:
            f.close()

    return doc
Exemplo n.º 8
0
    def create_presentation(self, vc, nonce, realm):
        vpid = lib.DIDURL_NewByDid(self.did, "jwtvp".encode())
        type0 = ffi.new("char[]", "VerifiablePresentation".encode())
        types = ffi.new("char **", type0)

        vp = lib.Presentation_Create(vpid, self.did, types, 1, nonce.encode(),
                                     realm.encode(), ffi.NULL, self.store,
                                     self.storepass, 1, vc)
        lib.DIDURL_Destroy(vpid)

        # print_err()
        vp_json = ffi.string(lib.Presentation_ToJson(vp, True)).decode()
        # print(vp_json)
        logging.debug(f"vp_json: {vp_json}")
        return vp_json
Exemplo n.º 9
0
    def __create_token(self, auth_info, subject):
        if not isinstance(auth_info, dict):
            return None, "auth info isn't dict type"

        doc = lib.DIDStore_LoadDID(self.store, self.did)
        if not doc:
            return None, self.get_error_message("The doc load from did")

        builder = lib.DIDDocument_GetJwtBuilder(doc)
        if not builder:
            return None, "Can't get jwt builder."

        lib.JWTBuilder_SetHeader(builder, "typ".encode(), "JWT".encode())
        lib.JWTBuilder_SetHeader(builder, "version".encode(), "1.0".encode())

        lib.JWTBuilder_SetSubject(builder, subject.encode())
        lib.JWTBuilder_SetAudience(builder, auth_info["id"].encode())
        lib.JWTBuilder_SetExpiration(builder, auth_info["expTime"])

        props = {}
        for key in auth_info:
            if key != "expTime" and key != "id":
                props[key] = auth_info[key]

        props_str = json.dumps(props)
        ret = lib.JWTBuilder_SetClaim(builder, "props".encode(),
                                      props_str.encode())
        if not ret:
            return None, self.get_error_message(
                "JWTBuilder_SetClaim 'props' to a token")

        lib.JWTBuilder_Sign(builder, ffi.NULL, self.storepass)
        token = lib.JWTBuilder_Compact(builder)
        if not token:
            return None, self.get_error_message("Compact builder to a token")

        token = ffi.string(token).decode()
        lib.JWTBuilder_Destroy(builder)

        return token, None
    def test_4_inter_put_file(self):
        self.init_vault_service(self.host1, self.token1)
        self.init_backup_service(self.host2, self.token2)
        vc = self.user_did.issue_backup_auth(self.hive_did1, self.host2,
                                             self.hive_did2)
        vc_json = ffi.string(lib.Credential_ToString(vc, True)).decode()

        content = {"backup_credential": vc_json}

        host, backup_token, err = view.h_auth.backup_auth_request(content)
        self.assertIsNone(err)
        input_text = "this is a test put file"
        file_name = "test_put_file.txt"

        temp = BytesIO()
        temp.write(input_text.encode(encoding="utf-8"))
        temp.seek(0)
        temp.name = 'temp.txt'
        url = self.host2 + INTER_BACKUP_FILE_URL + '?file=' + file_name
        r = requests.put(url,
                         data=temp,
                         headers={"Authorization": "token " + backup_token})
        self.assert200(r.status_code)

        r = requests.get(host + INTER_BACKUP_FILE_URL + "?file=" + file_name,
                         stream=True,
                         headers={"Authorization": "token " + backup_token})
        self.assertEquals(r.text, input_text)

        r = requests.delete(host + INTER_BACKUP_FILE_URL + "?file=" +
                            file_name,
                            headers={"Authorization": "token " + backup_token})
        self.assert200(r.status_code)

        r = requests.get(host + INTER_BACKUP_FILE_URL + "?file=" + file_name,
                         stream=True,
                         headers={"Authorization": "token " + backup_token})
        self.assertEquals(r.status_code, NOT_FOUND)
    def test_1_save_restore_hive_node(self):
        self.init_vault_service(self.host1, self.token1)
        self.add_vault_data(self.host1, self.token1)
        self.check_vault_data(self.host1, self.token1)

        self.init_backup_service(self.host2, self.token2)

        vc = self.user_did.issue_backup_auth(self.hive_did1, self.host2,
                                             self.hive_did2)
        vc_json = ffi.string(lib.Credential_ToString(vc, True)).decode()

        self.save_to_backup(self.host1, self.token1, vc_json)

        self.clean_vault_data(self.host1, self.token1)
        self.restore_from_backup(self.host1, self.token1, vc_json)

        time.sleep(2)

        self.check_vault_data(self.host1, self.token1)

        # active test
        self.init_vault_service(self.host2, self.token2)
        self.active_backup_vault(self.host2, self.token2)
        self.check_vault_data(self.host2, self.token2)
Exemplo n.º 12
0
    def create_vp_token(self, vp_json, subject, hive_did, expire):
        doc = lib.DIDStore_LoadDID(self.store, self.did)
        builder = lib.DIDDocument_GetJwtBuilder(doc)
        ticks = int(datetime.now().timestamp())
        iat = ticks
        nbf = ticks
        exp = ticks + expire

        lib.JWTBuilder_SetHeader(builder, "type".encode(), "JWT".encode())
        lib.JWTBuilder_SetHeader(builder, "version".encode(), "1.0".encode())

        lib.JWTBuilder_SetSubject(builder, subject.encode())
        lib.JWTBuilder_SetAudience(builder, hive_did.encode())
        lib.JWTBuilder_SetIssuedAt(builder, iat)
        lib.JWTBuilder_SetExpiration(builder, exp)
        lib.JWTBuilder_SetNotBefore(builder, nbf)
        lib.JWTBuilder_SetClaimWithJson(builder, "presentation".encode(),
                                        vp_json.encode())

        lib.JWTBuilder_Sign(builder, ffi.NULL, self.storepass)
        token = ffi.string(lib.JWTBuilder_Compact(builder)).decode()
        lib.JWTBuilder_Destroy(builder)
        # print(token)
        return token
Exemplo n.º 13
0
def get_error_message():
    return str(ffi.string(lib.DIDError_GetLastErrorMessage()),
               encoding='utf-8')
Exemplo n.º 14
0
    def __get_auth_token_info(self, props):
        # get jwt
        body = request.get_json(force=True, silent=True)
        if body is None:
            return None, "The parameter is not application/json"
        jwt = body.get('jwt', None)

        if jwt is None:
            return None, "The jwt is none."

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

        vp_str = lib.JWT_GetClaimAsJson(jws, "presentation".encode())
        if not vp_str:
            lib.JWT_Destroy(jws)
            return None, "The jwt's presentation is none."

        vp = lib.Presentation_FromJson(vp_str)
        if not vp:
            lib.JWT_Destroy(jws)
            return None, "The presentation string is error, unable to rebuild to a presentation object."

        vp_json = json.loads(ffi.string(vp_str).decode())
        lib.JWT_Destroy(jws)

        # check vp
        if lib.Presentation_IsValid(vp) != 1:
            return None, self.get_error_message("Presentation isValid")
        # print(ffi.string(vp_str).decode())

        # check nonce
        nonce = lib.Presentation_GetNonce(vp)
        if not nonce:
            return None, "The nonce is none."
        nonce = ffi.string(nonce).decode()
        if nonce is None:
            return None, "The nonce is isn't valid."

        # check did:nonce from db
        info = get_did_info_by_nonce(nonce)
        if info is None:
            return None, "The nonce is error."

        # check realm
        realm = lib.Presentation_GetRealm(vp)
        if not realm:
            return None, "The realm is none."
        realm = ffi.string(realm).decode()
        if realm is None:
            return None, "The realm is isn't valid."

        if realm != self.get_did_string():
            return None, "The realm is error."

        # check vc
        count = lib.Presentation_GetCredentialCount(vp)
        if count < 1:
            return None, "The credential count is error."

        if not "verifiableCredential" in vp_json:
            return None, "The credential isn't exist."

        vcs_json = vp_json["verifiableCredential"]
        if not isinstance(vcs_json, list):
            return None, "The verifiableCredential isn't valid"

        vc_json = vcs_json[0]
        if vc_json is None:
            return None, "The credential isn't exist"

        vc_str = json.dumps(vc_json)

        credential_info, err = self.get_credential_info(vc_str, props)
        if not credential_info is None:
            if credential_info["id"] != info[APP_INSTANCE_DID]:
                return None, "The app instance did is error."
            credential_info["nonce"] = nonce
            if info[DID_INFO_NONCE_EXPIRED] < int(datetime.now().timestamp()):
                return None, "The nonce is expired"

        return credential_info, err
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_GetMessage()).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
Exemplo n.º 16
0
 def get_error_message(self, prompt):
     err_message = ffi.string(lib.DIDError_GetLastErrorMessage()).decode()
     if not prompt is None:
         err_message = prompt + " error: " + err_message
     return err_message