summaryrefslogtreecommitdiffstats
path: root/pki/base/util/src/com/netscape/cmsutil/util
diff options
context:
space:
mode:
authormharmsen <mharmsen@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2011-10-04 01:17:41 +0000
committermharmsen <mharmsen@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2011-10-04 01:17:41 +0000
commita4682ceae6774956461edd03b2485bbacea445f4 (patch)
tree94c475a125441da63101738220ce3972cf37db61 /pki/base/util/src/com/netscape/cmsutil/util
parent0c775428675d2cb1be9551f84e6b741ca813f77e (diff)
downloadpki-a4682ceae6774956461edd03b2485bbacea445f4.tar.gz
pki-a4682ceae6774956461edd03b2485bbacea445f4.tar.xz
pki-a4682ceae6774956461edd03b2485bbacea445f4.zip
Bugzilla Bug #688225 - (dogtagIPAv2.1) TRACKER: of the Dogtag fixes for freeIPA 2.1IPA_v2_RHEL_6_2_20111003
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/tags/IPA_v2_RHEL_6_2_20111003@2252 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
Diffstat (limited to 'pki/base/util/src/com/netscape/cmsutil/util')
-rw-r--r--pki/base/util/src/com/netscape/cmsutil/util/Cert.java189
-rw-r--r--pki/base/util/src/com/netscape/cmsutil/util/Fmt.java604
-rw-r--r--pki/base/util/src/com/netscape/cmsutil/util/HMACDigest.java202
-rw-r--r--pki/base/util/src/com/netscape/cmsutil/util/Utils.java251
4 files changed, 1246 insertions, 0 deletions
diff --git a/pki/base/util/src/com/netscape/cmsutil/util/Cert.java b/pki/base/util/src/com/netscape/cmsutil/util/Cert.java
new file mode 100644
index 000000000..6a2d32b32
--- /dev/null
+++ b/pki/base/util/src/com/netscape/cmsutil/util/Cert.java
@@ -0,0 +1,189 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.util;
+
+
+import netscape.security.pkcs.PKCS7;
+import netscape.security.x509.X509CRLImpl;
+import netscape.security.x509.X509CertImpl;
+import org.mozilla.jss.crypto.SignatureAlgorithm;
+//import sun.misc.BASE64Decoder;
+import com.netscape.osutil.OSUtil;
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509CRL;
+import java.security.cert.X509Certificate;
+
+public class Cert {
+
+ public static SignatureAlgorithm mapAlgorithmToJss(String algname) {
+ if (algname.equals("MD5withRSA"))
+ return SignatureAlgorithm.RSASignatureWithMD5Digest;
+ else if (algname.equals("MD2withRSA"))
+ return SignatureAlgorithm.RSASignatureWithMD2Digest;
+ else if (algname.equals("SHA1withRSA"))
+ return SignatureAlgorithm.RSASignatureWithSHA1Digest;
+ else if (algname.equals("SHA1withDSA"))
+ return SignatureAlgorithm.DSASignatureWithSHA1Digest;
+ else if (algname.equals("SHA256withRSA"))
+ return SignatureAlgorithm.RSASignatureWithSHA256Digest;
+ else if (algname.equals("SHA512withRSA"))
+ return SignatureAlgorithm.RSASignatureWithSHA512Digest;
+ else if (algname.equals("SHA1withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA1Digest;
+ else if (algname.equals("SHA256withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA256Digest;
+ else if (algname.equals("SHA384withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA384Digest;
+ else if (algname.equals("SHA512withEC"))
+ return SignatureAlgorithm.ECSignatureWithSHA512Digest;
+ return null;
+ }
+
+ public static String stripBrackets(String s) {
+ if (s == null) {
+ return s;
+ }
+
+ if ((s.startsWith("-----BEGIN CERTIFICATE-----")) &&
+ (s.endsWith("-----END CERTIFICATE-----"))) {
+ return (s.substring(27, (s.length() - 25)));
+ }
+
+ // To support Thawte's header and footer
+ if ((s.startsWith("-----BEGIN PKCS #7 SIGNED DATA-----")) &&
+ (s.endsWith("-----END PKCS #7 SIGNED DATA-----"))) {
+ return (s.substring(35, (s.length() - 33)));
+ }
+
+ return s;
+ }
+
+ public static String stripCRLBrackets(String s) {
+ if (s == null) {
+ return s;
+ }
+ if ((s.startsWith("-----BEGIN CERTIFICATE REVOCATION LIST-----")) &&
+ (s.endsWith("-----END CERTIFICATE REVOCATION LIST-----"))) {
+ return (s.substring(43, (s.length() - 41)));
+ }
+ return s;
+ }
+
+ public static String stripCertBrackets(String s) {
+ return stripBrackets(s);
+ }
+
+ // private static BASE64Decoder mDecoder = new BASE64Decoder();
+ public static X509CertImpl mapCert(String mime64)
+ throws IOException {
+ mime64 = stripCertBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ // byte rawPub[] = mDecoder.decodeBuffer(newval);
+ byte rawPub[] = OSUtil.AtoB( newval );
+ X509CertImpl cert = null;
+
+ try {
+ cert = new X509CertImpl(rawPub);
+ } catch (CertificateException e) {
+ }
+ return cert;
+ }
+
+ public static X509Certificate[] mapCertFromPKCS7(String mime64)
+ throws IOException {
+ mime64 = stripCertBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ // byte rawPub[] = mDecoder.decodeBuffer(newval);
+ byte rawPub[] = OSUtil.AtoB( newval );
+ PKCS7 p7 = null;
+
+ try {
+ p7 = new PKCS7(rawPub);
+ } catch (Exception e) {
+ throw new IOException( "p7 is null" );
+ }
+ return p7.getCertificates();
+ }
+
+ public static X509CRL mapCRL(String mime64)
+ throws IOException {
+ mime64 = stripCRLBrackets(mime64.trim());
+ String newval = normalizeCertStr(mime64);
+ // byte rawPub[] = mDecoder.decodeBuffer(newval);
+ byte rawPub[] = OSUtil.AtoB( newval );
+ X509CRL crl = null;
+
+ try {
+ crl = new X509CRLImpl(rawPub);
+ } catch (Exception e) {
+ }
+ return crl;
+ }
+
+ public static X509CRL mapCRL1(String mime64)
+ throws IOException {
+ mime64 = stripCRLBrackets(mime64.trim());
+
+ byte rawPub[] = OSUtil.AtoB(mime64);
+ X509CRL crl = null;
+
+ try {
+ crl = new X509CRLImpl(rawPub);
+ } catch (Exception e) {
+ throw new IOException(e.toString());
+ }
+ return crl;
+ }
+
+ public static String normalizeCertStr(String s) {
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ } else if (s.charAt(i) == ' ') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+
+ public static String normalizeCertStrAndReq(String s) {
+ String val = "";
+
+ for (int i = 0; i < s.length(); i++) {
+ if (s.charAt(i) == '\n') {
+ continue;
+ } else if (s.charAt(i) == '\r') {
+ continue;
+ } else if (s.charAt(i) == '"') {
+ continue;
+ }
+ val += s.charAt(i);
+ }
+ return val;
+ }
+}
+
diff --git a/pki/base/util/src/com/netscape/cmsutil/util/Fmt.java b/pki/base/util/src/com/netscape/cmsutil/util/Fmt.java
new file mode 100644
index 000000000..49b878c4c
--- /dev/null
+++ b/pki/base/util/src/com/netscape/cmsutil/util/Fmt.java
@@ -0,0 +1,604 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.util;
+
+// Fmt - some simple single-arg sprintf-like routines
+//
+// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. 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.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+
+
+/// Some simple single-arg sprintf-like routines.
+// <P>
+// It is apparently impossible to declare a Java method that accepts
+// variable numbers of any type of argument. You can declare it to take
+// Objects, but numeric variables and constants are not in fact Objects.
+// <P>
+// However, using the built-in string concatenation, it's almost as
+// convenient to make a series of single-argument formatting routines.
+// <P>
+// Fmt can format the following types:
+// <BLOCKQUOTE><CODE>
+// byte short int long float double char String Object
+// </CODE></BLOCKQUOTE>
+// For each type there is a set of overloaded methods, each returning
+// a formatted String. There's the plain formatting version:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( x )
+// </PRE></BLOCKQUOTE>
+// There's a version specifying a minimum field width:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( x, minWidth )
+// </PRE></BLOCKQUOTE>
+// And there's a version that takes flags:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( x, minWidth, flags )
+// </PRE></BLOCKQUOTE>
+// Currently available flags are:
+// <BLOCKQUOTE><PRE>
+// Fmt.ZF - zero-fill
+// Fmt.LJ - left justify
+// Fmt.HX - hexadecimal
+// Fmt.OC - octal
+// </PRE></BLOCKQUOTE>
+// The HX and OC flags imply unsigned output.
+// <P>
+// For doubles and floats, there's a significant-figures parameter before
+// the flags:
+// <BLOCKQUOTE><PRE>
+// Fmt.fmt( d )
+// Fmt.fmt( d, minWidth )
+// Fmt.fmt( d, minWidth, sigFigs )
+// Fmt.fmt( d, minWidth, sigFigs, flags )
+// </PRE></BLOCKQUOTE>
+// <P>
+// <A HREF="/resources/classes/Acme/Fmt.java">Fetch the software.</A><BR>
+// <A HREF="/resources/classes/Acme.tar.Z">Fetch the entire Acme package.</A>
+// <HR>
+// Similar classes:
+// <UL>
+// <LI> Andrew Scherpbier's <A HREF="http://www.sdsu.edu/doc/java-SDSU/sdsu.FormatString.html">FormatString</A>
+// Tries to allow variable numbers of arguments by
+// supplying overloaded routines with different combinations of parameters,
+// but doesn't actually supply that many. The floating point conversion
+// is described as "very incomplete".
+// <LI> Core Java's <A HREF="http://www.apl.jhu.edu/~hall/java/CoreJava-Format.html">Format</A>.
+// The design seems a little weird. They want you to create an instance,
+// passing the format string to the constructor, and then call an instance
+// method with your data to do the actual formatting. The extra steps are
+// pointless; better to just use static methods.
+// </UL>
+
+public class Fmt {
+
+ // Flags.
+ /// Zero-fill.
+ public static final int ZF = 1;
+ /// Left justify.
+ public static final int LJ = 2;
+ /// Hexadecimal.
+ public static final int HX = 4;
+ /// Octal.
+ public static final int OC = 8;
+ // Was a number - internal use.
+ private static final int WN = 16;
+
+ // byte
+ public static String fmt(byte b) {
+ return fmt(b, 0, 0);
+ }
+
+ public static String fmt(byte b, int minWidth) {
+ return fmt(b, minWidth, 0);
+ }
+
+ public static String fmt(byte b, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal)
+ return fmt(Integer.toString(b & 0xff, 16), minWidth, flags | WN);
+ else if (octal)
+ return fmt(Integer.toString(b & 0xff, 8), minWidth, flags | WN);
+ else
+ return fmt(Integer.toString(b & 0xff), minWidth, flags | WN);
+ }
+
+ // short
+ public static String fmt(short s) {
+ return fmt(s, 0, 0);
+ }
+
+ public static String fmt(short s, int minWidth) {
+ return fmt(s, minWidth, 0);
+ }
+
+ public static String fmt(short s, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal)
+ return fmt(
+ Integer.toString(s & 0xffff, 16), minWidth, flags | WN);
+ else if (octal)
+ return fmt(
+ Integer.toString(s & 0xffff, 8), minWidth, flags | WN);
+ else
+ return fmt(Integer.toString(s), minWidth, flags | WN);
+ }
+
+ // int
+ public static String fmt(int i) {
+ return fmt(i, 0, 0);
+ }
+
+ public static String fmt(int i, int minWidth) {
+ return fmt(i, minWidth, 0);
+ }
+
+ public static String fmt(int i, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal)
+ return fmt(
+ Long.toString(i & 0xffffffffL, 16), minWidth, flags | WN);
+ else if (octal)
+ return fmt(
+ Long.toString(i & 0xffffffffL, 8), minWidth, flags | WN);
+ else
+ return fmt(Integer.toString(i), minWidth, flags | WN);
+ }
+
+ // long
+ public static String fmt(long l) {
+ return fmt(l, 0, 0);
+ }
+
+ public static String fmt(long l, int minWidth) {
+ return fmt(l, minWidth, 0);
+ }
+
+ public static String fmt(long l, int minWidth, int flags) {
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+
+ if (hexadecimal) {
+ if ((l & 0xf000000000000000L) != 0)
+ return fmt(
+ Long.toString(l >>> 60, 16) +
+ fmt(l & 0x0fffffffffffffffL, 15, HX | ZF),
+ minWidth, flags | WN);
+ else
+ return fmt(Long.toString(l, 16), minWidth, flags | WN);
+ } else if (octal) {
+ if ((l & 0x8000000000000000L) != 0)
+ return fmt(
+ Long.toString(l >>> 63, 8) +
+ fmt(l & 0x7fffffffffffffffL, 21, OC | ZF),
+ minWidth, flags | WN);
+ else
+ return fmt(Long.toString(l, 8), minWidth, flags | WN);
+ } else
+ return fmt(Long.toString(l), minWidth, flags | WN);
+ }
+
+ // float
+ public static String fmt(float f) {
+ return fmt(f, 0, 0, 0);
+ }
+
+ public static String fmt(float f, int minWidth) {
+ return fmt(f, minWidth, 0, 0);
+ }
+
+ public static String fmt(float f, int minWidth, int sigFigs) {
+ return fmt(f, minWidth, sigFigs, 0);
+ }
+
+ public static String fmt(float f, int minWidth, int sigFigs, int flags) {
+ if (sigFigs != 0)
+ return fmt(
+ sigFigFix(Float.toString(f), sigFigs), minWidth,
+ flags | WN);
+ else
+ return fmt(Float.toString(f), minWidth, flags | WN);
+ }
+
+ // double
+ public static String fmt(double d) {
+ return fmt(d, 0, 0, 0);
+ }
+
+ public static String fmt(double d, int minWidth) {
+ return fmt(d, minWidth, 0, 0);
+ }
+
+ public static String fmt(double d, int minWidth, int sigFigs) {
+ return fmt(d, minWidth, sigFigs, 0);
+ }
+
+ public static String fmt(double d, int minWidth, int sigFigs, int flags) {
+ if (sigFigs != 0)
+ return fmt(
+ sigFigFix(doubleToString(d), sigFigs), minWidth,
+ flags | WN);
+ else
+ return fmt(doubleToString(d), minWidth, flags | WN);
+ }
+
+ // char
+ public static String fmt(char c) {
+ return fmt(c, 0, 0);
+ }
+
+ public static String fmt(char c, int minWidth) {
+ return fmt(c, minWidth, 0);
+ }
+
+ public static String fmt(char c, int minWidth, int flags) {
+ // return fmt( Character.toString( c ), minWidth, flags );
+ // Character currently lacks a static toString method. Workaround
+ // is to make a temporary instance and use the instance toString.
+ return fmt(Character.valueOf(c).toString(), minWidth, flags);
+ }
+
+ // Object
+ public static String fmt(Object o) {
+ return fmt(o, 0, 0);
+ }
+
+ public static String fmt(Object o, int minWidth) {
+ return fmt(o, minWidth, 0);
+ }
+
+ public static String fmt(Object o, int minWidth, int flags) {
+ return fmt(o.toString(), minWidth, flags);
+ }
+
+ // String
+ public static String fmt(String s) {
+ return fmt(s, 0, 0);
+ }
+
+ public static String fmt(String s, int minWidth) {
+ return fmt(s, minWidth, 0);
+ }
+
+ public static String fmt(String s, int minWidth, int flags) {
+ int len = s.length();
+ boolean zeroFill = ((flags & ZF) != 0);
+ boolean leftJustify = ((flags & LJ) != 0);
+ boolean hexadecimal = ((flags & HX) != 0);
+ boolean octal = ((flags & OC) != 0);
+ boolean wasNumber = ((flags & WN) != 0);
+
+ if ((hexadecimal || octal || zeroFill) && !wasNumber)
+ throw new InternalError("Acme.Fmt: number flag on a non-number");
+ if (zeroFill && leftJustify)
+ throw new InternalError("Acme.Fmt: zero-fill left-justify is silly");
+ if (hexadecimal && octal)
+ throw new InternalError("Acme.Fmt: can't do both hex and octal");
+ if (len >= minWidth)
+ return s;
+ int fillWidth = minWidth - len;
+ StringBuffer fill = new StringBuffer(fillWidth);
+
+ for (int i = 0; i < fillWidth; ++i)
+ if (zeroFill)
+ fill.append('0');
+ else
+ fill.append(' ');
+ if (leftJustify)
+ return s + fill;
+ else if (zeroFill && s.startsWith("-"))
+ return "-" + fill + s.substring(1);
+ else
+ return fill + s;
+ }
+
+ // Internal routines.
+
+ private static String sigFigFix(String s, int sigFigs) {
+ // First dissect the floating-point number string into sign,
+ // integer part, fraction part, and exponent.
+ String sign;
+ String unsigned;
+
+ if (s.startsWith("-") || s.startsWith("+")) {
+ sign = s.substring(0, 1);
+ unsigned = s.substring(1);
+ } else {
+ sign = "";
+ unsigned = s;
+ }
+ String mantissa;
+ String exponent;
+ int eInd = unsigned.indexOf('e');
+
+ if (eInd == -1) {
+ mantissa = unsigned;
+ exponent = "";
+ } else {
+ mantissa = unsigned.substring(0, eInd);
+ exponent = unsigned.substring(eInd);
+ }
+ StringBuffer number, fraction;
+ int dotInd = mantissa.indexOf('.');
+
+ if (dotInd == -1) {
+ number = new StringBuffer(mantissa);
+ fraction = new StringBuffer("");
+ } else {
+ number = new StringBuffer(mantissa.substring(0, dotInd));
+ fraction = new StringBuffer(mantissa.substring(dotInd + 1));
+ }
+
+ int numFigs = number.length();
+ int fracFigs = fraction.length();
+
+ if( ( numFigs == 0 || number.toString().equals( "0" ) ) &&
+ fracFigs > 0 ) {
+ // Don't count leading zeros in the fraction.
+ numFigs = 0;
+ for (int i = 0; i < fraction.length(); ++i) {
+ if (fraction.charAt(i) != '0')
+ break;
+ --fracFigs;
+ }
+ }
+ int mantFigs = numFigs + fracFigs;
+
+ if (sigFigs > mantFigs) {
+ // We want more figures; just append zeros to the fraction.
+ for (int i = mantFigs; i < sigFigs; ++i)
+ fraction.append('0');
+ } else if (sigFigs < mantFigs && sigFigs >= numFigs) {
+ // Want fewer figures in the fraction; chop.
+ fraction.setLength(
+ fraction.length() - (fracFigs - (sigFigs - numFigs)));
+ // Round?
+ } else if (sigFigs < numFigs) {
+ // Want fewer figures in the number; turn them to zeros.
+ fraction.setLength(0); // should already be zero, but make sure
+ for (int i = sigFigs; i < numFigs; ++i)
+ number.setCharAt(i, '0');
+ // Round?
+ }
+ // Else sigFigs == mantFigs, which is fine.
+
+ if (fraction.length() == 0)
+ return sign + number + exponent;
+ else
+ return sign + number + "." + fraction + exponent;
+ }
+
+ /// Improved version of Double.toString(), returns more decimal places.
+ // <P>
+ // The JDK 1.0.2 version of Double.toString() returns only six decimal
+ // places on some systems. In JDK 1.1 full precision is returned on
+ // all platforms.
+ // @deprecated
+ // @see java.lang.Double.toString
+ public static String doubleToString(double d) {
+ // Handle special numbers first, to avoid complications.
+ if (Double.isNaN(d))
+ return "NaN";
+ if (d == Double.NEGATIVE_INFINITY)
+ return "-Inf";
+ if (d == Double.POSITIVE_INFINITY)
+ return "Inf";
+
+ // Grab the sign, and then make the number positive for simplicity.
+ boolean negative = false;
+
+ if (d < 0.0D) {
+ negative = true;
+ d = -d;
+ }
+
+ // Get the native version of the unsigned value, as a template.
+ String unsStr = Double.toString(d);
+
+ // Dissect out the exponent.
+ String mantStr, expStr;
+ int exp;
+ int eInd = unsStr.indexOf('e');
+
+ if (eInd == -1) {
+ mantStr = unsStr;
+ expStr = "";
+ exp = 0;
+ } else {
+ mantStr = unsStr.substring(0, eInd);
+ expStr = unsStr.substring(eInd + 1);
+ if (expStr.startsWith("+"))
+ exp = Integer.parseInt(expStr.substring(1));
+ else
+ exp = Integer.parseInt(expStr);
+ }
+
+ // Dissect out the number part.
+ String numStr;
+ int dotInd = mantStr.indexOf('.');
+
+ if (dotInd == -1)
+ numStr = mantStr;
+ else
+ numStr = mantStr.substring(0, dotInd);
+ long num;
+
+ if (numStr.length() == 0)
+ num = 0;
+ else
+ num = Integer.parseInt(numStr);
+
+ // Build the new mantissa.
+ StringBuffer newMantBuf = new StringBuffer(numStr + ".");
+ double p = Math.pow(10, exp);
+ double frac = d - num * p;
+ String digits = "0123456789";
+ int nDigits = 16 - numStr.length(); // about 16 digits in a double
+
+ for (int i = 0; i < nDigits; ++i) {
+ p /= 10.0D;
+ int dig = (int) (frac / p);
+
+ if (dig < 0) dig = 0;
+ if (dig > 9) dig = 9;
+ newMantBuf.append(digits.charAt(dig));
+ frac -= dig * p;
+ }
+
+ if ((int) (frac / p + 0.5D) == 1) {
+ // Round up.
+ boolean roundMore = true;
+
+ for (int i = newMantBuf.length() - 1; i >= 0; --i) {
+ int dig = digits.indexOf(newMantBuf.charAt(i));
+
+ if (dig == -1)
+ continue;
+ ++dig;
+ if (dig == 10) {
+ newMantBuf.setCharAt(i, '0');
+ continue;
+ }
+ newMantBuf.setCharAt(i, digits.charAt(dig));
+ roundMore = false;
+ break;
+ }
+ if (roundMore) {
+ // If this happens, we need to prepend a 1. But I haven't
+ // found a test case yet, so I'm leaving it out for now.
+ // But if you get this message, please let me know!
+ newMantBuf.append("ROUNDMORE");
+ }
+ }
+
+ // Chop any trailing zeros.
+ int len = newMantBuf.length();
+
+ while (newMantBuf.charAt(len - 1) == '0')
+ newMantBuf.setLength(--len);
+ // And chop a trailing dot, if any.
+ if (newMantBuf.charAt(len - 1) == '.')
+ newMantBuf.setLength(--len);
+
+ // Done.
+ return (negative ? "-" : "") +
+ newMantBuf +
+ (expStr.length() != 0 ? ("e" + expStr) : "");
+ }
+
+ /******************************************************************************
+ /// Test program.
+ public static void main( String[] args )
+ {
+ System.out.println( "Starting tests." );
+ show( Fmt.fmt( "Hello there." ) );
+ show( Fmt.fmt( 123 ) );
+ show( Fmt.fmt( 123, 10 ) );
+ show( Fmt.fmt( 123, 10, Fmt.ZF ) );
+ show( Fmt.fmt( 123, 10, Fmt.LJ ) );
+ show( Fmt.fmt( -123 ) );
+ show( Fmt.fmt( -123, 10 ) );
+ show( Fmt.fmt( -123, 10, Fmt.ZF ) );
+ show( Fmt.fmt( -123, 10, Fmt.LJ ) );
+ show( Fmt.fmt( (byte) 0xbe, 22, Fmt.OC ) );
+ show( Fmt.fmt( (short) 0xbabe, 22, Fmt.OC ) );
+ show( Fmt.fmt( 0xcafebabe, 22, Fmt.OC ) );
+ show( Fmt.fmt( 0xdeadbeefcafebabeL, 22, Fmt.OC ) );
+ show( Fmt.fmt( 0x8000000000000000L, 22, Fmt.OC ) );
+ show( Fmt.fmt( (byte) 0xbe, 16, Fmt.HX ) );
+ show( Fmt.fmt( (short) 0xbabe, 16, Fmt.HX ) );
+ show( Fmt.fmt( 0xcafebabe, 16, Fmt.HX ) );
+ show( Fmt.fmt( 0xdeadbeefcafebabeL, 16, Fmt.HX ) );
+ show( Fmt.fmt( 0x8000000000000000L, 16, Fmt.HX ) );
+ show( Fmt.fmt( 'c' ) );
+ show( Fmt.fmt( new java.util.Date() ) );
+ show( Fmt.fmt( 123.456F ) );
+ show( Fmt.fmt( 123456000000000000.0F ) );
+ show( Fmt.fmt( 123.456F, 0, 8 ) );
+ show( Fmt.fmt( 123.456F, 0, 7 ) );
+ show( Fmt.fmt( 123.456F, 0, 6 ) );
+ show( Fmt.fmt( 123.456F, 0, 5 ) );
+ show( Fmt.fmt( 123.456F, 0, 4 ) );
+ show( Fmt.fmt( 123.456F, 0, 3 ) );
+ show( Fmt.fmt( 123.456F, 0, 2 ) );
+ show( Fmt.fmt( 123.456F, 0, 1 ) );
+ show( Fmt.fmt( 123456000000000000.0F, 0, 4 ) );
+ show( Fmt.fmt( -123.456F, 0, 4 ) );
+ show( Fmt.fmt( -123456000000000000.0F, 0, 4 ) );
+ show( Fmt.fmt( 123.0F ) );
+ show( Fmt.fmt( 123.0D ) );
+ show( Fmt.fmt( 1.234567890123456789F ) );
+ show( Fmt.fmt( 1.234567890123456789D ) );
+ show( Fmt.fmt( 1234567890123456789F ) );
+ show( Fmt.fmt( 1234567890123456789D ) );
+ show( Fmt.fmt( 0.000000000000000000001234567890123456789F ) );
+ show( Fmt.fmt( 0.000000000000000000001234567890123456789D ) );
+ show( Fmt.fmt( 12300.0F ) );
+ show( Fmt.fmt( 12300.0D ) );
+ show( Fmt.fmt( 123000.0F ) );
+ show( Fmt.fmt( 123000.0D ) );
+ show( Fmt.fmt( 1230000.0F ) );
+ show( Fmt.fmt( 1230000.0D ) );
+ show( Fmt.fmt( 12300000.0F ) );
+ show( Fmt.fmt( 12300000.0D ) );
+ show( Fmt.fmt( Float.NaN ) );
+ show( Fmt.fmt( Float.POSITIVE_INFINITY ) );
+ show( Fmt.fmt( Float.NEGATIVE_INFINITY ) );
+ show( Fmt.fmt( Double.NaN ) );
+ show( Fmt.fmt( Double.POSITIVE_INFINITY ) );
+ show( Fmt.fmt( Double.NEGATIVE_INFINITY ) );
+ show( Fmt.fmt( 1.0F / 8.0F ) );
+ show( Fmt.fmt( 1.0D / 8.0D ) );
+ System.out.println( "Done with tests." );
+ }
+
+ private static void show( String str )
+ {
+ System.out.println( "#" + str + "#" );
+ }
+ ******************************************************************************/
+
+}
diff --git a/pki/base/util/src/com/netscape/cmsutil/util/HMACDigest.java b/pki/base/util/src/com/netscape/cmsutil/util/HMACDigest.java
new file mode 100644
index 000000000..c1ab2003d
--- /dev/null
+++ b/pki/base/util/src/com/netscape/cmsutil/util/HMACDigest.java
@@ -0,0 +1,202 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.util;
+
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/**
+ * This class implements the HMAC algorithm specified in RFC 2104 using
+ * any MessageDigest.
+ *
+ * @author mikep
+ * @version $Revision$, $Date$
+ * @see java.security.MessageDigest
+ */
+public class HMACDigest implements Cloneable {
+ public static final int PAD_BYTES = 64;
+ public static final int IPAD = 0x36;
+ public static final int OPAD = 0x5C;
+
+ /**
+ * inner padding - key XORd with ipad
+ */
+ private byte[] mKeyIpad = new byte[PAD_BYTES];
+
+ /**
+ * outer padding - key XORd with opad
+ */
+ private byte[] mKeyOpad = new byte[PAD_BYTES];
+
+ /**
+ * The real MessageDigest
+ */
+ private MessageDigest mMD = null;
+
+ /**
+ * Creates an HMACDigest
+ *
+ * @param md The MessageDigest to be used for the HMAC calculation. It
+ * must be clonable.
+ */
+ public HMACDigest(MessageDigest md) {
+ mMD = md;
+ }
+
+ /**
+ * Creates an HMACDigest and initializes the HMAC function
+ * with the given key.
+ *
+ * @param md The MessageDigest to be used for the HMAC calculation. It
+ * must be clonable.
+ * @param key The key value to be used in the HMAC calculation
+ */
+ public HMACDigest(MessageDigest md, byte[] key) {
+ this(md);
+ init(key);
+ }
+
+ /**
+ * Return the MessageDigest used for this HMAC
+ */
+ public MessageDigest getMessageDigest() {
+ return mMD;
+ }
+
+ /**
+ * Initialize the HMAC function
+ *
+ * The HMAC transform looks like:
+ *
+ * hash(key XOR opad, hash(key XOR ipad, text))
+ *
+ * where key is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ *
+ * This routine must be called after every reset.
+ *
+ * @param key The password used to protect the hash value
+ */
+ public void init(byte[] key) {
+ int i;
+
+ reset();
+
+ // If the key is longer than 64 bytes, just hash it down
+ if (key.length > 64) {
+ key = mMD.digest(key);
+ mMD.reset(); // Redundant?
+ }
+
+ // Copy the key. Truncate if key is too long
+ for (i = 0; i < key.length && i < PAD_BYTES; i++) {
+ mKeyIpad[i] = key[i];
+ mKeyOpad[i] = key[i];
+ }
+
+ // XOR in the pads
+ for (i = 0; i < PAD_BYTES; i++) {
+ mKeyIpad[i] ^= IPAD;
+ mKeyOpad[i] ^= OPAD;
+ }
+
+ mMD.update(mKeyIpad);
+
+ // Hmmm, we really shouldn't key Opad around in memory for so
+ // long, but it would just force the user to key their key around
+ // until digest() time. Oh well, at least clear the key and Ipad
+ for (i = 0; i < PAD_BYTES; i++) {
+ mKeyIpad[i] = 0;
+ }
+ for (i = 0; i < key.length; i++) {
+ key[0] = 0;
+ }
+ }
+
+ /**
+ * Updates the digest using the specified array of bytes.
+ *
+ * @param input the array of bytes.
+ */
+ public void update(byte[] input) {
+ mMD.update(input);
+ }
+
+ /**
+ * Completes the HMAC computation with the outer pad
+ * The digest is reset after this call is made.
+ *
+ * @return the array of bytes for the resulting hash value.
+ */
+ public byte[] digest() {
+ byte[] finalDigest;
+ byte[] innerDigest = mMD.digest();
+
+ mMD.reset(); // Redundant?
+ mMD.update(mKeyOpad);
+ mMD.update(innerDigest);
+ finalDigest = mMD.digest();
+ reset(); // Clear pad arrays
+ return finalDigest;
+ }
+
+ /**
+ * Resets the digest for further use.
+ */
+ public void reset() {
+ int i;
+
+ mMD.reset();
+
+ // Clear out the pads
+ for (i = 0; i < PAD_BYTES; i++) {
+ mKeyIpad[i] = 0;
+ mKeyOpad[i] = 0;
+ }
+ }
+
+ /**
+ * Clone the HMACDigest
+ *
+ * @return a clone if the implementation is cloneable.
+ * @exception CloneNotSupportedException if this is called on a
+ * MessageDigest implementation that does not support
+ * <code>Cloneable</code>.
+ */
+ public Object clone() throws CloneNotSupportedException {
+ int i;
+
+ HMACDigest hd = (HMACDigest) super.clone();
+
+ hd.mKeyOpad = new byte[PAD_BYTES];
+ hd.mKeyIpad = new byte[PAD_BYTES];
+
+ for (i = 0; i < PAD_BYTES; i++) {
+ hd.mKeyOpad[i] = mKeyOpad[i];
+ hd.mKeyIpad[i] = mKeyIpad[i];
+ }
+
+ hd.mMD = (MessageDigest) mMD.clone();
+ return hd;
+ }
+
+}
diff --git a/pki/base/util/src/com/netscape/cmsutil/util/Utils.java b/pki/base/util/src/com/netscape/cmsutil/util/Utils.java
new file mode 100644
index 000000000..9d0fb05ac
--- /dev/null
+++ b/pki/base/util/src/com/netscape/cmsutil/util/Utils.java
@@ -0,0 +1,251 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.util;
+
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+
+public class Utils {
+ /**
+ * Checks if this is NT.
+ */
+ public static boolean isNT() {
+ return ((File.separator).equals("\\"));
+ }
+
+ public static boolean exec(String cmd) {
+ try {
+ String cmds[] = null;
+ if (isNT()) {
+ // NT
+ cmds = new String[3];
+ cmds[0] = "cmd";
+ cmds[1] = "/c";
+ cmds[2] = cmd;
+ } else {
+ // UNIX
+ cmds = new String[3];
+ cmds[0] = "/bin/sh";
+ cmds[1] = "-c";
+ cmds[2] = cmd;
+ }
+ Process process = Runtime.getRuntime().exec(cmds);
+ process.waitFor();
+ BufferedReader pOut = null;
+ String l = null;
+
+ if (process.exitValue() == 0) {
+ /**
+ pOut = new BufferedReader(
+ new InputStreamReader(process.getInputStream()));
+ while ((l = pOut.readLine()) != null) {
+ System.out.println(l);
+ }
+ **/
+ return true;
+ } else {
+ /**
+ pOut = new BufferedReader(
+ new InputStreamReader(process.getErrorStream()));
+ l = null;
+ while ((l = pOut.readLine()) != null) {
+ System.out.println(l);
+ }
+ **/
+ return false;
+ }
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public static String SpecialURLDecode(String s) {
+ if (s == null)
+ return null;
+ ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ int c = (int) s.charAt(i);
+
+ if (c == '+') {
+ out.write(' ');
+ } else if (c == '#') {
+ int c1 = Character.digit(s.charAt(++i), 16);
+ int c2 = Character.digit(s.charAt(++i), 16);
+
+ out.write((char) (c1 * 16 + c2));
+ } else {
+ out.write(c);
+ }
+ } // end for
+ return out.toString();
+ }
+
+ public static byte[] SpecialDecode(String s) {
+ if (s == null)
+ return null;
+ ByteArrayOutputStream out = new ByteArrayOutputStream(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ int c = (int) s.charAt(i);
+
+ if (c == '+') {
+ out.write(' ');
+ } else if (c == '#') {
+ int c1 = Character.digit(s.charAt(++i), 16);
+ int c2 = Character.digit(s.charAt(++i), 16);
+
+ out.write((char) (c1 * 16 + c2));
+ } else {
+ out.write(c);
+ }
+ } // end for
+ return out.toByteArray();
+ }
+
+ public static String SpecialEncode(byte data[]) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < data.length; i++) {
+ sb.append("%");
+ if ((data[i] & 0xff) < 16) {
+ sb.append("0");
+ }
+ sb.append(Integer.toHexString((data[i] & 0xff)));
+ }
+ return sb.toString().toUpperCase();
+ }
+
+ public static void checkHost(String hostname) throws UnknownHostException {
+ InetAddress addr = InetAddress.getByName(hostname);
+ }
+
+ public static void copy(String orig, String dest) {
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(orig));
+ PrintWriter out = new PrintWriter(
+ new BufferedWriter(new FileWriter(dest)));
+ String line = "";
+ while (in.ready()) {
+ line = in.readLine();
+ if (line != null)
+ out.println(line);
+ }
+ in.close();
+ out.close();
+ } catch (Exception ee) {
+ }
+ }
+
+ public static void copyStream(InputStream in, OutputStream out) throws IOException {
+ byte[] buf = new byte[4096];
+ int len;
+
+ while ((len = in.read(buf)) != -1) {
+ out.write(buf, 0, len);
+ }
+ }
+
+ public static void copyStream(BufferedReader in, OutputStreamWriter out) throws IOException {
+ char[] buf = new char[4096];
+ int len;
+
+ while ((len = in.read(buf)) != -1) {
+ out.write(buf, 0, len);
+ }
+ }
+
+ /// Sorts an array of Strings.
+ // Java currently has no general sort function. Sorting Strings is
+ // common enough that it's worth making a special case.
+ public static void sortStrings(String[] strings) {
+ // Just does a bubblesort.
+ for (int i = 0; i < strings.length - 1; ++i) {
+ for (int j = i + 1; j < strings.length; ++j) {
+ if (strings[i].compareTo(strings[j]) > 0) {
+ String t = strings[i];
+
+ strings[i] = strings[j];
+ strings[j] = t;
+ }
+ }
+ }
+ }
+
+ /// Returns a date string formatted in Unix ls style - if it's within
+ // six months of now, Mmm dd hh:ss, else Mmm dd yyyy.
+ public static String lsDateStr(Date date) {
+ long dateTime = date.getTime();
+
+ if (dateTime == -1L)
+ return "------------";
+ long nowTime = System.currentTimeMillis();
+ SimpleDateFormat formatter = new SimpleDateFormat();
+
+ if (Math.abs(nowTime - dateTime) < 183L * 24L * 60L * 60L * 1000L)
+ formatter.applyPattern("MMM dd hh:ss");
+ else
+ formatter.applyPattern("MMM dd yyyy");
+ return formatter.format(date);
+ }
+
+ /**
+ * compares contents two byte arrays returning true if exactly same.
+ */
+ static public boolean byteArraysAreEqual(byte[] a, byte[] b) {
+ if (a.length != b.length)
+ return false;
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != b[i])
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * strips out double quotes around String parameter
+ * @param s the string potentially bracketed with double quotes
+ * @return string stripped of surrounding double quotes
+ */
+ public static String stripQuotes(String s) {
+ if (s == null) {
+ return s;
+ }
+
+ if ((s.startsWith("\"")) && (s.endsWith("\""))) {
+ return (s.substring(1, (s.length() - 1)));
+ }
+
+ return s;
+ }
+
+ /**
+ * returns an array of strings from a vector of Strings
+ * there'll be trouble if the Vector contains something other
+ * than just Strings
+ */
+ public static String[] getStringArrayFromVector(Vector v) {
+ String s[] = new String[v.size()];
+
+ v.copyInto(s);
+ return s;
+ }
+
+}