1 package org.apache.commons.openpgp;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import org.bouncycastle.bcpg.ArmoredOutputStream;
21 import org.bouncycastle.bcpg.BCPGOutputStream;
22 import org.bouncycastle.jce.provider.BouncyCastleProvider;
23 import org.bouncycastle.openpgp.PGPException;
24 import org.bouncycastle.openpgp.PGPPrivateKey;
25 import org.bouncycastle.openpgp.PGPSecretKey;
26 import org.bouncycastle.openpgp.PGPSignature;
27 import org.bouncycastle.openpgp.PGPSignatureGenerator;
28 import org.bouncycastle.openpgp.PGPUtil;
29
30 import java.io.ByteArrayOutputStream;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.NoSuchProviderException;
35 import java.security.Security;
36 import java.security.SignatureException;
37
38
39
40
41
42
43 public class BouncyCastleOpenPgpStreamingSigner
44 implements OpenPgpStreamingSigner
45 {
46 private static final String PROVIDER = "BC";
47
48 private PGPSignatureGenerator sGen;
49
50 private final ByteArrayOutputStream signatureBytes;
51
52 private BCPGOutputStream bOut;
53
54 public BouncyCastleOpenPgpStreamingSigner( String keyId, KeyRing keyRing, boolean asciiArmor )
55 throws OpenPgpException
56 {
57 signatureBytes = new ByteArrayOutputStream();
58 init( asciiArmor, signatureBytes, keyRing, keyId );
59 }
60
61 public BouncyCastleOpenPgpStreamingSigner( OutputStream signature, String keyId, KeyRing keyRing,
62 boolean asciiArmor )
63 throws OpenPgpException
64 {
65 signatureBytes = null;
66 init( asciiArmor, signature, keyRing, keyId );
67 }
68
69 private void init( boolean asciiArmor, OutputStream signature, KeyRing keyRing, String keyId )
70 throws OpenPgpException
71 {
72
73 Security.addProvider( new BouncyCastleProvider() );
74
75 OutputStream out;
76 if ( asciiArmor )
77 {
78 out = new ArmoredOutputStream( signature );
79 }
80 else
81 {
82 out = signature;
83 }
84 bOut = new BCPGOutputStream( out );
85
86 try
87 {
88 PGPSecretKey pgpSec = keyRing.getSecretKey( keyId );
89 PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey( keyRing.getPassword(), PROVIDER );
90 sGen = new PGPSignatureGenerator( pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1, PROVIDER );
91 sGen.initSign( PGPSignature.BINARY_DOCUMENT, pgpPrivKey );
92 }
93 catch ( NoSuchAlgorithmException e )
94 {
95 throw new OpenPgpException(
96 "Unable to find the correct algorithm for PGP - check that the Bouncy Castle provider is correctly installed",
97 e );
98 }
99 catch ( NoSuchProviderException e )
100 {
101 throw new OpenPgpException(
102 "Unable to find the correct provider for PGP - check that the Bouncy Castle provider is correctly installed",
103 e );
104 }
105 catch ( PGPException e )
106 {
107
108 throw new OpenPgpException( "Error calculating detached signature", e );
109 }
110 }
111
112 public void update( byte[] buf )
113 throws OpenPgpException
114 {
115 update( buf, 0, buf.length );
116 }
117
118 public void update( byte[] buf, int offset, int length )
119 throws OpenPgpException
120 {
121 try
122 {
123 sGen.update( buf, offset, length );
124 }
125 catch ( SignatureException e )
126 {
127
128 throw new OpenPgpException( "Error calculating detached signature", e );
129 }
130 }
131
132 public byte[] finish()
133 throws OpenPgpException, IOException
134 {
135 try
136 {
137 sGen.generate().encode( bOut );
138 }
139 catch ( PGPException e )
140 {
141
142 throw new OpenPgpException( "Error calculating detached signature", e );
143 }
144 catch ( SignatureException e )
145 {
146
147 throw new OpenPgpException( "Error calculating detached signature", e );
148 }
149 bOut.close();
150 return signatureBytes != null ? signatureBytes.toByteArray() : null;
151 }
152 }