/*
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.transport;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.util.Base64;
import org.eclipse.jgit.util.Hex;

abstract class WalkEncryption {
	static final WalkEncryption NONE = new NoEncryption();

	static final String JETS3T_CRYPTO_VER = "jets3t-crypto-ver"; //$NON-NLS-1$

	static final String JETS3T_CRYPTO_ALG = "jets3t-crypto-alg"; //$NON-NLS-1$

	// Note: encrypt -> request state machine, step 1.
	abstract OutputStream encrypt(OutputStream output) throws IOException;

	// Note: encrypt -> request state machine, step 2.
	abstract void request(HttpURLConnection conn, String prefix) throws IOException;

	// Note: validate -> decrypt state machine, step 1.
	abstract void validate(HttpURLConnection conn, String prefix) throws IOException;

	// Note: validate -> decrypt state machine, step 2.
	abstract InputStream decrypt(InputStream input) throws IOException;


	// TODO mixed ciphers
	// consider permitting mixed ciphers to facilitate algorithm migration
	// i.e. user keeps the password, but changes the algorithm
	// then existing remote entries will still be readable
	/**
	 * Validate
	 *
	 * @param u
	 *            a {@link java.net.HttpURLConnection} object.
	 * @param prefix
	 *            a {@link java.lang.String} object.
	 * @param version
	 *            a {@link java.lang.String} object.
	 * @param name
	 *            a {@link java.lang.String} object.
	 * @throws java.io.IOException
	 *             if any.
	 */
	protected void validateImpl(final HttpURLConnection u, final String prefix,
			final String version, final String name) throws IOException {
		String v;

		v = u.getHeaderField(prefix + JETS3T_CRYPTO_VER);
		if (v == null)
			v = ""; //$NON-NLS-1$
		if (!version.equals(v))
			throw new IOException(MessageFormat.format(JGitText.get().unsupportedEncryptionVersion, v));

		v = u.getHeaderField(prefix + JETS3T_CRYPTO_ALG);
		if (v == null)
			v = ""; //$NON-NLS-1$
		// Standard names are not case-sensitive.
		// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
		if (!name.equalsIgnoreCase(v))
			throw new IOException(MessageFormat.format(JGitText.get().unsupportedEncryptionAlgorithm, v));
	}

	IOException error(Throwable why) {
		return new IOException(MessageFormat
				.format(JGitText.get().encryptionError,
				why.getMessage()), why);
	}

	private static class NoEncryption extends WalkEncryption {
		@Override
		void request(HttpURLConnection u, String prefix) {
			// Don't store any request properties.
		}

		@Override
		void validate(HttpURLConnection u, String prefix)
				throws IOException {
			validateImpl(u, prefix, "", ""); //$NON-NLS-1$ //$NON-NLS-2$
		}

		@Override
		InputStream decrypt(InputStream in) {
			return in;
		}

		@Override
		OutputStream encrypt(OutputStream os) {
			return os;
		}
	}

	/**
	 * JetS3t compatibility reference: <a href=
	 * "https://bitbucket.org/jmurty/jets3t/src/156c00eb160598c2e9937fd6873f00d3190e28ca/src/org/jets3t/service/security/EncryptionUtil.java">
	 * EncryptionUtil.java</a>
	 * <p>
	 * Note: EncryptionUtil is inadequate:
	 * <ul>
	 * <li>EncryptionUtil.isCipherAvailableForUse checks encryption only which
	 * "always works", but in JetS3t both encryption and decryption use non-IV
	 * aware algorithm parameters for all PBE specs, which breaks in case of AES
	 * <li>that means that only non-IV algorithms will work round trip in
	 * JetS3t, such as PBEWithMD5AndDES and PBEWithSHAAndTwofish-CBC
	 * <li>any AES based algorithms such as "PBE...With...And...AES" will not
	 * work, since they need proper IV setup
	 * </ul>
	 */
	static class JetS3tV2 extends WalkEncryption {

		static final String VERSION = "2"; //$NON-NLS-1$

		static final String ALGORITHM = "PBEWithMD5AndDES"; //$NON-NLS-1$

		static final int ITERATIONS = 5000;

		static final int KEY_SIZE = 32;

		static final byte[] SALT = { //
				(byte) 0xA4, (byte) 0x0B, (byte) 0xC8, (byte) 0x34, //
				(byte) 0xD6, (byte) 0x95, (byte) 0xF3, (byte) 0x13 //
		};

		// Size 16, see com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE
		static final byte[] ZERO_AES_IV = new byte[16];

		private static final String CRYPTO_VER = VERSION;

		private final String cryptoAlg;

		private final SecretKey secretKey;

		private final AlgorithmParameterSpec paramSpec;

		JetS3tV2(final String algo, final String key)
				throws GeneralSecurityException {
			cryptoAlg = algo;

			// Verify if cipher is present.
			Cipher cipher = InsecureCipherFactory.create(cryptoAlg);

			// Standard names are not case-sensitive.
			// http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
			String cryptoName = cryptoAlg.toUpperCase(Locale.ROOT);

			if (!cryptoName.startsWith("PBE")) //$NON-NLS-1$
				throw new GeneralSecurityException(JGitText.get().encryptionOnlyPBE);

			PBEKeySpec keySpec = new PBEKeySpec(key.toCharArray(), SALT, ITERATIONS, KEY_SIZE);
			secretKey = SecretKeyFactory.getInstance(algo).generateSecret(keySpec);

			// Detect algorithms which require initialization vector.
			boolean useIV = cryptoName.contains("AES"); //$NON-NLS-1$

			// PBEParameterSpec algorithm parameters are supported from Java 8.
			if (useIV) {
				// Support IV where possible:
				// * since JCE provider uses random IV for PBE/AES
				// * and there is no place to store dynamic IV in JetS3t V2
				// * we use static IV, and tolerate increased security risk
				// TODO back port this change to JetS3t V2
				// See:
				// https://bitbucket.org/jmurty/jets3t/raw/156c00eb160598c2e9937fd6873f00d3190e28ca/src/org/jets3t/service/security/EncryptionUtil.java
				// http://cr.openjdk.java.net/~mullan/webrevs/ascarpin/webrev.00/raw_files/new/src/share/classes/com/sun/crypto/provider/PBES2Core.java
				IvParameterSpec paramIV = new IvParameterSpec(ZERO_AES_IV);
				paramSpec = new PBEParameterSpec(SALT, ITERATIONS, paramIV);
			} else {
				// Strict legacy JetS3t V2 compatibility, with no IV support.
				paramSpec = new PBEParameterSpec(SALT, ITERATIONS);
			}

			// Verify if cipher + key are allowed by policy.
			cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
			cipher.doFinal();
		}

		@Override
		void request(HttpURLConnection u, String prefix) {
			u.setRequestProperty(prefix + JETS3T_CRYPTO_VER, CRYPTO_VER);
			u.setRequestProperty(prefix + JETS3T_CRYPTO_ALG, cryptoAlg);
		}

		@Override
		void validate(HttpURLConnection u, String prefix)
				throws IOException {
			validateImpl(u, prefix, CRYPTO_VER, cryptoAlg);
		}

		@Override
		OutputStream encrypt(OutputStream os) throws IOException {
			try {
				final Cipher cipher = InsecureCipherFactory.create(cryptoAlg);
				cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
				return new CipherOutputStream(os, cipher);
			} catch (GeneralSecurityException e) {
				throw error(e);
			}
		}

		@Override
		InputStream decrypt(InputStream in) throws IOException {
			try {
				final Cipher cipher = InsecureCipherFactory.create(cryptoAlg);
				cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
				return new CipherInputStream(in, cipher);
			} catch (GeneralSecurityException e) {
				throw error(e);
			}
		}
	}

	/** Encryption property names. */
	interface Keys {
		// Remote S3 meta: V1 algorithm name or V2 profile name.
		String JGIT_PROFILE = "jgit-crypto-profile"; //$NON-NLS-1$

		// Remote S3 meta: JGit encryption implementation version.
		String JGIT_VERSION = "jgit-crypto-version"; //$NON-NLS-1$

		// Remote S3 meta: base-64 encoded cipher algorithm parameters.
		String JGIT_CONTEXT = "jgit-crypto-context"; //$NON-NLS-1$

		// Amazon S3 connection configuration file profile property suffixes:
		String X_ALGO = ".algo"; //$NON-NLS-1$
		String X_KEY_ALGO = ".key.algo"; //$NON-NLS-1$
		String X_KEY_SIZE = ".key.size"; //$NON-NLS-1$
		String X_KEY_ITER = ".key.iter"; //$NON-NLS-1$
		String X_KEY_SALT = ".key.salt"; //$NON-NLS-1$
	}

	/** Encryption constants and defaults. */
	interface Vals {
		// Compatibility defaults.
		String DEFAULT_VERS = "0"; //$NON-NLS-1$
		String DEFAULT_ALGO = JetS3tV2.ALGORITHM;
		String DEFAULT_KEY_ALGO = JetS3tV2.ALGORITHM;
		String DEFAULT_KEY_SIZE = Integer.toString(JetS3tV2.KEY_SIZE);
		String DEFAULT_KEY_ITER = Integer.toString(JetS3tV2.ITERATIONS);
		String DEFAULT_KEY_SALT = Hex.toHexString(JetS3tV2.SALT);

		String EMPTY = ""; //$NON-NLS-1$

		// Match white space.
		String REGEX_WS = "\\s+"; //$NON-NLS-1$

		// Match PBE ciphers, i.e: PBEWithMD5AndDES
		String REGEX_PBE = "(PBE).*(WITH).+(AND).+"; //$NON-NLS-1$

		// Match transformation ciphers, i.e: AES/CBC/PKCS5Padding
		String REGEX_TRANS = "(.+)/(.+)/(.+)"; //$NON-NLS-1$
	}

	static GeneralSecurityException securityError(String message,
			Throwable cause) {
		GeneralSecurityException e = new GeneralSecurityException(
				MessageFormat.format(JGitText.get().encryptionError, message));
		e.initCause(cause);
		return e;
	}

	/**
	 * Base implementation of JGit symmetric encryption. Supports V2 properties
	 * format.
	 */
	abstract static class SymmetricEncryption extends WalkEncryption
			implements Keys, Vals {

		/** Encryption profile, root name of group of related properties. */
		final String profile;

		/** Encryption version, reflects actual implementation class. */
		final String version;

		/** Full cipher algorithm name. */
		final String cipherAlgo;

		/** Cipher algorithm name for parameters lookup. */
		final String paramsAlgo;

		/** Generated secret key. */
		final SecretKey secretKey;

		SymmetricEncryption(Properties props) throws GeneralSecurityException {

			profile = props.getProperty(AmazonS3.Keys.CRYPTO_ALG);
			version = props.getProperty(AmazonS3.Keys.CRYPTO_VER);
			String pass = props.getProperty(AmazonS3.Keys.PASSWORD);

			cipherAlgo = props.getProperty(profile + X_ALGO, DEFAULT_ALGO);

			String keyAlgo = props.getProperty(profile + X_KEY_ALGO, DEFAULT_KEY_ALGO);
			String keySize = props.getProperty(profile + X_KEY_SIZE, DEFAULT_KEY_SIZE);
			String keyIter = props.getProperty(profile + X_KEY_ITER, DEFAULT_KEY_ITER);
			String keySalt = props.getProperty(profile + X_KEY_SALT, DEFAULT_KEY_SALT);

			// Verify if cipher is present.
			Cipher cipher = InsecureCipherFactory.create(cipherAlgo);

			// Verify if key factory is present.
			SecretKeyFactory factory = SecretKeyFactory.getInstance(keyAlgo);

			final int size;
			try {
				size = Integer.parseInt(keySize);
			} catch (Exception e) {
				throw securityError(X_KEY_SIZE + EMPTY + keySize, e);
			}

			final int iter;
			try {
				iter = Integer.parseInt(keyIter);
			} catch (Exception e) {
				throw securityError(X_KEY_ITER + EMPTY + keyIter, e);
			}

			final byte[] salt;
			try {
				salt = Hex.decode(keySalt.replaceAll(REGEX_WS, EMPTY));
			} catch (Exception e) {
				throw securityError(X_KEY_SALT + EMPTY + keySalt, e);
			}

			KeySpec keySpec = new PBEKeySpec(pass.toCharArray(), salt, iter, size);

			SecretKey keyBase = factory.generateSecret(keySpec);

			String name = cipherAlgo.toUpperCase(Locale.ROOT);
			Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name);
			Matcher matcherTrans = Pattern.compile(REGEX_TRANS).matcher(name);
			if (matcherPBE.matches()) {
				paramsAlgo = cipherAlgo;
				secretKey = keyBase;
			} else if (matcherTrans.find()) {
				paramsAlgo = matcherTrans.group(1);
				secretKey = new SecretKeySpec(keyBase.getEncoded(), paramsAlgo);
			} else {
				throw new GeneralSecurityException(MessageFormat.format(
						JGitText.get().unsupportedEncryptionAlgorithm,
						cipherAlgo));
			}

			// Verify if cipher + key are allowed by policy.
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);
			cipher.doFinal();

		}

		// Shared state encrypt -> request.
		volatile String context;

		@Override
		OutputStream encrypt(OutputStream output) throws IOException {
			try {
				Cipher cipher = InsecureCipherFactory.create(cipherAlgo);
				cipher.init(Cipher.ENCRYPT_MODE, secretKey);
				AlgorithmParameters params = cipher.getParameters();
				if (params == null) {
					context = EMPTY;
				} else {
					context = Base64.encodeBytes(params.getEncoded());
				}
				return new CipherOutputStream(output, cipher);
			} catch (Exception e) {
				throw error(e);
			}
		}

		@Override
		void request(HttpURLConnection conn, String prefix) throws IOException {
			conn.setRequestProperty(prefix + JGIT_PROFILE, profile);
			conn.setRequestProperty(prefix + JGIT_VERSION, version);
			conn.setRequestProperty(prefix + JGIT_CONTEXT, context);
			// No cleanup:
			// single encrypt can be followed by several request
			// from the AmazonS3.putImpl() multiple retry attempts
			// context = null; // Cleanup encrypt -> request transition.
			// TODO re-factor AmazonS3.putImpl to be more transaction-like
		}

		// Shared state validate -> decrypt.
		volatile Cipher decryptCipher;

		@Override
		void validate(HttpURLConnection conn, String prefix)
				throws IOException {
			String prof = conn.getHeaderField(prefix + JGIT_PROFILE);
			String vers = conn.getHeaderField(prefix + JGIT_VERSION);
			String cont = conn.getHeaderField(prefix + JGIT_CONTEXT);

			if (prof == null) {
				throw new IOException(MessageFormat
						.format(JGitText.get().encryptionError, JGIT_PROFILE));
			}
			if (vers == null) {
				throw new IOException(MessageFormat
						.format(JGitText.get().encryptionError, JGIT_VERSION));
			}
			if (cont == null) {
				throw new IOException(MessageFormat
						.format(JGitText.get().encryptionError, JGIT_CONTEXT));
			}
			if (!profile.equals(prof)) {
				throw new IOException(MessageFormat.format(
						JGitText.get().unsupportedEncryptionAlgorithm, prof));
			}
			if (!version.equals(vers)) {
				throw new IOException(MessageFormat.format(
						JGitText.get().unsupportedEncryptionVersion, vers));
			}
			try {
				decryptCipher = InsecureCipherFactory.create(cipherAlgo);
				if (cont.isEmpty()) {
					decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
				} else {
					AlgorithmParameters params = AlgorithmParameters
							.getInstance(paramsAlgo);
					params.init(Base64.decode(cont));
					decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, params);
				}
			} catch (Exception e) {
				throw error(e);
			}
		}

		@Override
		InputStream decrypt(InputStream input) throws IOException {
			try {
				return new CipherInputStream(input, decryptCipher);
			} finally {
				decryptCipher = null; // Cleanup validate -> decrypt transition.
			}
		}
	}

	/**
	 * Provides JetS3t-like encryption with AES support. Uses V1 connection file
	 * format. For reference, see: 'jgit-s3-connection-v-1.properties'.
	 */
	static class JGitV1 extends SymmetricEncryption {

		static final String VERSION = "1"; //$NON-NLS-1$

		// Re-map connection properties V1 -> V2.
		static Properties wrap(String algo, String pass) {
			Properties props = new Properties();
			props.put(AmazonS3.Keys.CRYPTO_ALG, algo);
			props.put(AmazonS3.Keys.CRYPTO_VER, VERSION);
			props.put(AmazonS3.Keys.PASSWORD, pass);
			props.put(algo + Keys.X_ALGO, algo);
			props.put(algo + Keys.X_KEY_ALGO, algo);
			props.put(algo + Keys.X_KEY_ITER, DEFAULT_KEY_ITER);
			props.put(algo + Keys.X_KEY_SIZE, DEFAULT_KEY_SIZE);
			props.put(algo + Keys.X_KEY_SALT, DEFAULT_KEY_SALT);
			return props;
		}

		JGitV1(String algo, String pass)
				throws GeneralSecurityException {
			super(wrap(algo, pass));
			String name = cipherAlgo.toUpperCase(Locale.ROOT);
			Matcher matcherPBE = Pattern.compile(REGEX_PBE).matcher(name);
			if (!matcherPBE.matches())
				throw new GeneralSecurityException(
						JGitText.get().encryptionOnlyPBE);
		}

	}

	/**
	 * Supports both PBE and non-PBE algorithms. Uses V2 connection file format.
	 * For reference, see: 'jgit-s3-connection-v-2.properties'.
	 */
	static class JGitV2 extends SymmetricEncryption {

		static final String VERSION = "2"; //$NON-NLS-1$

		JGitV2(Properties props)
				throws GeneralSecurityException {
			super(props);
		}
	}

	/**
	 * Encryption factory.
	 *
	 * @param props
	 *            configuration properties
	 * @return instance this object
	 * @throws GeneralSecurityException
	 *             if generic security failure occurred
	 */
	static WalkEncryption instance(Properties props)
			throws GeneralSecurityException {

		String algo = props.getProperty(AmazonS3.Keys.CRYPTO_ALG, Vals.DEFAULT_ALGO);
		String vers = props.getProperty(AmazonS3.Keys.CRYPTO_VER, Vals.DEFAULT_VERS);
		String pass = props.getProperty(AmazonS3.Keys.PASSWORD);

		if (pass == null) // Disable encryption.
			return WalkEncryption.NONE;

		switch (vers) {
		case Vals.DEFAULT_VERS:
			return new JetS3tV2(algo, pass);
		case JGitV1.VERSION:
			return new JGitV1(algo, pass);
		case JGitV2.VERSION:
			return new JGitV2(props);
		default:
			throw new GeneralSecurityException(MessageFormat.format(
					JGitText.get().unsupportedEncryptionVersion, vers));
		}
	}
}
