📄 jtlsutil.java
字号:
/************************************************************************
*
* $Id: JTlsUtil.java,v 1.2 2002/03/04 21:42:58 echtcherbina Exp $
*
* Copyright (c) 2001 Sun Microsystems, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Sun Microsystems, Inc. for Project JXTA."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
* must not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact Project JXTA at http://www.jxta.org.
*
* 5. Products derived from this software may not be called "JXTA",
* nor may "JXTA" appear in their name, without prior written
* permission of Sun.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SUN MICROSYSTEMS OR
* ITS CONTRIBUTORS BE LIABLE 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.
*
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of Project JXTA. For more
* information on Project JXTA, please see
* <http://www.jxta.org/>.
*
* This license is based on the BSD license adopted by the Apache Foundation.
*********************************************************************************/
package net.jxta.impl.endpoint.tls;
import COM.claymoresystems.sslg.SSLPolicyInt;
import COM.claymoresystems.ptls.SSLDebug;
import COM.claymoresystems.cert.WrappedObject;
import COM.claymoresystems.cert.CertVerify;
import COM.claymoresystems.cert.X509Cert;
import COM.claymoresystems.sslg.DistinguishedName;
import net.jxta.endpoint.*;
import net.jxta.document.MimeMediaType;
import net.jxta.impl.endpoint.MessageElementImpl;
import net.jxta.impl.endpoint.MessageImpl;
import java.util.Vector;
import java.util.StringTokenizer;
import java.util.NoSuchElementException;
import java.util.Enumeration;
import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.security.SecureRandom;
import org.apache.log4j.Priority;
import org.apache.log4j.Category;
import jxta.security.hash.*;
import jxta.security.crypto.*;
import jxta.security.cipher.Cipher;
import jxta.security.cipher.Key;
import jxta.security.util.URLBase64;
import jxta.security.impl.crypto.*;
import jxta.security.impl.cipher.KeyBuilder;
import jxta.security.impl.cipher.RC4Cipher;
import jxta.security.impl.cipher.SecretKey;
import jxta.security.impl.random.JRandom;
import jxta.security.exceptions.CryptoException;
import org.apache.log4j.Category;
public class JTlsUtil {
private static final Category LOG = Category.getInstance(JTlsUtil.class.getName());
public JTlsUtil() {;}
// remove all elements from jmsg given the namespace
static public void removeElements(Message jmsg)
{
Enumeration e = jmsg.getElements(); // get them in FIFO order
while (e.hasMoreElements()) {
MessageElement elt1 = (MessageElement)e.nextElement();
// if (LOG.isEnabledFor(Priority.DEBUG))
// LOG.debug("REMOVED " + elt1.getName());
jmsg.removeElement(elt1);
}
}
/**
* Get next element
* @param m Mesasge
* @param elt If null, then return first element. Otherwise, the
* succeeding element
*
* @return element if found, else null
*/
static public MessageElement getNextElement(Message m, MessageElement elt)
{
Enumeration e = ((MessageImpl) m).getElementsInFifoOrder(); // XDR us FIFO
boolean theNext = false;
while (e.hasMoreElements()) {
MessageElement elt1 = (MessageElement)e.nextElement();
if (elt == null || theNext) return elt1;
if (elt == elt1) theNext = true;
}
return null;
}
// return the length in bytes of the message, m.
static public int getMessageLength(Message m)
{
Enumeration els;
int length;
//// Message signature to placate the bad man..
// dos.writeBytes("jxmg");
length = 4;
// dos.writeByte(MESSAGE_VERSION);
length += 1;
//dos.writeShort(elementCount);
length += 2;
//// Sum up element lengths
els = ((MessageImpl) m).getElementsInFifoOrder();
while(els.hasMoreElements()) {
MessageElement el = (MessageElement)els.nextElement();
// add up the element fields
length += 4; // "jxel"
//dos.writeByte(nsid);
length += 1;
// dos.writeByte(flags);
length += 1;
// name
String[] names = MessageElement.parseName(el.getName());
String namespace = names[0];
String name = names[1];
length += stringLength(names[1]);
// Media type
MimeMediaType type = el.getType();
if (type != null) {
length += stringLength(type.toString());
}
// size of data: both length and "length bytes"
// are written
length += 4; // length field
length += el.getLength(); // and bytes
}
return length;
}
// return the written length of a string
// in a jxta message: [length, data] pair is written
static private int stringLength(String str)
{
int strlen = 2; // length is a short
// now the number of bytes which is
// encoding dependent
try {
byte[] b = str.getBytes("UTF8"); // UTF-8: b.length == str.length()
strlen += b.length;
} catch (IOException uex) {
System.out.println("JXTATLSutil.stringLength: " +
uex.getMessage());
strlen += str.length(); // under estimate if we
// change the encoding
}
return strlen;
}
/*
* The following code is taken from pureTLS directly.
*/
/**
SSLClient.java
Copyright (C) 1999, Claymore Systems, Inc.
All Rights Reserved.
ekr@rtfm.com Fri Jun 18 07:57:59 1999
This package is a SSLv3/TLS implementation written by Eric Rescorla
<ekr@rtfm.com> and licensed by Claymore Systems, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Claymore Systems, Inc.
4. Neither the name of Claymore Systems, Inc. nor the name of Eric
Rescorla may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
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 $
*/
// Parses a ":" separated list of TLS cipher suites
static public short[] parseCipherSuites(String suites)
throws ArrayIndexOutOfBoundsException {
StringTokenizer t=new StringTokenizer(suites,":",false);
Vector v=new Vector();
try {
for (;;) {
String tok = t.nextToken();
int num;
if ((num = SSLPolicyInt.getCipherSuiteNumber(tok)) > -1) {
v.addElement(new Integer(num));
}
}
} catch (NoSuchElementException e)
{;} // Our loop exit
if (v.size() > 0) {
short[] retval=new short[v.size()];
for(int i=0; i < v.size(); i++) {
Integer x = (Integer)v.elementAt(i);
retval[i] = x.shortValue();
}
return retval;
} else
return null;
}
// Get the path for our private crypto environment.
public static String getPCEPath()
{
//return "";
String fsep = null;
try {
fsep = System.getProperty("file.separator");
} catch (Exception e) {;} // should never happen
String path = JTlsDefs.PCEDIR + fsep;
return path;
}
// For root certificates
public static String getPCERootPath()
{
//return "";
String fsep = null;
try {
fsep = System.getProperty("file.separator");
} catch (Exception e) {;} // should never happen
String path = JTlsDefs.PCEDIR + fsep + JTlsDefs.ROOTDIR +
fsep;
return path;
}
// For client certificates
public static String getPCEClientPath()
{
//return "";
String fsep = null;
try {
fsep = System.getProperty("file.separator");
} catch (Exception e) {;} // should never happen
String path = JTlsDefs.PCEDIR + fsep + JTlsDefs.CLIENTDIR +
fsep;
return path;
}
// For the password file
public static String getPCEPasswdPath()
{
//return "";
String fsep = null;
try {
fsep = System.getProperty("file.separator");
} catch (Exception e) {;} // should never happen
String path = JTlsDefs.PCEDIR + fsep + JTlsDefs.PASSWORDDIR +
fsep;
return path;
}
// Read pass phrase
// It is a wrapped object which contains a String.
public static String readPassPhrase(String path, String password)
throws IOException
{
// Read the file and decrypt its contents to yield the
// PASSHPRASE file
File f = new File(path);
int size = (int)f.length();
byte[] ciphertext = new byte[size];
FileInputStream fr = new FileInputStream(f);
fr.read(ciphertext, 0, size);
fr.close();
// decrypt the ciphertext
byte[] plaintext = null;
try {
plaintext = tlsCipher(ciphertext, password, Cipher.MODE_DECRYPT);
} catch (jxta.security.exceptions.CryptoException e) {
throw new IOException("Could not decrypt " + path);
}
// System.out.println("PASSPHRASE file = " + new String(plaintext));
// extract the wrapped object (our passphrase);
// write plaintext to temp file
//PDA requirement 18.02.2002
// method File.createTempFile did not exist in jdk 1.1.8
// File tmp = File.createTempFile("yyj", null);
String filePath = System.getProperty( "java.io.tmpdir");
File tmp = new File (filePath, "yyj.tmp");
//PDA requirement 18.02.2002
FileOutputStream fout = new FileOutputStream(tmp);
fout.write(plaintext, 0, plaintext.length);
fout.close();
// Extract the wrapped object (our passphrase)
FileReader ff = new FileReader(tmp);
BufferedReader br = new BufferedReader(ff);
byte[] str64 = WrappedObject.loadObject(br, "PASSPHRASE", null);
br.close();
tmp.delete();
return new String(str64);
}
public static byte[] tlsCipher(byte[] data, String password, byte mode)
throws jxta.security.exceptions.CryptoException
{
// decrypt/encrypt the ciphertext using RC4
JxtaCrypto suite = new JxtaCryptoSuite(JxtaCrypto.MEMBER_RC4,
null, (byte)0, (byte)0);
jxta.security.cipher.Cipher rc4 = suite.getJxtaCipher();
SecretKey k1 = (SecretKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RC4,
KeyBuilder.LENGTH_RC4,
false);
byte[] pbytes = password.getBytes();
byte[] forkey = new byte[KeyBuilder.LENGTH_RC4 >>> 3];
// copy pbytes into forkey: Exactly key length in bytes.
for (int i = 0, j = 0; i < forkey.length; i++) {
forkey[i] = pbytes[j++];
if (j == pbytes.length) j = 0;
}
// set RC4 128 bit key
k1.setKey(forkey, 0);
// decrypt into ciphertext buffer
byte[] obuf = new byte[data.length];
rc4.init(k1, mode);
rc4.doFinal(data, 0, data.length, obuf, 0);
return obuf;
}
// Load a wrapped object in base64 format:
// The following three methods were modified
// from similar pureTLS methods.
/**
WrappedObject.java
Copyright (C) 1999, Claymore Systems, Inc.
All Rights Reserved.
ekr@rtfm.com Fri Jun 4 09:11:27 1999
This package is a SSLv3/TLS implementation written by Eric Rescorla
<ekr@rtfm.com> and licensed by Claymore Systems, Inc.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Claymore Systems, Inc.
4. Neither the name of Claymore Systems, Inc. nor the name of Eric
Rescorla may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -