~brian-thomason/+junk/bouncycastle

« back to all changes in this revision

Viewing changes to src/org/bouncycastle/crypto/signers/GenericSigner.java

  • Committer: Brian Thomason
  • Date: 2011-12-20 17:20:32 UTC
  • Revision ID: brian.thomason@canonical.com-20111220172032-rdtm13jgdxtksacr
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.bouncycastle.crypto.signers;
 
2
 
 
3
import org.bouncycastle.crypto.AsymmetricBlockCipher;
 
4
import org.bouncycastle.crypto.CipherParameters;
 
5
import org.bouncycastle.crypto.CryptoException;
 
6
import org.bouncycastle.crypto.DataLengthException;
 
7
import org.bouncycastle.crypto.Digest;
 
8
import org.bouncycastle.crypto.Signer;
 
9
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
 
10
import org.bouncycastle.crypto.params.ParametersWithRandom;
 
11
import org.bouncycastle.util.Arrays;
 
12
 
 
13
public class GenericSigner
 
14
    implements Signer
 
15
{
 
16
    private final AsymmetricBlockCipher engine;
 
17
    private final Digest digest;
 
18
    private boolean forSigning;
 
19
 
 
20
    public GenericSigner(
 
21
        AsymmetricBlockCipher engine,
 
22
        Digest                digest)
 
23
    {
 
24
        this.engine = engine;
 
25
        this.digest = digest;
 
26
    }
 
27
 
 
28
    /**
 
29
     * initialise the signer for signing or verification.
 
30
     *
 
31
     * @param forSigning
 
32
     *            true if for signing, false otherwise
 
33
     * @param parameters
 
34
     *            necessary parameters.
 
35
     */
 
36
    public void init(
 
37
        boolean          forSigning,
 
38
        CipherParameters parameters)
 
39
    {
 
40
        this.forSigning = forSigning;
 
41
        AsymmetricKeyParameter k;
 
42
 
 
43
        if (parameters instanceof ParametersWithRandom)
 
44
        {
 
45
            k = (AsymmetricKeyParameter)((ParametersWithRandom)parameters).getParameters();
 
46
        }
 
47
        else
 
48
        {
 
49
            k = (AsymmetricKeyParameter)parameters;
 
50
        }
 
51
 
 
52
        if (forSigning && !k.isPrivate())
 
53
        {
 
54
            throw new IllegalArgumentException("signing requires private key");
 
55
        }
 
56
 
 
57
        if (!forSigning && k.isPrivate())
 
58
        {
 
59
            throw new IllegalArgumentException("verification requires public key");
 
60
        }
 
61
 
 
62
        reset();
 
63
 
 
64
        engine.init(forSigning, parameters);
 
65
    }
 
66
 
 
67
    /**
 
68
     * update the internal digest with the byte b
 
69
     */
 
70
    public void update(
 
71
        byte input)
 
72
    {
 
73
        digest.update(input);
 
74
    }
 
75
 
 
76
    /**
 
77
     * update the internal digest with the byte array in
 
78
     */
 
79
    public void update(
 
80
        byte[]  input,
 
81
        int     inOff,
 
82
        int     length)
 
83
    {
 
84
        digest.update(input, inOff, length);
 
85
    }
 
86
 
 
87
    /**
 
88
     * Generate a signature for the message we've been loaded with using the key
 
89
     * we were initialised with.
 
90
     */
 
91
    public byte[] generateSignature()
 
92
        throws CryptoException, DataLengthException
 
93
    {
 
94
        if (!forSigning)
 
95
        {
 
96
            throw new IllegalStateException("GenericSigner not initialised for signature generation.");
 
97
        }
 
98
 
 
99
        byte[] hash = new byte[digest.getDigestSize()];
 
100
        digest.doFinal(hash, 0);
 
101
 
 
102
        return engine.processBlock(hash, 0, hash.length);
 
103
    }
 
104
 
 
105
    /**
 
106
     * return true if the internal state represents the signature described in
 
107
     * the passed in array.
 
108
     */
 
109
    public boolean verifySignature(
 
110
        byte[] signature)
 
111
    {
 
112
        if (forSigning)
 
113
        {
 
114
            throw new IllegalStateException("GenericSigner not initialised for verification");
 
115
        }
 
116
 
 
117
        byte[] hash = new byte[digest.getDigestSize()];
 
118
        digest.doFinal(hash, 0);
 
119
 
 
120
        try
 
121
        {
 
122
            byte[] sig = engine.processBlock(signature, 0, signature.length);
 
123
 
 
124
            return Arrays.constantTimeAreEqual(sig, hash);
 
125
        }
 
126
        catch (Exception e)
 
127
        {
 
128
            return false;
 
129
        }
 
130
    }
 
131
 
 
132
    public void reset()
 
133
    {
 
134
        digest.reset();
 
135
    }
 
136
}