Initail version
authorHyunwoo Kim <hwlove.kim@samsung.com>
Wed, 5 Jun 2013 11:09:01 +0000 (20:09 +0900)
committerHyunwoo Kim <hwlove.kim@samsung.com>
Wed, 5 Jun 2013 12:07:31 +0000 (21:07 +0900)
Change-Id: I1ad79e669d261c998bad4b59102227449056dde1
Signed-off-by: Hyunwoo Kim <hwlove.kim@samsung.com>
13 files changed:
LICENSE [new file with mode: 0644]
certificates/tizen-distributor-partner-manufacturer-signer.p12 [new file with mode: 0644]
certificates/tizen-distributor-partner-signer.p12 [new file with mode: 0644]
certificates/tizen-distributor-public-signer.p12 [new file with mode: 0644]
certificates/tizen_author.p12 [new file with mode: 0644]
macros/macros.sign [new file with mode: 0644]
packaging/package-signer.spec [new file with mode: 0644]
tools/hash-signer.sh [new file with mode: 0755]
tools/realpath.sh [new file with mode: 0755]
tools/sign-widget.sh [new file with mode: 0755]
tools/signing-template.sh [new file with mode: 0755]
tools/validate-widget.sh [new file with mode: 0755]
tools/xmldsig.rnc [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..247c97d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,203 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/certificates/tizen-distributor-partner-manufacturer-signer.p12 b/certificates/tizen-distributor-partner-manufacturer-signer.p12
new file mode 100644 (file)
index 0000000..fb0512c
Binary files /dev/null and b/certificates/tizen-distributor-partner-manufacturer-signer.p12 differ
diff --git a/certificates/tizen-distributor-partner-signer.p12 b/certificates/tizen-distributor-partner-signer.p12
new file mode 100644 (file)
index 0000000..9916077
Binary files /dev/null and b/certificates/tizen-distributor-partner-signer.p12 differ
diff --git a/certificates/tizen-distributor-public-signer.p12 b/certificates/tizen-distributor-public-signer.p12
new file mode 100644 (file)
index 0000000..329382e
Binary files /dev/null and b/certificates/tizen-distributor-public-signer.p12 differ
diff --git a/certificates/tizen_author.p12 b/certificates/tizen_author.p12
new file mode 100644 (file)
index 0000000..8a5a99d
Binary files /dev/null and b/certificates/tizen_author.p12 differ
diff --git a/macros/macros.sign b/macros/macros.sign
new file mode 100644 (file)
index 0000000..da6c0f0
--- /dev/null
@@ -0,0 +1,20 @@
+%undefine %tizen_sign
+%undefine tizen_author_flag
+%undefine tizen_dist_flag
+%tizen_sign_base ./
+%tizen_sign_level public
+%__arch_install_post   /usr/lib/rpm/check-buildroot
+
+%__os_install_post    \
+    /usr/lib/rpm//brp-compress \
+    %{!?__debug_package:/usr/lib/rpm/brp-strip %{__strip}} \
+    /usr/lib/rpm/brp-strip-static-archive %{__strip} \
+    /usr/lib/rpm/brp-strip-comment-note %{__strip} %{__objdump} \
+    /usr/lib/rpm/brp-python-bytecompile \
+    /usr/lib/rpm/brp-python-hardlink \
+    %{!?disable_docs_package:/usr/lib/rpm/tizen/find-docs.sh %{buildroot}} \
+    %{?tizen_author_sign: %define tizen_author_flag -a} \
+    %{?tizen_dist_sign: %define tizen_dist_flag -d} \
+    %{?tizen_sign:/usr/bin/hash-signer.sh %tizen_author_flag %tizen_dist_flag -p %tizen_sign_level  $RPM_BUILD_ROOT/%tizen_sign_base} \
+%{nil}
+
diff --git a/packaging/package-signer.spec b/packaging/package-signer.spec
new file mode 100644 (file)
index 0000000..64bd30d
--- /dev/null
@@ -0,0 +1,33 @@
+Name:       hash-signer
+Summary:    TBD
+Version:    0.0.1
+Release:    1
+Group:      TO_BE/FILLED_IN
+License:    TO BE FILLED IN
+Source0:    %{name}-%{version}.tar.gz
+Requires:   xmlstarlet
+Requires:   xmlsec1
+%description
+TBD
+
+%prep
+%setup -q
+
+%build
+
+
+%install
+rm -rf %{buildroot}
+
+mkdir -p %{buildroot}/opt/usr/share/certs/signer
+cp -arf certificates/* %{buildroot}/opt/usr/share/certs/signer/
+mkdir -p %{buildroot}/usr/bin
+cp -arf tools/* %{buildroot}/usr/bin/
+mkdir -p %{buildroot}/etc/rpm
+cp -arf macros/* %{buildroot}/etc/rpm/
+
+%files
+%defattr(-,root,root,-)
+/opt/usr/share/certs/signer/*
+/usr/bin/*
+/etc/rpm/*
diff --git a/tools/hash-signer.sh b/tools/hash-signer.sh
new file mode 100755 (executable)
index 0000000..8982138
--- /dev/null
@@ -0,0 +1,54 @@
+#/bin/bash
+
+generateAuthorSig=0
+generateDistSig=0
+baseDir="./"
+privilegeLevel="public"
+authSignCert="/opt/usr/share/certs/signer/tizen_author.p12"
+authSignCertPwd="tizenauthor"
+distSignCertPwd="tizenpkcs12passfordsigner"
+
+while getopts "adp:" o
+do
+    case "$o" in
+    a) generateAuthorSig=1;;
+    d) generateDistSig=1;;
+    p) privilegeLevel=$OPTARG;;
+    esac
+done
+
+shift $((OPTIND - 1))
+
+ls $1
+if test -e "$1"
+then
+    echo Base dir does not exist
+#    exit 2
+fi
+
+baseDir="$1"
+
+if [ "$privilegeLevel" == "partner" ]
+then
+       echo "Sign as partner level"
+    distSignCert="/opt/usr/share/certs/signer/tizen-distributor-partner-signer.p12"
+elif [ "$privilegeLevel" == "platform" ]
+then
+       echo "Sign as platform level"
+       distSignCert="/opt/usr/share/certs/signer/tizen-distributor-partner-manufacturer-signer.p12"
+else
+    echo "Sign as public level"
+       distSignCert="/opt/usr/share/certs/signer/tizen-distributor-public-signer.p12"
+fi
+
+if test "$generateAuthorSig" != "0"
+then
+    echo "Generate Author Signature"
+       /usr/bin/sign-widget.sh --pkcs12 "$authSignCert" --pwd "$authSignCertPwd" -a -x "$baseDir"
+fi
+
+if test "$generateDistSig" != "0"
+then
+    echo "Generate Distributor Signature"
+       /usr/bin/sign-widget.sh --pkcs12 "$distSignCert" --pwd "$distSignCertPwd" -x "$baseDir"
+fi
diff --git a/tools/realpath.sh b/tools/realpath.sh
new file mode 100755 (executable)
index 0000000..4c06fc4
--- /dev/null
@@ -0,0 +1,16 @@
+function realpath() {
+       target_file=$1
+       cd `dirname $target_file`
+       target_file=`basename $target_file`
+
+       # Iterate down a (possible) chain of symlinks
+       while test -L "$target_file"
+       do
+               target_file=`readlink $target_file`
+               cd `dirname $target_file`
+               target_file=`basename $target_file`
+       done
+       echo $(pwd -P)/$target_file
+}
+
+
diff --git a/tools/sign-widget.sh b/tools/sign-widget.sh
new file mode 100755 (executable)
index 0000000..6f7d971
--- /dev/null
@@ -0,0 +1,194 @@
+#!/bin/bash
+. $(dirname $0)/realpath.sh
+outname=signature1.xml
+identifier=""
+author=0
+# rsa by default http://www.w3.org/TR/widgets-digsig/#signature-algorithms
+KEYTYPE="rsa"
+
+if [ $# -eq 0 ]
+then
+    echo "Usage $0 [xmlsec options] [options] widget"
+    echo "     -o filename     Set signature filename (default: $outname)"
+    echo "     -i ID           Set dsp:Identifier value (default: <random>)"
+    echo "     -a  Set signature type to author"
+    echo "     -d  Set key type to DSA"
+    echo "     -u  Update digests and signature (in signature specified by -o), don't regenerate"
+    echo "     -c  Specify the X509 certificate"
+    echo "     -x  Don't verify after signing"
+    echo "     widget may be a directory or .wgt file"
+    echo
+    echo "You should include the following xmlsec options:"
+    echo "     --pkcs12 /absolute/path/to/keycert.p12"
+    echo "     --pwd password"
+    echo "  --trusted-pem   /absolute/path/to/root.pem"
+    echo "  --untrusted-pem /absolute/path/to/second.pem"
+    exit 2;
+fi
+
+while [[ $1 == --* ]]; do
+       XMLSECOPTIONS="$XMLSECOPTIONS $1"
+       if [[ $2 != --* ]]
+       then
+               XMLSECOPTIONS="$XMLSECOPTIONS $2"
+               shift 2
+       else
+               echo Missing argument
+               exit 2
+       fi
+done
+
+certfile=""
+validate=1
+update=0
+while getopts "o:i:aduc:x" o
+do
+       case "$o" in
+       (o) outname=$OPTARG;;
+       (i) identifier="--identifier $OPTARG";;
+       (a) author=1;;
+       (d) KEYTYPE="dsa";;
+       (u) update=1;;
+       (c) certfiles=`printf "%s\n%s" "$certfiles" "$OPTARG"`;;
+       (x) validate=0;;
+       (*)  break;;
+       esac
+done
+shift $((OPTIND - 1))
+
+echo Key type $KEYTYPE
+
+if ! test -e "$1"
+then
+       echo $1 does not exist
+       exit 2
+fi
+
+temp=$(realpath "$1")
+WD=$(dirname "$temp")
+BASE=$(dirname $(realpath $0))
+WIDGET=$(basename "$1" .wgt)
+
+if [ -d "$1" ]
+then
+    echo "Package is a directory"
+    wgtdir="$1"
+else
+    wgtdir="/tmp/.$$/$WIDGET"
+    echo "Working in $wgtdir"
+    mkdir -p $wgtdir
+    unzip "$1" -d $wgtdir
+fi
+
+cd "$wgtdir"
+
+template=`mktemp /tmp/signature-tmp.XXXXX`
+tempsig=`mktemp /tmp/signature-tmp.XXXXX`
+tempsig2=`mktemp /tmp/signature-tmp.XXXXX`
+
+
+if [ $author -eq 1 ]
+then
+       outname="author-signature.xml"
+
+    if [ $update -eq 0 ]
+    then
+       $BASE/signing-template.sh --method $KEYTYPE --role author $identifier $(find . -type f -not -name 'signature*.xml' -not -name 'author-signature.xml' -not -name '*.wgt' -not -wholename "*CVS*" | sed -e 's,^\.\/,,'  |sed -e 's,\ ,%20,g' ) > $template
+       else
+        template=$outname
+    fi
+       
+       xmlsec1 sign $XMLSECOPTIONS --output $tempsig $template
+       ret=$?
+    if test "$ret" != "0"
+    then
+        echo "Failed to generate Author Signature. [$ret]"
+        exit $ret
+    fi
+else
+    if [ $update -eq 0 ]
+    then
+        $BASE/signing-template.sh --method $KEYTYPE --role distributor $identifier $(find . -type f -not -name 'signature*.xml' -not -name '*.wgt' -not -wholename "*CVS*" | sed -e 's,^\.\/,,' |sed -e 's,\ ,%20,g' ) > $template
+    else
+        template=$outname
+    fi
+       xmlsec1 sign $XMLSECOPTIONS --output $tempsig $template
+       ret=$?
+    if test "$ret" != "0"
+    then
+        echo "Failed to generate Distributor Signature. [$ret]"
+        exit $ret
+    fi
+fi
+
+for file in $certfiles
+do
+    if [ -n "$file" ]
+    then
+        echo "Adding certificate $file"
+        oldtemp=$tempsig
+        tempsig=`mktemp /tmp/tmp.XXXXX`
+        # Get the certificate and remove the header/footer
+        cert=`openssl x509 -in $file | grep -v -- "-----"`
+
+        xmlstarlet ed -P -N sig=http://www.w3.org/2000/09/xmldsig# -s "//sig:X509Data" -t elem -n "X509Certificate" -v "$cert" $oldtemp > $tempsig
+           ret=$?
+        if test "$ret" != "0"
+        then
+            echo "Failed to generate Author Signature. [$ret]"
+            exit $ret
+        fi
+    fi
+done
+
+# cp $tempsig $outname
+# Re-order
+xmlstarlet ed -P -N s="http://www.w3.org/2000/09/xmldsig#" -m "//s:Signature/s:KeyInfo/s:X509Data/s:X509Certificate[2]" "//s:Signature/s:KeyInfo/s:X509Data" $tempsig > $tempsig2
+ret=$?
+if test "$ret" != "0"
+then
+    echo "Failed to generate Distributor Signature. [$ret]"
+    exit $ret
+fi
+xmlstarlet ed -P -N s="http://www.w3.org/2000/09/xmldsig#" -m "//s:Signature/s:KeyInfo/s:X509Data/s:X509Certificate[1]" "//s:Signature/s:KeyInfo/s:X509Data" $tempsig2 > $outname
+ret=$?
+if test "$ret" != "0"
+then
+    echo "Failed to generate Distributor Signature. [$ret]"
+    exit $ret
+fi
+chmod 744 $outname
+
+
+if [ $update -eq 1 ]
+then
+    echo "Updated $outname"
+else
+    echo "Signed $outname"
+fi
+
+if [ $validate -eq 1 ]
+then
+    echo -n "Validating... "
+    validatecmd="$BASE/validate-widget.sh $XMLSECOPTIONS $PWD"
+    $validatecmd 
+    if [ "$?" -ne 0 ]
+    then
+        echo "FAILED with command:"
+        echo "$validatecmd"
+    else
+        echo "SUCCESS"
+    fi
+    echo
+fi
+
+cd $WD
+if [ -f "$1" ]
+then
+    echo "Zipping widget..."
+    rm -f "$1"
+    zip -jr $WD/$WIDGET.wgt $wgtdir
+    rm -rf $wgtdir
+fi
+
+echo Signed $1
diff --git a/tools/signing-template.sh b/tools/signing-template.sh
new file mode 100755 (executable)
index 0000000..44b1c27
--- /dev/null
@@ -0,0 +1,84 @@
+#!/bin/bash
+role="distributor"
+method="rsa"
+#identifier=`uuid`
+identifier="Tizen"
+usage() {
+cat <<EOL
+Options:
+       --role distributor (default: $role)
+       --method dsa (default: $method)
+       --identifier dsa (default: <random>)
+EOL
+}
+while [[ $1 == -* ]]; do
+       case "$1" in
+               -h|--help|-\?) usage; exit 0;;
+               --role) role=$2; shift 2;;
+               --method) method=$2; shift 2;;
+               --identifier) identifier=$2; shift 2;;
+               --) shift; break;;
+               -*) echo "invalid option: $1"; usage; exit 1;;
+       esac
+done
+
+case "$method" in
+       rsa) method="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";;
+       dsa) method="http://www.w3.org/2000/09/xmldsig#dsa-sha1";;
+       ecdsa) method="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256";;
+       *) echo invalid signature method $method; usage; exit 1;;
+esac
+
+target=`echo $role | sed 's/\([a-z]\)\([a-zA-Z0-9]*\)/\u\1\2/g'`Signature
+
+cat << EOL
+<?xml version="1.0" encoding="UTF-8"?>
+<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="$target">
+ <SignedInfo>
+  <CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11" />
+  <SignatureMethod Algorithm="$method" />
+EOL
+
+for i in "$@"
+do
+tempi=`echo $i | sed -e 's,%20,\ ,g'`
+cat << EOL
+  <Reference URI="$tempi">
+   <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+   <DigestValue></DigestValue>
+  </Reference>
+EOL
+done
+
+cat << EOL
+  <Reference URI="#prop">
+   <Transforms>
+    <Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/>
+   </Transforms>
+   <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
+   <DigestValue></DigestValue>
+  </Reference>
+ </SignedInfo>
+ <SignatureValue>
+ </SignatureValue>
+ <KeyInfo>
+  <X509Data>
+  </X509Data>
+ </KeyInfo>
+ <Object Id="prop">
+  <SignatureProperties
+   xmlns:dsp="http://www.w3.org/2009/xmldsig-properties">
+   <SignatureProperty Id="profile" Target="#$target">
+    <dsp:Profile URI="http://www.w3.org/ns/widgets-digsig#profile"/>
+   </SignatureProperty>
+   <SignatureProperty Id="role" Target="#$target">
+    <dsp:Role
+      URI="http://www.w3.org/ns/widgets-digsig#role-${role}"/>
+   </SignatureProperty>
+   <SignatureProperty Id="identifier" Target="#$target">
+    <dsp:Identifier>${identifier}</dsp:Identifier>
+   </SignatureProperty>
+  </SignatureProperties>
+ </Object>
+</Signature>
+EOL
diff --git a/tools/validate-widget.sh b/tools/validate-widget.sh
new file mode 100755 (executable)
index 0000000..8d3ee70
--- /dev/null
@@ -0,0 +1,89 @@
+#!/bin/bash
+# kai.hendry@wacapps.net
+
+. $(dirname $0)/realpath.sh
+
+if [ $# -eq 0 ]
+then
+    echo "Usage $0 [xmlsec options] [options]  widget"
+    echo "     widget may be a directory or .wgt file"
+    echo
+    echo "Be sure to use the following xmlsec options:"
+    echo " --trusted-pem /absolute/path/to/cert.pem"
+    echo " --untrusted-pem /absolute/path/to/cert.pem"
+    echo " --pkcs12 /absolute/path/file.p12"
+    echo " --pwd password"
+    exit;
+fi
+
+while [[ $1 == --* ]]; do
+       XMLSECOPTIONS="$XMLSECOPTIONS $1"
+       if [[ $2 != --* ]]
+       then
+               XMLSECOPTIONS="$XMLSECOPTIONS $2"
+               shift 2
+       else
+               echo Missing argument
+               exit
+       fi
+done
+
+shift $((OPTIND - 1))
+
+toolsdir=$(dirname $(realpath $0))
+
+if [ -d "$1" ]
+then
+    echo "Widget is a directory"
+    wgtdir="$1"
+else
+    wgtdir="/tmp/.$$"
+    echo "Working in $wgtdir"
+    mkdir -p $wgtdir
+    unzip -q "$1" -d $wgtdir
+fi
+
+cd "$wgtdir"
+
+result=0
+signedwidget=0
+for i in $(find . -name author-signature.xml -o -name 'signature*.xml')
+do
+    signedwidget=1
+       if ! rnv $toolsdir/xmldsig.rnc $i
+       then
+               echo $i FAILED widget digsig schema check
+               result=1
+       fi
+
+       # http://www.w3.org/TR/widgets-digsig/#signature-algorithms
+       SIGMETHOD=$(xmlstarlet sel -N sig=http://www.w3.org/2000/09/xmldsig#  -t -m "//sig:SignatureMethod/@Algorithm" -v . $i)
+       case "$SIGMETHOD" in
+               (http://www.w3.org/2001/04/xmldsig-more#rsa-sha256)
+                       echo Signature method RSA
+                       ;;
+               (http://www.w3.org/2000/09/xmldsig#dsa-sha1)
+                       echo Signature method DSA
+                       ;;
+               (http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256)
+                       echo Signature method ECDSA
+                       ;;
+               (*) echo Unknown Signature Method && continue;;
+       esac
+
+       echo if xmlsec1 verify $XMLSECOPTIONS $i
+       if xmlsec1 verify $XMLSECOPTIONS $i
+       then
+               echo VALID SIGNATURE: $i
+       else
+               echo INVALID SIGNATURE: $i
+               result=1
+       fi
+done
+
+if [ $signedwidget -eq 0 ]
+then
+    echo "UNSIGNED WIDGET"
+fi
+
+exit $result
diff --git a/tools/xmldsig.rnc b/tools/xmldsig.rnc
new file mode 100644 (file)
index 0000000..3c52e74
--- /dev/null
@@ -0,0 +1,253 @@
+namespace ds = "http://www.w3.org/2000/09/xmldsig#"
+
+# Relax NG Grammar for XML Signatures
+# Namespace: http://www.w3.org/2000/09/xmldsig#
+# $Revision: 1.6 $ on $Date: 2011-05-24 13:40:54 $ by $Author: mcaceres $
+#
+# Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+# of Technology, Institut National de Recherche en Informatique et en
+# Automatique, Keio University). All Rights Reserved.
+# http://www.w3.org/Consortium/Legal/
+#
+# This document is governed by the W3C Software License [1] as described
+# in the FAQ [2].
+#
+# [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+# [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+#
+# Constructed by hand from xmldsig-core-schema.xsd by
+# Norman.Walsh@marklogic.com on 5 May 2008.
+#
+# Notes:
+#
+# You must not use the RELAX NG DTD Compatibility features with this
+# grammar. DTD Compatibility features, ID type attributes, and
+# wildcard attributes are mutually exclusive.
+#
+# The definition for the Signature element includes a SignatureType
+# pattern. The rest of the patterns are "inline". This is a matter of
+# style. I constructed only one "type" pattern as an example of the
+# style, not because it's significant in the Signature pattern.
+
+start = Signature
+
+# Start Signature
+
+SignatureType = 
+   attribute Id { xsd:ID }?,
+   SignedInfo,
+   SignatureValue,
+   KeyInfo?,
+   Object*
+
+Signature = element ds:Signature {
+   SignatureType
+}
+
+SignatureValue = element ds:SignatureValue {
+   attribute Id { xsd:ID }?,
+   xsd:base64Binary
+}
+
+# Start SignedInfo
+
+SignedInfo = element ds:SignedInfo {
+   attribute Id { xsd:ID }?,
+   CanonicalizationMethod,
+   SignatureMethod,
+   Reference+
+}
+
+CanonicalizationMethod = element ds:CanonicalizationMethod {
+   attribute Algorithm { xsd:anyURI },
+   (text | anyElement)*
+}
+
+SignatureMethod = element ds:SignatureMethod {
+   attribute Algorithm { xsd:anyURI },
+   (text | HMACOutputLength | anyOtherElement)*
+}
+
+# Start Reference
+
+Reference = element ds:Reference {
+   attribute Id { xsd:ID }?,
+   attribute URI { xsd:anyURI }?,
+   attribute Type { xsd:anyURI }?,
+   Transforms?,
+   DigestMethod,
+   DigestValue
+}
+
+Transforms = element ds:Transforms {
+   Transform+
+}
+
+Transform = element ds:Transform {
+   attribute Algorithm { xsd:anyURI },
+   (anyOtherElement | XPath)*
+}
+
+XPath = element ds:XPath {
+   xsd:string
+}
+
+# End Reference
+
+DigestMethod = element ds:DigestMethod {
+   attribute Algorithm { xsd:anyURI },
+   anyOtherElement*
+}
+
+DigestValue = element ds:DigestValue {
+   DigestValueType
+}
+
+DigestValueType = xsd:base64Binary
+
+# End SignedInfo
+
+# Start KeyInfo
+
+KeyInfo = element ds:KeyInfo {
+   attribute Id { xsd:ID }?,
+   (text | KeyName | KeyValue
+    | RetrievalMethod | X509Data | PGPData | SPKIData | MgmtData
+    | anyOtherElement)*
+}
+
+KeyName = element ds:KeyName { xsd:string }
+
+MgmtData = element ds:MgmtData { xsd:string }
+
+KeyValue = element ds:KeyValue {
+   (text | DSAKeyValue | RSAKeyValue | anyOtherElement)*
+}
+
+RetrievalMethod = element ds:RetrievalMethod {
+   attribute URI { xsd:anyURI },
+   attribute Type { xsd:anyURI }?,
+   Transforms?
+}
+
+# Start X509Data
+
+X509Data = element ds:X509Data {
+   (X509IssuerSerial | X509SKI | X509SubjectName | X509Certificate | X509CRL
+    | anyOtherElement)*
+}
+
+X509IssuerSerial = element ds:X509IssuerSerial {
+   X509IssuerName,
+   X509SerialNumber
+}
+
+X509IssuerName = element ds:X509IssuerName { xsd:string }
+
+X509SerialNumber = element ds:X509SerialNumber { xsd:integer }
+
+X509SKI = element ds:X509SKI { xsd:base64Binary }
+
+X509SubjectName = element ds:X509SubjectName { xsd:string }
+
+X509Certificate = element ds:X509Certificate { xsd:base64Binary }
+
+X509CRL = element ds:X509CRL { xsd:base64Binary }
+
+# End X509Data
+
+# Begin PGPData
+
+PGPData = element ds:PGPData {
+   ((PGPKeyID,PGPKeyPacket?,anyOtherElement*)
+    | (PGPKeyPacket,anyOtherElement*))
+}
+
+PGPKeyID = element ds:PGPKeyID { xsd:base64Binary }
+
+PGPKeyPacket = element ds:PGPKeyPacket { xsd:base64Binary  }
+
+# End PGPData
+
+# Begin SPKIData
+
+SPKIData = element ds:SPKIData {
+   (SPKISexp,anyOtherElement*)+
+}
+
+SPKISexp = element ds:SPKISexp { xsd:base64Binary }
+
+# End SPKIData
+
+# End KeyInfo
+
+# Start Object (Manifest, SignatureProperty)
+
+Object = element ds:Object {
+   attribute Id { xsd:ID }?,
+   attribute MimeType { xsd:string }?,
+   attribute Encoding { xsd:anyURI }?,
+   (anyElement|text)*
+}
+
+Manifest = element ds:Manifest {
+   attribute Id { xsd:ID }?,
+   Reference+
+}
+
+SignatureProperties = element ds:SignatureProperties {
+   attribute Id { xsd:ID }?,
+   SignatureProperty+
+}
+   
+SignatureProperty = element ds:SignatureProperty {
+   attribute Id { xsd:ID }?,
+   attribute Target { xsd:anyURI },
+   anyOtherElement+
+}
+
+# End Object (Manifest, SignatureProperty)
+
+# Start Algorithm Parameters
+
+HMACOutputLength = element ds:HMACOutputLength {
+   xsd:integer
+}
+
+# Start KeyValue Element-types
+
+DSAKeyValue = element ds:DSAKeyValue {
+   (P,Q)?, G?, Y, J?, (Seed, PgenCounter)?
+}
+
+P = element ds:P { CryptoBinary }
+Q = element ds:Q { CryptoBinary }
+G = element ds:G { CryptoBinary }
+Y = element ds:Y { CryptoBinary }
+J = element ds:J { CryptoBinary }
+Seed = element ds:Seed { CryptoBinary }
+PgenCounter = element ds:PgenCounter { CryptoBinary }
+
+CryptoBinary = xsd:base64Binary
+
+RSAKeyValue = element ds:RSAKeyValue {
+   Modulus,
+   Exponent
+}
+
+Modulus = element ds:Modulus { CryptoBinary }
+Exponent = element ds:Exponent { CryptoBinary }
+
+# End KeyValue Element-types
+
+# End Signature
+
+# Definitions for the *any* wild card and the *any other* wildcard
+
+anyAttribute = attribute * { text }
+
+anyElement = element * { (anyAttribute | text | anyElement)* }
+
+anyOtherElement = element * - ds:* { (anyAttribute | text | anyOtherElement)* }
+
+# EOF