001: package org.bouncycastle.openpgp.examples;
002:
003: import org.bouncycastle.bcpg.ArmoredOutputStream;
004: import org.bouncycastle.bcpg.BCPGOutputStream;
005: import org.bouncycastle.bcpg.sig.NotationData;
006: import org.bouncycastle.jce.provider.BouncyCastleProvider;
007: import org.bouncycastle.openpgp.PGPPrivateKey;
008: import org.bouncycastle.openpgp.PGPPublicKey;
009: import org.bouncycastle.openpgp.PGPPublicKeyRing;
010: import org.bouncycastle.openpgp.PGPSecretKey;
011: import org.bouncycastle.openpgp.PGPSecretKeyRing;
012: import org.bouncycastle.openpgp.PGPSignature;
013: import org.bouncycastle.openpgp.PGPSignatureGenerator;
014: import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
015: import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
016: import org.bouncycastle.openpgp.PGPUtil;
017:
018: import java.io.ByteArrayInputStream;
019: import java.io.ByteArrayOutputStream;
020: import java.io.FileInputStream;
021: import java.io.FileOutputStream;
022: import java.io.OutputStream;
023: import java.security.Security;
024: import java.util.Iterator;
025:
026: /**
027: * A simple utility class that directly signs a public key and writes the signed key to "SignedKey.asc" in
028: * the current working directory.
029: * <p>
030: * To sign a key: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue.<br/>
031: * </p><p>
032: * To display a NotationData packet from a publicKey previously signed: DirectKeySignature signedPublicKeyFile.<br/>
033: * </p><p>
034: * <b>Note</b>: this example will silently overwrite files, nor does it pay any attention to
035: * the specification of "_CONSOLE" in the filename. It also expects that a single pass phrase
036: * will have been used.
037: * </p>
038: */
039: public class DirectKeySignature {
040: public static void main(String[] args) throws Exception {
041: Security.addProvider(new BouncyCastleProvider());
042:
043: if (args.length == 1) {
044: PGPPublicKeyRing ring = new PGPPublicKeyRing(PGPUtil
045: .getDecoderStream(new FileInputStream(args[0])));
046: PGPPublicKey key = ring.getPublicKey();
047:
048: // iterate through all direct key signautures and look for NotationData subpackets
049: Iterator iter = key
050: .getSignaturesOfType(PGPSignature.DIRECT_KEY);
051: while (iter.hasNext()) {
052: PGPSignature sig = (PGPSignature) iter.next();
053:
054: System.out.println("Signature date is: "
055: + sig.getHashedSubPackets()
056: .getSignatureCreationTime());
057:
058: NotationData[] data = sig.getHashedSubPackets()
059: .getNotationDataOccurences();//.getSubpacket(SignatureSubpacketTags.NOTATION_DATA);
060:
061: for (int i = 0; i < data.length; i++) {
062: System.out.println("Found Notaion named '"
063: + data[i].getNotationName()
064: + "' with content '"
065: + data[i].getNotationValue() + "'.");
066: }
067: }
068: } else if (args.length == 5) {
069: // gather command line arguments
070: PGPSecretKeyRing secRing = new PGPSecretKeyRing(PGPUtil
071: .getDecoderStream(new FileInputStream(args[0])));
072: String secretKeyPass = args[1];
073: PGPPublicKeyRing ring = new PGPPublicKeyRing(PGPUtil
074: .getDecoderStream(new FileInputStream(args[2])));
075: String notationName = args[3];
076: String notationValue = args[4];
077:
078: // create the signed keyRing
079: PGPPublicKeyRing sRing = null;
080: sRing = new PGPPublicKeyRing(new ByteArrayInputStream(
081: signPublicKey(secRing.getSecretKey(),
082: secretKeyPass, ring.getPublicKey(),
083: notationName, notationValue, true)));
084: ring = sRing;
085:
086: // write the created keyRing to file
087: ArmoredOutputStream out = new ArmoredOutputStream(
088: new FileOutputStream("SignedKey.asc"));
089: sRing.encode(out);
090: out.flush();
091: out.close();
092: } else {
093: System.err
094: .println("usage: DirectKeySignature secretKeyFile secretKeyPass publicKeyFile(key to be signed) NotationName NotationValue");
095: System.err
096: .println("or: DirectKeySignature signedPublicKeyFile");
097:
098: }
099: }
100:
101: private static byte[] signPublicKey(PGPSecretKey secretKey,
102: String secretKeyPass, PGPPublicKey keyToBeSigned,
103: String notationName, String notationValue, boolean armor)
104: throws Exception {
105: OutputStream out = new ByteArrayOutputStream();
106:
107: if (armor) {
108: out = new ArmoredOutputStream(out);
109: }
110:
111: PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(
112: secretKeyPass.toCharArray(), "BC");
113:
114: PGPSignatureGenerator sGen = new PGPSignatureGenerator(
115: secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1,
116: "BC");
117:
118: sGen.initSign(PGPSignature.DIRECT_KEY, pgpPrivKey);
119:
120: BCPGOutputStream bOut = new BCPGOutputStream(out);
121:
122: sGen.generateOnePassVersion(false).encode(bOut);
123:
124: PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
125:
126: boolean isHumanReadable = true;
127:
128: spGen.setNotationData(true, isHumanReadable, notationName,
129: notationValue);
130:
131: PGPSignatureSubpacketVector packetVector = spGen.generate();
132: sGen.setHashedSubpackets(packetVector);
133:
134: bOut.flush();
135:
136: return PGPPublicKey.addCertification(keyToBeSigned,
137: sGen.generate()).getEncoded();
138: }
139: }
|