diff options
author | mharmsen <mharmsen@c9f7a03b-bd48-0410-a16d-cbbf54688b0b> | 2011-10-04 01:17:41 +0000 |
---|---|---|
committer | mharmsen <mharmsen@c9f7a03b-bd48-0410-a16d-cbbf54688b0b> | 2011-10-04 01:17:41 +0000 |
commit | a4682ceae6774956461edd03b2485bbacea445f4 (patch) | |
tree | 94c475a125441da63101738220ce3972cf37db61 /pki/base/util/src/com/netscape/cmsutil/util | |
parent | 0c775428675d2cb1be9551f84e6b741ca813f77e (diff) | |
download | pki-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.java | 189 | ||||
-rw-r--r-- | pki/base/util/src/com/netscape/cmsutil/util/Fmt.java | 604 | ||||
-rw-r--r-- | pki/base/util/src/com/netscape/cmsutil/util/HMACDigest.java | 202 | ||||
-rw-r--r-- | pki/base/util/src/com/netscape/cmsutil/util/Utils.java | 251 |
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; + } + +} |