package org.thoughtcrime.SMP.crypto.SMP;
/*
* Copyright @ 2015 Atlassian Pty Ltd
*
* 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.
*/
import android.util.Log;
import org.spongycastle.util.BigIntegers;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.PublicKey;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
/**
* @author George Politis modified by ludwig on 27/06/15
*/
public class SMPOutputStream extends FilterOutputStream implements
SerializationConstants {
private static final String TAG = SMPOutputStream.class.getSimpleName();
public SMPOutputStream(OutputStream out) {
super(out);
}
private void writeNumber(int value, int length) throws IOException {
Log.d(TAG, "writeNumber value: " + value);
byte[] b = new byte[length];
for (int i = 0; i < length; i++) {
int offset = (b.length - 1 - i) * 8;
b[i] = (byte) ((value >>> offset) & 0xFF);
}
write(b);
}
public void writeBigInt(BigInteger bi) throws IOException {
byte[] b = BigIntegers.asUnsignedByteArray(bi);
writeData(b);
}
public void writeByte(int b) throws IOException {
writeNumber(b, TYPE_LEN_BYTE);
}
public void writeData(byte[] b) throws IOException {
int len = (b == null || b.length < 0) ? 0 : b.length;
writeNumber(len, DATA_LEN);
if (len > 0)
write(b);
}
public void writeInt(int i) throws IOException {
writeNumber(i, TYPE_LEN_INT);
}
public void writeShort(int s) throws IOException {
writeNumber(s, TYPE_LEN_SHORT);
}
/*
public void writeMac(byte[] mac) throws IOException {
if (mac == null || mac.length != TYPE_LEN_MAC)
throw new IllegalArgumentException();
write(mac);
}
public void writeCtr(byte[] ctr) throws IOException {
if (ctr == null || ctr.length < 1)
return;
int i = 0;
while (i < TYPE_LEN_CTR && i < ctr.length) {
write(ctr[i]);
i++;
}
}
public void writeDHPublicKey(DHPublicKey dhPublicKey) throws IOException {
byte[] b = BigIntegers.asUnsignedByteArray(dhPublicKey.getY());
writeData(b);
}
*/
public void writePublicKey(PublicKey pubKey) throws IOException {
if (!(pubKey instanceof DSAPublicKey))
throw new UnsupportedOperationException(
"Key types other than DSA are not supported at the moment.");
DSAPublicKey dsaKey = (DSAPublicKey) pubKey;
writeShort(0);
DSAParams dsaParams = dsaKey.getParams();
writeBigInt(dsaParams.getP());
writeBigInt(dsaParams.getQ());
writeBigInt(dsaParams.getG());
writeBigInt(dsaKey.getY());
}
/*
public void writeTlvData(byte[] b) throws IOException {
int len = (b == null || b.length < 0) ? 0 : b.length;
writeNumber(len, TLV_LEN);
if (len > 0)
write(b);
}
public void writeSignature(byte[] signature, PublicKey pubKey)
throws IOException {
if (!pubKey.getAlgorithm().equals("DSA"))
throw new UnsupportedOperationException();
out.write(signature);
}
public void writeMysteriousX(SignatureX x) throws IOException {
writePublicKey(x.longTermPublicKey);
writeInt(x.dhKeyID);
writeSignature(x.signature, x.longTermPublicKey);
}
public void writeMysteriousX(SignatureM m) throws IOException {
writeBigInt(m.localPubKey.getY());
writeBigInt(m.remotePubKey.getY());
writePublicKey(m.localLongTermPubKey);
writeInt(m.keyPairID);
}
public void writeMysteriousT(MysteriousT t) throws IOException {
writeShort(t.protocolVersion);
writeByte(t.messageType);
if (t.protocolVersion == 3) {
writeInt(t.senderInstanceTag);
writeInt(t.receiverInstanceTag);
}
writeByte(t.flags);
writeInt(t.senderKeyID);
writeInt(t.recipientKeyID);
writeDHPublicKey(t.nextDH);
writeCtr(t.ctr);
writeData(t.encryptedMessage);
}
*/
}