alan
alan

Reputation: 131

BouncyCastle decryption - premature end of stream in PartialInputStream

I am trying to decrypt and verify an encrypted a file but an getting an exception java.io.EOFException: premature end of stream in PartialInputStream when doing the integrity check. The data is correctly being decrypted and the signature checked.

The exception occurs in pbe.verify().

Does anyone know why this might be happening and how to fix it?

I am using jdk15on version 1.51.

The code is as follows:

public static void decryptFile(InputStream in, OutputStream out, InputStream keyIn, InputStream publicKeyIn, char[] passwd)
           throws Exception {
      Security.addProvider(new BouncyCastleProvider());

      in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);

      PGPObjectFactory pgpF = new PGPObjectFactory(in);
      PGPEncryptedDataList enc;

      Object o = pgpF.nextObject();
      //
      // the first object might be a PGP marker packet.
      //
      if (o instanceof  PGPEncryptedDataList) {
         enc = (PGPEncryptedDataList) o;
      } else {
         enc = (PGPEncryptedDataList) pgpF.nextObject();
      }

      //
      // find the secret key
      //
      Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
      PGPPrivateKey sKey = null;
      PGPPublicKeyEncryptedData pbe = null;

      while (sKey == null && it.hasNext()) {
         pbe = it.next();

         sKey = findPrivateKey(keyIn, pbe.getKeyID(), passwd);
      }

      if (sKey == null) {
         throw new IllegalArgumentException("Secret key for message not found.");
      }

      InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

      PGPObjectFactory plainFact = new PGPObjectFactory(clear);

      Object message = plainFact.nextObject();


      PGPOnePassSignatureList onePassSignatureList = null;
      PGPSignatureList signatureList = null;
      PGPCompressedData compressedData;

      ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();

      if (message instanceof  PGPCompressedData) {
         PGPCompressedData cData = (PGPCompressedData) message;
         PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());

         message = pgpFact.nextObject();

         if (message instanceof  PGPLiteralData) {
            PGPLiteralData ld = (PGPLiteralData) message;

            InputStream unc = ld.getInputStream();
            int ch;

            Streams.pipeAll(unc, actualOutput);
         } else if (message instanceof  PGPOnePassSignatureList) {
            PGPPublicKey publicKey = readPublicKey(publicKeyIn);
             onePassSignatureList = (PGPOnePassSignatureList) message;
            if (onePassSignatureList == null) {
               throw new PGPException("Poor PGP. Signatures not found.");
            } else {
               if (publicKey != null) {
                  PGPLiteralData p2 = (PGPLiteralData) pgpFact.nextObject();
                  int ch;
                  InputStream dln = p2.getInputStream();

                  Streams.pipeAll(dln, actualOutput);
                  PGPOnePassSignature ops = onePassSignatureList.get(0);
                  ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);

                  ops.update(actualOutput.toByteArray());

                  PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();
                  if (!ops.verify(p3.get(0))) {
                     throw new PGPException("Signature verification failed!");
                  }
                  out.close();
               }
            }
         } else {
            throw new PGPException("Message is not a simple encrypted file - type unknown.");
         }
      }

      if (pbe.isIntegrityProtected()) {
         if (!pbe.verify()) {
            throw new PGPException("Message failed integrity check");
         }
      }
      out.write(actualOutput.toByteArray());
      out.flush();
      out.close();
   }

The full stack trace:

SEVERE: Servlet.service() for servlet appServlet threw exception
java.io.EOFException: premature end of stream in PartialInputStream
    at org.bouncycastle.bcpg.BCPGInputStream$PartialInputStream.read(Unknown Source)
    at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
    at java.io.InputStream.read(InputStream.java:82)
    at org.bouncycastle.crypto.io.CipherInputStream.nextChunk(Unknown Source)
    at org.bouncycastle.crypto.io.CipherInputStream.read(Unknown Source)
    at org.bouncycastle.bcpg.BCPGInputStream.read(Unknown Source)
    at org.bouncycastle.openpgp.PGPEncryptedData$TruncatedStream.read(Unknown Source)
    at org.bouncycastle.util.io.TeeInputStream.read(Unknown Source)
    at org.bouncycastle.openpgp.PGPEncryptedData.verify(Unknown Source)
    at com.bstonetech.ptms.integration.util.PGPUtils.decryptFile(PGPUtils.java:314)
    at com.bstonetech.ptms.integration.service.encryption.EncryptionService.decrypt(EncryptionService.java:252)
    at com.bstonetech.ptms.integration.service.file.FileService.createStringFile(FileService.java:583)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:201)
    at com.sun.proxy.$Proxy35.createStringFile(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)
    at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)
    at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:166)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:317)
    at org.springframework.integration.util.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:155)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:93)
    at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:89)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:99)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.sendOutput(AbstractMessageProducingHandler.java:231)
    at org.springframework.integration.handler.AbstractMessageProducingHandler.produceOutput(AbstractMessageProducingHandler.java:154)
    at org.springframework.iListening for transport dt_socket at address: 80 01ntegration.handler.AbstractMessageProducingHandler.sendOutputs(AbstractMessageProducingHandler.java:102)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:105)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:147)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:143)
    at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:135)
    at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:295)
    at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.actualDoHandleRequest(HttpRequestHandlingEndpointSupport.java:527)
    at org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport.doHandleRequest(HttpRequestHandlingEndpointSupport.java:404)
    at org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway.handleRequest(HttpRequestHandlingMessagingGateway.java:103)
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:620)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662) Listening for transport dt_socket at address: 8001

Upvotes: 3

Views: 2831

Answers (1)

Ahmet Başar
Ahmet Başar

Reputation: 1

You may forget close/flush streams in the encryptAndSign method.

Upvotes: 0

Related Questions