/*
 * 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.CERT_PATH_ENCODING;
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 org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.io.OutputStream;
import java.security.cert.CertPath;
import java.security.cert.CertificateEncodingException;
import java.util.List;

/**
 * Serializes a {@link KeyChainSnapshot} instance to XML.
 */
public class KeyChainSnapshotSerializer {

    /**
     * Serializes {@code keyChainSnapshot} to XML, writing to {@code outputStream}.
     *
     * @throws IOException if there was an IO error writing to the stream.
     * @throws CertificateEncodingException if the {@link CertPath} from
     *     {@link KeyChainSnapshot#getTrustedHardwareCertPath()} is not encoded correctly.
     */
    public static void serialize(KeyChainSnapshot keyChainSnapshot, OutputStream outputStream)
            throws IOException, CertificateEncodingException {
        XmlSerializer xmlSerializer = Xml.newSerializer();
        xmlSerializer.setOutput(outputStream, OUTPUT_ENCODING);
        xmlSerializer.startDocument(
                /*encoding=*/ null,
                /*standalone=*/ null);
        xmlSerializer.startTag(NAMESPACE, TAG_KEY_CHAIN_SNAPSHOT);
        writeKeyChainSnapshotProperties(xmlSerializer, keyChainSnapshot);
        writeKeyChainProtectionParams(xmlSerializer,
                keyChainSnapshot.getKeyChainProtectionParams());
        writeApplicationKeys(xmlSerializer,
                keyChainSnapshot.getWrappedApplicationKeys());
        xmlSerializer.endTag(NAMESPACE, TAG_KEY_CHAIN_SNAPSHOT);
        xmlSerializer.endDocument();
    }

    private static void writeApplicationKeys(
            XmlSerializer xmlSerializer, List<WrappedApplicationKey> wrappedApplicationKeys)
            throws IOException {
        xmlSerializer.startTag(NAMESPACE, TAG_APPLICATION_KEYS);
        for (WrappedApplicationKey key : wrappedApplicationKeys) {
            xmlSerializer.startTag(NAMESPACE, TAG_APPLICATION_KEY);
            writeApplicationKeyProperties(xmlSerializer, key);
            xmlSerializer.endTag(NAMESPACE, TAG_APPLICATION_KEY);
        }
        xmlSerializer.endTag(NAMESPACE, TAG_APPLICATION_KEYS);
    }

    private static void writeApplicationKeyProperties(
            XmlSerializer xmlSerializer, WrappedApplicationKey applicationKey) throws IOException {
        writePropertyTag(xmlSerializer, TAG_ALIAS, applicationKey.getAlias());
        writePropertyTag(xmlSerializer, TAG_KEY_MATERIAL, applicationKey.getEncryptedKeyMaterial());
    }

    private static void writeKeyChainProtectionParams(
            XmlSerializer xmlSerializer,
            List<KeyChainProtectionParams> keyChainProtectionParamsList) throws IOException {
        xmlSerializer.startTag(NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS_LIST);
        for (KeyChainProtectionParams keyChainProtectionParams : keyChainProtectionParamsList) {
            xmlSerializer.startTag(NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS);
            writeKeyChainProtectionParamsProperties(xmlSerializer, keyChainProtectionParams);
            xmlSerializer.endTag(NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS);
        }
        xmlSerializer.endTag(NAMESPACE, TAG_KEY_CHAIN_PROTECTION_PARAMS_LIST);
    }

    private static void writeKeyChainProtectionParamsProperties(
            XmlSerializer xmlSerializer, KeyChainProtectionParams keyChainProtectionParams)
            throws IOException {
        writePropertyTag(xmlSerializer, TAG_USER_SECRET_TYPE,
                keyChainProtectionParams.getUserSecretType());
        writePropertyTag(xmlSerializer, TAG_LOCK_SCREEN_UI_TYPE,
                keyChainProtectionParams.getLockScreenUiFormat());

        // NOTE: Do not serialize the 'secret' field. It should never be set anyway for snapshots
        // we generate.

        writeKeyDerivationParams(xmlSerializer, keyChainProtectionParams.getKeyDerivationParams());
    }

    private static void writeKeyDerivationParams(
            XmlSerializer xmlSerializer, KeyDerivationParams keyDerivationParams)
            throws IOException {
        xmlSerializer.startTag(NAMESPACE, TAG_KEY_DERIVATION_PARAMS);
        writeKeyDerivationParamsProperties(
                xmlSerializer, keyDerivationParams);
        xmlSerializer.endTag(NAMESPACE, TAG_KEY_DERIVATION_PARAMS);
    }

    private static void writeKeyDerivationParamsProperties(
            XmlSerializer xmlSerializer, KeyDerivationParams keyDerivationParams)
            throws IOException {
        writePropertyTag(xmlSerializer, TAG_ALGORITHM, keyDerivationParams.getAlgorithm());
        writePropertyTag(xmlSerializer, TAG_SALT, keyDerivationParams.getSalt());
        writePropertyTag(xmlSerializer, TAG_MEMORY_DIFFICULTY,
                keyDerivationParams.getMemoryDifficulty());
    }

    private static void writeKeyChainSnapshotProperties(
            XmlSerializer xmlSerializer, KeyChainSnapshot keyChainSnapshot)
            throws IOException, CertificateEncodingException {

        writePropertyTag(xmlSerializer, TAG_SNAPSHOT_VERSION,
                keyChainSnapshot.getSnapshotVersion());
        writePropertyTag(xmlSerializer, TAG_MAX_ATTEMPTS, keyChainSnapshot.getMaxAttempts());
        writePropertyTag(xmlSerializer, TAG_COUNTER_ID, keyChainSnapshot.getCounterId());
        writePropertyTag(xmlSerializer, TAG_RECOVERY_KEY_MATERIAL,
                keyChainSnapshot.getEncryptedRecoveryKeyBlob());
        writePropertyTag(xmlSerializer, TAG_SERVER_PARAMS, keyChainSnapshot.getServerParams());
        writePropertyTag(xmlSerializer, TAG_TRUSTED_HARDWARE_CERT_PATH,
                keyChainSnapshot.getTrustedHardwareCertPath());
    }

    private static void writePropertyTag(
            XmlSerializer xmlSerializer, String propertyName, long propertyValue)
            throws IOException {
        xmlSerializer.startTag(NAMESPACE, propertyName);
        xmlSerializer.text(Long.toString(propertyValue));
        xmlSerializer.endTag(NAMESPACE, propertyName);
    }

    private static void writePropertyTag(
            XmlSerializer xmlSerializer, String propertyName, String propertyValue)
            throws IOException {
        xmlSerializer.startTag(NAMESPACE, propertyName);
        xmlSerializer.text(propertyValue);
        xmlSerializer.endTag(NAMESPACE, propertyName);
    }

    private static void writePropertyTag(
            XmlSerializer xmlSerializer, String propertyName, byte[] propertyValue)
            throws IOException {
        xmlSerializer.startTag(NAMESPACE, propertyName);
        xmlSerializer.text(Base64.encodeToString(propertyValue, /*flags=*/ Base64.DEFAULT));
        xmlSerializer.endTag(NAMESPACE, propertyName);
    }

    private static void writePropertyTag(
            XmlSerializer xmlSerializer, String propertyName, CertPath certPath)
            throws IOException, CertificateEncodingException {
        writePropertyTag(xmlSerializer, propertyName, certPath.getEncoded(CERT_PATH_ENCODING));
    }

    // Statics only
    private KeyChainSnapshotSerializer() {}
}
