Hi Jim,

Please find below a short example that demonstrates how to append signature
subpackets.

        PGPSecretKeyRing certKey = ...
        String privateKeyPassword = ...

        PGPSignatureSubpacketGenerator hashed = new
PGPSignatureSubpacketGenerator();
        hashed.setSignatureCreationTime(false, new Date());
        hashed.setRevocationReason(false, reason, description);

        PGPSignatureSubpacketGenerator unhashed = new
PGPSignatureSubpacketGenerator();
        unhashed.setIssuerKeyID(false, certKey.getPublicKey().getKeyID());

        PGPSignatureGenerator sGen = new
PGPSignatureGenerator(certKey.getPublicKey().getAlgorithm(),
                                                HashAlgorithmTags.SHA1,

PGPLib.BOUNCY_CASTLE_PROVIDER);
        sGen.initSign(PGPSignature.KEY_REVOCATION,

certKey.getSecretKey().extractPrivateKey(privateKeyPassword.toCharArray(),

                            "BC");

         sGen.setHashedSubpackets(hashed.generate());
         sGen.setUnhashedSubpackets(unhashed.generate());

Cheers,
Atanas Krachev

2012/6/27 Jim Treinen <jtrei...@gmail.com>

> Hi Atanas,
>
> Thank you very much for your advice on this topic.  I am pretty new with
> BouncyCastle, and I haven't had much luck getting this to work, do you
> happen to have an example of creating hashed packets and adding them to the
> output?
>
> I appreciate your help, and thanks again,
>
> Jim.
>
>
> On Fri, Jun 15, 2012 at 3:38 AM, Atanas Krachev <akrac...@gmail.com>wrote:
>
>> Hi Jim,
>>
>> In theory a revocation certificate is a text file that you use in the
>> case that you have lost either your private key or it's password
>> to revoke your public key.
>>
>> The text file is a signature created just like you do it:
>> sGen.InitSign(PgpSignature.KeyRevocation, pgpPrivKey);
>>
>> but you have to add additionally :
>> 1. two hashed packets: CreationTime and RevocationReason
>> 2. one unhashed packet : IssuerKeyID (in your case
>> pgpSec.GetPublicKey().KeyId)
>>
>> the signature does not have to be updated (sGen.Update is useless)
>>
>> and there is one final thing:
>> because ArmoredOutputStream has no way of producing correct revocation
>> certificate headers
>> you have to manually replace the generated ones with -----BEGIN PGP
>> PUBLIC KEY BLOCK----- and -----END PGP PUBLIC KEY BLOCK-----
>>
>> In short that's it.
>>
>> Cheers,
>> Atanas Krachev
>>
>> 2012/6/15 Jim Treinen <jtrei...@gmail.com>
>>
>>> Hello everyone,
>>>
>>> We are trying to create revocation certificates at key pair generation
>>> time.  We have the following code working, which works great for signing
>>> and verifying challenge strings, however, when using it to create (what I
>>> thought) were revocation certificates, it creates another detached
>>> signature (adopted from the detached signature example), but the signature
>>> does not verify as a valid revocation cert.
>>>
>>> The stringToSign being passed in, is the public key, and the boolean,
>>> when set to true, is our attempt to generate a revocation cert.
>>>
>>> Thanks in advance,
>>>
>>> Jim T.
>>>
>>>
>>> private string _createSignature(KeyModel keyModel, string stringToSign, 
>>> bool isRevocation)
>>>
>>>         {
>>>
>>>
>>>             Stream outputStream;
>>>
>>>             PgpSecretKey pgpSec;
>>>
>>>             PgpPrivateKey pgpPrivKey;
>>>
>>>             MemoryStream privateKeyStream;
>>>
>>>             outputStream = new MemoryStream();
>>>
>>>
>>>             ArmoredOutputStream armoredOutputStream
>>> = new ArmoredOutputStream(outputStream);
>>>
>>>
>>>             byte[] toSignByteArray = Encoding.ASCII.GetBytes(
>>> stringToSign );
>>>
>>>             MemoryStream toSignStream
>>> = new MemoryStream(toSignByteArray);
>>>
>>>
>>>             // Get the private key
>>>
>>>             using (InsecureByteArray iba
>>> = new InsecureByteArray(KeyModel.PrivateKey, Encoding.ASCII))
>>>
>>>             {
>>>
>>>                 privateKeyStream = new MemoryStream(iba.Value);
>>>
>>>                 pgpSec = this.ReadSecretKey(privateKeyStream);
>>>
>>>                 privateKeyStream.Close();
>>>
>>>             }
>>>
>>>
>>>
>>>             using (InsecureCharArray ica
>>> = new InsecureCharArray(KeyModel.Passphrase))
>>>
>>>             {
>>>
>>>                 pgpPrivKey = pgpSec.ExtractPrivateKey(ica.Value);
>>>
>>>             }
>>>
>>>
>>>             PgpSignatureGenerator sGen
>>> = new PgpSignatureGenerator(pgpSec.PublicKey.Algorithm, 
>>> HashAlgorithmTag.Sha256);
>>>
>>>             if (isRevocation)
>>>
>>>             {
>>>
>>>                 sGen.InitSign(PgpSignature.KeyRevocation, pgpPrivKey);
>>>
>>>             }
>>>
>>>             else
>>>
>>>             {
>>>
>>>                 sGen.InitSign(PgpSignature.BinaryDocument, pgpPrivKey);
>>>
>>>             }
>>>
>>>
>>>             BcpgOutputStream bOut
>>> = new BcpgOutputStream(armoredOutputStream);
>>>
>>>
>>>
>>>             int ch = 0;
>>>
>>>             while ((ch = toSignStream.ReadByte()) >= 0)
>>>
>>>             {
>>>
>>>                 // lOut.WriteByte((byte)ch);
>>>
>>>                 sGen.Update((byte)ch);
>>>
>>>             }
>>>
>>>
>>>
>>>
>>>             // send the signature to the output stream
>>>
>>>             sGen.Generate().Encode(bOut);
>>>
>>>
>>>             // Clean up
>>>
>>>             bOut.Close();           // BcpgOutputStream
>>>
>>>             toSignStream.Close();            // input file stream
>>>
>>>
>>>             outputStream.Position = 0;
>>>
>>>             StreamReader reader = new StreamReader(outputStream);
>>>
>>>             string signature = reader.ReadToEnd();
>>>
>>>
>>>             armoredOutputStream.Close();   // armored stream
>>>
>>>             outputStream.Close();   // underlying stream
>>>
>>>
>>>
>>>             reader.Close();
>>>
>>>
>>>             return signature;
>>>
>>>
>>>         }
>>>
>>
>>
>

Reply via email to