├── MAINTENANCE.md ├── SECURITY.md ├── README.md ├── dbxupdate-split.py ├── test-instance ├── aws-secureboot-blob ├── .github └── workflows │ └── pr.yaml └── LICENSE /MAINTENANCE.md: -------------------------------------------------------------------------------- 1 | # Maintenance 2 | 3 | Some info about maintaining this repository. 4 | 5 | ## New release 6 | 7 | To do a new release 8 | 9 | 1. make sure everything is included in current `main` (eg. check for open PRs) 10 | 1. create a new tag. The tag should have the format of a serial (eg. `20230329`) 11 | 1. push the tag 12 | 13 | Then the github action will create a new release including the binary blob. 14 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting a vulnerability 2 | To report a security issue, file a [Private Security Report](https://github.com/Canonical/aws-secureboot-blob/security/advisories/new) 3 | with a description of the issue, the steps you took to create the issue, 4 | affected versions, and, if known, mitigations for the issue. 5 | The [Ubuntu Security disclosure and embargo policy](https://ubuntu.com/security/disclosure-policy) 6 | contains more information about what you can expect when you contact us and what we expect from you. 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aws-secureboot-blob 2 | 3 | The `aws-secureboot-blob` creates a binary blob containing 4 | a pre-filled variable store containing the UEFI Secure Boot keys. 5 | This binary blob can then be used to boot a AWS EC2 instance 6 | with secure boot enabled. 7 | 8 | See also the [AWS documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/aws-binary-blob-creation.html). 9 | 10 | ## requirements 11 | 12 | To be able to run `aws-secureboot-blob`, some software needs 13 | to be installed: 14 | 15 | ``` 16 | sudo apt install --yes sbsigntool efitools 17 | sudo snap install uefivars 18 | ``` 19 | 20 | ## usage 21 | 22 | To create the binary blob, do: 23 | 24 | ``` 25 | ./aws-secureboot-blob 26 | ``` 27 | 28 | That will create the blob (by default for `amd64`) file called 29 | `aws-uefiblob.bin`. 30 | 31 | The blob can then be used during image registration. For details how 32 | to create a new AMI based on an existing Ubuntu AMI, see the `test-instance` script. 33 | 34 | 35 | ## contributing 36 | 37 | We welcome external contributions. Before proposing changes please 38 | [create an issue](https://github.com/canonical/aws-secureboot-blob/issues/new?template=Blank+issue) 39 | describing the request. This helps ensure we prioritize accordingly and avoid duplicating effort. 40 | 41 | When a pull request is opened against this repository it is expected that it will fail 42 | when initiated from a fork. The pipeline tests secureboot in a Canonical provided AWS account, 43 | which is not allowed to be launched from a fork. Changes from external contributors will be manually tested 44 | Maintainers of this repository should push their branches to origin to allow for end to end testing 45 | in the pull request. 46 | -------------------------------------------------------------------------------- /dbxupdate-split.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | Split the signature and content from a dbxupdate.bin file (eg. 5 | from /usr/share/secureboot/updates/dbx/ ). That splitted dbxupdate.bin.esl 6 | file can than be used together with https://github.com/awslabs/python-uefivars 7 | 8 | Inspired by https://www.powershellgallery.com/packages/SplitDbxContent/1.0 9 | """ 10 | 11 | import argparse 12 | import sys 13 | import struct 14 | 15 | 16 | def _parser(): 17 | parser = argparse.ArgumentParser( 18 | description='split a secureboot dbxupdate.bin') 19 | parser.add_argument( 20 | '--content', default='dbxupdate.bin.esl', 21 | help='the content filename to write. default: %(default)s') 22 | parser.add_argument( 23 | '--signature', default='dbxupdate.bin.p7', 24 | help='the signature filename to write. default: %(default)s') 25 | parser.add_argument( 26 | 'dbxupdate', help='path to the dbxupdate.bin file') 27 | return parser 28 | 29 | 30 | if __name__ == '__main__': 31 | parser = _parser() 32 | args = parser.parse_args() 33 | 34 | with open(args.dbxupdate, 'rb') as f: 35 | buf = f.read() 36 | # the wCertificateType (UINT16) must be WIN_CERT_TYPE_EFI_GUID 37 | wCertificateType, = struct.unpack('H', buf[22:24]) 38 | if wCertificateType != 0x0ef1: 39 | print(f'Certificate type is 0x{wCertificateType:04x} not WIN_CERT_TYPE_EFI_GUID (0x0ef1).', file=sys.stderr) 40 | sys.exit(3) 41 | 42 | # Identify file signature 43 | chop = buf[40:] 44 | 45 | if hex(chop[0]) != '0x30' or hex(chop[1]) != '0x82': 46 | print('error: can not find signature', file=sys.stderr) 47 | sys.exit(1) 48 | 49 | # Signature is known to be ASN size plus header of 4 bytes 50 | signature_length = (chop[2] * 256) + chop[3] + 4 51 | signature = chop[0:signature_length] 52 | 53 | if signature_length > (len(buf) + 40): 54 | print('error: signature longer than file size', file=sys.stderr) 55 | sys.exit(2) 56 | 57 | # the dbxupdate.bin content without the signature 58 | content = chop[signature_length:] 59 | with open(args.content, 'wb') as c: 60 | for byte in content: 61 | c.write(byte.to_bytes(1, byteorder='big')) 62 | 63 | # the dbxupdate.bin signature without the content 64 | with open(args.signature, 'wb') as s: 65 | for byte in signature: 66 | s.write(byte.to_bytes(1, byteorder='big')) 67 | -------------------------------------------------------------------------------- /test-instance: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | # that var is set by github actions 4 | GITHUB_ENV=${GITHUB_ENV:-/dev/null} 5 | # the architecture to use 6 | ARCH=amd64 7 | # the AWS architecture 8 | ARCH_AWS="${ARCH}" 9 | # the suite to get the base image for 10 | SUITE=jammy 11 | # the AWS region to use 12 | AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:-eu-central-1} 13 | # the path to the varstore blob (created by aws-secureboot-blob) 14 | VARSTORE_BLOB=${VARSTORE_BLOB:-blobs/blob.bin} 15 | # the AMI name 16 | AMI_NEW_NAME=aws-secureboot-blob-${ARCH}-$(date '+%Y%m%d%H%M%S') 17 | # AWS key pair name 18 | KEY_NAME=${KEY_NAME:-github-actions} 19 | # AWS instance type 20 | INSTANCE_TYPE=${INSTANCE_TYPE:-t3.medium} 21 | 22 | # convert the AWS architecture 23 | if [ "${ARCH_AWS}" = "amd64" ]; then 24 | ARCH_AWS="x86_64" 25 | fi 26 | 27 | # get the latest ami for given suite and arch 28 | AMI=$(aws ssm get-parameters --names "/aws/service/canonical/ubuntu/server/${SUITE}/stable/current/${ARCH}/hvm/ebs-gp2/ami-id" --query 'Parameters[0].Value' --output text) 29 | echo "AMI=${AMI}" >> "${GITHUB_ENV}" 30 | 31 | # get the snapshot for that ami 32 | AMI_SNAPSHOT=$(aws ec2 describe-images --image-id "${AMI}"|jq -r '.Images[0].BlockDeviceMappings[0].Ebs.SnapshotId') 33 | echo "AMI_SNAPSHOT=${AMI_SNAPSHOT}" >> "${GITHUB_ENV}" 34 | 35 | # copy the snapshot 36 | AMI_SNAPSHOT_NEW=$(aws ec2 copy-snapshot --source-region "${AWS_DEFAULT_REGION}" --source-snapshot-id "${AMI_SNAPSHOT}" --description "aws-secureboot-blob testing; copied from ${AMI_SNAPSHOT}"|jq -r '.SnapshotId') 37 | echo "AMI_SNAPSHOT_NEW=${AMI_SNAPSHOT_NEW}" >> "${GITHUB_ENV}" 38 | aws ec2 wait snapshot-completed --snapshot-ids "${AMI_SNAPSHOT_NEW}" 39 | 40 | # create new AMI 41 | AMI_NEW=$(aws ec2 register-image --name "${AMI_NEW_NAME}" --uefi-data "$(cat "${VARSTORE_BLOB}")" --block-device-mappings "DeviceName=/dev/sda1,Ebs= {SnapshotId=""${AMI_SNAPSHOT_NEW}"",DeleteOnTermination=true}" --architecture "${ARCH_AWS}" --root-device-name /dev/sda1 --virtualization-type hvm --ena-support --boot-mode uefi|jq -r '.ImageId') 42 | echo "AMI_NEW=${AMI_NEW}" >> "${GITHUB_ENV}" 43 | aws ec2 wait image-exists --image-ids "${AMI_NEW}" 44 | aws ec2 wait image-available --image-ids "${AMI_NEW}" 45 | 46 | # boot instance 47 | INSTANCE=$(aws ec2 run-instances --image-id "${AMI_NEW}" --instance-type "${INSTANCE_TYPE}" --key-name "${KEY_NAME}"|jq -r '.Instances[].InstanceId') 48 | echo "INSTANCE=${INSTANCE}" >> "${GITHUB_ENV}" 49 | INSTANCE_IP=$(aws ec2 describe-instances --instance-ids "${INSTANCE}"|jq -r '.Reservations[].Instances[].PublicIpAddress') 50 | echo "INSTANCE_IP=${INSTANCE_IP}" >> "${GITHUB_ENV}" 51 | -------------------------------------------------------------------------------- /aws-secureboot-blob: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | # create a binary UEFI variable store blob which 4 | # can be used create a AWS EC2 instance that support secure boot 5 | # 6 | # commands taken from https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/aws-binary-blob-creation.html 7 | 8 | 9 | function create_blob() { 10 | local WORKDIR=$1 11 | local RESULT=$2 12 | 13 | # Create an empty PK signature list 14 | touch "${WORKDIR}"/empty_key.crt 15 | cert-to-efi-sig-list "${WORKDIR}"/empty_key.crt "${WORKDIR}"/PK.esl 16 | 17 | # Download the KEK certificates 18 | curl -s -L https://go.microsoft.com/fwlink/?LinkId=321185 --output "${WORKDIR}"/MicCorKEKCA2011_2011-06-24.crt 19 | # Wrap the KEK certificates in a UEFI signature list (siglist) 20 | sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output "${WORKDIR}"/MS_Win_KEK.esl "${WORKDIR}"/MicCorKEKCA2011_2011-06-24.crt 21 | 22 | # Download Microsoft's db certificates 23 | # MicWinProPCA2011_2011-10-19.crt is not needed. it's used to sign Microsoft products 24 | # we use the crt from the shim-signed source package (the microsoft link to the same file is https://www.microsoft.com/pkiops/certs/MicCorUEFCA2011_2011-06-27.crt) 25 | curl -s https://git.launchpad.net/ubuntu/+source/shim-signed/plain/MicCorUEFCA2011_2011-06-27.crt --output "${WORKDIR}"/MicCorUEFCA2011_2011-06-27.pem 26 | openssl x509 -outform der -in "${WORKDIR}"/MicCorUEFCA2011_2011-06-27.pem -out "${WORKDIR}"/MicCorUEFCA2011_2011-06-27.crt 27 | 28 | # Generate the db signature list 29 | sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output "${WORKDIR}"/MS_UEFI_db.esl "${WORKDIR}"/MicCorUEFCA2011_2011-06-27.crt 30 | 31 | # Build a UEFI variable store using the uefivars.py script 32 | # uefivars script taken from https://github.com/awslabs/python-uefivars 33 | uefivars -i none -o aws -O "$RESULT" -P "${WORKDIR}"/PK.esl -K "${WORKDIR}"/MS_Win_KEK.esl --db "${WORKDIR}"/MS_UEFI_db.esl 34 | } 35 | 36 | 37 | function usage() { 38 | cat << EOF >&2 39 | usage: $0 [-a|o|h] 40 | 41 | options: 42 | o output filename. default: aws-uefiblob.bin 43 | h this help 44 | EOF 45 | } 46 | 47 | 48 | function cleanup { 49 | rm -rf "${TMPDIR}" 50 | } 51 | 52 | 53 | while getopts "ho:" option; do 54 | case $option in 55 | h) 56 | usage 57 | exit;; 58 | o) 59 | OUTPUT=$OPTARG;; 60 | \?) 61 | echo "Error: Invalid option" 62 | exit;; 63 | esac 64 | done 65 | 66 | TMPDIR=$(mktemp --directory aws-build-varstore-blob.XXXXXXXXXX) 67 | trap cleanup EXIT 68 | OUTPUT=${OUTPUT:-aws-uefiblob.bin} 69 | 70 | 71 | create_blob "${TMPDIR}" "${OUTPUT}" 72 | -------------------------------------------------------------------------------- /.github/workflows/pr.yaml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags: 8 | - '*' 9 | pull_request: 10 | branches: [ main ] 11 | 12 | jobs: 13 | shellcheck: 14 | name: Shellcheck 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Run ShellCheck 19 | uses: ludeeus/action-shellcheck@master 20 | build-blob: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v2 25 | - name: Install dependencies 26 | run: | 27 | sudo snap install uefivars 28 | sudo apt-get install --yes efitools 29 | - uses: actions/checkout@v2 30 | - name: Run aws-secureboot-blob 31 | run: | 32 | ./aws-secureboot-blob -o blob.bin 33 | # for debugging 34 | uefivars -i aws -o json -I blob.bin 35 | - uses: actions/upload-artifact@v4 36 | with: 37 | name: blob-artifact 38 | path: blob.bin 39 | dbxupdate-split: 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Checkout 43 | uses: actions/checkout@v2 44 | - name: Install dependencies 45 | run: | 46 | sudo apt-get install --yes openssl 47 | - name: Run dbxupdate-split 48 | run: | 49 | ./dbxupdate-split.py /usr/share/secureboot/updates/dbx/dbxupdate_x64.bin 50 | openssl asn1parse -inform DER -in dbxupdate.bin.p7 51 | release: 52 | if: startsWith(github.ref, 'refs/tags/') 53 | runs-on: ubuntu-latest 54 | needs: aws-test 55 | steps: 56 | - uses: actions/download-artifact@v4 57 | with: 58 | name: blob-artifact 59 | path: blobs 60 | - name: create github release 61 | uses: softprops/action-gh-release@v1 62 | with: 63 | files: | 64 | blobs/blob.bin 65 | aws-test: 66 | runs-on: ubuntu-latest 67 | needs: build-blob 68 | permissions: 69 | id-token: write 70 | contents: read 71 | env: 72 | AWS_DEFAULT_REGION: eu-central-1 73 | steps: 74 | - name: Git clone the repository 75 | uses: actions/checkout@v3 76 | - uses: actions/download-artifact@v4 77 | with: 78 | name: blob-artifact 79 | path: blobs 80 | - run: ls -al 81 | working-directory: blobs 82 | - name: configure aws credentials 83 | uses: aws-actions/configure-aws-credentials@v1 84 | with: 85 | role-to-assume: arn:aws:iam::156445921216:role/github-actions-role 86 | role-session-name: gh-action-session 87 | aws-region: eu-central-1 88 | - uses: webfactory/ssh-agent@v0.5.4 89 | with: 90 | ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} 91 | 92 | - name: create test instance 93 | run: | 94 | ./test-instance 95 | 96 | - name: ssh to instance 97 | run: | 98 | ssh-add -l 99 | ssh -o ConnectionAttempts=30 -o ConnectTimeout=5 -o StrictHostKeyChecking=no ubuntu@${{ env.INSTANCE_IP }} cat /etc/os-release 100 | 101 | - name: run tests 102 | run: | 103 | cat << EOF > test.sh 104 | #!/bin/bash -eux 105 | 106 | # wait for cloud-init to finish 107 | cloud-init status --wait 108 | 109 | # secure boot should be enabled 110 | mokutil --sb-state|grep enabled 111 | 112 | # install tools for more checks 113 | apt-get update 114 | apt-cache policy efitools 115 | apt-get install --yes efitools 116 | 117 | efi-readvar -v KEK 118 | efi-readvar -v db 119 | efi-readvar -v dbx 120 | EOF 121 | 122 | chmod a+x test.sh 123 | scp -o StrictHostKeyChecking=no test.sh ubuntu@${{ env.INSTANCE_IP }}: 124 | ssh -o StrictHostKeyChecking=no ubuntu@${{ env.INSTANCE_IP }} sudo ./test.sh 125 | 126 | - name: terminate instance 127 | if: always() 128 | run: | 129 | if [ ! -z "${{ env.INSTANCE }}" ]; then 130 | aws ec2 terminate-instances --instance-ids ${{ env.INSTANCE }} 131 | fi 132 | 133 | - name: deregister new AMI 134 | if: always() 135 | run: | 136 | if [ ! -z "${{ env.AMI_NEW }}" ]; then 137 | aws ec2 deregister-image --image-id ${{ env.AMI_NEW }} 138 | fi 139 | - name: cleanup copied Snapshot 140 | if: always() 141 | run: | 142 | if [ ! -z "${{ env.AMI_SNAPSHOT_NEW }}" ]; then 143 | aws ec2 delete-snapshot --snapshot-id ${{ env.AMI_SNAPSHOT_NEW }} 144 | fi 145 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------