001: package org.bouncycastle.openpgp;
002:
003: import java.security.NoSuchProviderException;
004: import java.security.SecureRandom;
005: import java.util.ArrayList;
006: import java.util.Iterator;
007: import java.util.List;
008:
009: import org.bouncycastle.bcpg.*;
010:
011: /**
012: * Generator for a PGP master and subkey ring. This class will generate
013: * both the secret and public key rings
014: */
015: public class PGPKeyRingGenerator {
016: List keys = new ArrayList();
017:
018: private String id;
019: private int encAlgorithm;
020: private int certificationLevel;
021: private char[] passPhrase;
022: private boolean useSHA1;
023: private PGPKeyPair masterKey;
024: private PGPSignatureSubpacketVector hashedPcks;
025: private PGPSignatureSubpacketVector unhashedPcks;
026: private SecureRandom rand;
027: private String provider;
028:
029: /**
030: * Create a new key ring generator using old style checksumming. It is recommended to use
031: * SHA1 checksumming where possible.
032: *
033: * @param certificationLevel the certification level for keys on this ring.
034: * @param masterKey the master key pair.
035: * @param id the id to be associated with the ring.
036: * @param encAlgorithm the algorithm to be used to protect secret keys.
037: * @param passPhrase the passPhrase to be used to protect secret keys.
038: * @param hashedPcks packets to be included in the certification hash.
039: * @param unhashedPcks packets to be attached unhashed to the certification.
040: * @param rand input secured random
041: * @param provider the provider to use for encryption.
042: *
043: * @throws PGPException
044: * @throws NoSuchProviderException
045: */
046: public PGPKeyRingGenerator(int certificationLevel,
047: PGPKeyPair masterKey, String id, int encAlgorithm,
048: char[] passPhrase, PGPSignatureSubpacketVector hashedPcks,
049: PGPSignatureSubpacketVector unhashedPcks,
050: SecureRandom rand, String provider) throws PGPException,
051: NoSuchProviderException {
052: this (certificationLevel, masterKey, id, encAlgorithm,
053: passPhrase, false, hashedPcks, unhashedPcks, rand,
054: provider);
055: }
056:
057: /**
058: * Create a new key ring generator.
059: *
060: * @param certificationLevel the certification level for keys on this ring.
061: * @param masterKey the master key pair.
062: * @param id the id to be associated with the ring.
063: * @param encAlgorithm the algorithm to be used to protect secret keys.
064: * @param passPhrase the passPhrase to be used to protect secret keys.
065: * @param useSHA1 checksum the secret keys with SHA1 rather than the older 16 bit checksum.
066: * @param hashedPcks packets to be included in the certification hash.
067: * @param unhashedPcks packets to be attached unhashed to the certification.
068: * @param rand input secured random
069: * @param provider the provider to use for encryption.
070: *
071: * @throws PGPException
072: * @throws NoSuchProviderException
073: */
074: public PGPKeyRingGenerator(int certificationLevel,
075: PGPKeyPair masterKey, String id, int encAlgorithm,
076: char[] passPhrase, boolean useSHA1,
077: PGPSignatureSubpacketVector hashedPcks,
078: PGPSignatureSubpacketVector unhashedPcks,
079: SecureRandom rand, String provider) throws PGPException,
080: NoSuchProviderException {
081: this .certificationLevel = certificationLevel;
082: this .masterKey = masterKey;
083: this .id = id;
084: this .encAlgorithm = encAlgorithm;
085: this .passPhrase = passPhrase;
086: this .useSHA1 = useSHA1;
087: this .hashedPcks = hashedPcks;
088: this .unhashedPcks = unhashedPcks;
089: this .rand = rand;
090: this .provider = provider;
091:
092: keys.add(new PGPSecretKey(certificationLevel, masterKey, id,
093: encAlgorithm, passPhrase, useSHA1, hashedPcks,
094: unhashedPcks, rand, provider));
095: }
096:
097: /**
098: * Add a sub key to the key ring to be generated with default certification and inheriting
099: * the hashed/unhashed packets of the master key.
100: *
101: * @param keyPair
102: * @throws PGPException
103: */
104: public void addSubKey(PGPKeyPair keyPair) throws PGPException {
105: addSubKey(keyPair, hashedPcks, unhashedPcks);
106: }
107:
108: /**
109: * Add a subkey with specific hashed and unhashed packets associated with it and default
110: * certification.
111: *
112: * @param keyPair public/private key pair.
113: * @param hashedPcks hashed packet values to be included in certification.
114: * @param unhashedPcks unhashed packets values to be included in certification.
115: * @throws PGPException
116: */
117: public void addSubKey(PGPKeyPair keyPair,
118: PGPSignatureSubpacketVector hashedPcks,
119: PGPSignatureSubpacketVector unhashedPcks)
120: throws PGPException {
121: try {
122: PGPSignatureGenerator sGen = new PGPSignatureGenerator(
123: masterKey.getPublicKey().getAlgorithm(),
124: HashAlgorithmTags.SHA1, provider);
125:
126: //
127: // generate the certification
128: //
129: sGen.initSign(PGPSignature.SUBKEY_BINDING, masterKey
130: .getPrivateKey());
131:
132: sGen.setHashedSubpackets(hashedPcks);
133: sGen.setUnhashedSubpackets(unhashedPcks);
134:
135: List subSigs = new ArrayList();
136:
137: subSigs.add(sGen.generateCertification(masterKey
138: .getPublicKey(), keyPair.getPublicKey()));
139:
140: keys.add(new PGPSecretKey(keyPair, null, subSigs,
141: encAlgorithm, passPhrase, useSHA1, rand, provider));
142: } catch (PGPException e) {
143: throw e;
144: } catch (Exception e) {
145: throw new PGPException("exception adding subkey: ", e);
146: }
147: }
148:
149: /**
150: * Return the secret key ring.
151: *
152: * @return a secret key ring.
153: */
154: public PGPSecretKeyRing generateSecretKeyRing() {
155: return new PGPSecretKeyRing(keys);
156: }
157:
158: /**
159: * Return the public key ring that corresponds to the secret key ring.
160: *
161: * @return a public key ring.
162: */
163: public PGPPublicKeyRing generatePublicKeyRing() {
164: Iterator it = keys.iterator();
165: List pubKeys = new ArrayList();
166:
167: pubKeys.add(((PGPSecretKey) it.next()).getPublicKey());
168:
169: while (it.hasNext()) {
170: PGPPublicKey k = new PGPPublicKey(
171: ((PGPSecretKey) it.next()).getPublicKey());
172:
173: k.publicPk = new PublicSubkeyPacket(k.getAlgorithm(), k
174: .getCreationTime(), k.publicPk.getKey());
175:
176: pubKeys.add(k);
177: }
178:
179: return new PGPPublicKeyRing(pubKeys);
180: }
181: }
|