📄 jtlsutil.java
字号:
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
$Id: JTlsUtil.java,v 1.2 2002/03/04 21:42:58 echtcherbina Exp $
*/
public static String loadObject(BufferedReader rdr, String end)
throws IOException {
if(findObject(rdr, end))
return readBlock(rdr);
else
return null;
}
public static boolean findObject(BufferedReader br,String end)
throws IOException {
String prefix="-----BEGIN ";
String postfix=(end==null)?"-----":end + "-----";
String line;
for(;;) {
line=br.readLine();
if(line==null)
return false;
if(!line.startsWith(prefix))
continue;
if(!line.endsWith(postfix))
continue;
break;
}
return true;
}
// We read a block of n-lines (\n terminated)
// and return a String of n-lines concatenated
// together. This keeps the format consistent with
// the pureTLS requirements.
public static String readBlock(BufferedReader br)
throws IOException {
String line;
ByteArrayOutputStream bos=new ByteArrayOutputStream();
OutputStreamWriter ow=new OutputStreamWriter(bos);
for (;;) {
line = br.readLine();
if (line==null)
break;
if (line.startsWith("-----END "))
break;
// Write a line back
ow.write(line, 0, line.length());
ow.write('\n');
}
ow.flush();
byte[] b64data = bos.toByteArray();
return new String(b64data);
}
// Write a wrapped object ALREADY base64 encoded,
// and is a concatenated String of n lines(\n terminated)
//
// Here, output format is required for pureTLS .pem files
// It must be a sequence of \n terminated lines.
public static void writeBase64Object(String object, String type,
BufferedWriter out)
throws IOException {
// Write the header
String start= "-----BEGIN " + type + "-----";
out.write(start);
out.newLine();
// write the base64 encoded object
out.write(object);
String finish = "-----END "+type+"-----";
out.write(finish);
out.newLine();
out.flush();
}
// Write a root certificate
public static void writeRootCert(String cert, String path)
throws IOException {
FileWriter fw = new FileWriter(path);
BufferedWriter bw = new BufferedWriter(fw);
writeBase64Object(cert, "CERTIFICATE", bw);
fw.close();
}
// Verify a signed certificate
// The issuer is the root
// The cert is to be verified
// To verify a self-signed cert, root == cert
public static boolean verifySignedCert(String root, String cert)
{
try {
String[] args = new String[2];
args[0] = root;
args[1] = cert;
CertVerify.main(args);
} catch (Exception e) {
if (SSLDebug.getDebug(SSLDebug.DEBUG_JXTA)) {
System.out.println("Exception: " + e.getMessage() +
"\n Cannot verify cert =" + cert +
"\n Root = " + root);
}
return false;
}
return true;
}
// Password file code
static final int SALTSIZE = 8;
static final int PASSES = 11;
public static boolean passwdExists() {
String path = getPCEPasswdPath();
File f = new File(path);
try {
if (f.exists()) {
String pwfile = path + JTlsDefs.PASSWORDFILE;
File g = new File(pwfile);
if (g.exists()) return true;
}
} catch (SecurityException s) {
LOG.debug("passwdExists, exception:", s);
return false;
}
return false;
}
// check for valid password
// create a password entry and compare it to current entry
public static boolean validPasswd(String passwd) {
if (passwdExists()) {
// get the real entry
String pwd = null;
try {
pwd = getPasswordEntry();
} catch (IOException e) {
LOG.debug("validPasswd:", e);
return false;
}
// System.out.println("\nvalidPassword, pwd = " + passwd + ", old entry = " + pwd); // xxx
// extract the salt and password hash
int index = pwd.indexOf((int)',');
String salt64 = pwd.substring(0, index);
String thePwd = pwd.substring(index+1);
// Get real salt
byte[] sb64 = salt64.getBytes();
byte[] salt = null;
try {
salt = URLBase64.decode(sb64, 0, sb64.length);
} catch (jxta.security.exceptions.CryptoException e) {
LOG.debug("validPasswd:", e);
return false;
}
// make an entry with this passwd and the existing salt
String generated = null;
try {
generated = makePasswdEntry(passwd, salt);
// System.out.println("\nvalidPassword, gen = " + generated);
} catch (IOException e) {
LOG.debug("validPasswd:", e);
return false;
}
// compare the entries
int gindex = generated.indexOf((int)',');
String genPwd = generated.substring(gindex+1);
// do the compare
// System.out.println("\nvalidPassword: thePwd = " + thePwd + " Gen = " + genPwd); // xxx
if (genPwd.compareTo(thePwd) == 0) {
// System.out.println("\nvalidPasswd will return true");
return true;
} else {
// System.out.println("\nvalidPasswd will return false");
return false;
}
} else // password file is not there
return false;
}
// Create password file
public static void createPasswdFile(String password, boolean overwrite)
throws SecurityException, IOException
{
if (!overwrite && passwdExists()) {
throw
new SecurityException("Cannot create password file. It already exists.");
}
// create the file
String path = getPCEPasswdPath();
File f = new File(path);
File g = new File(path + JTlsDefs.PASSWORDFILE);
if (f.exists()) { // have the directory
// remove any existing pwd file
if (g.exists()) g.delete();
} else // make the directory
f.mkdir();
// OK. We have the directory. Get the entry
String pwdentry = makePasswdEntry(password, null);
// System.out.println("createPasswdFile, pwd = " + password + ", entry = " + pwdentry); // xxx
FileWriter fw = new FileWriter(g);
BufferedWriter bw = new BufferedWriter(fw);
// write a line (this is all base64 text)
bw.write(pwdentry, 0, pwdentry.length());
bw.newLine();
bw.flush();
bw.close();
}
//
// Return a password entry from the password file in base64
public static String getPasswordEntry()
throws IOException {
String path = getPCEPasswdPath() + JTlsDefs.PASSWORDFILE;
FileReader f = new FileReader(path);
BufferedReader bis = new BufferedReader(f);
String entry = bis.readLine();
return entry;
}
//
// Given a password String, make the entry to write
// in the password file
public static String makePasswdEntry(String passwd, byte[] useThisSalt)
throws IOException {
byte[] salt = null;
if (useThisSalt == null) {
SecureRandom rng = null;
try {
rng = PeerCerts.seedSRN();
} catch (jxta.security.exceptions.CryptoException cex) {
// should never happen
//LOG.debug("Could not seed SRN: ", cex);
return null;
}
// make some salt
salt = new byte[SALTSIZE];
rng.nextBytes(salt);
// COM.claymoresystems.util.Util.xdump("Salt = ",salt);
} else {
// Already salty
salt = useThisSalt;
}
byte[] str64 = null;
byte[] buf = null;
try {
JxtaCrypto suite = new JxtaCryptoSuite(JxtaCrypto.MEMBER_SHA1, null,
(byte)0, (byte)0);
Hash sha1 = suite.getJxtaHash(Hash.ALG_SHA1);
// for the digest
int diglen = sha1.getDigestLength();
byte[] digest = new byte[diglen];
// prepare to hash
byte[] pbytes = passwd.getBytes();
int pwlen = passwd.length() + SALTSIZE;
int buflen = (pwlen < diglen ? diglen : pwlen);
buf = new byte[buflen];
// copy salt and pass word into the buffer
System.arraycopy(salt, 0, buf, 0, SALTSIZE);
System.arraycopy(pbytes, 0, buf, SALTSIZE, pbytes.length);
// hash buffer, and then rehash resulting digest
int len = pwlen;
for (int i = 0; i <= PASSES; i++) {
sha1.doFinal(buf, 0, len, digest, 0);
System.arraycopy(digest, 0, buf, 0, digest.length);
len = digest.length;
}
// base 64 encode digest
str64 = URLBase64.encode(digest);
// COM.claymoresystems.util.Util.xdump("digest = ",digest);
} catch (jxta.security.exceptions.CryptoException cex) {
throw new IOException("makePasswdEntry: Cannot generate password file");
}
// OK. Now create the final output byte area
// SALT,str64
byte[] salt64 = URLBase64.encode(salt);
String saltStr = new String(salt64);
String pwdStr = new String(str64);
// salt,password in base64
return new String(saltStr + "," + pwdStr);
}
public static boolean principalIsIssuer(String principal)
{
// Get root cert name
String rootfile = getPCERootPath() + JTlsDefs.CLIENTROOT;
try {
// Get the encoded cert
byte[] cert_ber = CertVerify.loadCert(rootfile);
// Decode the cert
X509Cert cert = new X509Cert(cert_ber);
// get the IssuerName
DistinguishedName issuer = cert.getIssuerName();
// Get the peername which is CN field
String name = issuer.getNameString();
// System.out.println("Cert principal = " + principal +
// ", issuer = " + name);
// find peername in name
// This parse is not 100% thorough
int cn = name.indexOf(principal);
if (cn != -1 && cn >= 3) {
// Make sure we begin with CN=
String cnstr = name.substring(cn-3,cn);
if (cnstr.compareTo("CN=") != 0) {
// System.out.println("CN= is really =" + cnstr);
return false;
}
// OK, we MUST have <string>-CA. Check that out
int endc = cn + principal.length();
String endStr = name.substring(endc, endc + 3);
// should = "-CA"
if (endStr.compareTo("-CA") == 0) {
// compares up to -CA. Check the rest ...
String fstr = name.substring(cn,endc);
if (fstr.compareTo(principal) == 0)
return true;
}
}
return false;
} catch (Exception e) {
// we are in trouble here.
SSLDebug.debug(SSLDebug.DEBUG_JXTA, "Exception validating principal:" +
e.getMessage());
return false;
}
}
static int getSequenceNumber(MessageElement elt)
throws NumberFormatException {
String[] names = MessageElement.parseName(elt.getName());
String namespace = names[0];
String sequenceStr = names[1];
Integer i = new Integer(sequenceStr);
return i.intValue();
}
// Do a hex dump of a byte array
static String hex[]={"0","1","2","3","4","5","6","7","8","9",
"a","b","c","d","e","f"};
public static String toHex(byte[] arr, int offset, int len){
StringBuffer str = new StringBuffer();
for(int i = offset; i < len; i++) {
if ((i>0) && ((i%12)==0)) str.append("\n");
str.append(hex[(arr[i] >> 4) & 0x0f]);
str.append(hex[arr[i] & 0x0f]);
str.append(" ");
}
return str.toString();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -