Author: ogusakov
Date: Mon Aug 11 17:08:39 2008
New Revision: 684996

URL: http://svn.apache.org/viewvc?rev=684996&view=rev
Log:
implemented PGP signatures, changed StreamVerifier modus operandi to get 
initialized with signature upfront as crypto signature needs that. Changed http 
client to follow this new paradigm

Added:
    
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/Messages.properties
    
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpHelper.java
    
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifier.java
    
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifierFactory.java

Added: 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/Messages.properties
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/Messages.properties?rev=684996&view=auto
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/Messages.properties
 (added)
+++ 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/Messages.properties
 Mon Aug 11 17:08:39 2008
@@ -0,0 +1,23 @@
+null.input.stream=input stream should not be null
+bad.key.id=bad hex key id: {0}
+
+no.secret.key=no secret key {0} in the specified keyring
+no.public.key=no public key {0} in the specified keyring
+
+null.private.key=supplied key cannot be null
+
+null.verify.signature=out of sequence call to verify signature: verifier has 
not been initialized yet
+
+bad.verify.signature.state=out of sequence call to produce signature: verifier 
has not been initialized yet
+
+no.signatures.in.stream=no signatures found in the input streamn
+no.objects.in.stream=no pgp objects found in the input streamn
+
+bad.factory.init.verify=cannot initialize signature verification factory 
without trusted ring
+bad.factory.init.verify.empty=trusted ring read in is null, cannot proceed
+bad.factory.init.generate=cannot initialize signature generation factory 
without secret key
+
+no.stream.processor=neither signature generator nor signature verifier has 
been initialized. Don't know what to do.
+no.trusted.ring=trusted ring seem to be empty. There is no one I can trust, so 
signature verification is pointless.
+no.signature.string=there is signature supplied, so signature verification is 
pointless.
+

Added: 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpHelper.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpHelper.java?rev=684996&view=auto
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpHelper.java
 (added)
+++ 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpHelper.java
 Mon Aug 11 17:08:39 2008
