You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2018/12/16 16:51:09 UTC
svn commit: r1849036 - in /poi/branches/hemf: ./ jenkins/ sonar/
sonar/ooxml/ src/integrationtest/org/apache/poi/
src/java/org/apache/poi/sl/usermodel/
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/
src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facet...
Author: kiwiwings
Date: Sun Dec 16 16:51:08 2018
New Revision: 1849036
URL: http://svn.apache.org/viewvc?rev=1849036&view=rev
Log:
merge trunk
Added:
poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/DSigRelation.java
- copied unchanged from r1848974, poi/trunk/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/DSigRelation.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/draw/
- copied from r1849030, poi/trunk/src/ooxml/java/org/apache/poi/xslf/draw/
poi/branches/hemf/test-data/xmldsign/bug63011_key1.pem
- copied unchanged from r1848974, poi/trunk/test-data/xmldsign/bug63011_key1.pem
poi/branches/hemf/test-data/xmldsign/bug63011_key2.pem
- copied unchanged from r1848974, poi/trunk/test-data/xmldsign/bug63011_key2.pem
Removed:
poi/branches/hemf/src/ooxml/testcases/org/apache/poi/poifs/crypt/PkiTestUtils.java
Modified:
poi/branches/hemf/ (props changed)
poi/branches/hemf/build.gradle
poi/branches/hemf/build.xml
poi/branches/hemf/jenkins/create_jobs.groovy
poi/branches/hemf/sonar/ooxml/pom.xml
poi/branches/hemf/sonar/pom.xml
poi/branches/hemf/src/integrationtest/org/apache/poi/TestAllFiles.java
poi/branches/hemf/src/java/org/apache/poi/sl/usermodel/PictureData.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java
poi/branches/hemf/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
poi/branches/hemf/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
Propchange: poi/branches/hemf/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sun Dec 16 16:51:08 2018
@@ -6,4 +6,4 @@
/poi/branches/ss_border_property_template:1747847-1748074
/poi/branches/xml_signature:1617139-1628347
/poi/branches/xssf_structured_references:1747607-1747656
-/poi/trunk:693591-694881,695264-695420,695621,695649-711764,1839877-1840323,1840325-1843031,1843033-1845612,1845617-1847068,1847083,1847263,1847418,1847428-1847429,1847436-1847438,1847442,1847454,1847487,1847493-1847494,1847496,1847861,1848115,1848179,1848432,1848438,1848492
+/poi/trunk:693591-694881,695264-695420,695621,695649-711764,1839877-1840323,1840325-1843031,1843033-1845612,1845617-1847068,1847083,1847263,1847418,1847428-1847429,1847436-1847438,1847442,1847454,1847487,1847493-1847494,1847496,1847861,1848115,1848179,1848432,1848438,1848492,1848494,1848538-1848539,1848591,1848601,1848642,1848655,1848809,1848811,1848974-1848975,1849030,1849032
Modified: poi/branches/hemf/build.gradle
URL: http://svn.apache.org/viewvc/poi/branches/hemf/build.gradle?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/build.gradle (original)
+++ poi/branches/hemf/build.gradle Sun Dec 16 16:51:08 2018
@@ -91,7 +91,7 @@ subprojects {
// See https://github.com/melix/japicmp-gradle-plugin
apply plugin: 'me.champeau.gradle.japicmp'
- version = '4.0.1-SNAPSHOT'
+ version = '4.0.2-SNAPSHOT'
ext {
japicmpversion = '4.0.0'
}
@@ -233,6 +233,11 @@ project('ooxml') {
compile 'org.bouncycastle:bcpkix-jdk15on:1.60'
compile 'com.github.virtuald:curvesapi:1.05'
+ // compile only, don't add it to our dist as it blows up the size
+ compile 'org.apache.xmlgraphics:batik-all:1.10'
+ compile 'xml-apis:xml-apis-ext:1.3.04'
+ compile 'org.apache.xmlgraphics:xmlgraphics-commons:2.3'
+
// for ooxml-lite, should we move this somewhere else?
compile 'junit:junit:4.12'
Modified: poi/branches/hemf/build.xml
URL: http://svn.apache.org/viewvc/poi/branches/hemf/build.xml?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/build.xml (original)
+++ poi/branches/hemf/build.xml Sun Dec 16 16:51:08 2018
@@ -217,6 +217,14 @@ under the License.
<property name="dsig.sl4j-api.jar" location="${compile.lib}/slf4j-api-1.7.25.jar"/>
<property name="dsig.sl4j-api.url" value="${repository.m2}/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar"/>
+ <!-- svg/batik libs - not part of the distribution -->
+ <property name="svg.batik-all.url" value="${repository.m2}/maven2/org/apache/xmlgraphics/batik-all/1.10/batik-all-1.10.jar"/>
+ <property name="svg.batik-all.jar" value="${compile.lib}/batik-all-1.10.jar"/>
+ <property name="svg.xml-apis-ext.url" value="${repository.m2}/maven2/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04.jar"/>
+ <property name="svg.xml-apis-ext.jar" value="${compile.lib}/xml-apis-ext-1.3.04.jar"/>
+ <property name="svg.xmlgraphics-commons.url" value="${repository.m2}/maven2/org/apache/xmlgraphics/xmlgraphics-commons/2.3/xmlgraphics-commons-2.3.jar"/>
+ <property name="svg.xmlgraphics-commons.jar" value="${compile.lib}/xmlgraphics-commons-2.3.jar"/>
+
<!-- jars in the ooxml-lib directory, see the fetch-ooxml-jars target-->
<property name="ooxml.curvesapi.jar" location="${ooxml.lib}/curvesapi-1.05.jar"/>
<property name="ooxml.curvesapi.url"
@@ -395,6 +403,12 @@ under the License.
<pathelement location="${scratchpad.output.dir}" unless:true="${scratchpad.ignore}"/>
</path>
+ <path id="batik.classpath">
+ <pathelement location="${svg.batik-all.jar}"/>
+ <pathelement location="${svg.xml-apis-ext.jar}"/>
+ <pathelement location="${svg.xmlgraphics-commons.jar}"/>
+ </path>
+
<path id="ooxml-lite.classpath">
<path refid="ooxml.base.classpath"/>
<!-- instead of ooxml-xsds.jar use the filtered classes-->
@@ -402,11 +416,13 @@ under the License.
<pathelement location="${ooxml.output.dir}"/>
<pathelement location="${ooxml.output.test.dir}"/>
<pathelement location="${main.output.test.dir}"/>
+ <path refid="batik.classpath"/>
</path>
<path id="ooxml.classpath">
<pathelement location="${ooxml.xsds.jar}"/>
<path refid="ooxml.base.classpath"/>
+ <path refid="batik.classpath"/>
</path>
<path id="ooxml.lite.verify.classpath">
@@ -777,6 +793,9 @@ under the License.
<available file="${ooxml.test.reflections.jar}"/>
<available file="${ooxml.test.guava.jar}"/>
<available file="${ooxml.test.javassist.jar}"/>
+ <available file="${svg.xml-apis-ext.jar}"/>
+ <available file="${svg.batik-all.jar}"/>
+ <available file="${svg.xmlgraphics-commons.jar}"/>
</and>
<isset property="disconnected"/>
</or>
@@ -791,6 +810,9 @@ under the License.
<downloadfile src="${ooxml.test.reflections.url}" dest="${ooxml.test.reflections.jar}"/>
<downloadfile src="${ooxml.test.guava.url}" dest="${ooxml.test.guava.jar}"/>
<downloadfile src="${ooxml.test.javassist.url}" dest="${ooxml.test.javassist.jar}"/>
+ <downloadfile src="${svg.batik-all.url}" dest="${svg.batik-all.jar}"/>
+ <downloadfile src="${svg.xml-apis-ext.url}" dest="${svg.xml-apis-ext.jar}"/>
+ <downloadfile src="${svg.xmlgraphics-commons.url}" dest="${svg.xmlgraphics-commons.jar}"/>
</target>
<target name="check-svn-jars">
<condition property="svn.jars.present">
@@ -932,6 +954,7 @@ under the License.
</xmlbean>
<local name="loaderMethod"/>
+ <!-- the space between "public static" is on purpose to prevent double execution -->
<property name="loaderMethod"><![CDATA[
private static java.lang.ref.SoftReference<org.apache.xmlbeans.SchemaTypeLoader> typeLoader;
@@ -944,7 +967,7 @@ under the License.
return stl;
}
- public static \2 newInstance\(\) \{]]></property>
+ public static \2 newInstance\(\) \{]]></property>
<replaceregexp byline="true" match="(\s*)public static ([^ ]+) newInstance\(\) \{" replace="${loaderMethod}">
<fileset dir="${xmlbean.sources.dir}" includes="**/*.java" excludes="**/impl/**"/>
Modified: poi/branches/hemf/jenkins/create_jobs.groovy
URL: http://svn.apache.org/viewvc/poi/branches/hemf/jenkins/create_jobs.groovy?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/jenkins/create_jobs.groovy (original)
+++ poi/branches/hemf/jenkins/create_jobs.groovy Sun Dec 16 16:51:08 2018
@@ -70,9 +70,7 @@ def poijobs = [
'-Djava.locale.providers=JRE,CLDR'],
skipcigame: true
],
- [ name: 'POI-DSL-IBM-JDK', jdk: 'IBMJDK', trigger: triggerSundays,
- // some OOXML tests fail with strange XML parsing errors and missing JCE unlimited strength requirements
- disabled: true, skipcigame: true
+ [ name: 'POI-DSL-IBM-JDK', jdk: 'IBMJDK', trigger: triggerSundays, skipcigame: true
],
[ name: 'POI-DSL-old-Xerces', trigger: triggerSundays,
shell: "test -f ${xercesLib} || wget -O ${xercesLib} ${xercesUrl}\n",
Modified: poi/branches/hemf/sonar/ooxml/pom.xml
URL: http://svn.apache.org/viewvc/poi/branches/hemf/sonar/ooxml/pom.xml?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/sonar/ooxml/pom.xml (original)
+++ poi/branches/hemf/sonar/ooxml/pom.xml Sun Dec 16 16:51:08 2018
@@ -185,5 +185,12 @@
<version>1.19</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <!-- don't add it to the distribution -->
+ <groupId>org.apache.xmlgraphics</groupId>
+ <artifactId>batik-all</artifactId>
+ <version>1.10</version>
+ </dependency>
</dependencies>
</project>
Modified: poi/branches/hemf/sonar/pom.xml
URL: http://svn.apache.org/viewvc/poi/branches/hemf/sonar/pom.xml?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/sonar/pom.xml (original)
+++ poi/branches/hemf/sonar/pom.xml Sun Dec 16 16:51:08 2018
@@ -268,9 +268,7 @@
</goals>
<configuration>
<target>
- <property name="xmlbean.sources.dir"
- location="${basedir}/target/generated-sources/xmlbeans"/>
-
+ <!-- the space between "public static" is on purpose to prevent double execution -->
<property name="loaderMethod"><![CDATA[
private static java.lang.ref.SoftReference<org.apache.xmlbeans.SchemaTypeLoader> typeLoader;
@@ -283,25 +281,26 @@
return stl;
}
- public static \2 newInstance\(\) \{]]></property>
+ public static \2 newInstance\(\) \{]]></property>
+
+ <fileset id="xsrc" dir="${basedir}/target/generated-sources/xmlbeans" includes="**/*.java" excludes="**/impl/**"/>
<replaceregexp byline="true"
match="(\s*)public static ([^ ]+) newInstance\(\) \{"
replace="${loaderMethod}">
- <fileset dir="${xmlbean.sources.dir}" includes="**/*.java"
- excludes="**/impl/**"/>
+ <fileset refid="xsrc"/>
</replaceregexp>
- <replace dir="${xmlbean.sources.dir}" includes="**/*.java"
- excludes="**/impl/**">
+ <replace>
+ <fileset refid="xsrc"/>
<replacetoken>org.apache.xmlbeans.XmlBeans.getContextTypeLoader
</replacetoken>
<replacevalue>getTypeLoader</replacevalue>
</replace>
<!-- remove deprecated warnings, as we prefer the array methods - see #56854 -->
- <replace dir="${xmlbean.sources.dir}" includes="**/*.java"
- excludes="**/impl/**">
+ <replace>
+ <fileset refid="xsrc"/>
<replacetoken><![CDATA[ * @deprecated
]]></replacetoken>
</replace>
Modified: poi/branches/hemf/src/integrationtest/org/apache/poi/TestAllFiles.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/integrationtest/org/apache/poi/TestAllFiles.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/integrationtest/org/apache/poi/TestAllFiles.java (original)
+++ poi/branches/hemf/src/integrationtest/org/apache/poi/TestAllFiles.java Sun Dec 16 16:51:08 2018
@@ -211,7 +211,13 @@ public class TestAllFiles {
HANDLERS.put("spreadsheet/BigSSTRecord2CR7", new NullFileHandler());
HANDLERS.put("spreadsheet/BigSSTRecordCR", new NullFileHandler());
HANDLERS.put("spreadsheet/test_properties1", new NullFileHandler());
-
+
+ // keystore files
+ HANDLERS.put(".pfx", new NullFileHandler());
+ HANDLERS.put(".pem", new NullFileHandler());
+ HANDLERS.put(".jks", new NullFileHandler());
+ HANDLERS.put(".pkcs12", new NullFileHandler());
+
Map<String,String> passmap = new HashMap<>();
passmap.put("slideshow/Password_Protected-hello.ppt", "hello");
passmap.put("slideshow/Password_Protected-56-hello.ppt", "hello");
Modified: poi/branches/hemf/src/java/org/apache/poi/sl/usermodel/PictureData.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/java/org/apache/poi/sl/usermodel/PictureData.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/java/org/apache/poi/sl/usermodel/PictureData.java (original)
+++ poi/branches/hemf/src/java/org/apache/poi/sl/usermodel/PictureData.java Sun Dec 16 16:51:08 2018
@@ -46,7 +46,10 @@ public interface PictureData {
/** WordPerfect graphics (.wpg) */
WPG(-1,12,"image/x-wpg",".wpg"),
/** Microsoft Windows Media Photo image (.wdp) */
- WDP(-1,13,"image/vnd.ms-photo",".wdp");
+ WDP(-1,13,"image/vnd.ms-photo",".wdp"),
+ /** Scalable vector graphics (.svg) - supported by Office 2016 and higher */
+ SVG(-1, -1, "image/svg+xml", ".svg")
+ ;
public final int nativeId, ooxmlId;
public final String contentType,extension;
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureConfig.java Sun Dec 16 16:51:08 2018
@@ -174,6 +174,13 @@ public class SignatureConfig {
*/
private boolean updateConfigOnValidate = false;
+ /**
+ * if true, the signature is added to the existing signatures
+ *
+ * @since POI 4.0.2
+ */
+ private boolean allowMultipleSignatures = false;
+
/**
* Inits and checks the config object.
@@ -1008,4 +1015,25 @@ public class SignatureConfig {
public void setUpdateConfigOnValidate(boolean updateConfigOnValidate) {
this.updateConfigOnValidate = updateConfigOnValidate;
}
+
+ /**
+ * @return true, if multiple signatures can be attached
+ *
+ * @since POI 4.0.2
+ */
+ public boolean isAllowMultipleSignatures() {
+ return allowMultipleSignatures;
+ }
+
+ /**
+ * Activate multiple signatures
+ *
+ * @param allowMultipleSignatures if true, the signature will be added,
+ * otherwise all existing signatures will be replaced by the current
+ *
+ * @since POI 4.0.2
+ */
+ public void setAllowMultipleSignatures(boolean allowMultipleSignatures) {
+ this.allowMultipleSignatures = allowMultipleSignatures;
+ }
}
\ No newline at end of file
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignatureInfo.java Sun Dec 16 16:51:08 2018
@@ -59,7 +59,6 @@ import org.apache.jcp.xml.dsig.internal.
import org.apache.jcp.xml.dsig.internal.dom.DOMSubTreeData;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
-import org.apache.poi.openxml4j.opc.ContentTypes;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
@@ -377,9 +376,8 @@ public class SignatureInfo implements Si
xmlSignContext.setURIDereferencer(uriDereferencer);
}
- for (Map.Entry<String,String> me : signatureConfig.getNamespacePrefixes().entrySet()) {
- xmlSignContext.putNamespacePrefix(me.getKey(), me.getValue());
- }
+ signatureConfig.getNamespacePrefixes().forEach(xmlSignContext::putNamespacePrefix);
+
xmlSignContext.setDefaultNamespacePrefix("");
// signatureConfig.getNamespacePrefixes().get(XML_DIGSIG_NS));
@@ -516,9 +514,7 @@ public class SignatureInfo implements Si
protected void writeDocument(Document document) throws MarshalException {
XmlOptions xo = new XmlOptions();
Map<String,String> namespaceMap = new HashMap<>();
- for(Map.Entry<String,String> entry : signatureConfig.getNamespacePrefixes().entrySet()){
- namespaceMap.put(entry.getValue(), entry.getKey());
- }
+ signatureConfig.getNamespacePrefixes().forEach((k,v) -> namespaceMap.put(v,k));
xo.setSaveSuggestedPrefixes(namespaceMap);
xo.setUseDefaultNamespace();
@@ -530,43 +526,58 @@ public class SignatureInfo implements Si
*/
OPCPackage pkg = signatureConfig.getOpcPackage();
- PackagePartName sigPartName, sigsPartName;
try {
- // <Override PartName="/_xmlsignatures/sig1.xml" ContentType="application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"/>
- sigPartName = PackagingURIHelper.createPartName("/_xmlsignatures/sig1.xml");
// <Default Extension="sigs" ContentType="application/vnd.openxmlformats-package.digital-signature-origin"/>
- sigsPartName = PackagingURIHelper.createPartName("/_xmlsignatures/origin.sigs");
- } catch (InvalidFormatException e) {
- throw new MarshalException(e);
- }
+ final DSigRelation originDesc = DSigRelation.ORIGIN_SIGS;
+ PackagePartName originPartName = PackagingURIHelper.createPartName(originDesc.getFileName(0));
- PackagePart sigPart = pkg.getPart(sigPartName);
- if (sigPart == null) {
- sigPart = pkg.createPart(sigPartName, ContentTypes.DIGITAL_SIGNATURE_XML_SIGNATURE_PART);
- }
+ PackagePart originPart = pkg.getPart(originPartName);
+ if (originPart == null) {
+ // touch empty marker file
+ originPart = pkg.createPart(originPartName, originDesc.getContentType());
+ pkg.addRelationship(originPartName, TargetMode.INTERNAL, originDesc.getRelation());
+ }
- try {
- OutputStream os = sigPart.getOutputStream();
- SignatureDocument sigDoc = SignatureDocument.Factory.parse(document, DEFAULT_XML_OPTIONS);
- sigDoc.save(os, xo);
- os.close();
- } catch (Exception e) {
- throw new MarshalException("Unable to write signature document", e);
- }
+ // <Override PartName="/_xmlsignatures/sig1.xml" ContentType="application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"/>
+ final DSigRelation sigDesc = DSigRelation.SIG;
+ int nextSigIdx = pkg.getUnusedPartIndex(sigDesc.getDefaultFileName());
- PackagePart sigsPart = pkg.getPart(sigsPartName);
- if (sigsPart == null) {
- // touch empty marker file
- sigsPart = pkg.createPart(sigsPartName, ContentTypes.DIGITAL_SIGNATURE_ORIGIN_PART);
- }
+ if (!signatureConfig.isAllowMultipleSignatures()) {
+ PackageRelationshipCollection prc = originPart.getRelationshipsByType(sigDesc.getRelation());
+ for (int i=2; i<nextSigIdx; i++) {
+ PackagePartName pn = PackagingURIHelper.createPartName(sigDesc.getFileName(i));
+ for (PackageRelationship rel : prc) {
+ PackagePart pp = originPart.getRelatedPart(rel);
+ if (pp.getPartName().equals(pn)) {
+ originPart.removeRelationship(rel.getId());
+ prc.removeRelationship(rel.getId());
+ break;
+ }
+ }
+
+ pkg.removePart(pkg.getPart(pn));
+ }
+ nextSigIdx = 1;
+ }
- PackageRelationshipCollection relCol = pkg.getRelationshipsByType(PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
- for (PackageRelationship pr : relCol) {
- pkg.removeRelationship(pr.getId());
- }
- pkg.addRelationship(sigsPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE_ORIGIN);
- sigsPart.addRelationship(sigPartName, TargetMode.INTERNAL, PackageRelationshipTypes.DIGITAL_SIGNATURE);
+ PackagePartName sigPartName = PackagingURIHelper.createPartName(sigDesc.getFileName(nextSigIdx));
+ PackagePart sigPart = pkg.getPart(sigPartName);
+ if (sigPart == null) {
+ sigPart = pkg.createPart(sigPartName, sigDesc.getContentType());
+ originPart.addRelationship(sigPartName, TargetMode.INTERNAL, sigDesc.getRelation());
+ } else {
+ sigPart.clear();
+ }
+
+ try (OutputStream os = sigPart.getOutputStream()) {
+ SignatureDocument sigDoc = SignatureDocument.Factory.parse(document, DEFAULT_XML_OPTIONS);
+ sigDoc.save(os, xo);
+ }
+
+ } catch (Exception e) {
+ throw new MarshalException("Unable to write signature document", e);
+ }
}
private Element getDsigElement(final Document document, final String localName) {
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/SignaturePart.java Sun Dec 16 16:51:08 2018
@@ -185,9 +185,7 @@ public class SignaturePart {
final Map<String,String> nsMap = new HashMap<>();
{
- for (Map.Entry<String,String> me : signatureConfig.getNamespacePrefixes().entrySet()) {
- nsMap.put(me.getValue(), me.getKey());
- }
+ signatureConfig.getNamespacePrefixes().forEach((k,v) -> nsMap.put(v,k));
nsMap.put("dsss", MS_DIGSIG_NS);
nsMap.put("ds", XML_DIGSIG_NS);
}
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/poifs/crypt/dsig/facets/KeyInfoSignatureFacet.java Sun Dec 16 16:51:08 2018
@@ -129,10 +129,8 @@ public class KeyInfoSignatureFacet exten
DOMSignContext domSignContext = (nextSibling == null)
? new DOMSignContext(key, n)
: new DOMSignContext(key, n, nextSibling);
- for (Map.Entry<String,String> me : signatureConfig.getNamespacePrefixes().entrySet()) {
- domSignContext.putNamespacePrefix(me.getKey(), me.getValue());
- }
-
+ signatureConfig.getNamespacePrefixes().forEach(domSignContext::putNamespacePrefix);
+
DOMStructure domStructure = new DOMStructure(n);
domKeyInfo.marshal(domStructure, domSignContext);
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureData.java Sun Dec 16 16:51:08 2018
@@ -218,6 +218,8 @@ public final class XSLFPictureData exten
return PictureType.WDP;
} else if (XSLFRelation.IMAGE_TIFF.getContentType().equals(ct)) {
return PictureType.TIFF;
+ } else if (XSLFRelation.IMAGE_SVG.getContentType().equals(ct)) {
+ return PictureType.SVG;
} else {
return null;
}
@@ -237,6 +239,7 @@ public final class XSLFPictureData exten
case WPG: return XSLFRelation.IMAGE_WPG;
case WDP: return XSLFRelation.IMAGE_WDP;
case TIFF: return XSLFRelation.IMAGE_TIFF;
+ case SVG: return XSLFRelation.IMAGE_SVG;
default: return null;
}
}
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFPictureShape.java Sun Dec 16 16:51:08 2018
@@ -19,18 +19,31 @@
package org.apache.poi.xslf.usermodel;
+import static org.apache.poi.openxml4j.opc.PackageRelationshipTypes.CORE_PROPERTIES_ECMA376_NS;
+
+import java.awt.Dimension;
import java.awt.Insets;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URI;
+import javax.imageio.ImageIO;
import javax.xml.namespace.QName;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.PictureShape;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
+import org.apache.poi.util.Units;
+import org.apache.poi.xslf.draw.SVGImageRenderer;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
@@ -55,6 +68,11 @@ public class XSLFPictureShape extends XS
implements PictureShape<XSLFShape,XSLFTextParagraph> {
private static final POILogger LOG = POILogFactory.getLogger(XSLFPictureShape.class);
+ private static final String DML_NS = "http://schemas.microsoft.com/office/drawing/2010/main";
+ private static final String SVG_NS = "http://schemas.microsoft.com/office/drawing/2016/SVG/main";
+ private static final String BITMAP_URI = "{28A0092B-C50C-407E-A947-70E740481C1C}";
+ private static final String SVG_URI = "{96DAC541-7B7A-43D3-8B79-37D633B846F1}";
+
private XSLFPictureData _data;
/*package*/ XSLFPictureShape(CTPicture shape, XSLFSheet sheet) {
@@ -196,6 +214,97 @@ public class XSLFPictureShape extends XS
return (r == null) ? null : new Insets(r.getT(), r.getL(), r.getB(), r.getR());
}
+ /**
+ * Add a SVG image reference
+ * @param svgPic a previously imported svg image
+ */
+ public void setSvgImage(XSLFPictureData svgPic) {
+ CTBlip blip = getBlip();
+ CTOfficeArtExtensionList extLst = blip.isSetExtLst() ? blip.getExtLst() : blip.addNewExtLst();
+
+ final int bitmapId = getExt(extLst, BITMAP_URI);
+ CTOfficeArtExtension extBitmap;
+ if (bitmapId == -1) {
+ extBitmap = extLst.addNewExt();
+ extBitmap.setUri(BITMAP_URI);
+ XmlCursor cur = extBitmap.newCursor();
+ cur.toEndToken();
+ cur.beginElement(new QName(DML_NS, "useLocalDpi", "a14"));
+ cur.insertNamespace("a14", DML_NS);
+ cur.insertAttributeWithValue("val", "0");
+ cur.dispose();
+ }
+
+ final int svgId = getExt(extLst, SVG_URI);;
+ if (svgId != -1) {
+ extLst.removeExt(svgId);
+ }
+
+ String svgRelId = getSheet().getRelationId(svgPic);
+ if (svgRelId == null) {
+ svgRelId = getSheet().addRelation(null, XSLFRelation.IMAGE_SVG, svgPic).getRelationship().getId();
+ }
+
+ CTOfficeArtExtension svgBitmap = extLst.addNewExt();
+ svgBitmap.setUri(SVG_URI);
+ XmlCursor cur = svgBitmap.newCursor();
+ cur.toEndToken();
+ cur.beginElement(new QName(SVG_NS, "svgBlip", "asvg"));
+ cur.insertNamespace("asvg", SVG_NS);
+ cur.insertAttributeWithValue(new QName(CORE_PROPERTIES_ECMA376_NS, "embed", "rel"), svgRelId);
+ cur.dispose();
+ }
+
+ /**
+ * Convienence method for adding SVG images, which generates the preview image
+ * @param sheet the sheet to add
+ * @param svgPic the svg picture to add
+ * @param previewType the preview picture type or null (defaults to PNG) - currently only JPEG,GIF,PNG are allowed
+ * @param anchor the image anchor (for calculating the preview image size) or
+ * null (the preview size is taken from the svg picture bounds)
+ */
+ public static XSLFPictureShape addSvgImage(XSLFSheet sheet, XSLFPictureData svgPic, PictureType previewType, Rectangle2D anchor) throws IOException {
+
+ SVGImageRenderer renderer = new SVGImageRenderer();
+ try (InputStream is = svgPic.getInputStream()) {
+ renderer.loadImage(is, svgPic.getType().contentType);
+ }
+
+ Dimension dim = renderer.getDimension();
+ Rectangle2D anc = (anchor != null) ? anchor
+ : new Rectangle2D.Double(0,0, Units.pixelToPoints((int)dim.getWidth()), Units.pixelToPoints((int)dim.getHeight()));
+
+ PictureType pt = (previewType != null) ? previewType : PictureType.PNG;
+ if (pt != PictureType.JPEG || pt != PictureType.GIF || pt != PictureType.PNG) {
+ pt = PictureType.PNG;
+ }
+
+ BufferedImage thmBI = renderer.getImage(dim);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(100000);
+ // use extension instead of enum name, because of "jpeg"
+ ImageIO.write(thmBI, pt.extension.substring(1), bos);
+
+ XSLFPictureData pngPic = sheet.getSlideShow().addPicture(new ByteArrayInputStream(bos.toByteArray()), pt);
+
+ XSLFPictureShape shape = sheet.createPicture(pngPic);
+ shape.setAnchor(anc);
+ shape.setSvgImage(svgPic);
+ return shape;
+ }
+
+
+ private int getExt(CTOfficeArtExtensionList extLst, String uri) {
+ final int size = extLst.sizeOfExtArray();
+ for (int i=0; i<size; i++) {
+ CTOfficeArtExtension ext = extLst.getExtArray(i);
+ if (uri.equals(ext.getUri())) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+
@Override
void copy(XSLFShape sh){
super.copy(sh);
@@ -219,11 +328,11 @@ public class XSLFPictureShape extends XS
nvPr.unsetCustDataLst();
}
if(blip.isSetExtLst()) {
-
+ // TODO: check for SVG copying
CTOfficeArtExtensionList extLst = blip.getExtLst();
//noinspection deprecation
for(CTOfficeArtExtension ext : extLst.getExtArray()){
- String xpath = "declare namespace a14='http://schemas.microsoft.com/office/drawing/2010/main' $this//a14:imgProps/a14:imgLayer";
+ String xpath = "declare namespace a14='"+ DML_NS +"' $this//a14:imgProps/a14:imgLayer";
XmlObject[] obj = ext.selectPath(xpath);
if(obj != null && obj.length == 1){
XmlCursor c = obj[0].newCursor();
@@ -234,6 +343,5 @@ public class XSLFPictureShape extends XS
}
}
}
-
}
}
\ No newline at end of file
Modified: poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java (original)
+++ poi/branches/hemf/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRelation.java Sun Dec 16 16:51:08 2018
@@ -16,6 +16,8 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
+import static org.apache.poi.openxml4j.opc.PackageRelationshipTypes.IMAGE_PART;
+
import java.util.HashMap;
import java.util.Map;
@@ -159,80 +161,87 @@ public final class XSLFRelation extends
public static final XSLFRelation IMAGE_EMF = new XSLFRelation(
PictureType.EMF.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.emf",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_WMF = new XSLFRelation(
PictureType.WMF.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.wmf",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_PICT = new XSLFRelation(
PictureType.PICT.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.pict",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_JPEG = new XSLFRelation(
PictureType.JPEG.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.jpeg",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_PNG = new XSLFRelation(
PictureType.PNG.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.png",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_DIB = new XSLFRelation(
PictureType.DIB.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.dib",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_GIF = new XSLFRelation(
PictureType.GIF.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.gif",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_TIFF = new XSLFRelation(
PictureType.TIFF.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.tiff",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_EPS = new XSLFRelation(
PictureType.EPS.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.eps",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_BMP = new XSLFRelation(
PictureType.BMP.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.bmp",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_WPG = new XSLFRelation(
PictureType.WPG.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.wpg",
XSLFPictureData.class
);
public static final XSLFRelation IMAGE_WDP = new XSLFRelation(
PictureType.WDP.contentType,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
"/ppt/media/image#.wdp",
XSLFPictureData.class
);
+ public static final XSLFRelation IMAGE_SVG = new XSLFRelation(
+ PictureType.SVG.contentType,
+ IMAGE_PART,
+ "/ppt/media/image#.svg",
+ XSLFPictureData.class
+ );
+
public static final XSLFRelation IMAGES = new XSLFRelation(
null,
- "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+ IMAGE_PART,
null,
XSLFPictureData.class
);
Modified: poi/branches/hemf/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java (original)
+++ poi/branches/hemf/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestSignatureInfo.java Sun Dec 16 16:51:08 2018
@@ -29,6 +29,7 @@ import static org.junit.Assert.assertNot
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -36,19 +37,30 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.OutputStream;
+import java.math.BigInteger;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyPair;
+import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.cert.CRLException;
import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAKeyGenParameterSpec;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
@@ -56,7 +68,9 @@ import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import javax.xml.crypto.MarshalException;
import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import org.apache.jcp.xml.dsig.internal.dom.DOMSignedInfo;
@@ -90,8 +104,53 @@ import org.apache.poi.xssf.streaming.SXS
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.SystemProperties;
import org.apache.xmlbeans.XmlObject;
+import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x500.X500Name;
+import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
+import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.bouncycastle.asn1.x509.BasicConstraints;
+import org.bouncycastle.asn1.x509.CRLNumber;
+import org.bouncycastle.asn1.x509.CRLReason;
+import org.bouncycastle.asn1.x509.DistributionPoint;
+import org.bouncycastle.asn1.x509.DistributionPointName;
+import org.bouncycastle.asn1.x509.Extension;
+import org.bouncycastle.asn1.x509.Extensions;
+import org.bouncycastle.asn1.x509.GeneralName;
+import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyUsage;
+import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
+import org.bouncycastle.cert.X509CRLHolder;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.cert.X509ExtensionUtils;
+import org.bouncycastle.cert.X509v2CRLBuilder;
+import org.bouncycastle.cert.X509v3CertificateBuilder;
+import org.bouncycastle.cert.jcajce.JcaX509CRLConverter;
+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
+import org.bouncycastle.cert.ocsp.BasicOCSPResp;
+import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.CertificateID;
+import org.bouncycastle.cert.ocsp.CertificateStatus;
+import org.bouncycastle.cert.ocsp.OCSPReq;
+import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
import org.bouncycastle.cert.ocsp.OCSPResp;
+import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
+import org.bouncycastle.cert.ocsp.Req;
+import org.bouncycastle.cert.ocsp.RevokedStatus;
+import org.bouncycastle.crypto.params.RSAKeyParameters;
+import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.operator.ContentSigner;
+import org.bouncycastle.operator.DigestCalculator;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.etsi.uri.x01903.v13.DigestAlgAndValueType;
import org.etsi.uri.x01903.v13.QualifyingPropertiesType;
import org.junit.AfterClass;
@@ -408,7 +467,7 @@ public class TestSignatureInfo {
try (OPCPackage pkg = OPCPackage.open(copy(sigCopy), PackageAccess.READ_WRITE)) {
initKeyPair("Test", "CN=Test");
- final X509CRL crl = PkiTestUtils.generateCrl(x509, keyPair.getPrivate());
+ final X509CRL crl = generateCrl(x509, keyPair.getPrivate());
// setup
SignatureConfig signatureConfig = new SignatureConfig();
@@ -481,7 +540,7 @@ public class TestSignatureInfo {
final RevocationData revocationData = new RevocationData();
revocationData.addCRL(crl);
- OCSPResp ocspResp = PkiTestUtils.createOcspResp(x509, false,
+ OCSPResp ocspResp = createOcspResp(x509, false,
x509, x509, keyPair.getPrivate(), "SHA1withRSA", cal.getTimeInMillis());
revocationData.addOCSP(ocspResp.getEncoded());
@@ -721,20 +780,86 @@ public class TestSignatureInfo {
@Test
public void testMultiSign() throws Exception {
- initKeyPair("KeyA", "CN=KeyA");
- //KeyPair keyPairA = keyPair;
- //X509Certificate x509A = x509;
- initKeyPair("KeyB", "CN=KeyB");
- //KeyPair keyPairB = keyPair;
- //X509Certificate x509B = x509;
-
- File tpl = copy(testdata.getFile("bug58630.xlsx"));
+ cal = LocaleUtil.getLocaleCalendar(LocaleUtil.TIMEZONE_UTC);
+ cal.clear();
+ cal.setTimeZone(LocaleUtil.TIMEZONE_UTC);
+ cal.set(2018, Calendar.DECEMBER, 14);
+
+ // test signing with separate opened packages
+ File tpl = copy(testdata.getFile("hello-world-unsigned.xlsx"));
+ try (OPCPackage pkg = OPCPackage.open(tpl)) {
+ signPkg63011(pkg, "bug63011_key1.pem", true);
+ }
+
+ try (OPCPackage pkg = OPCPackage.open(tpl)) {
+ signPkg63011(pkg, "bug63011_key2.pem", true);
+ }
+
+ verifyPkg63011(tpl, true);
+
+ // test signing with single opened package
+ tpl = copy(testdata.getFile("hello-world-unsigned.xlsx"));
try (OPCPackage pkg = OPCPackage.open(tpl)) {
- //SignatureConfig signatureConfig = new SignatureConfig();
- assertNotNull(pkg);
+ signPkg63011(pkg, "bug63011_key1.pem", true);
+ signPkg63011(pkg, "bug63011_key2.pem", true);
+ }
+
+ verifyPkg63011(tpl, true);
+
+ try (OPCPackage pkg = OPCPackage.open(tpl)) {
+ signPkg63011(pkg, "bug63011_key1.pem", true);
+ signPkg63011(pkg, "bug63011_key2.pem", false);
+ }
+
+ verifyPkg63011(tpl, false);
+ }
+
+ private void verifyPkg63011(File tpl, boolean multi) throws InvalidFormatException, IOException {
+ try (OPCPackage pkg = OPCPackage.open(tpl, PackageAccess.READ)) {
+ SignatureConfig sic = new SignatureConfig();
+ sic.setOpcPackage(pkg);
+ SignatureInfo si = new SignatureInfo();
+ si.setSignatureConfig(sic);
+ List<X509Certificate> result = new ArrayList<>();
+ for (SignaturePart sp : si.getSignatureParts()) {
+ if (sp.validate()) {
+ result.add(sp.getSigner());
+ }
+ }
+
+ assertNotNull(result);
+
+ if (multi) {
+ assertEquals(2, result.size());
+ assertEquals("CN=Muj Klic", result.get(0).getSubjectDN().toString());
+ assertEquals("CN=My Second key", result.get(1).getSubjectDN().toString());
+ } else {
+ assertEquals(1, result.size());
+ assertEquals("CN=My Second key", result.get(0).getSubjectDN().toString());
+ }
+
+ assertTrue(si.verifySignature());
+ pkg.revert();
}
}
+ private void signPkg63011(OPCPackage pkg, String pemFile, boolean multi)
+ throws IOException, CertificateException, XMLSignatureException, MarshalException {
+ assertNotNull(pkg);
+ initKeyFromPEM(testdata.getFile(pemFile));
+
+ SignatureConfig config = new SignatureConfig();
+ config.setKey(keyPair.getPrivate());
+ config.setSigningCertificateChain(Collections.singletonList(x509));
+ config.setExecutionTime(cal.getTime());
+ config.setAllowMultipleSignatures(multi);
+ config.setOpcPackage(pkg);
+
+ SignatureInfo si = new SignatureInfo();
+ si.setSignatureConfig(config);
+ si.confirmSignature();
+ }
+
@Test
public void testRetrieveCertificate() throws InvalidFormatException, IOException {
SignatureConfig sic = new SignatureConfig();
@@ -829,14 +954,14 @@ public class TestSignatureInfo {
x509 = (X509Certificate)keystore.getCertificate(alias);
keyPair = new KeyPair(x509.getPublicKey(), (PrivateKey)key);
} else {
- keyPair = PkiTestUtils.generateKeyPair();
+ keyPair = generateKeyPair();
Date notBefore = cal.getTime();
Calendar cal2 = (Calendar)cal.clone();
cal2.add(Calendar.YEAR, 1);
Date notAfter = cal2.getTime();
KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature);
- x509 = PkiTestUtils.generateCertificate(keyPair.getPublic(), subjectDN
+ x509 = generateCertificate(keyPair.getPublic(), subjectDN
, notBefore, notAfter, null, keyPair.getPrivate(), true, 0, null, null, keyUsage);
keystore.setKeyEntry(alias, keyPair.getPrivate(), password, new Certificate[]{x509});
@@ -849,6 +974,27 @@ public class TestSignatureInfo {
}
}
+ private void initKeyFromPEM(File pemFile) throws IOException, CertificateException {
+ // see https://stackoverflow.com/questions/11787571/how-to-read-pem-file-to-get-private-and-public-key
+ PrivateKey key = null;
+ x509 = null;
+
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(pemFile), StandardCharsets.ISO_8859_1))) {
+ PEMParser parser = new PEMParser(br);
+ for (Object obj; (obj = parser.readObject()) != null; ) {
+ if (obj instanceof PrivateKeyInfo) {
+ key = new JcaPEMKeyConverter().setProvider("BC").getPrivateKey((PrivateKeyInfo)obj);
+ } else if (obj instanceof X509CertificateHolder) {
+ x509 = new JcaX509CertificateConverter().setProvider("BC").getCertificate((X509CertificateHolder)obj);
+ }
+ }
+ }
+
+ if (key != null && x509 != null) {
+ keyPair = new KeyPair(x509.getPublicKey(), key);
+ }
+ }
+
private static File copy(File input) throws IOException {
String extension = input.getName().replaceAll(".*?(\\.[^.]+)?$", "$1");
if (extension == null || extension.isEmpty()) {
@@ -872,4 +1018,187 @@ public class TestSignatureInfo {
return tmpFile;
}
+ private static KeyPair generateKeyPair() throws Exception {
+ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+ SecureRandom random = new SecureRandom();
+ keyPairGenerator.initialize(new RSAKeyGenParameterSpec(1024,
+ RSAKeyGenParameterSpec.F4), random);
+ return keyPairGenerator.generateKeyPair();
+ }
+
+ private static X509Certificate generateCertificate(PublicKey subjectPublicKey,
+ String subjectDn, Date notBefore, Date notAfter,
+ X509Certificate issuerCertificate, PrivateKey issuerPrivateKey,
+ boolean caFlag, int pathLength, String crlUri, String ocspUri,
+ KeyUsage keyUsage)
+ throws IOException, OperatorCreationException, CertificateException
+ {
+ String signatureAlgorithm = "SHA1withRSA";
+ X500Name issuerName;
+ if (issuerCertificate != null) {
+ issuerName = new X509CertificateHolder(issuerCertificate.getEncoded()).getIssuer();
+ } else {
+ issuerName = new X500Name(subjectDn);
+ }
+
+ RSAPublicKey rsaPubKey = (RSAPublicKey)subjectPublicKey;
+ RSAKeyParameters rsaSpec = new RSAKeyParameters(false, rsaPubKey.getModulus(), rsaPubKey.getPublicExponent());
+
+ SubjectPublicKeyInfo subjectPublicKeyInfo =
+ SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(rsaSpec);
+
+ DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()
+ .setProvider("BC").build().get(CertificateID.HASH_SHA1);
+
+ X509v3CertificateBuilder certificateGenerator = new X509v3CertificateBuilder(
+ issuerName
+ , new BigInteger(128, new SecureRandom())
+ , notBefore
+ , notAfter
+ , new X500Name(subjectDn)
+ , subjectPublicKeyInfo
+ );
+
+ X509ExtensionUtils exUtils = new X509ExtensionUtils(digestCalc);
+ SubjectKeyIdentifier subKeyId = exUtils.createSubjectKeyIdentifier(subjectPublicKeyInfo);
+ AuthorityKeyIdentifier autKeyId = (issuerCertificate != null)
+ ? exUtils.createAuthorityKeyIdentifier(new X509CertificateHolder(issuerCertificate.getEncoded()))
+ : exUtils.createAuthorityKeyIdentifier(subjectPublicKeyInfo);
+
+ certificateGenerator.addExtension(Extension.subjectKeyIdentifier, false, subKeyId);
+ certificateGenerator.addExtension(Extension.authorityKeyIdentifier, false, autKeyId);
+
+ if (caFlag) {
+ BasicConstraints bc;
+
+ if (-1 == pathLength) {
+ bc = new BasicConstraints(true);
+ } else {
+ bc = new BasicConstraints(pathLength);
+ }
+ certificateGenerator.addExtension(Extension.basicConstraints, false, bc);
+ }
+
+ if (null != crlUri) {
+ int uri = GeneralName.uniformResourceIdentifier;
+ DERIA5String crlUriDer = new DERIA5String(crlUri);
+ GeneralName gn = new GeneralName(uri, crlUriDer);
+
+ DERSequence gnDer = new DERSequence(gn);
+ GeneralNames gns = GeneralNames.getInstance(gnDer);
+
+ DistributionPointName dpn = new DistributionPointName(0, gns);
+ DistributionPoint distp = new DistributionPoint(dpn, null, null);
+ DERSequence distpDer = new DERSequence(distp);
+ certificateGenerator.addExtension(Extension.cRLDistributionPoints, false, distpDer);
+ }
+
+ if (null != ocspUri) {
+ int uri = GeneralName.uniformResourceIdentifier;
+ GeneralName ocspName = new GeneralName(uri, ocspUri);
+
+ AuthorityInformationAccess authorityInformationAccess =
+ new AuthorityInformationAccess(X509ObjectIdentifiers.ocspAccessMethod, ocspName);
+
+ certificateGenerator.addExtension(Extension.authorityInfoAccess, false, authorityInformationAccess);
+ }
+
+ if (null != keyUsage) {
+ certificateGenerator.addExtension(Extension.keyUsage, true, keyUsage);
+ }
+
+ JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(signatureAlgorithm);
+ signerBuilder.setProvider("BC");
+
+ X509CertificateHolder certHolder =
+ certificateGenerator.build(signerBuilder.build(issuerPrivateKey));
+
+ /*
+ * Next certificate factory trick is needed to make sure that the
+ * certificate delivered to the caller is provided by the default
+ * security provider instead of BouncyCastle. If we don't do this trick
+ * we might run into trouble when trying to use the CertPath validator.
+ */
+// CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+// certificate = (X509Certificate) certificateFactory
+// .generateCertificate(new ByteArrayInputStream(certificate
+// .getEncoded()));
+ return new JcaX509CertificateConverter().getCertificate(certHolder);
+ }
+
+ private static X509CRL generateCrl(X509Certificate issuer, PrivateKey issuerPrivateKey)
+ throws CertificateEncodingException, IOException, CRLException, OperatorCreationException {
+
+ X509CertificateHolder holder = new X509CertificateHolder(issuer.getEncoded());
+ X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(holder.getIssuer(), new Date());
+ crlBuilder.setNextUpdate(new Date(new Date().getTime() + 100000));
+ JcaContentSignerBuilder contentBuilder = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC");
+
+ CRLNumber crlNumber = new CRLNumber(new BigInteger("1234"));
+
+ crlBuilder.addExtension(Extension.cRLNumber, false, crlNumber);
+ X509CRLHolder x509Crl = crlBuilder.build(contentBuilder.build(issuerPrivateKey));
+ return new JcaX509CRLConverter().setProvider("BC").getCRL(x509Crl);
+ }
+
+ private static OCSPResp createOcspResp(X509Certificate certificate,
+ boolean revoked, X509Certificate issuerCertificate,
+ X509Certificate ocspResponderCertificate,
+ PrivateKey ocspResponderPrivateKey, String signatureAlgorithm,
+ long nonceTimeinMillis)
+ throws Exception {
+ DigestCalculator digestCalc = new JcaDigestCalculatorProviderBuilder()
+ .setProvider("BC").build().get(CertificateID.HASH_SHA1);
+ X509CertificateHolder issuerHolder = new X509CertificateHolder(issuerCertificate.getEncoded());
+ CertificateID certId = new CertificateID(digestCalc, issuerHolder, certificate.getSerialNumber());
+
+ // request
+ //create a nonce to avoid replay attack
+ BigInteger nonce = BigInteger.valueOf(nonceTimeinMillis);
+ DEROctetString nonceDer = new DEROctetString(nonce.toByteArray());
+ Extension ext = new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, true, nonceDer);
+ Extensions exts = new Extensions(ext);
+
+ OCSPReqBuilder ocspReqBuilder = new OCSPReqBuilder();
+ ocspReqBuilder.addRequest(certId);
+ ocspReqBuilder.setRequestExtensions(exts);
+ OCSPReq ocspReq = ocspReqBuilder.build();
+
+
+ SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo
+ (CertificateID.HASH_SHA1, ocspResponderCertificate.getPublicKey().getEncoded());
+
+ BasicOCSPRespBuilder basicOCSPRespBuilder = new BasicOCSPRespBuilder(keyInfo, digestCalc);
+ basicOCSPRespBuilder.setResponseExtensions(exts);
+
+ // request processing
+ Req[] requestList = ocspReq.getRequestList();
+ for (Req ocspRequest : requestList) {
+ CertificateID certificateID = ocspRequest.getCertID();
+ CertificateStatus certificateStatus = CertificateStatus.GOOD;
+ if (revoked) {
+ certificateStatus = new RevokedStatus(new Date(), CRLReason.privilegeWithdrawn);
+ }
+ basicOCSPRespBuilder.addResponse(certificateID, certificateStatus);
+ }
+
+ // basic response generation
+ X509CertificateHolder[] chain = null;
+ if (!ocspResponderCertificate.equals(issuerCertificate)) {
+ // TODO: HorribleProxy can't convert array input params yet
+ chain = new X509CertificateHolder[] {
+ new X509CertificateHolder(ocspResponderCertificate.getEncoded()),
+ issuerHolder
+ };
+ }
+
+ ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA")
+ .setProvider("BC").build(ocspResponderPrivateKey);
+ BasicOCSPResp basicOCSPResp = basicOCSPRespBuilder.build(contentSigner, chain, new Date(nonceTimeinMillis));
+
+
+ OCSPRespBuilder ocspRespBuilder = new OCSPRespBuilder();
+
+ return ocspRespBuilder.build(OCSPRespBuilder.SUCCESSFUL, basicOCSPResp);
+ }
}
Modified: poi/branches/hemf/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
URL: http://svn.apache.org/viewvc/poi/branches/hemf/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java?rev=1849036&r1=1849035&r2=1849036&view=diff
==============================================================================
--- poi/branches/hemf/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java (original)
+++ poi/branches/hemf/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java Sun Dec 16 16:51:08 2018
@@ -16,14 +16,17 @@
==================================================================== */
package org.apache.poi.xslf.usermodel;
+import static org.apache.poi.POIDataSamples.TEST_PROPERTY;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import java.awt.geom.Rectangle2D;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@@ -247,4 +250,24 @@ public class TestXSLFPictureShape {
slideShow.close();
}
+
+
+ @Test
+ public void renderSvgImage() throws Exception {
+ String dataDirName = System.getProperty(TEST_PROPERTY);
+ final String SVG_FILE = (dataDirName != null ? "../" : "") + "src/documentation/resources/images/project-header.svg";
+ XMLSlideShow ppt = new XMLSlideShow();
+ XSLFSlide slide = ppt.createSlide();
+
+ XSLFPictureData svgPic = ppt.addPicture(new File(dataDirName, SVG_FILE), PictureType.SVG);
+ XSLFPictureShape shape = XSLFPictureShape.addSvgImage(slide, svgPic, PictureType.JPEG, null);
+
+ Rectangle2D anchor = shape.getAnchor();
+ anchor.setRect(100, 100, anchor.getWidth(), anchor.getHeight());
+ shape.setAnchor(anchor);
+
+// try (FileOutputStream fos = new FileOutputStream("svgtest.pptx")) {
+// ppt.write(fos);
+// }
+ }
}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org