Temporarily include bndlib 1.47 for testing purposes (not yet on central)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1185095 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java
new file mode 100644
index 0000000..630597f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java
@@ -0,0 +1,67 @@
+package aQute.libg.cryptography;
+
+import java.math.*;
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+import java.util.regex.*;
+
+public class Crypto {
+ static final Pattern RSA_PRIVATE = Pattern
+ .compile("\\s*RSA.Private\\((\\p{xDigit})+:(\\p{xDigit})+\\)\\s*");
+ static final Pattern RSA_PUBLIC = Pattern
+ .compile("\\s*RSA.Public\\((\\p{xDigit})+:(\\p{xDigit})+\\)\\s*");
+
+ /**
+ *
+ * @param <T>
+ * @param spec
+ * @return
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked") public static <T> T fromString(String spec, Class<T> c) throws Exception {
+ if ( PrivateKey.class.isAssignableFrom(c)) {
+ Matcher m = RSA_PRIVATE.matcher(spec);
+ if ( m.matches()) {
+ return (T) RSA.createPrivate(
+ new BigInteger(m.group(1)), new BigInteger(m.group(2)));
+ }
+ throw new IllegalArgumentException("No such private key " + spec );
+ }
+
+ if ( PublicKey.class.isAssignableFrom(c)) {
+ Matcher m = RSA_PUBLIC.matcher(spec);
+ if ( m.matches()) {
+ return (T) RSA.create( new RSAPublicKeySpec(
+ new BigInteger(m.group(1)), new BigInteger(m.group(2))));
+ }
+ throw new IllegalArgumentException("No such public key " + spec );
+ }
+ return null;
+ }
+
+ public static String toString( Object key ) {
+ if ( key instanceof RSAPrivateKey ) {
+ RSAPrivateKey pk = (RSAPrivateKey) key;
+ return "RSA.Private(" + pk.getModulus() + ":" + pk.getPrivateExponent() + ")";
+ }
+ if ( key instanceof RSAPublicKey ) {
+ RSAPublicKey pk = (RSAPublicKey) key;
+ return "RSA.Private(" + pk.getModulus() + ":" + pk.getPublicExponent() + ")";
+ }
+ return null;
+ }
+
+
+ public static <T extends Digest> Signer<T> signer(PrivateKey key, Digester<T> digester) throws NoSuchAlgorithmException {
+ Signature s = Signature.getInstance(key.getAlgorithm() + "with" + digester.getAlgorithm());
+ return new Signer<T>(s,digester);
+ }
+
+ public static Verifier verifier(PublicKey key, Digest digest) throws NoSuchAlgorithmException {
+ Signature s = Signature.getInstance(key.getAlgorithm() + "with" + digest.getAlgorithm());
+ return new Verifier(s,digest);
+ }
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java
new file mode 100644
index 0000000..f70caa0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java
@@ -0,0 +1,25 @@
+package aQute.libg.cryptography;
+
+import aQute.lib.hex.*;
+
+public abstract class Digest {
+ final byte[] digest;
+
+ protected Digest(byte[] checksum, int width) {
+ this.digest = checksum;
+ if (digest.length != width)
+ throw new IllegalArgumentException("Invalid width for digest: " + digest.length
+ + " expected " + width);
+ }
+
+
+ public byte[] digest() {
+ return digest;
+ }
+
+ @Override public String toString() {
+ return String.format("%s(d=%s)", getAlgorithm(), Hex.toHexString(digest));
+ }
+
+ public abstract String getAlgorithm();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java
new file mode 100644
index 0000000..50b9659
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java
@@ -0,0 +1,35 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+import aQute.lib.io.*;
+
+public abstract class Digester<T extends Digest> extends OutputStream {
+ protected MessageDigest md;
+
+ public Digester(MessageDigest instance){
+ md = instance;
+ }
+ @Override
+ public void write( byte[] buffer, int offset, int length) throws IOException{
+ md.update(buffer,offset,length);
+ }
+ @Override
+ public void write( int b) throws IOException{
+ md.update((byte) b);
+ }
+
+ public MessageDigest getMessageDigest() throws Exception {
+ return md;
+ }
+
+ public T from(InputStream in) throws Exception {
+ IO.copy(in,this);
+ return digest();
+ }
+
+ public abstract T digest() throws Exception;
+ public abstract T digest( byte [] bytes) throws Exception;
+ public abstract String getAlgorithm();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java
new file mode 100644
index 0000000..160ec05
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java
@@ -0,0 +1,8 @@
+package aQute.libg.cryptography;
+
+
+public abstract class Key implements java.security.Key {
+ private static final long serialVersionUID = 1L;
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java b/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java
new file mode 100644
index 0000000..3fd7158
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java
@@ -0,0 +1,33 @@
+package aQute.libg.cryptography;
+
+import java.security.*;
+
+
+
+public class MD5 extends Digest {
+ public final static String ALGORITHM = "MD5";
+
+ public static Digester<MD5> getDigester() throws Exception {
+ return new Digester<MD5>(MessageDigest.getInstance(ALGORITHM)) {
+
+ @Override public MD5 digest() throws Exception {
+ return new MD5(md.digest());
+ }
+
+ @Override public MD5 digest(byte[] bytes) {
+ return new MD5(bytes);
+ }
+ @Override public String getAlgorithm() {
+ return ALGORITHM;
+ }
+ };
+ }
+
+
+ public MD5(byte[] digest) {
+ super(digest,16);
+ }
+
+ @Override public String getAlgorithm() { return ALGORITHM; }
+
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java b/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java
new file mode 100644
index 0000000..61bafb5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java
@@ -0,0 +1,43 @@
+package aQute.libg.cryptography;
+
+import java.math.*;
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import aQute.libg.tuple.*;
+
+public class RSA {
+ final static String ALGORITHM = "RSA";
+
+ final static KeyFactory factory = getKeyFactory();
+
+ static private KeyFactory getKeyFactory() {
+ try {
+ return KeyFactory.getInstance(ALGORITHM);
+ } catch (Exception e) {
+ // built in
+ }
+ return null;
+ }
+
+ public static RSAPrivateKey create(RSAPrivateKeySpec keyspec) throws InvalidKeySpecException {
+ return (RSAPrivateKey) factory.generatePrivate(keyspec);
+ }
+ public static RSAPublicKey create(RSAPublicKeySpec keyspec) throws InvalidKeySpecException {
+ return (RSAPublicKey) factory.generatePrivate(keyspec);
+ }
+
+ public static RSAPublicKey createPublic(BigInteger m, BigInteger e) throws InvalidKeySpecException {
+ return create( new RSAPublicKeySpec(m,e));
+ }
+ public static RSAPrivateKey createPrivate(BigInteger m, BigInteger e) throws InvalidKeySpecException {
+ return create( new RSAPrivateKeySpec(m,e));
+ }
+
+ public static Pair<RSAPrivateKey, RSAPublicKey> generate() throws NoSuchAlgorithmException {
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
+ KeyPair keypair = kpg.generateKeyPair();
+ return new Pair<RSAPrivateKey,RSAPublicKey>( (RSAPrivateKey) keypair.getPrivate(), (RSAPublicKey) keypair.getPublic());
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java
new file mode 100644
index 0000000..22e725b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java
@@ -0,0 +1,33 @@
+package aQute.libg.cryptography;
+
+import java.security.*;
+
+
+
+public class SHA1 extends Digest {
+ public final static String ALGORITHM = "SHA1";
+
+ public static Digester<SHA1> getDigester() throws NoSuchAlgorithmException {
+ MessageDigest md = MessageDigest.getInstance(ALGORITHM);
+ return new Digester<SHA1>(md) {
+ @Override public SHA1 digest() throws Exception {
+ return new SHA1(md.digest());
+ }
+
+ @Override public SHA1 digest(byte[] bytes) {
+ return new SHA1(bytes);
+ }
+ @Override public String getAlgorithm() {
+ return ALGORITHM;
+ }
+ };
+ }
+
+ public SHA1(byte[] b) {
+ super(b, 20);
+ }
+
+
+ @Override public String getAlgorithm() { return ALGORITHM; }
+
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java
new file mode 100644
index 0000000..a068677
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java
@@ -0,0 +1,35 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+public class Signer<D extends Digest> extends OutputStream {
+ Signature signature;
+ Digester<D> digester;
+
+ Signer(Signature s, Digester<D> digester) {
+ this.signature = s;
+ this.digester = digester;
+ }
+
+ @Override public void write(byte[] buffer, int offset, int length) throws IOException {
+ try {
+ signature.update(buffer, offset, length);
+ } catch (SignatureException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override public void write(int b) throws IOException {
+ try {
+ signature.update((byte) b);
+ } catch (SignatureException e) {
+ throw new IOException(e);
+ }
+ }
+
+
+ public D signature() throws Exception {
+ return digester.digest(signature().digest());
+ }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java
new file mode 100644
index 0000000..90d6993
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java
@@ -0,0 +1,38 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+
+public class Verifier extends OutputStream {
+ final Signature signature;
+ final Digest d;
+
+ Verifier(Signature s, Digest d) {
+ this.signature = s;
+ this.d = d;
+ }
+
+ @Override
+ public void write( byte[] buffer, int offset, int length) throws IOException {
+ try {
+ signature.update(buffer, offset, length);
+ } catch (SignatureException e) {
+ throw new IOException(e);
+ }
+ }
+
+ @Override
+ public void write( int b) throws IOException {
+ try {
+ signature.update((byte) b);
+ } catch (SignatureException e) {
+ throw new IOException(e);
+ }
+ }
+
+ public boolean verify() throws Exception {
+ return signature.verify(d.digest());
+ }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo b/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo
@@ -0,0 +1 @@
+version 1.0