import { IoTizeDevice } from "../iotize-device";
import { LibWordArray } from 'crypto-js';
import { ScramLoginResponseBody } from "../model";
import { Encoder } from "../../core/converter";
export interface UsernamePassword {
    username: string;
    password: string;
}
export interface AuthMethod<LoginParam> {
    login(params: LoginParam): Promise<any>;
    logout(): Promise<any>;
    getSessionKey(): Uint8Array;
}
export declare type InputDataType = Uint8Array | string | LibWordArray;
export declare class AuthError extends Error {
    static Code: {
        INVALID_SERVER_PROOF: number;
        SCRAM_DISABLED: number;
    };
    code: number;
    constructor(code: number, message: string);
}
export declare class InvalidServerKey extends AuthError {
    deviceServerProof: Uint8Array;
    expectedServerProof: Uint8Array;
    constructor(deviceServerProof: Uint8Array, expectedServerProof: Uint8Array);
}
export declare namespace ScramAuth {
    interface ConstantKeys {
        storedKey: Uint8Array;
        serverKey: Uint8Array;
        saltedPassword: Uint8Array;
        hashedPassword: Uint8Array;
    }
    interface Keys extends ConstantKeys {
        clientProof: Uint8Array;
        serverProof: Uint8Array;
    }
}
export declare class ScramAuth implements AuthMethod<UsernamePassword> {
    protected device: IoTizeDevice;
    static CRC_LENGTH: number;
    static CLIENT_NONCE_SIZE: number;
    static SERVER_NONCE_SIZE: number;
    static PASSWORD_LENGTH: number;
    static ITERATION_NUMBER_SIZE: number;
    sessionData: {
        options?: ScramLoginResponseBody;
        key?: Uint8Array;
        username?: string;
        clientNonce?: number;
    };
    static COMMUNICATION_KEY_LABEL: string;
    static CLIENT_KEY_LABEL: string;
    static SERVER_KEY_LABEL: string;
    static KEY_SIZE: number;
    static CLIENT_KEY_ITERATION_NUMBER: number;
    static SERVER_KEY_ITERATION_NUMBER: number;
    static USER_SALT_SIZE: number;
    static SCRAM_PASSWORD_LENGTH: number;
    nonceGenerator: () => number;
    saltGenerator: () => Uint8Array;
    static stringConverter: Encoder<string, Uint8Array>;
    constructor(device: IoTizeDevice);
    changeUserPassword(newPassword: string, groupId: number, salt?: Uint8Array): Promise<void>;
    /**
     * Perform login
     *
     * @param params
     *
     * @throws Error if scram is not activated
     */
    login(params: UsernamePassword): Promise<void>;
    static createScramPasswordKey(newPassword: string, options: {
        salt: Uint8Array;
        iterationNumber: number;
    }): Uint8Array;
    private static computeBaseKeys;
    static computeKeys(credentials: UsernamePassword, loginBody: ScramLoginResponseBody, clientNonce: number): ScramAuth.Keys;
    logout(): Promise<any>;
    static clientProof(storedKey: Uint8Array, clientNonce: number, serverNonce: number): Uint8Array;
    static serverProof(serverKey: Uint8Array, clientNonce: number, serverNonce: number): Uint8Array;
    getSessionKey(): Uint8Array;
    generateNonce(): number;
    /**
     *
     * @param input
     */
    static HASH(input: InputDataType, salt: InputDataType, iteration: number): Uint8Array;
    /**
     *
     * @param input
     */
    static HMAC(input: InputDataType, key: InputDataType): Uint8Array;
    static hashPassword(password: string): Uint8Array;
    /**
     * SaltedPwd = PBKDF2 ( HashedPassword, UserSalt, ItCnt )
     * @param password
     * @param userSalt
     * @param iteration
     */
    static saltedPassword(hashedPassword: InputDataType, userSalt: InputDataType, iterations: number): Uint8Array;
    /**
     * ClientKey = HMAC ( SaltedPwd | « ClientKey »)
     * @param saltedPassword
     */
    /**
     * StoredKey = H ( ClientKey )
     * @param saltedPassword
     */
    static storedKey(saltedPassword: InputDataType): Uint8Array;
    static serverKey(saltedPassword: InputDataType): Uint8Array;
    /**
     * ClientSignature = HMAC ( StoredKey | ClientNonce | ServerNonce )
     * @param key
     * @param nonce1
     * @param nonce2
     */
    static computeProof(key: Uint8Array, nonce1: number, nonce2: number): Uint8Array;
    /**
     * Client proof must be 16 bytes
     * ClientProof = StoredKey ^ ClientSignature
     */
    static XOR(value1: Uint8Array, value2: Uint8Array): Uint8Array;
    /**
     * ClientProofCheck = StoredKey ^ ClientProof
     * @param storedKey
     * @param clientProof
     */
    static clientProofCheck(storedKey: Uint8Array, clientProof: Uint8Array): Uint8Array;
    /**
     * CommunicationKey = H ( ClientNonce | ServerNonce | StoredKey | « CommunicationKey » )
     * @param clientNonce
     * @param serverNonce
     * @param storedKey
     */
    static computeSessionKey(clientNonce: number, serverNonce: number, userSalt: Uint8Array, serverKey: Uint8Array, storedKey: Uint8Array): Uint8Array;
    /**
     *
     * @param input
     */
    static encodeLabel(input: string): Uint8Array;
}
