📄 jtlsutil.java
字号:
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 + -