001: package org.bouncycastle.openpgp;
002:
003: import org.bouncycastle.bcpg.BCPGInputStream;
004: import org.bouncycastle.bcpg.BCPGOutputStream;
005: import org.bouncycastle.bcpg.OnePassSignaturePacket;
006:
007: import java.io.ByteArrayOutputStream;
008: import java.io.IOException;
009: import java.io.OutputStream;
010: import java.security.InvalidKeyException;
011: import java.security.NoSuchProviderException;
012: import java.security.Signature;
013: import java.security.SignatureException;
014:
015: /**
016: * A one pass signature object.
017: */
018: public class PGPOnePassSignature {
019: private OnePassSignaturePacket sigPack;
020: private int signatureType;
021:
022: private Signature sig;
023:
024: private byte lastb;
025:
026: PGPOnePassSignature(BCPGInputStream pIn) throws IOException,
027: PGPException {
028: this ((OnePassSignaturePacket) pIn.readPacket());
029: }
030:
031: PGPOnePassSignature(OnePassSignaturePacket sigPack)
032: throws PGPException {
033: this .sigPack = sigPack;
034: this .signatureType = sigPack.getSignatureType();
035:
036: try {
037: this .sig = Signature.getInstance(PGPUtil.getSignatureName(
038: sigPack.getKeyAlgorithm(), sigPack
039: .getHashAlgorithm()), PGPUtil
040: .getDefaultProvider());
041: } catch (Exception e) {
042: throw new PGPException("can't set up signature object.", e);
043: }
044: }
045:
046: /**
047: * Initialise the signature object for verification.
048: *
049: * @param pubKey
050: * @param provider
051: * @throws NoSuchProviderException
052: * @throws PGPException
053: */
054: public void initVerify(PGPPublicKey pubKey, String provider)
055: throws NoSuchProviderException, PGPException {
056: lastb = 0;
057:
058: try {
059: sig.initVerify(pubKey.getKey(provider));
060: } catch (InvalidKeyException e) {
061: throw new PGPException("invalid key.", e);
062: }
063: }
064:
065: public void update(byte b) throws SignatureException {
066: if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) {
067: if (b == '\r') {
068: sig.update((byte) '\r');
069: sig.update((byte) '\n');
070: } else if (b == '\n') {
071: if (lastb != '\r') {
072: sig.update((byte) '\r');
073: sig.update((byte) '\n');
074: }
075: } else {
076: sig.update(b);
077: }
078:
079: lastb = b;
080: } else {
081: sig.update(b);
082: }
083: }
084:
085: public void update(byte[] bytes) throws SignatureException {
086: if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) {
087: for (int i = 0; i != bytes.length; i++) {
088: this .update(bytes[i]);
089: }
090: } else {
091: sig.update(bytes);
092: }
093: }
094:
095: public void update(byte[] bytes, int off, int length)
096: throws SignatureException {
097: if (signatureType == PGPSignature.CANONICAL_TEXT_DOCUMENT) {
098: int finish = off + length;
099:
100: for (int i = off; i != finish; i++) {
101: this .update(bytes[i]);
102: }
103: } else {
104: sig.update(bytes, off, length);
105: }
106: }
107:
108: /**
109: * Verify the calculated signature against the passed in PGPSignature.
110: *
111: * @param pgpSig
112: * @return boolean
113: * @throws PGPException
114: * @throws SignatureException
115: */
116: public boolean verify(PGPSignature pgpSig) throws PGPException,
117: SignatureException {
118: sig.update(pgpSig.getSignatureTrailer());
119:
120: return sig.verify(pgpSig.getSignature());
121: }
122:
123: public long getKeyID() {
124: return sigPack.getKeyID();
125: }
126:
127: public int getSignatureType() {
128: return sigPack.getSignatureType();
129: }
130:
131: public int getHashAlgorithm() {
132: return sigPack.getHashAlgorithm();
133: }
134:
135: public int getKeyAlgorithm() {
136: return sigPack.getKeyAlgorithm();
137: }
138:
139: public byte[] getEncoded() throws IOException {
140: ByteArrayOutputStream bOut = new ByteArrayOutputStream();
141:
142: this .encode(bOut);
143:
144: return bOut.toByteArray();
145: }
146:
147: public void encode(OutputStream outStream) throws IOException {
148: BCPGOutputStream out;
149:
150: if (outStream instanceof BCPGOutputStream) {
151: out = (BCPGOutputStream) outStream;
152: } else {
153: out = new BCPGOutputStream(outStream);
154: }
155:
156: out.writePacket(sigPack);
157: }
158: }
|