@@ -0,0 +1,173 @@
+package org.apache.maven.mercury.crypto.pgp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Security;
+import java.security.SignatureException;
+import java.util.Iterator;
+
+import org.apache.maven.mercury.crypto.api.StreamVerifierException;
+import org.bouncycastle.bcpg.ArmoredOutputStream;
+import org.bouncycastle.bcpg.BCPGOutputStream;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.openpgp.PGPException;
+import org.bouncycastle.openpgp.PGPLiteralData;
+import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
+import org.bouncycastle.openpgp.PGPCompressedData;
+import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
+import org.bouncycastle.openpgp.PGPObjectFactory;
+import org.bouncycastle.openpgp.PGPOnePassSignature;
+import org.bouncycastle.openpgp.PGPOnePassSignatureList;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRing;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSecretKey;
+import org.bouncycastle.openpgp.PGPSecretKeyRing;
+import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.bouncycastle.openpgp.PGPSignatureGenerator;
+import org.bouncycastle.openpgp.PGPSignatureList;
+import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
+import org.bouncycastle.openpgp.PGPUtil;
+import org.codehaus.plexus.i18n.DefaultLanguage;
+import org.codehaus.plexus.i18n.Language;
+
+/**
+ * PGP helper - collection of utility methods, loosely based on one of the
+ * Bouncy Castle's SignedFileProcessor.java
+ * 
+ */
+public class PgpHelper
+{
+  public static final String PROVIDER = "BC";
+  public static final String EXTENSION = "asc";
+
+  private static final Language lang = new DefaultLanguage( PgpHelper.class );
+  
//---------------------------------------------------------------------------------
+  static 
+  {
+    Security.addProvider( new BouncyCastleProvider() );
+  }
+  
//---------------------------------------------------------------------------------
+  /**
+   * load a key ring stream and find the secret key by hex id
+   * 
+   * @param in PGP keystore
+   * @param hexId key id
+   * @return
+   * @throws IOException
+   * @throws PGPException
+   */
+  public static PGPSecretKeyRing readKeyRing( InputStream in, String hexId )
+  throws IOException, PGPException
+  {
+    if( in == null )
+      throw new IllegalArgumentException( lang.getMessage( "null.input.stream" 
) );
+
+    if( hexId == null || hexId.length() < 16 )
+      throw new IllegalArgumentException( lang.getMessage( "bad.key.id", hexId 
) );
+    
+    long id = hexToId( hexId );
+
+    in = PGPUtil.getDecoderStream( in );
+
+    PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection( in );
+
+    Iterator<PGPSecretKeyRing> ringIt = pgpSec.getKeyRings();
+
+    while( ringIt.hasNext() )
+    {
+      PGPSecretKeyRing keyRing = ringIt.next();
+      PGPSecretKey key = keyRing.getSecretKey( id );
+      if( key != null )
+        return keyRing;
+    }
+
+    throw new IllegalArgumentException( lang.getMessage( "no.secret.key", 
hexId ) );
+  }
+  
//---------------------------------------------------------------------------------
+  public static long hexToId( String hexId )
+  {
+    return Long.parseLong( hexId, 16 );
+  }
+  
//---------------------------------------------------------------------------------
+  public static PGPSignature readSignature( InputStream inS )
+  throws IOException, PGPException
+  {
+    if( inS == null )
+      throw new IllegalArgumentException( "null.input.stream" );
+    
+    InputStream in = inS;
+    in = PGPUtil.getDecoderStream( in );
+  
+    PGPObjectFactory pgpObjectFactory = new PGPObjectFactory( in );
+    PGPSignatureList sigList = null;
+
+    Object pgpObject = pgpObjectFactory.nextObject();
+    
+    if( pgpObject == null )
+      throw new PGPException( lang.getMessage( "no.objects.in.stream" ) );
+
+    if( pgpObject instanceof PGPCompressedData )
+    {
+        PGPCompressedData cd = (PGPCompressedData)pgpObject;
+
+        pgpObjectFactory = new PGPObjectFactory( cd.getDataStream() );
+        
+        sigList = (PGPSignatureList)pgpObjectFactory.nextObject();
+    }
+    else
+    {
+        sigList = (PGPSignatureList)pgpObject;
+    }
+    
+    if( sigList.size() < 1 )
+      throw new PGPException( lang.getMessage( "no.signatures.in.stream" ) );
+    
+    PGPSignature sig = sigList.get(0);
+    
+    return sig;
+  }
+  
//---------------------------------------------------------------------------------
+  public static String streamToString( InputStream in )
+  throws IOException
+  {
+    if( in == null )
+      return null;
+
+    ByteArrayOutputStream ba = new ByteArrayOutputStream();
+    int b = 0;
+    while( (b = in.read()) != -1 )
+      ba.write( b );
+    
+    return ba.toString();
+  }
+  
//---------------------------------------------------------------------------------
+  public static String fileToString( String fileName )
+  throws IOException
+  {
+    FileInputStream fis = null;
+    try
+    {
+      fis = new FileInputStream( fileName );
+      return streamToString( fis );
+    }
+    finally
+    {
+      if( fis != null ) try { fis.close(); } catch( Exception any ) {}
+    }
+  }
+  
//---------------------------------------------------------------------------------
+  
//---------------------------------------------------------------------------------
+}

Added: 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifier.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifier.java?rev=684996&view=auto
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifier.java
 (added)
+++ 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifier.java
 Mon Aug 11 17:08:39 2008
@@ -0,0 +1,210 @@
+package org.apache.maven.mercury.crypto.pgp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.NoSuchProviderException;
+import java.security.SignatureException;
+
+import org.apache.maven.mercury.crypto.api.AbstractStreamVerifier;
+import org.apache.maven.mercury.crypto.api.StreamObserverException;
+import org.apache.maven.mercury.crypto.api.StreamVerifier;
+import org.apache.maven.mercury.crypto.api.StreamVerifierAttributes;
+import org.apache.maven.mercury.crypto.api.StreamVerifierException;
+import org.bouncycastle.bcpg.ArmoredOutputStream;
+import org.bouncycastle.bcpg.BCPGOutputStream;
+import org.bouncycastle.openpgp.PGPCompressedData;
+import org.bouncycastle.openpgp.PGPException;
+import org.bouncycastle.openpgp.PGPObjectFactory;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSecretKey;
+import org.bouncycastle.openpgp.PGPSignature;
+import org.bouncycastle.openpgp.PGPSignatureGenerator;
+import org.bouncycastle.openpgp.PGPSignatureList;
+import org.bouncycastle.openpgp.PGPUtil;
+import org.codehaus.plexus.i18n.DefaultLanguage;
+import org.codehaus.plexus.i18n.Language;
+import org.codehaus.plexus.util.StringInputStream;
+
+/**
+ * lightweight pgp stream encoder, created one per stream
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class PgpStreamVerifier
+extends AbstractStreamVerifier
+implements StreamVerifier
+{
+  public static final String TYPE = "pgp";
+  private static final Language lang = new DefaultLanguage( 
PgpStreamVerifier.class );
+  
+  private PGPPublicKeyRingCollection trustedPublicKeyRing;
+
+  private PGPSignatureGenerator signatureGenerator;
+
+  private PGPSignature signature;
+  
+  private String signatureString;
+
+  
//-----------------------------------------------------------------------------------
+  public PgpStreamVerifier( StreamVerifierAttributes attributes )
+  {
+    super( attributes );
+  }
+  
//-----------------------------------------------------------------------------------
+  public void init( PGPPublicKeyRingCollection trustedPublicKeyRing )
+  {
+    this.trustedPublicKeyRing = trustedPublicKeyRing;
+  }
+  
//-----------------------------------------------------------------------------------
+  public void init( PGPPrivateKey privateKey, int algorithm, int 
digestAlgorithm )
+  throws StreamVerifierException
+  {
+    if( privateKey == null )
+      throw new IllegalArgumentException( lang.getMessage( "null.private.key" 
));
+    
+    try
+    {
+      signatureGenerator = new PGPSignatureGenerator(   algorithm
+                                                      , digestAlgorithm
+                                                      , PgpHelper.PROVIDER
+                                                    );
+      signatureGenerator.initSign( PGPSignature.BINARY_DOCUMENT, privateKey );
+      
+      signatureString = null;
+    }
+    catch( Exception e )
+    {
+      throw new StreamVerifierException(e);
+    }
+  }
+  
+  
//-----------------------------------------------------------------------------------
+  public void byteReady( int b )
+  throws StreamObserverException
+  {
+    try
+    {
+      if( signature == null )
+      {
+        if( signatureGenerator == null )
+          throw new StreamVerifierException( lang.getMessage( 
"no.stream.processor" ) );
+        signatureGenerator.update( (byte)b );
+      }
+      else
+        signature.update( (byte)b );
+    }
+    catch( SignatureException e )
+    {
+      throw new StreamObserverException(e);
+    }
+  }
+
+  
//-----------------------------------------------------------------------------------
+  public void bytesReady( byte[] b, int off, int len )
+  throws StreamObserverException
+  {
+    try
+    {
+      if( signature == null )
+      {
+        if( signatureGenerator == null )
+          throw new StreamVerifierException( lang.getMessage( 
"no.stream.processor" ) );
+        signatureGenerator.update( b, off, len );
+      }
+      else
+        signature.update( b, off, len );
+    }
+    catch( SignatureException e )
+    {
+      throw new StreamObserverException(e);
+    }
+  }
+  
//-----------------------------------------------------------------------------------
+  public void initSignature( String signatureString )
+  throws StreamVerifierException
+  {
+    try
+    {
+      if( trustedPublicKeyRing == null )
+        throw new StreamVerifierException( lang.getMessage( "no.trusted.ring" 
) );
+
+      if( signatureString == null || signatureString.length() < 1 )
+        throw new StreamVerifierException( lang.getMessage( 
"no.signature.string" ) );
+
+      signature = PgpHelper.readSignature( new ByteArrayInputStream( 
signatureString.getBytes() ) );
+      
+      if( signature == null )
+        throw new StreamVerifierException( "no.signatures.in.stream" );
+      
+      signature.initVerify( trustedPublicKeyRing.getPublicKey( 
signature.getKeyID() ), PgpHelper.PROVIDER );
+    }
+    catch( Exception e )
+    {
+      throw new StreamVerifierException(e);
+    }
+    
+    if( signature == null )
+      throw new StreamVerifierException("no.signatures.in.stream");
+    
+  }
+  
//-----------------------------------------------------------------------------------
+  public boolean verifySignature()
+  throws StreamVerifierException
+  {
+
+    if( signature == null )
+      throw new StreamVerifierException( lang.getMessage( 
"null.verify.signature" ));
+
+    try
+    {
+      return signature.verify();
+    }
+    catch( Exception e )
+    {
+      throw new StreamVerifierException( e );
+    }
+  }
+
+  
//-----------------------------------------------------------------------------------
+  public String getSignature()
+  throws StreamVerifierException
+  {
+    if( signatureString != null )
+      return signatureString;
+    
+    if( signatureGenerator == null )
+      throw new StreamVerifierException("bad.verify.signature.state");
+    
+    BCPGOutputStream signaturePgpBytes = null;
+    try
+    {
+      ByteArrayOutputStream signatureBytes = new ByteArrayOutputStream();
+      ArmoredOutputStream aos = new ArmoredOutputStream( signatureBytes );
+      signaturePgpBytes = new BCPGOutputStream( aos );
+      signatureGenerator.generate().encode( signaturePgpBytes );
+      signaturePgpBytes.finish();
+      aos.flush();
+      aos.close();
+      signatureString = signatureBytes.toString();
+    }
+    catch( Exception e )
+    {
+      throw new StreamVerifierException( e );
+    }
+    finally
+    {
+      if( signaturePgpBytes != null ) try { signaturePgpBytes.close(); } 
catch( Exception any ) {}
+    }
+    
+    signatureGenerator = null;
+    
+    return signatureString;
+  }
+  
//-----------------------------------------------------------------------------------
+  
//-----------------------------------------------------------------------------------
+}

Added: 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifierFactory.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifierFactory.java?rev=684996&view=auto
==============================================================================
--- 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifierFactory.java
 (added)
+++ 
maven/sandbox/trunk/mercury/mercury-crypto/mercury-crypto-basic/src/main/java/org/apache/maven/mercury/crypto/pgp/PgpStreamVerifierFactory.java
 Mon Aug 11 17:08:39 2008
@@ -0,0 +1,128 @@
+package org.apache.maven.mercury.crypto.pgp;
+
+import java.io.InputStream;
+
+import org.apache.maven.mercury.crypto.api.AbstractStreamVerifierFactory;
+import org.apache.maven.mercury.crypto.api.StreamVerifier;
+import org.apache.maven.mercury.crypto.api.StreamVerifierAttributes;
+import org.apache.maven.mercury.crypto.api.StreamVerifierException;
+import org.apache.maven.mercury.crypto.api.StreamVerifierFactory;
+import org.bouncycastle.openpgp.PGPPrivateKey;
+import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
+import org.bouncycastle.openpgp.PGPSecretKey;
+import org.bouncycastle.openpgp.PGPSecretKeyRing;
+import org.bouncycastle.openpgp.PGPUtil;
+import org.codehaus.plexus.i18n.DefaultLanguage;
+import org.codehaus.plexus.i18n.Language;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class PgpStreamVerifierFactory
+extends AbstractStreamVerifierFactory
+implements StreamVerifierFactory
+{
+
+  public static final String DEFAULT_EXTENSION = PgpHelper.EXTENSION;
+
+  private static final Language lang = new DefaultLanguage( 
PgpStreamVerifierFactory.class );
+
+  private PGPPublicKeyRingCollection  trustedPublicKeyRing;
+  
+  private PGPPrivateKey privateKey;
+  
+  private int algorithm = 0;
+  
+  private int digestAlgorithm = PGPUtil.SHA1;
+  
+  
//--------------------------------------------------------------------------------------------
+  public PgpStreamVerifierFactory( StreamVerifierAttributes attributes
+                                  , InputStream trustedPublicKeyRingStream
+                                  )
+  throws StreamVerifierException
+  {
+    super( attributes );
+    init( trustedPublicKeyRingStream );
+    
+  }
+  
//--------------------------------------------------------------------------------------------
+  public PgpStreamVerifierFactory( StreamVerifierAttributes attributes
+                                  , InputStream secretKeyRingStream
+                                  , String secretKeyId
+                                  , String secretKeyPass
+                                  )
+  throws StreamVerifierException
+  {
+    super( attributes );
+    init( secretKeyRingStream, secretKeyId, secretKeyPass );
+  }
+  
//--------------------------------------------------------------------------------------------
+  public void init(  InputStream trustedPublicKeyRingStream )
+  throws StreamVerifierException
+  {
+    try
+    {
+      if( trustedPublicKeyRingStream != null )
+      {
+        trustedPublicKeyRing = new 
PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(trustedPublicKeyRingStream));
+        if( trustedPublicKeyRing == null )
+          throw new StreamVerifierException( lang.getMessage( 
"bad.factory.init.verify.empty" ) );
+      }
+      else
+        throw new StreamVerifierException( lang.getMessage( 
"bad.factory.init.verify" ) );
+    }
+    catch( Exception e )
+    {
+      throw new StreamVerifierException(e);
+    }
+  }
+  
//--------------------------------------------------------------------------------------------
+  public void init( InputStream secretKeyRingStream
+                  , String secretKeyId
+                  , String secretKeyPass
+                  )
+  throws StreamVerifierException
+  {
+    try
+    {
+      if( secretKeyRingStream != null && secretKeyId != null && secretKeyPass 
!= null )
+      {
+        PGPSecretKeyRing secRing = PgpHelper.readKeyRing( secretKeyRingStream, 
secretKeyId );
+        PGPSecretKey secKey = secRing.getSecretKey( PgpHelper.hexToId( 
secretKeyId ) );
+        privateKey = secKey.extractPrivateKey( secretKeyPass.toCharArray(), 
PgpHelper.PROVIDER );
+        algorithm =  secKey.getPublicKey().getAlgorithm();
+      }
+      else
+        throw new StreamVerifierException( lang.getMessage( 
"bad.factory.init.generate" ) );
+    }
+    catch( Exception e )
+    {
+      throw new StreamVerifierException(e);
+    }
+  }
+  
//--------------------------------------------------------------------------------------------
+  public String getDefaultExtension()
+  {
+    return DEFAULT_EXTENSION;
+  }
+  
//--------------------------------------------------------------------------------------------
+  public StreamVerifier newInstance()
+  throws StreamVerifierException
+  {
+    PgpStreamVerifier sv = new PgpStreamVerifier( attributes );
+    
+    if( privateKey != null )
+      sv.init( privateKey, algorithm, digestAlgorithm );
+    
+    if( trustedPublicKeyRing != null )
+      sv.init( trustedPublicKeyRing );
+    
+    return sv;
+  }
+  
//--------------------------------------------------------------------------------------------
+  
//--------------------------------------------------------------------------------------------
+}


Reply via email to