Re: Incomplete Armored Detached Signature
David Hook <dgh-rTAZ0PM/[email protected]>
| Newsgroups | gmane.comp.encryption.bouncy-castle.devel |
|---|---|
| Message-ID | <[email protected]> |
flush() doesn't do the same as close() in the case of the ArmoredOutputStream - the close() is needed to recognise when to write the final checksum. Other classes assume it's always fine to call flush - it isn't though if the checksum gets output. This is the reason why close on an ArmoredOutputStream doesn't actually close the underlying stream, it just "closes" the current PGP stream. I appreciate this sounds a bit weird... but the alternatives made even less sense (and in the case of flush, didn't actually work). Regards, David On 22/06/18 17:14, Rogan Dawes wrote: > If bOut wraps aOut, shouldn't the flush()/close() on bOut do the same > on aOut? > > Sounds like a bug to me? > > Rogan > > > On Fri, Jun 22, 2018 at 2:15 AM David Hook <dgh-rTAZ0PM/[email protected] > <mailto:dgh-rTAZ0PM/[email protected]>> wrote: > > > aOut needs to be closed. > > Regards, > > David > > > On 22/06/18 02:58, Russell Haley wrote: >> >> >> On Wed, Jun 20, 2018 at 11:08 PM, Rogan Dawes <[email protected] >> <mailto:[email protected]>> wrote: >> >> Missing flush() on bOut? >> >> >> Thanks for the suggestion. I just retested and flush(), finish() >> or both don't seem to have an effect: >> >> >> -----BEGIN PGP SIGNATURE----- >> Version: BCPG v1.59 >> >> iJwEAAECAAYFAlsr144ACgkQQmMlIjYrRyHvCAP7B/nqHGTO/48QprAg/JoXTu4s >> SCglKa1U3PbgZX0plAphmiu8og+ZWPaaVQ6zSR7GYkAxqv4MG4Fq2jdZRLEErrTW >> QzNgRJT7QXocky/7S2VAU8rgGFdNzkxkY2XHFsS82ZlEvfbeBLqv68zwjKpM18gp >> mPWTadnOoTXQJsXF >> >> >> private OutputStream createSignature(InputStream script, >> InputStream keyIn, char[] pass, boolean armor) >> throws GeneralSecurityException, IOException, PGPException >> { >> OutputStream out = new ByteArrayOutputStream(); >> ArmoredOutputStream aOut = null; >> if (armor){ >> aOut = new ArmoredOutputStream(out); >> } >> >> PGPSecretKey pgpSec = readSecretKey(keyIn); >> PGPPrivateKey pgpPrivKey = >> pgpSec.extractPrivateKey(new >> JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass)); >> PGPSignatureGenerator sGen = new PGPSignatureGenerator(new >> JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), >> PGPUtil.SHA1).setProvider("BC")); >> >> sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); >> >> BCPGOutputStream bOut = new >> BCPGOutputStream((aOut!=null)?aOut:out); >> InputStream fIn = new BufferedInputStream(script); >> >> int ch; >> while ((ch = fIn.read()) >= 0){ >> sGen.update((byte)ch); >> } >> >> fIn.close(); >> >> sGen.generate().encode(bOut); >> bOut.flush(); >> bOut.finish(); >> return out; >> } >> >> If there are no other suggestions I'll try running the example code. >> >> Russ >> >> >> >> On Wed, 20 Jun 2018 at 21:19 Russell Haley >> <[email protected] <mailto:[email protected]>> wrote: >> >> Hi, >> >> I have a function that creates a detached signature and >> returns a ByteArrayOutputStream. That signature is put in >> a zip file comment. When I run create the signature >> without armor and use DatatypeConverter.printHexBinary >> to "encode" it, everything works. However, when I have >> tried to use the armor API my signature is incomplete: >> >> -----BEGIN PGP SIGNATURE----- >> Version: BCPG v1.59 >> >> iJwEAAECAAYFAlsqpWQACgkQQmMlIjYrRyEkTwP/TJAULzklDhQ49fJwpdxd8AD2 >> rtVktEq5gFupRBp4Zoi9BqzHbhrymhiCRuZgq1jAJGd5+qpErfwrFCmPevTq6ksE >> 4qtauuUw30WRzDbNzO53+6ZENUA2EDQFawfSQPG1/VpI9NOLsKsbEGBrdax7BJJO >> wHx9Lab29VPPBXCb >> >> >> When attempting to verify the signature I get "premature >> end of stream in PartialInputStream". When using my on >> 'encoding' I get a verified signature. >> >> The createSignature function I'm using is pretty close to >> the example code (I changed where the final output stream >> lives and I don't close it explicitly in this function): >> >> private OutputStream createSignature(InputStream script, >> InputStream keyIn, char[] pass, boolean armor) >> throws GeneralSecurityException, IOException, PGPException >> { >> OutputStream out = new ByteArrayOutputStream(); >> ArmoredOutputStream aOut = null; >> if (armor){ >> aOut = new ArmoredOutputStream(out); >> } >> >> PGPSecretKey pgpSec = readSecretKey(keyIn); >> PGPPrivateKey pgpPrivKey = >> pgpSec.extractPrivateKey(new >> JcePBESecretKeyDecryptorBuilder().setProvider("BC").build(pass)); >> PGPSignatureGenerator sGen = new >> PGPSignatureGenerator(new >> JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), >> PGPUtil.SHA1).setProvider("BC")); >> >> sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); >> >> BCPGOutputStream bOut = new >> BCPGOutputStream((aOut!=null)?aOut:out); >> InputStream fIn = new >> BufferedInputStream(script); >> >> int ch; >> while ((ch = fIn.read()) >= 0){ >> sGen.update((byte)ch); >> } >> >> fIn.close(); >> >> sGen.generate().encode(bOut); >> return out; >> } >> >> I've put a breakpoint at the "return out" and the >> signature is truncated before it leaves the function. I >> checked the ArmouredOutputStream and nothing looks >> suspect to my untrained eye. Does anyone have some >> thoughts on what I've missed? >> >> Thanks, >> Russ >> >> >> >