/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.locksettings.recoverablekeystore.serialization;

import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.CERTIFICATE_FACTORY_TYPE;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.NAMESPACE;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.OUTPUT_ENCODING;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_ALGORITHM;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_ALIAS;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_APPLICATION_KEY;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_APPLICATION_KEYS;

import static com.android.server.locksettings.recoverablekeystore.serialization
        .KeyChainSnapshotSchema.TAG_BACKEND_PUBLIC_KEY;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_COUNTER_ID;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_RECOVERY_KEY_MATERIAL;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_KEY_CHAIN_PROTECTION_PARAMS;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_KEY_CHAIN_PROTECTION_PARAMS_LIST;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_KEY_CHAIN_SNAPSHOT;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_KEY_DERIVATION_PARAMS;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_KEY_MATERIAL;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_LOCK_SCREEN_UI_TYPE;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_MAX_ATTEMPTS;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_MEMORY_DIFFICULTY;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_SALT;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_SERVER_PARAMS;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_SNAPSHOT_VERSION;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_TRUSTED_HARDWARE_CERT_PATH;
import static com.android.server.locksettings.recoverablekeystore.serialization.KeyChainSnapshotSchema.TAG_USER_SECRET_TYPE;

import android.security.keystore.recovery.KeyChainProtectionParams;
import android.security.keystore.recovery.KeyChainSnapshot;
import android.security.keystore.recovery.KeyDerivationParams;
import android.security.keystore.recovery.WrappedApplicationKey;
import android.util.Base64;
import android.util.Xml;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertPath;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

/**
 * Deserializes a {@link android.security.keystore.recovery.KeyChainSnapshot} instance from XML.
 */
public class KeyChainSnapshotDeserializer {

    /**
     * Deserializes a {@link KeyChainSnapshot} instance from the XML in the {@code inputStream}.
     *
     * @throws IOException if there is an IO error reading from the stream.
     * @throws KeyChainSnapshotParserException if the XML does not conform to the expected XML for
     *     a snapshot.
     */
    public static KeyChainSnapshot deserialize(InputStream inputStream)
            throws KeyChainSnapshotParserException, IOException {
        try {
            return deserializeInternal(inputStream);
        } catch (XmlPullParserException e) {
            throw new KeyChainSnapshotParserException("Malformed KeyChainSnapshot XML", e);
        }
    }

    private static KeyChainSnapshot deserializeInternal(InputStream inputStream) throws IOException,
            XmlPullParserException, KeyChainSnapshotParserException {
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(inputStream, OUTPUT_ENCODING);

        parser.nextTag();
        parser.require(XmlPullParser.START_TAG, NAMESPACE, TAG_KEY_CHAIN_SNAPSHOT);

        KeyChainSnapshot.Builder builder = new KeyChainSnapshot.Builder();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }

            String name = parser.getName();

