[Webfunds-commits] java/webfunds/ricardian ArmouredKeyException.java KeyUtil.java
Ian Grigg
iang@cypherpunks.ai
Sun, 27 Aug 2000 17:56:40 -0400 (AST)
iang 00/08/27 17:56:40
Modified: webfunds/ricardian KeyUtil.java
Added: webfunds/ricardian ArmouredKeyException.java
Log:
Moved more PGPKey String processing utility methods into KeyUtil,
taken from SignContractWizard.KeyPanel of yesterday. Aim is to
get all generic string processing handy tools in here, and possibly
into something within OpenPGP some time so that we can manipulate
the special cases more easily.
Added Armoured exception which is used within these routines.
Revision Changes Path
1.5 +103 -15 java/webfunds/ricardian/KeyUtil.java
Index: KeyUtil.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/ricardian/KeyUtil.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- KeyUtil.java 2000/08/26 22:57:21 1.4
+++ KeyUtil.java 2000/08/27 21:56:40 1.5
@@ -13,16 +13,39 @@
/** Static methods only. */
private KeyUtil() {}
+ /**
+ * Manifest constant for *internal* end of line for OpenPGP.
+ * OpenPGP Signatures (and Ricardian Hashes) are calculated with
+ * this as the end of line (but note that storage occurs with
+ * the platform end of line).
+ */
+ public final static String eoln = "\r\n"; // how PGP cleartext is prepared
+ public static String getOpenPGPEndOfLine() { return eoln; }
+
+ /**
+ * Remember to convert on output. This is here more for doco...
+ */
+ public static String getPlatformEndOfLine()
+ { return System.getProperty("line.separator"); }
+
public static PGPPublicKey publicKeyFromString(String s)
- throws PGPException
+ throws ArmouredKeyException
{
- PGPArmoury armouredKey = new PGPArmoury(s);
- PGPKeyFactory factory = new PGPKeyFactory();
- Vector keys = factory.decodeKeys(armouredKey.getPayload());
- PGPPublicKey pk = (PGPPublicKey)keys.elementAt(0);
- return pk;
+ PGPKey key = keyFromString(s);
+ if (key instanceof PGPSecretKey)
+ throw new ArmouredKeyException(ArmouredKeyException.ISA_SECRET);
+ return (PGPPublicKey)key;
}
+ public static PGPSecretKey secretKeyFromString(String s)
+ throws ArmouredKeyException
+ {
+ PGPKey key = keyFromString(s);
+ if (key instanceof PGPPublicKey)
+ throw new ArmouredKeyException(ArmouredKeyException.ISA_PUBLIC);
+ return (PGPSecretKey)key;
+ }
+
static final String PUBLIC_KEY_BLOCK = "PGP PUBLIC KEY BLOCK";
static final String SECRET_KEY_BLOCK = "PGP PRIVATE KEY BLOCK";
@@ -41,8 +64,69 @@
}
+ /**
+ * Load up an armoured key from a string.
+ * No checking other than that intrinsic in de-armouring and
+ * insisting on one and one only key.
+ */
+ public static PGPKey keyFromString(String keyAsArmouredString)
+ throws ArmouredKeyException
+ {
+
+ if (keyAsArmouredString == null)
+ return null;
+
+ // check key
+ PGPArmoury akey;
+ try {
+ akey = new PGPArmoury(keyAsArmouredString);
+ } catch (IllegalArgumentException iae) {
+ throw new ArmouredKeyException(ArmouredKeyException.NOT_ARMOURED,
+ iae.getMessage());
+ }
+
+ // get the unarmoured key
+ PGPKeyFactory factory = new PGPKeyFactory();
+ Vector keys;
+ try {
+ keys = factory.decodeKeys(akey.getPayload());
+ } catch (PGPFatalDataFormatException ex) {
+ throw new ArmouredKeyException(ArmouredKeyException.CORRUPT,
+ ex.getMessage());
+ }
+
+ if (keys.size() > 1)
+ throw new ArmouredKeyException(ArmouredKeyException.TOO_MANY_KEYS);
+ if (keys.size() < 1)
+ throw new ArmouredKeyException(ArmouredKeyException.EMPTY_PAYLOAD);
+
+ return (PGPKey)keys.elementAt(0);
+
+ }
+
+
+ /**
+ * Read a Public Key from a string and return the key.
+ * It must be signed by the signer, if provided (can be null).
+ * It must be self-signed.
+ * It must have the tag in it somewhere.
+ * Additional sigs are stripped.
+ */
+ public static PGPPublicKey checkArmouredPublicKey(String armouredKey,
+ String tag,
+ PGPPublicKey signer)
+ throws StripKeyException, ArmouredKeyException
+ {
+
+ PGPPublicKey pk = publicKeyFromString(armouredKey);
+ // check that the signer has signed
+
+ return KeyUtil.stripAndVerifyKey(pk, tag, signer);
+ }
+
+
/**
* Strip the given key of all superfluous data. The key being returned
* will have at most one userId (containing the string userIdTag) which
@@ -56,7 +140,7 @@
* If the requested userId doesn't exist or is not self-signed or
* has multiple self-sigs or isn't signed by userIdSigner or has
* multiple sigs by userIdSigner (dunno if that's possible) or has
- * multiple matching userIds.
+ * multiple matching userIds. See the number in StripKeyException.
*/
public static PGPPublicKey
stripAndVerifyKey(PGPPublicKey key,
@@ -75,7 +159,7 @@
// find the userId we want
PGPUserID uid = findUserId(key, userIdTag);
if (uid == null)
- throw new StripKeyException(
+ throw new StripKeyException(StripKeyException.NO_SUCH_USERID,
"UserId with tag (" + userIdTag + ") doesn't exist.");
// strip sigs we don't want
@@ -88,9 +172,10 @@
if (sig.verify(key)) newSigs.addElement(sig);
}
+ if (newSigs.size()==0)
+ throw new StripKeyException(StripKeyException.NOT_SELF_SIGNED);
if (newSigs.size()!=1)
- throw new StripKeyException(
- "Key is not self-signed or has multiple self-signatures.");
+ throw new StripKeyException(StripKeyException.TOO_MANY_SELFS);
// (optional) retain userIdSigner sig
if (userIdSigner!=null) {
@@ -99,9 +184,10 @@
if (sig.verify(userIdSigner)) newSigs.addElement(sig);
}
- if (newSigs.size()!=2)
- throw new StripKeyException(
- "Key is not signed or has multiple sigs.");
+ if (newSigs.size()<2)
+ throw new StripKeyException(StripKeyException.NOT_SIGNED);
+ if (newSigs.size()>2)
+ throw new StripKeyException(StripKeyException.TOO_MANY_SIGS);
}
newSigs.trimToSize();
@@ -120,7 +206,8 @@
// something went wrong, dunno what
e.printStackTrace();
- throw new StripKeyException(e.getMessage());
+ throw new StripKeyException(StripKeyException.CATCH_ALL,
+ e.getMessage());
}
}
@@ -201,7 +288,8 @@
if( isMatch(s, userIdTag) ) {
if (res!=null)
throw new StripKeyException(
- "Multiple matching userIds found.");
+ StripKeyException.TOO_MANY_USERID,
+ "Multiple matching userIds found.");
else
res = uid;
}
1.1 java/webfunds/ricardian/ArmouredKeyException.java
Index: ArmouredKeyException.java
===================================================================
/*
* $Id: ArmouredKeyException.java,v 1.1 2000/08/27 21:56:40 iang Exp $
*
* Copyright (c) 2000 Systemics Inc on behalf of
* the WebFunds Development Team. All Rights Reserved.
*/
package webfunds.ricardian;
public class ArmouredKeyException
extends Exception
{
/**
* Known Contract failure modes detected.
*/
public static final int UNKNOWN = 0,
CATCH_ALL = 1, // catch all for other errors
ISA_SECRET = 2, // not a public, got secret
ISA_PUBLIC = 3, // not a secret, got public
NOT_ARMOURED = 4, // not armoured in PGP style
EMPTY_PAYLOAD = 5, // no keys found in armour
TOO_MANY_KEYS = 6, // more than one
CORRUPT = 7; // armour is corrupt or bad
public static final String[] errors = {
"<not set, old Ex>",
"'miscellaneous error'",
"Is A Secret Key, Not Public!",
"Is A Public Key, Not Secret!",
"Not Signed By Signer",
"Empty Armoured Payload, No Keys Found",
"More Than One Key Found In Armoured Payload",
"Armour Is Corrupt",
};
/**
* What error number has been set by the thrower.
*/
protected int errno = UNKNOWN;
public int getErrno() { return errno; }
public String getErrnoString()
{
if (! (0 <= errno && errno < errors.length) )
return "<invalid: " + errno + ">";
String e = errors[errno];
return "(" + errno + ") " + ((e == null) ? "'unknown'" : e);
}
public String toString()
{
String s = "";
if (errno > 0)
s += getErrnoString() + ": ";
s += super.toString();
return s;
}
public ArmouredKeyException() { super(); }
/** @param msg string interpretation */
public ArmouredKeyException(String msg) { super(msg); }
/** @param errno an identified error from public constants above */
public ArmouredKeyException(int errno) { super(); this.errno = errno;}
public ArmouredKeyException(int e, String m) { super(m); this.errno = e; }
}