diff options
author | Jihoon Song <jihoon80.song@samsung.com> | 2014-04-23 10:31:34 +0900 |
---|---|---|
committer | Taeyoung Son <taeyoung2.son@samsung.com> | 2014-04-23 11:02:30 +0900 |
commit | f2346398d554839e9b2bed7535b1db230e00f2d3 (patch) | |
tree | 1ebbf307ff30c79cdbb70fabcf994bf1ee8b77cb | |
parent | 877e058adbb89eeb563923e479ef2ee1aaf39a00 (diff) | |
download | common-eplugin-f2346398d554839e9b2bed7535b1db230e00f2d3.tar.gz common-eplugin-f2346398d554839e9b2bed7535b1db230e00f2d3.tar.bz2 common-eplugin-f2346398d554839e9b2bed7535b1db230e00f2d3.zip |
SIGN: Supported InputStream resources and real path mode
Change-Id: I47e1d4ba7a65cffb0b2cf3db3cc59a015bb03d16
Signed-off-by: Jihoon Song <jihoon80.song@samsung.com>
-rw-r--r-- | org.tizen.common.sign/src/org/tizen/common/sign/model/ResolverCustomResource.java (renamed from org.tizen.common.sign/src/org/tizen/common/sign/model/ResolverInputStream.java) | 72 | ||||
-rw-r--r-- | org.tizen.common.sign/src/org/tizen/common/sign/signer/TizenIncrementalSigner.java | 90 | ||||
-rw-r--r-- | org.tizen.common.sign/test/src/org/tizen/common/sign/TizenIncrementalSignerTest.java | 84 |
3 files changed, 202 insertions, 44 deletions
diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/model/ResolverInputStream.java b/org.tizen.common.sign/src/org/tizen/common/sign/model/ResolverCustomResource.java index 74afce51b..5801cb998 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/model/ResolverInputStream.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/model/ResolverCustomResource.java @@ -31,7 +31,9 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.xml.security.signature.XMLSignatureInput; @@ -43,21 +45,18 @@ import org.tizen.common.util.Assert; import org.tizen.common.util.IOUtil; import org.w3c.dom.Attr; -public class ResolverInputStream extends ResolverLocalFilesystem { +public class ResolverCustomResource extends ResolverLocalFilesystem { protected final Logger logger = getLogger( getClass() ); - protected final Map<String, InputStream> isMap; + protected final Map<String, InputStream> isMap; // InputStream map + protected final Map<String, String> realPathMap; // Real path map protected InputStream authorSignatureXML; // for author signature - public ResolverInputStream() { - this( new HashMap<String, InputStream>() ); - } - - public ResolverInputStream(Map<String, InputStream> isMap) { - Assert.notNull( isMap ); - this.isMap = isMap; + public ResolverCustomResource() { + this.isMap = new HashMap<String, InputStream>(); + this.realPathMap = new HashMap<String, String>(); } /** @@ -76,13 +75,50 @@ public class ResolverInputStream extends ResolverLocalFilesystem { Assert.notNull( uri ); Assert.notNull( is ); - return isMap.put( uri, is ); + return this.isMap.put( uri, is ); + } + + public InputStream[] addInputStreams(Map<String, InputStream> isMap) { + List<InputStream> list = new ArrayList<InputStream>(); + + if ( isMap != null ) { + for( String key : isMap.keySet() ) { + list.add( addInputStream( key, isMap.get( key ) ) ); + } + } + + return list.toArray( new InputStream[0] ); } public InputStream removeInputStream(String uri) { Assert.notNull( uri ); - return isMap.remove( uri ); + return this.isMap.remove( uri ); + } + + public String addRealPath(String uri, String realPath) { + Assert.notNull( uri ); + Assert.notNull( realPath ); + + return this.realPathMap.put( uri, realPath ); + } + + public String[] addRealPaths(Map<String, String> realPathMap) { + List<String> list = new ArrayList<String>(); + + if ( realPathMap != null ) { + for( String key : realPathMap.keySet() ) { + list.add( addRealPath( key, realPathMap.get( key ) ) ); + } + } + + return list.toArray( new String[0] ); + } + + public String removeRealPath(String uri) { + Assert.notNull( uri ); + + return this.realPathMap.remove( uri ); } public boolean hasAuthorSignatureXML() { @@ -98,16 +134,19 @@ public class ResolverInputStream extends ResolverLocalFilesystem { if ( uri != null ) { String value = uri.getValue(); + // try to InputStream if ( this.isMap.containsKey( value ) ) { return true; } + // try to required resource if ( hasAuthorSignatureXML() && SignatureUtility.getAuthorFilename().equals( value ) ) { return true; } } + // default local file policy return super.engineCanResolve( uri, baseURI ); } @@ -125,9 +164,13 @@ public class ResolverInputStream extends ResolverLocalFilesystem { final URL url = new URL( new URL( baseURI ), value ); if ( this.isMap.containsKey( value ) ) { - // a mapped resource + // a mapped resource for input stream is = this.isMap.get( value ); is.reset(); + } else if ( this.realPathMap.containsKey( value ) ) { + // a mapped resource for real path + String realPath = this.realPathMap.get( value ); + is = openStream( new URL( realPath ) ); } else if ( hasAuthorSignatureXML() && SignatureUtility.getAuthorFilename().equals( value ) ) { // the author signature @@ -136,7 +179,7 @@ public class ResolverInputStream extends ResolverLocalFilesystem { } else { // a local file // Bug Patch : Too many file opens problem because All stream is opened until finish work. - is = new ByteArrayInputStream( IOUtil.getBytes( url.openStream(), true ) ); + is = openStream( url ); } XMLSignatureInput input = new XMLSignatureInput( is ); @@ -149,4 +192,7 @@ public class ResolverInputStream extends ResolverLocalFilesystem { } } + private InputStream openStream(URL url) throws IOException { + return new ByteArrayInputStream( IOUtil.getBytes( url.openStream(), true ) ); + } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/signer/TizenIncrementalSigner.java b/org.tizen.common.sign/src/org/tizen/common/sign/signer/TizenIncrementalSigner.java index a82c3343c..e52efa797 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/signer/TizenIncrementalSigner.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/signer/TizenIncrementalSigner.java @@ -82,7 +82,7 @@ import org.tizen.common.sign.model.Delta; import org.tizen.common.sign.model.ReferenceCache; import org.tizen.common.sign.model.ReferenceDelegator; import org.tizen.common.sign.model.DeltaState; -import org.tizen.common.sign.model.ResolverInputStream; +import org.tizen.common.sign.model.ResolverCustomResource; import org.tizen.common.sign.model.SignatureConstants; import org.tizen.common.sign.preferences.SigningProfile; import org.tizen.common.sign.preferences.SigningProfileItem; @@ -106,6 +106,10 @@ public class TizenIncrementalSigner { protected static final Logger logger = getLogger( TizenIncrementalSigner.class ); + public enum ResourceMode { + ORIGINAL, HAVE_REAL + }; + // Reflection constants private static final String REFERENCES_IN_SIGNEDINFO = "references"; @@ -129,8 +133,26 @@ public class TizenIncrementalSigner { private XMLSignature signature; // a sign module protected Map<String, InputStream> isMap; + protected Map<String, String> realPathMap; protected InputStream authorSignatureXML; + protected ResourceMode mode = ResourceMode.ORIGINAL; + + + static { + // initialize for the xmlsec module + Init.init(); + + try { + // remove a default namespace prefix like "ns:" + XMLSignature.setDefaultPrefix( Constants.SignatureSpecNS, StringUtil.EMPTY_STRING ); + } catch (XMLSecurityException e) { + logger.error( e.getMessage(), e ); + } + + // TODO: unknown purpose. a related class is PEMReader. + Security.addProvider( new BouncyCastleProvider() ); + } /** * Constructor @@ -147,23 +169,15 @@ public class TizenIncrementalSigner { initialize(); } + public void setMode(ResourceMode mode) { + Assert.notNull( mode ); + this.mode = mode; + } + /** * Initialize for pre-process */ protected void initialize() { - // initialize for the xmlsec module - Init.init(); - - try { - // remove a default namespace prefix like "ns:" - XMLSignature.setDefaultPrefix( Constants.SignatureSpecNS, StringUtil.EMPTY_STRING ); - } catch (XMLSecurityException e) { - logger.error( e.getMessage(), e ); - } - - // TODO: unknown purpose. a related class is PEMReader. - Security.addProvider( new BouncyCastleProvider() ); - // set default parser for incremental resources FileHandler defaultHandler = new StandardFileHandler(); defaultHandler.setCurrentWorkingDirectory( new File( this.rootPath ).getAbsolutePath() ); @@ -370,15 +384,25 @@ public class TizenIncrementalSigner { return this.isMap.put( uri, is ); } - protected ResolverInputStream getResourceResolver() { - ResolverInputStream resolver = null; + public void setRealPathMap(Map<String, String> realPathMap) { + this.realPathMap = realPathMap; + } + + public String addRealPath(String uri, String realPath) { + Assert.notNull( uri ); + Assert.notNull( realPath ); - if ( this.isMap != null ) { - resolver = new ResolverInputStream( this.isMap ); - } else { - resolver = new ResolverInputStream(); + if ( this.realPathMap == null ) { + this.realPathMap = new HashMap<String, String>(); } + return this.realPathMap.put( uri, realPath ); + } + + protected ResolverCustomResource getResourceResolver() { + ResolverCustomResource resolver = new ResolverCustomResource(); + resolver.addInputStreams( this.isMap ); + resolver.addRealPaths( this.realPathMap ); resolver.setAuthorSignatureXML( this.authorSignatureXML ); return resolver; @@ -423,7 +447,18 @@ public class TizenIncrementalSigner { restoreReferenceList( refs, bAuthor ); } else { // process all elements - List<String> resources = findResources( new File( this.rootPath ), bAuthor ); + List<String> resources = new ArrayList<String>(); + + // Add real paths + if ( this.realPathMap != null ) { + for( String mapKey: this.realPathMap.keySet() ) { + resources.add( mapKey ); + } + } else { + if ( this.mode == ResourceMode.ORIGINAL ) { + resources = findResources( new File( this.rootPath ), bAuthor ); + } + } // if is distributor and not have an author, add if ( ordinal != SigningProfile.AUTHOR_ORDINAL ) { @@ -433,6 +468,14 @@ public class TizenIncrementalSigner { } } + // Add InputStreams + if ( this.isMap != null ) { + for( String mapKey: this.isMap.keySet() ) { + resources.add( mapKey ); + } + } + + // write resources to Document addResources( resources ); } @@ -685,7 +728,7 @@ public class TizenIncrementalSigner { for ( File child : resource.listFiles() ) { list.addAll( findResources( child, bAuthor ) ); } - } else { + } else if ( resource.isFile() ){ // If not filtered resource, remember a path. if ( isFilterResource( resource, bAuthor ) == false ) { String path = FilenameUtil.getRelativePath( this.rootPath, resource.getPath() ); @@ -1073,8 +1116,7 @@ public class TizenIncrementalSigner { } // get key from key store - keyStore.getKey( alias, pwd ); - return true; + return keyStore.getKey( alias, pwd ) != null; } catch(FileNotFoundException e) { throw e; } catch(IOException e) { diff --git a/org.tizen.common.sign/test/src/org/tizen/common/sign/TizenIncrementalSignerTest.java b/org.tizen.common.sign/test/src/org/tizen/common/sign/TizenIncrementalSignerTest.java index 651bec200..e3843bece 100644 --- a/org.tizen.common.sign/test/src/org/tizen/common/sign/TizenIncrementalSignerTest.java +++ b/org.tizen.common.sign/test/src/org/tizen/common/sign/TizenIncrementalSignerTest.java @@ -28,6 +28,7 @@ package org.tizen.common.sign; import static org.junit.Assert.*; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; @@ -52,6 +53,7 @@ import org.tizen.common.sign.preferences.SigningProfileItem; import org.tizen.common.sign.signer.DeltaListResourceParser; import org.tizen.common.sign.signer.ReferenceCacheParser; import org.tizen.common.sign.signer.TizenIncrementalSigner; +import org.tizen.common.sign.signer.TizenIncrementalSigner.ResourceMode; import org.tizen.common.sign.util.SignatureUtility; import org.tizen.common.util.FileUtil; import org.tizen.common.util.IOUtil; @@ -82,7 +84,15 @@ public class TizenIncrementalSignerTest { protected final File cache = new File( TEST_RESOURCE_DIR, ReferenceCacheParser.FILENAME ); - protected void createDeltaFile(File deltaFile, String content) throws IOException { + protected void createFile(File deltaFile, String content) throws IOException { + File parentFile = deltaFile.getParentFile(); + if ( ! parentFile.isDirectory() ) { + boolean bMkdir = parentFile.mkdirs(); + if ( bMkdir == false ) { + throw new IOException( "Failed to create parent directory: " + parentFile ); + } + } + FileOutputStream os = null; try { os = new FileOutputStream( deltaFile ); @@ -153,7 +163,7 @@ public class TizenIncrementalSignerTest { testResult( result1, result2 ); // incremental sign with add delta - createDeltaFile( delta, src.getPath() + "C__DEL__" + ADDED_DEST ); + createFile( delta, src.getPath() + "C__DEL__" + ADDED_DEST ); TizenIncrementalSigner signer3 = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); byte[][] result3 = signer3.sign( true ); @@ -166,7 +176,7 @@ public class TizenIncrementalSignerTest { testResult( result3, result4 ); // incremental sign with change delta - createDeltaFile( delta, src2.getPath() + "C__DEL__" + ADDED_DEST ); + createFile( delta, src2.getPath() + "C__DEL__" + ADDED_DEST ); TizenIncrementalSigner signer7 = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); byte[][] result7 = signer7.sign( true ); @@ -179,7 +189,7 @@ public class TizenIncrementalSignerTest { testResult( result7, result8 ); // incremental sign with remove delta - createDeltaFile( delta, src.getPath() + "D__DEL__" + ADDED_DEST ); + createFile( delta, src.getPath() + "D__DEL__" + ADDED_DEST ); TizenIncrementalSigner signer5 = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); byte[][] result5 = signer5.sign( true ); @@ -427,7 +437,7 @@ public class TizenIncrementalSignerTest { } } - @Ignore // this is a functionality test +// @Ignore // this is a functionality test @Test public void testSignItemWithOutputStream2() throws Exception { SigningProfile profile = new SigningProfile(""); @@ -448,7 +458,7 @@ public class TizenIncrementalSignerTest { // incremental sign using OutputStream File src1 = new File( TEST_RESOURCE_DIR, ADDED_SRC2 ); - createDeltaFile( delta, src1.getPath() + "C__DEL__" + ADDED_DEST ); + createFile( delta, src1.getPath() + "C__DEL__" + ADDED_DEST ); ByteArrayOutputStream[] oss2 = { new ByteArrayOutputStream(), new ByteArrayOutputStream(), @@ -458,7 +468,7 @@ public class TizenIncrementalSignerTest { TizenIncrementalSigner signer2 = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); signer2.sign( true, oss2 ); - createDeltaFile( delta, src1.getPath() + "D__DEL__" + ADDED_DEST ); + createFile( delta, src1.getPath() + "D__DEL__" + ADDED_DEST ); ByteArrayOutputStream[] oss3 = { new ByteArrayOutputStream(), new ByteArrayOutputStream(), @@ -475,4 +485,64 @@ public class TizenIncrementalSignerTest { tearDownForFilesystem(); } } + + @Test + public void testSignItemWithInputStream() throws Exception { + SigningProfile profile = new SigningProfile(""); + profile.createProfileItem( 0, TESTKEY, TESTKEY_PWD, null, null ); + profile.createProfileItem( 1, TESTKEY, TESTKEY_PWD, null, null ); + + try { + File ggFile = new File( TEST_RESOURCE_DIR, "gg.txt" ); + + // fully sign using OutputStream + ByteArrayOutputStream[] oss1 = { + new ByteArrayOutputStream(), + new ByteArrayOutputStream(), + new ByteArrayOutputStream() + }; + TizenIncrementalSigner signer = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); + + createFile( ggFile, "xxx" ); + + for ( String[] testRes : testResources ) { + String uri = testRes[0]; + String content = testRes[1]; + signer.addInputStream( uri, new ByteArrayInputStream( content.getBytes() ) ); + } + signer.setMode( ResourceMode.HAVE_REAL ); + signer.sign( false, oss1 ); + + // incremental sign using OutputStream + createFile( delta, ggFile + "C__DEL__" + "aa/gg.txt" ); + + ByteArrayOutputStream[] oss2 = { + new ByteArrayOutputStream(), + new ByteArrayOutputStream(), + new ByteArrayOutputStream() + }; + + TizenIncrementalSigner signer2 = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); + signer.setMode( ResourceMode.HAVE_REAL ); + signer2.sign( true, oss2 ); + + ggFile.delete(); + createFile( delta, ggFile + "D__DEL__" + "aa/gg.txt" ); + ByteArrayOutputStream[] oss3 = { + new ByteArrayOutputStream(), + new ByteArrayOutputStream(), + new ByteArrayOutputStream() + }; + + TizenIncrementalSigner signer3 = new TizenIncrementalSigner( profile, TEST_RESOURCE_DIR ); + signer.setMode( ResourceMode.HAVE_REAL ); + signer3.sign( true, oss3 ); + + assertTrue( Arrays.equals( oss1[0].toByteArray(), oss3[0].toByteArray() ) ); + assertTrue( Arrays.equals( oss1[1].toByteArray(), oss3[1].toByteArray() ) ); + assertTrue( Arrays.equals( oss1[2].toByteArray(), oss3[2].toByteArray() ) ); + } finally { + tearDownForFilesystem(); + } + } } |