            switch (name) {
                case TAG_SNAPSHOT_VERSION:
                    builder.setSnapshotVersion(readIntTag(parser, TAG_SNAPSHOT_VERSION));
                    break;

                case TAG_RECOVERY_KEY_MATERIAL:
                    builder.setEncryptedRecoveryKeyBlob(
                            readBlobTag(parser, TAG_RECOVERY_KEY_MATERIAL));
                    break;

                case TAG_COUNTER_ID:
                    builder.setCounterId(readLongTag(parser, TAG_COUNTER_ID));
                    break;

                case TAG_SERVER_PARAMS:
                    builder.setServerParams(readBlobTag(parser, TAG_SERVER_PARAMS));
                    break;

                case TAG_MAX_ATTEMPTS:
                    builder.setMaxAttempts(readIntTag(parser, TAG_MAX_ATTEMPTS));
                    break;

                case TAG_TRUSTED_HARDWARE_CERT_PATH:
                    try {
                        builder.setTrustedHardwareCertPath(
                                readCertPathTag(parser, TAG_TRUSTED_HARDWARE_CERT_PATH));
                    } catch (CertificateException e) {
                        throw new KeyChainSnapshotParserException(
                                "Could not set trustedHardwareCertPath", e);
                    }
                    break;

                case TAG_BACKEND_PUBLIC_KEY:
                    builder.setTrustedHardwarePublicKey(
                            readBlobTag(parser, TAG_BACKEND_PUBLIC_KEY));
                    break;

                case TAG_KEY_CHAIN_PROTECTION_PARAMS_LIST:
                    builder.setKeyChainProtectionParams(readKeyChainProtectionParamsList(parser));
                    break;

                case TAG_APPLICATION_KEYS:
                    builder.setWrappedApplicationKeys(readWrappedApplicationKeys(parser));
                    break;

                default:
                    throw new KeyChainSnapshotParserException(String.format(
                            Locale.US, "Unexpected tag %s in keyChainSnapshot", name));
            }
        }

        parser.require(XmlPullParser.END_TAG, NAMESPACE, TAG_KEY_CHAIN_SNAPSHOT);
        try {
            return builder.build();
        } catch (NullPointerException e) {
            throw new KeyChainSnapshotParserException("Failed to build KeyChainSnapshot", e);
        }
    }

    private static List<WrappedApplicationKey> readWrappedApplicationKeys(XmlPullParser parser)
            throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, TAG_APPLICATION_KEYS);
        ArrayList<WrappedApplicationKey> keys = new ArrayList<>();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            keys.add(readWrappedApplicationKey(parser));
        }
        parser.require(XmlPullParser.END_TAG, NAMESPACE, TAG_APPLICATION_KEYS);
        return keys;
    }

    private static WrappedApplicationKey readWrappedApplicationKey(XmlPullParser parser)
            throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, TAG_APPLICATION_KEY);
        WrappedApplicationKey.Builder builder = new WrappedApplicationKey.Builder();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }

            String name = parser.getName();

            switch (name) {
                case TAG_ALIAS:
                    builder.setAlias(readStringTag(parser, TAG_ALIAS));
                    break;

                case TAG_KEY_MATERIAL:
                    builder.setEncryptedKeyMaterial(readBlobTag(parser, TAG_KEY_MATERIAL));
                    break;

                default:
                    throw new KeyChainSnapshotParserException(String.format(
                            Locale.US, "Unexpected tag %s in wrappedApplicationKey", name));
            }
        }
        parser.require(XmlPullParser.END_TAG, NAMESPACE, TAG_APPLICATION_KEY);

        try {
            return builder.build();
        } catch (NullPointerException e) {
            throw new KeyChainSnapshotParserException("Failed to build WrappedApplicationKey", e);
        }
    }

    private static List<KeyChainProtectionParams> readKeyChainProtectionParamsList(
            XmlPullParser parser) throws IOException, XmlPullParserException,
            KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS_LIST);

        ArrayList<KeyChainProtectionParams> keyChainProtectionParamsList = new ArrayList<>();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }
            keyChainProtectionParamsList.add(readKeyChainProtectionParams(parser));
        }

        parser.require(XmlPullParser.END_TAG, NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS_LIST);
        return keyChainProtectionParamsList;
    }

    private static KeyChainProtectionParams readKeyChainProtectionParams(XmlPullParser parser)
        throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS);

        KeyChainProtectionParams.Builder builder = new KeyChainProtectionParams.Builder();
        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }

            String name = parser.getName();

            switch (name) {
                case TAG_LOCK_SCREEN_UI_TYPE:
                    builder.setLockScreenUiFormat(readIntTag(parser, TAG_LOCK_SCREEN_UI_TYPE));
                    break;

                case TAG_USER_SECRET_TYPE:
                    builder.setUserSecretType(readIntTag(parser, TAG_USER_SECRET_TYPE));
                    break;

                case TAG_KEY_DERIVATION_PARAMS:
                    builder.setKeyDerivationParams(readKeyDerivationParams(parser));
                    break;

                default:
                    throw new KeyChainSnapshotParserException(String.format(
                            Locale.US,
                            "Unexpected tag %s in keyChainProtectionParams",
                            name));

            }
        }

        parser.require(XmlPullParser.END_TAG, NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS);

        try {
            return builder.build();
        } catch (NullPointerException e) {
            throw new KeyChainSnapshotParserException(
                    "Failed to build KeyChainProtectionParams", e);
        }
    }

    private static KeyDerivationParams readKeyDerivationParams(XmlPullParser parser)
            throws XmlPullParserException, IOException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, TAG_KEY_DERIVATION_PARAMS);

        int memoryDifficulty = -1;
        int algorithm = -1;
        byte[] salt = null;

        while (parser.next() != XmlPullParser.END_TAG) {
            if (parser.getEventType() != XmlPullParser.START_TAG) {
                continue;
            }

            String name = parser.getName();

            switch (name) {
                case TAG_MEMORY_DIFFICULTY:
                    memoryDifficulty = readIntTag(parser, TAG_MEMORY_DIFFICULTY);
                    break;

                case TAG_ALGORITHM:
                    algorithm = readIntTag(parser, TAG_ALGORITHM);
                    break;

                case TAG_SALT:
                    salt = readBlobTag(parser, TAG_SALT);
                    break;

                default:
                    throw new KeyChainSnapshotParserException(
                            String.format(
                                    Locale.US,
                                    "Unexpected tag %s in keyDerivationParams",
                                    name));
            }
        }

        if (salt == null) {
            throw new KeyChainSnapshotParserException("salt was not set in keyDerivationParams");
        }

        KeyDerivationParams keyDerivationParams = null;

        switch (algorithm) {
            case KeyDerivationParams.ALGORITHM_SHA256:
                keyDerivationParams = KeyDerivationParams.createSha256Params(salt);
                break;

            case KeyDerivationParams.ALGORITHM_SCRYPT:
                keyDerivationParams = KeyDerivationParams.createScryptParams(
                        salt, memoryDifficulty);
                break;

            default:
                throw new KeyChainSnapshotParserException(
                        "Unknown algorithm in keyDerivationParams");
        }

        parser.require(XmlPullParser.END_TAG, NAMESPACE, TAG_KEY_DERIVATION_PARAMS);
        return keyDerivationParams;
    }

    private static int readIntTag(XmlPullParser parser, String tagName)
            throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, tagName);
        String text = readText(parser);
        parser.require(XmlPullParser.END_TAG, NAMESPACE, tagName);
        try {
            return Integer.valueOf(text);
        } catch (NumberFormatException e) {
            throw new KeyChainSnapshotParserException(
                    String.format(
                            Locale.US, "%s expected int but got '%s'", tagName, text), e);
        }
    }

    private static long readLongTag(XmlPullParser parser, String tagName)
            throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, tagName);
        String text = readText(parser);
        parser.require(XmlPullParser.END_TAG, NAMESPACE, tagName);
        try {
            return Long.valueOf(text);
        } catch (NumberFormatException e) {
            throw new KeyChainSnapshotParserException(
                    String.format(
                            Locale.US, "%s expected long but got '%s'", tagName, text), e);
        }
    }

    private static String readStringTag(XmlPullParser parser, String tagName)
            throws IOException, XmlPullParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, tagName);
        String text = readText(parser);
        parser.require(XmlPullParser.END_TAG, NAMESPACE, tagName);
        return text;
    }

    private static byte[] readBlobTag(XmlPullParser parser, String tagName)
            throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        parser.require(XmlPullParser.START_TAG, NAMESPACE, tagName);
        String text = readText(parser);
        parser.require(XmlPullParser.END_TAG, NAMESPACE, tagName);

        try {
            return Base64.decode(text, /*flags=*/ Base64.DEFAULT);
        } catch (IllegalArgumentException e) {
            throw new KeyChainSnapshotParserException(
                    String.format(
                            Locale.US,
                            "%s expected base64 encoded bytes but got '%s'",
                            tagName, text), e);
        }
    }

    private static CertPath readCertPathTag(XmlPullParser parser, String tagName)
            throws IOException, XmlPullParserException, KeyChainSnapshotParserException {
        byte[] bytes = readBlobTag(parser, tagName);
        try {
            return CertificateFactory.getInstance(CERTIFICATE_FACTORY_TYPE)
                    .generateCertPath(new ByteArrayInputStream(bytes));
        } catch (CertificateException e) {
            throw new KeyChainSnapshotParserException("Could not parse CertPath in tag " + tagName,
                    e);
        }
    }

    private static String readText(XmlPullParser parser)
            throws IOException, XmlPullParserException {
        String result = "";
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.getText();
            parser.nextTag();
        }
        return result;
    }

    // Statics only
    private KeyChainSnapshotDeserializer() {}
}
