From 0783cdeb1fa74a634d58832a21f1489ce998e294 Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Fri, 25 Oct 2019 20:00:52 +0000 Subject: [PATCH] Remove references to DatatypeConverter git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1868953 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/poi/hpsf/Property.java | 11 +++++------ .../poi/poifs/crypt/dsig/SignatureInfo.java | 13 ++++++++----- .../dsig/services/TSPTimeStampService.java | 5 ++--- .../usermodel/helpers/XSSFPasswordHelper.java | 17 ++++++++++------- .../poifs/crypt/dsig/TestSignatureConfig.java | 5 ++--- .../poi/ss/extractor/TestEmbeddedExtractor.java | 5 ++--- src/resources/devtools/forbidden-signatures.txt | 3 +++ .../apache/poi/poifs/storage/RawDataUtil.java | 7 +++---- 8 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/java/org/apache/poi/hpsf/Property.java b/src/java/org/apache/poi/hpsf/Property.java index 56f9ac2175..740530b6c0 100644 --- a/src/java/org/apache/poi/hpsf/Property.java +++ b/src/java/org/apache/poi/hpsf/Property.java @@ -22,12 +22,11 @@ import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; -import java.util.Calendar; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Locale; import java.util.concurrent.TimeUnit; -import javax.xml.bind.DatatypeConverter; - import org.apache.poi.hpsf.wellknown.PropertyIDMap; import org.apache.poi.util.CodePageUtil; import org.apache.poi.util.HexDump; @@ -453,10 +452,10 @@ public class Property { String str = String.format(Locale.ROOT, "%02d:%02d:%02d.%03d",hr,min,sec,ms); b.append(str); } else { - Calendar cal = Calendar.getInstance(LocaleUtil.TIMEZONE_UTC, Locale.ROOT); - cal.setTime(d); // use ISO-8601 timestamp format - b.append(DatatypeConverter.printDateTime(cal)); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ROOT); + df.setTimeZone(LocaleUtil.TIMEZONE_UTC); + b.append(df.format(d)); } } else if (type == Variant.VT_EMPTY || type == Variant.VT_NULL || value == null) { b.append("null"); diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java index 7fbed2459d..8f81566566 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java @@ -32,13 +32,13 @@ import java.io.OutputStream; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.util.ArrayList; +import java.util.Base64; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; -import javax.xml.bind.DatatypeConverter; import javax.xml.crypto.MarshalException; import javax.xml.crypto.URIDereferencer; import javax.xml.crypto.XMLStructure; @@ -58,6 +58,7 @@ import org.apache.jcp.xml.dsig.internal.dom.DOMReference; import org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo; import org.apache.jcp.xml.dsig.internal.dom.DOMSubTreeData; import org.apache.poi.EncryptedDocumentException; +import org.apache.poi.ooxml.util.DocumentHelper; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; @@ -72,11 +73,9 @@ import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.dsig.SignatureConfig.SignatureConfigurable; import org.apache.poi.poifs.crypt.dsig.facets.SignatureFacet; import org.apache.poi.poifs.crypt.dsig.services.RelationshipTransformService; -import org.apache.poi.ooxml.util.DocumentHelper; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.xml.security.Init; -import org.apache.xml.security.utils.Base64; import org.apache.xml.security.utils.XMLUtils; import org.apache.xmlbeans.XmlOptions; import org.w3.x2000.x09.xmldsig.SignatureDocument; @@ -239,7 +238,11 @@ public class SignatureInfo implements SignatureConfigurable { final PrivateKey key = signatureConfig.getKey(); final HashAlgorithm algo = signatureConfig.getDigestAlgo(); - if (algo.hashSize*4/3 > Base64.BASE64DEFAULTLENGTH && !XMLUtils.ignoreLineBreaks()) { + // taken from org.apache.xml.security.utils.Base64 + final int BASE64DEFAULTLENGTH = 76; + + + if (algo.hashSize*4/3 > BASE64DEFAULTLENGTH && !XMLUtils.ignoreLineBreaks()) { throw new EncryptedDocumentException("The hash size of the choosen hash algorithm ("+algo+" = "+algo.hashSize+" bytes), "+ "will motivate XmlSec to add linebreaks to the generated digest, which results in an invalid signature (... at least "+ "for Office) - please persuade it otherwise by adding '-Dorg.apache.xml.security.ignoreLineBreaks=true' to the JVM "+ @@ -254,7 +257,7 @@ public class SignatureInfo implements SignatureConfigurable { final DOMSubTreeData subTree = new DOMSubTreeData(el, true); signedInfo.getCanonicalizationMethod().transform(subTree, xmlSignContext, dos); - return DatatypeConverter.printBase64Binary(dos.sign()); + return Base64.getEncoder().encodeToString(dos.sign()); } catch (GeneralSecurityException|IOException|TransformException e) { throw new EncryptedDocumentException(e); } diff --git a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java index 7066f14cd7..ec6a3f0e2d 100644 --- a/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java +++ b/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/services/TSPTimeStampService.java @@ -38,13 +38,12 @@ import java.security.MessageDigest; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.xml.bind.DatatypeConverter; - import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.poifs.crypt.dsig.SignatureConfig; @@ -131,7 +130,7 @@ public class TSPTimeStampService implements TimeStampService { try { if (signatureConfig.getTspUser() != null) { String userPassword = signatureConfig.getTspUser() + ":" + signatureConfig.getTspPass(); - String encoding = DatatypeConverter.printBase64Binary(userPassword.getBytes(StandardCharsets.ISO_8859_1)); + String encoding = Base64.getEncoder().encodeToString(userPassword.getBytes(StandardCharsets.ISO_8859_1)); huc.setRequestProperty("Authorization", "Basic " + encoding); } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java index 1e305b4b85..167cee14ff 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFPasswordHelper.java @@ -21,15 +21,14 @@ package org.apache.poi.xssf.usermodel.helpers; import java.security.SecureRandom; import java.util.Arrays; +import java.util.Base64; import java.util.Locale; -import javax.xml.bind.DatatypeConverter; import javax.xml.namespace.QName; import org.apache.poi.poifs.crypt.CryptoFunctions; import org.apache.poi.poifs.crypt.HashAlgorithm; import org.apache.poi.util.Internal; -import org.apache.poi.util.LocaleUtil; import org.apache.poi.util.StringUtil; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; @@ -77,10 +76,12 @@ public final class XSSFPasswordHelper { // --> In this third stage, the reversed byte order legacy hash from the second stage shall // be converted to Unicode hex string representation byte[] hash = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCount, false); - + + Base64.Encoder enc64 = Base64.getEncoder(); + cur.insertAttributeWithValue(getAttrName(prefix, "algorithmName"), hashAlgo.jceId); - cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), DatatypeConverter.printBase64Binary(hash)); - cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), DatatypeConverter.printBase64Binary(salt)); + cur.insertAttributeWithValue(getAttrName(prefix, "hashValue"), enc64.encodeToString(hash)); + cur.insertAttributeWithValue(getAttrName(prefix, "saltValue"), enc64.encodeToString(salt)); cur.insertAttributeWithValue(getAttrName(prefix, "spinCount"), ""+spinCount); } cur.dispose(); @@ -118,9 +119,11 @@ public final class XSSFPasswordHelper { return false; } - byte[] hash1 = DatatypeConverter.parseBase64Binary(hashVal); + Base64.Decoder dec64 = Base64.getDecoder(); + + byte[] hash1 = dec64.decode(hashVal); HashAlgorithm hashAlgo = HashAlgorithm.fromString(algoName); - byte[] salt = DatatypeConverter.parseBase64Binary(saltVal); + byte[] salt = dec64.decode(saltVal); int spinCnt = Integer.parseInt(spinCount); byte[] hash2 = CryptoFunctions.hashPassword(password, hashAlgo, salt, spinCnt, false); return Arrays.equals(hash1, hash2); diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/dsig/TestSignatureConfig.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/dsig/TestSignatureConfig.java index d895c9ad34..fd6ffbeb62 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/dsig/TestSignatureConfig.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/dsig/TestSignatureConfig.java @@ -19,8 +19,7 @@ package org.apache.poi.poifs.crypt.dsig; import static org.junit.Assert.assertEquals; import java.io.IOException; - -import javax.xml.bind.DatatypeConverter; +import java.util.Base64; import org.apache.poi.poifs.crypt.HashAlgorithm; import org.junit.Ignore; @@ -53,7 +52,7 @@ public class TestSignatureConfig { for (final String[] check : checks) { final HashAlgorithm ha = HashAlgorithm.valueOf(check[0]); try (final DigestOutputStream dos = new DigestOutputStream(ha, null)) { - final String magic = DatatypeConverter.printBase64Binary(dos.getHashMagic()); + final String magic = Base64.getEncoder().encodeToString(dos.getHashMagic()); assertEquals("hash digest magic mismatches", check[1], magic); } } diff --git a/src/ooxml/testcases/org/apache/poi/ss/extractor/TestEmbeddedExtractor.java b/src/ooxml/testcases/org/apache/poi/ss/extractor/TestEmbeddedExtractor.java index 3f5a1c0a29..0b755b91d6 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/extractor/TestEmbeddedExtractor.java +++ b/src/ooxml/testcases/org/apache/poi/ss/extractor/TestEmbeddedExtractor.java @@ -25,10 +25,9 @@ import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Base64; import java.util.List; -import javax.xml.bind.DatatypeConverter; - import org.apache.poi.EncryptedDocumentException; import org.apache.poi.POIDataSamples; import org.apache.poi.hssf.HSSFTestDataSamples; @@ -109,7 +108,7 @@ public class TestEmbeddedExtractor { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] hash = md.digest(input); - return DatatypeConverter.printBase64Binary(hash); + return Base64.getEncoder().encodeToString(hash); } catch (NoSuchAlgorithmException e) { // doesn't happen throw new RuntimeException(e); diff --git a/src/resources/devtools/forbidden-signatures.txt b/src/resources/devtools/forbidden-signatures.txt index 9fda92e1b6..d296489896 100644 --- a/src/resources/devtools/forbidden-signatures.txt +++ b/src/resources/devtools/forbidden-signatures.txt @@ -134,3 +134,6 @@ java.lang.String#toString() #@defaultMessage Deprecated Java APIs #java.lang.StringBuffer #java.util.Hashtable + +@defaultMessage DatatypeConverter is not available in Java 9+ without adding add-opens - use java.util.Base64 +javax.xml.bind.DatatypeConverter \ No newline at end of file diff --git a/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java b/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java index 446ecdeec1..59f57e6e8b 100644 --- a/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java +++ b/src/testcases/org/apache/poi/poifs/storage/RawDataUtil.java @@ -20,10 +20,9 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; +import java.util.Base64; import java.util.zip.GZIPInputStream; -import javax.xml.bind.DatatypeConverter; - import org.apache.poi.util.HexDump; import org.apache.poi.util.HexRead; import org.apache.poi.util.IOUtils; @@ -96,7 +95,7 @@ public final class RawDataUtil { * @throws IOException if you copy and pasted the data wrong */ public static byte[] decompress(String data) throws IOException { - byte[] base64Bytes = DatatypeConverter.parseBase64Binary(data); + byte[] base64Bytes = Base64.getDecoder().decode(data); return IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(base64Bytes))); } @@ -112,6 +111,6 @@ public final class RawDataUtil { java.util.zip.GZIPOutputStream gz = new java.util.zip.GZIPOutputStream(bos); gz.write(data); gz.finish(); - return DatatypeConverter.printBase64Binary(bos.toByteArray()); + return Base64.getEncoder().encodeToString(bos.toByteArray()); } }