mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #32190 from errordeveloper/vendor-go-jose
Automatic merge from submit-queue Vendor github.com/square/go-jose for kubeadm and kube-discovery **What this PR does / why we need it**: This is to be used by `kubeadm` (#31221) and @dgoodwin's `kube-discovery` (PR pending). ***[xref kubernetes/features#11]*** ***[cc @kubernetes/sig-cluster-lifecycle]*** **Special notes for your reviewer**: This is first time I've used `godep`, so please verify if all is quite right about the diff. I'm not 100% sure if there should be secondary dependencies or not. ```release-note NONE ```
This commit is contained in:
		
							
								
								
									
										12
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										12
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -2068,6 +2068,18 @@
 | 
				
			|||||||
			"ImportPath": "github.com/spf13/pflag",
 | 
								"ImportPath": "github.com/spf13/pflag",
 | 
				
			||||||
			"Rev": "1560c1005499d61b80f865c04d39ca7505bf7f0b"
 | 
								"Rev": "1560c1005499d61b80f865c04d39ca7505bf7f0b"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "github.com/square/go-jose",
 | 
				
			||||||
 | 
								"Rev": "789a4c4bd4c118f7564954f441b29c153ccd6a96"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "github.com/square/go-jose/cipher",
 | 
				
			||||||
 | 
								"Rev": "789a4c4bd4c118f7564954f441b29c153ccd6a96"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "github.com/square/go-jose/json",
 | 
				
			||||||
 | 
								"Rev": "789a4c4bd4c118f7564954f441b29c153ccd6a96"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/stretchr/objx",
 | 
								"ImportPath": "github.com/stretchr/objx",
 | 
				
			||||||
			"Rev": "1a9d0bb9f541897e62256577b352fdbc1fb4fd94"
 | 
								"Rev": "1a9d0bb9f541897e62256577b352fdbc1fb4fd94"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										630
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										630
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -64394,6 +64394,636 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			|||||||
================================================================================
 | 
					================================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					= vendor/github.com/square/go-jose licensed under: =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					= vendor/github.com/square/go-jose/LICENSE 3b83ef96387f14655fc854ddc3c6bd57  -
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					= vendor/github.com/square/go-jose/cipher licensed under: =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					= vendor/github.com/square/go-jose/LICENSE 3b83ef96387f14655fc854ddc3c6bd57  -
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					= vendor/github.com/square/go-jose/json licensed under: =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					= vendor/github.com/square/go-jose/LICENSE 3b83ef96387f14655fc854ddc3c6bd57  -
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
================================================================================
 | 
					================================================================================
 | 
				
			||||||
= vendor/github.com/stretchr/objx licensed under: =
 | 
					= vendor/github.com/stretchr/objx licensed under: =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								cmd/kube-discovery/dummy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								cmd/kube-discovery/dummy.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						_ "github.com/square/go-jose"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								cmd/kubeadm/dummy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								cmd/kubeadm/dummy.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2014 The Kubernetes Authors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						_ "github.com/square/go-jose"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -11,8 +11,10 @@ cmd/kube-apiserver/app
 | 
				
			|||||||
cmd/kube-apiserver/app/options
 | 
					cmd/kube-apiserver/app/options
 | 
				
			||||||
cmd/kube-controller-manager
 | 
					cmd/kube-controller-manager
 | 
				
			||||||
cmd/kube-controller-manager/app/options
 | 
					cmd/kube-controller-manager/app/options
 | 
				
			||||||
 | 
					cmd/kube-discovery
 | 
				
			||||||
cmd/kube-dns
 | 
					cmd/kube-dns
 | 
				
			||||||
cmd/kube-proxy
 | 
					cmd/kube-proxy
 | 
				
			||||||
 | 
					cmd/kubeadm
 | 
				
			||||||
cmd/kubectl
 | 
					cmd/kubectl
 | 
				
			||||||
cmd/kubelet
 | 
					cmd/kubelet
 | 
				
			||||||
cmd/kubernetes-discovery
 | 
					cmd/kubernetes-discovery
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/square/go-jose/.gitcookies.sh.enc
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/square/go-jose/.gitcookies.sh.enc
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					'|<7C>&{t<>U|gG<67>(<1E><>Cy=+<13><><EFBFBD>c<EFBFBD>:u:/p<>#~<7E><>["<22>4<EFBFBD>!<21>n<EFBFBD>A<EFBFBD>DK<<3C>uf<75>h<>a<EFBFBD><14>:<3A><><EFBFBD><EFBFBD><EFBFBD>B/<2F>ؤ<EFBFBD><D8A4><08>_<EFBFBD>h<EFBFBD><68>S<17>T*w<>x<EFBFBD><78><12><>-<2D>|<7C><><EFBFBD>Ӄ<EFBFBD><D383><EFBFBD><EFBFBD><14>㣗A$$<24>6<EFBFBD><36><03>G)8n<38>p<EFBFBD><12>ˡ3̚<33>o<><6F>v<>B<>3<EFBFBD><33>]xݓ<78>2l<>G<EFBFBD>|qRޯ
 | 
				
			||||||
							
								
								
									
										7
									
								
								vendor/github.com/square/go-jose/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/square/go-jose/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					*~
 | 
				
			||||||
 | 
					.*.swp
 | 
				
			||||||
 | 
					*.out
 | 
				
			||||||
 | 
					*.test
 | 
				
			||||||
 | 
					*.pem
 | 
				
			||||||
 | 
					*.cov
 | 
				
			||||||
 | 
					jose-util/jose-util
 | 
				
			||||||
							
								
								
									
										43
									
								
								vendor/github.com/square/go-jose/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/square/go-jose/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					language: go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sudo: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					matrix:
 | 
				
			||||||
 | 
					  fast_finish: true
 | 
				
			||||||
 | 
					  allow_failures:
 | 
				
			||||||
 | 
					    - go: tip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go:
 | 
				
			||||||
 | 
					- 1.3
 | 
				
			||||||
 | 
					- 1.4
 | 
				
			||||||
 | 
					- 1.5
 | 
				
			||||||
 | 
					- 1.6
 | 
				
			||||||
 | 
					- 1.7
 | 
				
			||||||
 | 
					- tip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					before_script:
 | 
				
			||||||
 | 
					- export PATH=$HOME/.local/bin:$PATH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					before_install:
 | 
				
			||||||
 | 
					# Install encrypted gitcookies to get around bandwidth-limits
 | 
				
			||||||
 | 
					# that is causing Travis-CI builds to fail. For more info, see
 | 
				
			||||||
 | 
					# https://github.com/golang/go/issues/12933
 | 
				
			||||||
 | 
					- openssl aes-256-cbc -K $encrypted_1528c3c2cafd_key -iv $encrypted_1528c3c2cafd_iv -in .gitcookies.sh.enc -out .gitcookies.sh -d || true
 | 
				
			||||||
 | 
					- bash .gitcookies.sh || true
 | 
				
			||||||
 | 
					- go get github.com/wadey/gocovmerge
 | 
				
			||||||
 | 
					- go get github.com/mattn/goveralls
 | 
				
			||||||
 | 
					- go get golang.org/x/tools/cmd/cover || true
 | 
				
			||||||
 | 
					- go get code.google.com/p/go.tools/cmd/cover || true
 | 
				
			||||||
 | 
					- pip install cram --user `whoami`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					script:
 | 
				
			||||||
 | 
					- go test . -v -covermode=count -coverprofile=profile.cov
 | 
				
			||||||
 | 
					- go test ./cipher -v -covermode=count -coverprofile=cipher/profile.cov
 | 
				
			||||||
 | 
					- go test ./json -v # no coverage for forked encoding/json package
 | 
				
			||||||
 | 
					- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t
 | 
				
			||||||
 | 
					- cd ..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					after_success:
 | 
				
			||||||
 | 
					- gocovmerge *.cov */*.cov > merged.coverprofile
 | 
				
			||||||
 | 
					- $HOME/gopath/bin/goveralls -coverprofile merged.coverprofile -service=travis-ci
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								vendor/github.com/square/go-jose/BUG-BOUNTY.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/square/go-jose/BUG-BOUNTY.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					Serious about security
 | 
				
			||||||
 | 
					======================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Square recognizes the important contributions the security research community
 | 
				
			||||||
 | 
					can make. We therefore encourage reporting security issues with the code
 | 
				
			||||||
 | 
					contained in this repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you believe you have discovered a security vulnerability, please follow the
 | 
				
			||||||
 | 
					guidelines at <https://hackerone.com/square-open-source>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								vendor/github.com/square/go-jose/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/square/go-jose/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					# Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you would like to contribute code to go-jose you can do so through GitHub by
 | 
				
			||||||
 | 
					forking the repository and sending a pull request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When submitting code, please make every effort to follow existing conventions
 | 
				
			||||||
 | 
					and style in order to keep the code as readable as possible. Please also make
 | 
				
			||||||
 | 
					sure all tests pass by running `go test`, and format your code with `go fmt`.
 | 
				
			||||||
 | 
					We also recommend using `golint` and `errcheck`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Before your code can be accepted into the project you must also sign the
 | 
				
			||||||
 | 
					[Individual Contributor License Agreement][1].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
 | 
				
			||||||
							
								
								
									
										202
									
								
								vendor/github.com/square/go-jose/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/github.com/square/go-jose/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					                                 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.
 | 
				
			||||||
							
								
								
									
										212
									
								
								vendor/github.com/square/go-jose/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								vendor/github.com/square/go-jose/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,212 @@
 | 
				
			|||||||
 | 
					# Go JOSE 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[](https://godoc.org/gopkg.in/square/go-jose.v1) [](https://raw.githubusercontent.com/square/go-jose/master/LICENSE)
 | 
				
			||||||
 | 
					[](https://github.com/square/go-jose/releases)
 | 
				
			||||||
 | 
					[](https://travis-ci.org/square/go-jose)
 | 
				
			||||||
 | 
					[](https://coveralls.io/r/square/go-jose)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package jose aims to provide an implementation of the Javascript Object Signing
 | 
				
			||||||
 | 
					and Encryption set of standards. For the moment, it mainly focuses on encryption
 | 
				
			||||||
 | 
					and signing based on the JSON Web Encryption and JSON Web Signature standards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Disclaimer**: This library contains encryption software that is subject to
 | 
				
			||||||
 | 
					the U.S. Export Administration Regulations. You may not export, re-export,
 | 
				
			||||||
 | 
					transfer or download this code or any part of it in violation of any United
 | 
				
			||||||
 | 
					States law, directive or regulation. In particular this software may not be
 | 
				
			||||||
 | 
					exported or re-exported in any form or on any media to Iran, North Sudan,
 | 
				
			||||||
 | 
					Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any
 | 
				
			||||||
 | 
					US maintained blocked list.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Overview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The implementation follows the
 | 
				
			||||||
 | 
					[JSON Web Encryption](http://dx.doi.org/10.17487/RFC7516)
 | 
				
			||||||
 | 
					standard (RFC 7516) and
 | 
				
			||||||
 | 
					[JSON Web Signature](http://dx.doi.org/10.17487/RFC7515)
 | 
				
			||||||
 | 
					standard (RFC 7515). Tables of supported algorithms are shown below.
 | 
				
			||||||
 | 
					The library supports both the compact and full serialization formats, and has
 | 
				
			||||||
 | 
					optional support for multiple recipients. It also comes with a small
 | 
				
			||||||
 | 
					command-line utility
 | 
				
			||||||
 | 
					([`jose-util`](https://github.com/square/go-jose/tree/master/jose-util))
 | 
				
			||||||
 | 
					for dealing with JOSE messages in a shell.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Note**: We use a forked version of the `encoding/json` package from the Go
 | 
				
			||||||
 | 
					standard library which uses case-sensitive matching for member names (instead
 | 
				
			||||||
 | 
					of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)).
 | 
				
			||||||
 | 
					This is to avoid differences in interpretation of messages between go-jose and
 | 
				
			||||||
 | 
					libraries in other languages. If you do not like this behavior, you can use the
 | 
				
			||||||
 | 
					`std_json` build tag to disable it (though we do not recommend doing so).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We use [gopkg.in](https://gopkg.in) for versioning.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Version 1](https://gopkg.in/square/go-jose.v1) is the current stable version:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import "gopkg.in/square/go-jose.v1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The interface for [go-jose.v1](https://gopkg.in/square/go-jose.v1) will remain
 | 
				
			||||||
 | 
					backwards compatible. We're currently sketching out ideas for a new version, to
 | 
				
			||||||
 | 
					clean up the interface a bit. If you have ideas or feature requests [please let
 | 
				
			||||||
 | 
					us know](https://github.com/square/go-jose/issues/64)!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Supported algorithms
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See below for a table of supported algorithms. Algorithm identifiers match
 | 
				
			||||||
 | 
					the names in the
 | 
				
			||||||
 | 
					[JSON Web Algorithms](http://dx.doi.org/10.17487/RFC7518)
 | 
				
			||||||
 | 
					standard where possible. The
 | 
				
			||||||
 | 
					[Godoc reference](https://godoc.org/github.com/square/go-jose#pkg-constants)
 | 
				
			||||||
 | 
					has a list of constants.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Key encryption             | Algorithm identifier(s)
 | 
				
			||||||
 | 
					 :------------------------- | :------------------------------
 | 
				
			||||||
 | 
					 RSA-PKCS#1v1.5             | RSA1_5
 | 
				
			||||||
 | 
					 RSA-OAEP                   | RSA-OAEP, RSA-OAEP-256
 | 
				
			||||||
 | 
					 AES key wrap               | A128KW, A192KW, A256KW
 | 
				
			||||||
 | 
					 AES-GCM key wrap           | A128GCMKW, A192GCMKW, A256GCMKW
 | 
				
			||||||
 | 
					 ECDH-ES + AES key wrap     | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
 | 
				
			||||||
 | 
					 ECDH-ES (direct)           | ECDH-ES<sup>1</sup>
 | 
				
			||||||
 | 
					 Direct encryption          | dir<sup>1</sup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<sup>1. Not supported in multi-recipient mode</sup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Signing / MAC              | Algorithm identifier(s)
 | 
				
			||||||
 | 
					 :------------------------- | :------------------------------
 | 
				
			||||||
 | 
					 RSASSA-PKCS#1v1.5          | RS256, RS384, RS512
 | 
				
			||||||
 | 
					 RSASSA-PSS                 | PS256, PS384, PS512
 | 
				
			||||||
 | 
					 HMAC                       | HS256, HS384, HS512
 | 
				
			||||||
 | 
					 ECDSA                      | ES256, ES384, ES512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Content encryption         | Algorithm identifier(s)
 | 
				
			||||||
 | 
					 :------------------------- | :------------------------------
 | 
				
			||||||
 | 
					 AES-CBC+HMAC               | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512
 | 
				
			||||||
 | 
					 AES-GCM                    | A128GCM, A192GCM, A256GCM 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Compression                | Algorithm identifiers(s)
 | 
				
			||||||
 | 
					 :------------------------- | -------------------------------
 | 
				
			||||||
 | 
					 DEFLATE (RFC 1951)         | DEF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Supported key types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					See below for a table of supported key types. These are understood by the
 | 
				
			||||||
 | 
					library, and can be passed to corresponding functions such as `NewEncrypter` or
 | 
				
			||||||
 | 
					`NewSigner`. Note that if you are creating a new encrypter or signer with a
 | 
				
			||||||
 | 
					JsonWebKey, the key id of the JsonWebKey (if present) will be added to any
 | 
				
			||||||
 | 
					resulting messages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 Algorithm(s)               | Corresponding types
 | 
				
			||||||
 | 
					 :------------------------- | -------------------------------
 | 
				
			||||||
 | 
					 RSA                        | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey), *[jose.JsonWebKey](https://godoc.org/github.com/square/go-jose#JsonWebKey)
 | 
				
			||||||
 | 
					 ECDH, ECDSA                | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey), *[jose.JsonWebKey](https://godoc.org/github.com/square/go-jose#JsonWebKey)
 | 
				
			||||||
 | 
					 AES, HMAC                  | []byte, *[jose.JsonWebKey](https://godoc.org/github.com/square/go-jose#JsonWebKey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Encryption/decryption example using RSA:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```Go
 | 
				
			||||||
 | 
					// Generate a public/private key pair to use for this example. The library
 | 
				
			||||||
 | 
					// also provides two utility functions (LoadPublicKey and LoadPrivateKey)
 | 
				
			||||||
 | 
					// that can be used to load keys from PEM/DER-encoded data.
 | 
				
			||||||
 | 
					privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Instantiate an encrypter using RSA-OAEP with AES128-GCM. An error would
 | 
				
			||||||
 | 
					// indicate that the selected algorithm(s) are not currently supported.
 | 
				
			||||||
 | 
					publicKey := &privateKey.PublicKey
 | 
				
			||||||
 | 
					encrypter, err := NewEncrypter(RSA_OAEP, A128GCM, publicKey)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypt a sample plaintext. Calling the encrypter returns an encrypted
 | 
				
			||||||
 | 
					// JWE object, which can then be serialized for output afterwards. An error
 | 
				
			||||||
 | 
					// would indicate a problem in an underlying cryptographic primitive.
 | 
				
			||||||
 | 
					var plaintext = []byte("Lorem ipsum dolor sit amet")
 | 
				
			||||||
 | 
					object, err := encrypter.Encrypt(plaintext)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Serialize the encrypted object using the full serialization format.
 | 
				
			||||||
 | 
					// Alternatively you can also use the compact format here by calling
 | 
				
			||||||
 | 
					// object.CompactSerialize() instead.
 | 
				
			||||||
 | 
					serialized := object.FullSerialize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parse the serialized, encrypted JWE object. An error would indicate that
 | 
				
			||||||
 | 
					// the given input did not represent a valid message.
 | 
				
			||||||
 | 
					object, err = ParseEncrypted(serialized)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Now we can decrypt and get back our original plaintext. An error here
 | 
				
			||||||
 | 
					// would indicate the the message failed to decrypt, e.g. because the auth
 | 
				
			||||||
 | 
					// tag was broken or the message was tampered with.
 | 
				
			||||||
 | 
					decrypted, err := object.Decrypt(privateKey)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fmt.Printf(string(decrypted))
 | 
				
			||||||
 | 
					// output: Lorem ipsum dolor sit amet
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Signing/verification example using RSA:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```Go
 | 
				
			||||||
 | 
					// Generate a public/private key pair to use for this example. The library
 | 
				
			||||||
 | 
					// also provides two utility functions (LoadPublicKey and LoadPrivateKey)
 | 
				
			||||||
 | 
					// that can be used to load keys from PEM/DER-encoded data.
 | 
				
			||||||
 | 
					privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Instantiate a signer using RSASSA-PSS (SHA512) with the given private key.
 | 
				
			||||||
 | 
					signer, err := NewSigner(PS512, privateKey)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sign a sample payload. Calling the signer returns a protected JWS object,
 | 
				
			||||||
 | 
					// which can then be serialized for output afterwards. An error would
 | 
				
			||||||
 | 
					// indicate a problem in an underlying cryptographic primitive.
 | 
				
			||||||
 | 
					var payload = []byte("Lorem ipsum dolor sit amet")
 | 
				
			||||||
 | 
					object, err := signer.Sign(payload)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Serialize the encrypted object using the full serialization format.
 | 
				
			||||||
 | 
					// Alternatively you can also use the compact format here by calling
 | 
				
			||||||
 | 
					// object.CompactSerialize() instead.
 | 
				
			||||||
 | 
					serialized := object.FullSerialize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parse the serialized, protected JWS object. An error would indicate that
 | 
				
			||||||
 | 
					// the given input did not represent a valid message.
 | 
				
			||||||
 | 
					object, err = ParseSigned(serialized)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Now we can verify the signature on the payload. An error here would
 | 
				
			||||||
 | 
					// indicate the the message failed to verify, e.g. because the signature was
 | 
				
			||||||
 | 
					// broken or the message was tampered with.
 | 
				
			||||||
 | 
					output, err := object.Verify(&privateKey.PublicKey)
 | 
				
			||||||
 | 
					if err != nil {
 | 
				
			||||||
 | 
						panic(err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fmt.Printf(string(output))
 | 
				
			||||||
 | 
					// output: Lorem ipsum dolor sit amet
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More examples can be found in the [Godoc
 | 
				
			||||||
 | 
					reference](https://godoc.org/github.com/square/go-jose) for this package. The
 | 
				
			||||||
 | 
					[`jose-util`](https://github.com/square/go-jose/tree/master/jose-util)
 | 
				
			||||||
 | 
					subdirectory also contains a small command-line utility which might
 | 
				
			||||||
 | 
					be useful as an example.
 | 
				
			||||||
							
								
								
									
										520
									
								
								vendor/github.com/square/go-jose/asymmetric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										520
									
								
								vendor/github.com/square/go-jose/asymmetric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,520 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto"
 | 
				
			||||||
 | 
						"crypto/aes"
 | 
				
			||||||
 | 
						"crypto/ecdsa"
 | 
				
			||||||
 | 
						"crypto/rand"
 | 
				
			||||||
 | 
						"crypto/rsa"
 | 
				
			||||||
 | 
						"crypto/sha1"
 | 
				
			||||||
 | 
						"crypto/sha256"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/square/go-jose/cipher"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic RSA-based encrypter/verifier
 | 
				
			||||||
 | 
					type rsaEncrypterVerifier struct {
 | 
				
			||||||
 | 
						publicKey *rsa.PublicKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic RSA-based decrypter/signer
 | 
				
			||||||
 | 
					type rsaDecrypterSigner struct {
 | 
				
			||||||
 | 
						privateKey *rsa.PrivateKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic EC-based encrypter/verifier
 | 
				
			||||||
 | 
					type ecEncrypterVerifier struct {
 | 
				
			||||||
 | 
						publicKey *ecdsa.PublicKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A key generator for ECDH-ES
 | 
				
			||||||
 | 
					type ecKeyGenerator struct {
 | 
				
			||||||
 | 
						size      int
 | 
				
			||||||
 | 
						algID     string
 | 
				
			||||||
 | 
						publicKey *ecdsa.PublicKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic EC-based decrypter/signer
 | 
				
			||||||
 | 
					type ecDecrypterSigner struct {
 | 
				
			||||||
 | 
						privateKey *ecdsa.PrivateKey
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newRSARecipient creates recipientKeyInfo based on the given key.
 | 
				
			||||||
 | 
					func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) {
 | 
				
			||||||
 | 
						// Verify that key management algorithm is supported by this encrypter
 | 
				
			||||||
 | 
						switch keyAlg {
 | 
				
			||||||
 | 
						case RSA1_5, RSA_OAEP, RSA_OAEP_256:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientKeyInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if publicKey == nil {
 | 
				
			||||||
 | 
							return recipientKeyInfo{}, errors.New("invalid public key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientKeyInfo{
 | 
				
			||||||
 | 
							keyAlg: keyAlg,
 | 
				
			||||||
 | 
							keyEncrypter: &rsaEncrypterVerifier{
 | 
				
			||||||
 | 
								publicKey: publicKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newRSASigner creates a recipientSigInfo based on the given key.
 | 
				
			||||||
 | 
					func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) {
 | 
				
			||||||
 | 
						// Verify that key management algorithm is supported by this encrypter
 | 
				
			||||||
 | 
						switch sigAlg {
 | 
				
			||||||
 | 
						case RS256, RS384, RS512, PS256, PS384, PS512:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientSigInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if privateKey == nil {
 | 
				
			||||||
 | 
							return recipientSigInfo{}, errors.New("invalid private key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientSigInfo{
 | 
				
			||||||
 | 
							sigAlg: sigAlg,
 | 
				
			||||||
 | 
							publicKey: &JsonWebKey{
 | 
				
			||||||
 | 
								Key: &privateKey.PublicKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							signer: &rsaDecrypterSigner{
 | 
				
			||||||
 | 
								privateKey: privateKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newECDHRecipient creates recipientKeyInfo based on the given key.
 | 
				
			||||||
 | 
					func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) {
 | 
				
			||||||
 | 
						// Verify that key management algorithm is supported by this encrypter
 | 
				
			||||||
 | 
						switch keyAlg {
 | 
				
			||||||
 | 
						case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientKeyInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
 | 
				
			||||||
 | 
							return recipientKeyInfo{}, errors.New("invalid public key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientKeyInfo{
 | 
				
			||||||
 | 
							keyAlg: keyAlg,
 | 
				
			||||||
 | 
							keyEncrypter: &ecEncrypterVerifier{
 | 
				
			||||||
 | 
								publicKey: publicKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newECDSASigner creates a recipientSigInfo based on the given key.
 | 
				
			||||||
 | 
					func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) {
 | 
				
			||||||
 | 
						// Verify that key management algorithm is supported by this encrypter
 | 
				
			||||||
 | 
						switch sigAlg {
 | 
				
			||||||
 | 
						case ES256, ES384, ES512:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientSigInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if privateKey == nil {
 | 
				
			||||||
 | 
							return recipientSigInfo{}, errors.New("invalid private key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientSigInfo{
 | 
				
			||||||
 | 
							sigAlg: sigAlg,
 | 
				
			||||||
 | 
							publicKey: &JsonWebKey{
 | 
				
			||||||
 | 
								Key: &privateKey.PublicKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							signer: &ecDecrypterSigner{
 | 
				
			||||||
 | 
								privateKey: privateKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypt the given payload and update the object.
 | 
				
			||||||
 | 
					func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
 | 
				
			||||||
 | 
						encryptedKey, err := ctx.encrypt(cek, alg)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return recipientInfo{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientInfo{
 | 
				
			||||||
 | 
							encryptedKey: encryptedKey,
 | 
				
			||||||
 | 
							header:       &rawHeader{},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypt the given payload. Based on the key encryption algorithm,
 | 
				
			||||||
 | 
					// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
 | 
				
			||||||
 | 
					func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) {
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case RSA1_5:
 | 
				
			||||||
 | 
							return rsa.EncryptPKCS1v15(randReader, ctx.publicKey, cek)
 | 
				
			||||||
 | 
						case RSA_OAEP:
 | 
				
			||||||
 | 
							return rsa.EncryptOAEP(sha1.New(), randReader, ctx.publicKey, cek, []byte{})
 | 
				
			||||||
 | 
						case RSA_OAEP_256:
 | 
				
			||||||
 | 
							return rsa.EncryptOAEP(sha256.New(), randReader, ctx.publicKey, cek, []byte{})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decrypt the given payload and return the content encryption key.
 | 
				
			||||||
 | 
					func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
 | 
				
			||||||
 | 
						return ctx.decrypt(recipient.encryptedKey, KeyAlgorithm(headers.Alg), generator)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decrypt the given payload. Based on the key encryption algorithm,
 | 
				
			||||||
 | 
					// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
 | 
				
			||||||
 | 
					func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) {
 | 
				
			||||||
 | 
						// Note: The random reader on decrypt operations is only used for blinding,
 | 
				
			||||||
 | 
						// so stubbing is meanlingless (hence the direct use of rand.Reader).
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case RSA1_5:
 | 
				
			||||||
 | 
							defer func() {
 | 
				
			||||||
 | 
								// DecryptPKCS1v15SessionKey sometimes panics on an invalid payload
 | 
				
			||||||
 | 
								// because of an index out of bounds error, which we want to ignore.
 | 
				
			||||||
 | 
								// This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()
 | 
				
			||||||
 | 
								// only exists for preventing crashes with unpatched versions.
 | 
				
			||||||
 | 
								// See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k
 | 
				
			||||||
 | 
								// See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33
 | 
				
			||||||
 | 
								_ = recover()
 | 
				
			||||||
 | 
							}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Perform some input validation.
 | 
				
			||||||
 | 
							keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8
 | 
				
			||||||
 | 
							if keyBytes != len(jek) {
 | 
				
			||||||
 | 
								// Input size is incorrect, the encrypted payload should always match
 | 
				
			||||||
 | 
								// the size of the public modulus (e.g. using a 2048 bit key will
 | 
				
			||||||
 | 
								// produce 256 bytes of output). Reject this since it's invalid input.
 | 
				
			||||||
 | 
								return nil, ErrCryptoFailure
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cek, _, err := generator.genKey()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, ErrCryptoFailure
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
 | 
				
			||||||
 | 
							// prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
 | 
				
			||||||
 | 
							// the Million Message Attack on Cryptographic Message Syntax". We are
 | 
				
			||||||
 | 
							// therefore deliberately ignoring errors here.
 | 
				
			||||||
 | 
							_ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return cek, nil
 | 
				
			||||||
 | 
						case RSA_OAEP:
 | 
				
			||||||
 | 
							// Use rand.Reader for RSA blinding
 | 
				
			||||||
 | 
							return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{})
 | 
				
			||||||
 | 
						case RSA_OAEP_256:
 | 
				
			||||||
 | 
							// Use rand.Reader for RSA blinding
 | 
				
			||||||
 | 
							return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sign the given payload
 | 
				
			||||||
 | 
					func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
 | 
				
			||||||
 | 
						var hash crypto.Hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case RS256, PS256:
 | 
				
			||||||
 | 
							hash = crypto.SHA256
 | 
				
			||||||
 | 
						case RS384, PS384:
 | 
				
			||||||
 | 
							hash = crypto.SHA384
 | 
				
			||||||
 | 
						case RS512, PS512:
 | 
				
			||||||
 | 
							hash = crypto.SHA512
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return Signature{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasher := hash.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to documentation, Write() on hash never fails
 | 
				
			||||||
 | 
						_, _ = hasher.Write(payload)
 | 
				
			||||||
 | 
						hashed := hasher.Sum(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var out []byte
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case RS256, RS384, RS512:
 | 
				
			||||||
 | 
							out, err = rsa.SignPKCS1v15(randReader, ctx.privateKey, hash, hashed)
 | 
				
			||||||
 | 
						case PS256, PS384, PS512:
 | 
				
			||||||
 | 
							out, err = rsa.SignPSS(randReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
 | 
				
			||||||
 | 
								SaltLength: rsa.PSSSaltLengthAuto,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return Signature{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Signature{
 | 
				
			||||||
 | 
							Signature: out,
 | 
				
			||||||
 | 
							protected: &rawHeader{},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Verify the given payload
 | 
				
			||||||
 | 
					func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
 | 
				
			||||||
 | 
						var hash crypto.Hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case RS256, PS256:
 | 
				
			||||||
 | 
							hash = crypto.SHA256
 | 
				
			||||||
 | 
						case RS384, PS384:
 | 
				
			||||||
 | 
							hash = crypto.SHA384
 | 
				
			||||||
 | 
						case RS512, PS512:
 | 
				
			||||||
 | 
							hash = crypto.SHA512
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasher := hash.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to documentation, Write() on hash never fails
 | 
				
			||||||
 | 
						_, _ = hasher.Write(payload)
 | 
				
			||||||
 | 
						hashed := hasher.Sum(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case RS256, RS384, RS512:
 | 
				
			||||||
 | 
							return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)
 | 
				
			||||||
 | 
						case PS256, PS384, PS512:
 | 
				
			||||||
 | 
							return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypt the given payload and update the object.
 | 
				
			||||||
 | 
					func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case ECDH_ES:
 | 
				
			||||||
 | 
							// ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key.
 | 
				
			||||||
 | 
							return recipientInfo{
 | 
				
			||||||
 | 
								header: &rawHeader{},
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						generator := ecKeyGenerator{
 | 
				
			||||||
 | 
							algID:     string(alg),
 | 
				
			||||||
 | 
							publicKey: ctx.publicKey,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case ECDH_ES_A128KW:
 | 
				
			||||||
 | 
							generator.size = 16
 | 
				
			||||||
 | 
						case ECDH_ES_A192KW:
 | 
				
			||||||
 | 
							generator.size = 24
 | 
				
			||||||
 | 
						case ECDH_ES_A256KW:
 | 
				
			||||||
 | 
							generator.size = 32
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kek, header, err := generator.genKey()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return recipientInfo{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block, err := aes.NewCipher(kek)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return recipientInfo{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						jek, err := josecipher.KeyWrap(block, cek)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return recipientInfo{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientInfo{
 | 
				
			||||||
 | 
							encryptedKey: jek,
 | 
				
			||||||
 | 
							header:       &header,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get key size for EC key generator
 | 
				
			||||||
 | 
					func (ctx ecKeyGenerator) keySize() int {
 | 
				
			||||||
 | 
						return ctx.size
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get a content encryption key for ECDH-ES
 | 
				
			||||||
 | 
					func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
 | 
				
			||||||
 | 
						priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, randReader)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, rawHeader{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						headers := rawHeader{
 | 
				
			||||||
 | 
							Epk: &JsonWebKey{
 | 
				
			||||||
 | 
								Key: &priv.PublicKey,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return out, headers, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decrypt the given payload and return the content encryption key.
 | 
				
			||||||
 | 
					func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
 | 
				
			||||||
 | 
						if headers.Epk == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: missing epk header")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						publicKey, ok := headers.Epk.Key.(*ecdsa.PublicKey)
 | 
				
			||||||
 | 
						if publicKey == nil || !ok {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid epk header")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid public key in epk header")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apuData := headers.Apu.bytes()
 | 
				
			||||||
 | 
						apvData := headers.Apv.bytes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						deriveKey := func(algID string, size int) []byte {
 | 
				
			||||||
 | 
							return josecipher.DeriveECDHES(algID, apuData, apvData, ctx.privateKey, publicKey, size)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var keySize int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch KeyAlgorithm(headers.Alg) {
 | 
				
			||||||
 | 
						case ECDH_ES:
 | 
				
			||||||
 | 
							// ECDH-ES uses direct key agreement, no key unwrapping necessary.
 | 
				
			||||||
 | 
							return deriveKey(string(headers.Enc), generator.keySize()), nil
 | 
				
			||||||
 | 
						case ECDH_ES_A128KW:
 | 
				
			||||||
 | 
							keySize = 16
 | 
				
			||||||
 | 
						case ECDH_ES_A192KW:
 | 
				
			||||||
 | 
							keySize = 24
 | 
				
			||||||
 | 
						case ECDH_ES_A256KW:
 | 
				
			||||||
 | 
							keySize = 32
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						key := deriveKey(headers.Alg, keySize)
 | 
				
			||||||
 | 
						block, err := aes.NewCipher(key)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return josecipher.KeyUnwrap(block, recipient.encryptedKey)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sign the given payload
 | 
				
			||||||
 | 
					func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
 | 
				
			||||||
 | 
						var expectedBitSize int
 | 
				
			||||||
 | 
						var hash crypto.Hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case ES256:
 | 
				
			||||||
 | 
							expectedBitSize = 256
 | 
				
			||||||
 | 
							hash = crypto.SHA256
 | 
				
			||||||
 | 
						case ES384:
 | 
				
			||||||
 | 
							expectedBitSize = 384
 | 
				
			||||||
 | 
							hash = crypto.SHA384
 | 
				
			||||||
 | 
						case ES512:
 | 
				
			||||||
 | 
							expectedBitSize = 521
 | 
				
			||||||
 | 
							hash = crypto.SHA512
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						curveBits := ctx.privateKey.Curve.Params().BitSize
 | 
				
			||||||
 | 
						if expectedBitSize != curveBits {
 | 
				
			||||||
 | 
							return Signature{}, fmt.Errorf("square/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasher := hash.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to documentation, Write() on hash never fails
 | 
				
			||||||
 | 
						_, _ = hasher.Write(payload)
 | 
				
			||||||
 | 
						hashed := hasher.Sum(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r, s, err := ecdsa.Sign(randReader, ctx.privateKey, hashed)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return Signature{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						keyBytes := curveBits / 8
 | 
				
			||||||
 | 
						if curveBits%8 > 0 {
 | 
				
			||||||
 | 
							keyBytes += 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We serialize the outpus (r and s) into big-endian byte arrays and pad
 | 
				
			||||||
 | 
						// them with zeros on the left to make sure the sizes work out. Both arrays
 | 
				
			||||||
 | 
						// must be keyBytes long, and the output must be 2*keyBytes long.
 | 
				
			||||||
 | 
						rBytes := r.Bytes()
 | 
				
			||||||
 | 
						rBytesPadded := make([]byte, keyBytes)
 | 
				
			||||||
 | 
						copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sBytes := s.Bytes()
 | 
				
			||||||
 | 
						sBytesPadded := make([]byte, keyBytes)
 | 
				
			||||||
 | 
						copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := append(rBytesPadded, sBytesPadded...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Signature{
 | 
				
			||||||
 | 
							Signature: out,
 | 
				
			||||||
 | 
							protected: &rawHeader{},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Verify the given payload
 | 
				
			||||||
 | 
					func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
 | 
				
			||||||
 | 
						var keySize int
 | 
				
			||||||
 | 
						var hash crypto.Hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case ES256:
 | 
				
			||||||
 | 
							keySize = 32
 | 
				
			||||||
 | 
							hash = crypto.SHA256
 | 
				
			||||||
 | 
						case ES384:
 | 
				
			||||||
 | 
							keySize = 48
 | 
				
			||||||
 | 
							hash = crypto.SHA384
 | 
				
			||||||
 | 
						case ES512:
 | 
				
			||||||
 | 
							keySize = 66
 | 
				
			||||||
 | 
							hash = crypto.SHA512
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(signature) != 2*keySize {
 | 
				
			||||||
 | 
							return fmt.Errorf("square/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasher := hash.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to documentation, Write() on hash never fails
 | 
				
			||||||
 | 
						_, _ = hasher.Write(payload)
 | 
				
			||||||
 | 
						hashed := hasher.Sum(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r := big.NewInt(0).SetBytes(signature[:keySize])
 | 
				
			||||||
 | 
						s := big.NewInt(0).SetBytes(signature[keySize:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						match := ecdsa.Verify(ctx.publicKey, hashed, r, s)
 | 
				
			||||||
 | 
						if !match {
 | 
				
			||||||
 | 
							return errors.New("square/go-jose: ecdsa signature failed to verify")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										196
									
								
								vendor/github.com/square/go-jose/cipher/cbc_hmac.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								vendor/github.com/square/go-jose/cipher/cbc_hmac.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,196 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package josecipher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"crypto/cipher"
 | 
				
			||||||
 | 
						"crypto/hmac"
 | 
				
			||||||
 | 
						"crypto/sha256"
 | 
				
			||||||
 | 
						"crypto/sha512"
 | 
				
			||||||
 | 
						"crypto/subtle"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"hash"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						nonceBytes = 16
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC.
 | 
				
			||||||
 | 
					func NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) {
 | 
				
			||||||
 | 
						keySize := len(key) / 2
 | 
				
			||||||
 | 
						integrityKey := key[:keySize]
 | 
				
			||||||
 | 
						encryptionKey := key[keySize:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						blockCipher, err := newBlockCipher(encryptionKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var hash func() hash.Hash
 | 
				
			||||||
 | 
						switch keySize {
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							hash = sha256.New
 | 
				
			||||||
 | 
						case 24:
 | 
				
			||||||
 | 
							hash = sha512.New384
 | 
				
			||||||
 | 
						case 32:
 | 
				
			||||||
 | 
							hash = sha512.New
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &cbcAEAD{
 | 
				
			||||||
 | 
							hash:         hash,
 | 
				
			||||||
 | 
							blockCipher:  blockCipher,
 | 
				
			||||||
 | 
							authtagBytes: keySize,
 | 
				
			||||||
 | 
							integrityKey: integrityKey,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An AEAD based on CBC+HMAC
 | 
				
			||||||
 | 
					type cbcAEAD struct {
 | 
				
			||||||
 | 
						hash         func() hash.Hash
 | 
				
			||||||
 | 
						authtagBytes int
 | 
				
			||||||
 | 
						integrityKey []byte
 | 
				
			||||||
 | 
						blockCipher  cipher.Block
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *cbcAEAD) NonceSize() int {
 | 
				
			||||||
 | 
						return nonceBytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *cbcAEAD) Overhead() int {
 | 
				
			||||||
 | 
						// Maximum overhead is block size (for padding) plus auth tag length, where
 | 
				
			||||||
 | 
						// the length of the auth tag is equivalent to the key size.
 | 
				
			||||||
 | 
						return ctx.blockCipher.BlockSize() + ctx.authtagBytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Seal encrypts and authenticates the plaintext.
 | 
				
			||||||
 | 
					func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
 | 
				
			||||||
 | 
						// Output buffer -- must take care not to mangle plaintext input.
 | 
				
			||||||
 | 
						ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]
 | 
				
			||||||
 | 
						copy(ciphertext, plaintext)
 | 
				
			||||||
 | 
						ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cbc.CryptBlocks(ciphertext, ciphertext)
 | 
				
			||||||
 | 
						authtag := ctx.computeAuthTag(data, nonce, ciphertext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))
 | 
				
			||||||
 | 
						copy(out, ciphertext)
 | 
				
			||||||
 | 
						copy(out[len(ciphertext):], authtag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Open decrypts and authenticates the ciphertext.
 | 
				
			||||||
 | 
					func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						if len(ciphertext) < ctx.authtagBytes {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid ciphertext (too short)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						offset := len(ciphertext) - ctx.authtagBytes
 | 
				
			||||||
 | 
						expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])
 | 
				
			||||||
 | 
						match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])
 | 
				
			||||||
 | 
						if match != 1 {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid ciphertext (auth tag mismatch)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Make copy of ciphertext buffer, don't want to modify in place
 | 
				
			||||||
 | 
						buffer := append([]byte{}, []byte(ciphertext[:offset])...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(buffer)%ctx.blockCipher.BlockSize() > 0 {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid ciphertext (invalid length)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cbc.CryptBlocks(buffer, buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Remove padding
 | 
				
			||||||
 | 
						plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))
 | 
				
			||||||
 | 
						copy(out, plaintext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compute an authentication tag
 | 
				
			||||||
 | 
					func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
 | 
				
			||||||
 | 
						buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)
 | 
				
			||||||
 | 
						n := 0
 | 
				
			||||||
 | 
						n += copy(buffer, aad)
 | 
				
			||||||
 | 
						n += copy(buffer[n:], nonce)
 | 
				
			||||||
 | 
						n += copy(buffer[n:], ciphertext)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to documentation, Write() on hash.Hash never fails.
 | 
				
			||||||
 | 
						hmac := hmac.New(ctx.hash, ctx.integrityKey)
 | 
				
			||||||
 | 
						_, _ = hmac.Write(buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return hmac.Sum(nil)[:ctx.authtagBytes]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// resize ensures the the given slice has a capacity of at least n bytes.
 | 
				
			||||||
 | 
					// If the capacity of the slice is less than n, a new slice is allocated
 | 
				
			||||||
 | 
					// and the existing data will be copied.
 | 
				
			||||||
 | 
					func resize(in []byte, n uint64) (head, tail []byte) {
 | 
				
			||||||
 | 
						if uint64(cap(in)) >= n {
 | 
				
			||||||
 | 
							head = in[:n]
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							head = make([]byte, n)
 | 
				
			||||||
 | 
							copy(head, in)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tail = head[len(in):]
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Apply padding
 | 
				
			||||||
 | 
					func padBuffer(buffer []byte, blockSize int) []byte {
 | 
				
			||||||
 | 
						missing := blockSize - (len(buffer) % blockSize)
 | 
				
			||||||
 | 
						ret, out := resize(buffer, uint64(len(buffer))+uint64(missing))
 | 
				
			||||||
 | 
						padding := bytes.Repeat([]byte{byte(missing)}, missing)
 | 
				
			||||||
 | 
						copy(out, padding)
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Remove padding
 | 
				
			||||||
 | 
					func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) {
 | 
				
			||||||
 | 
						if len(buffer)%blockSize != 0 {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid padding")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						last := buffer[len(buffer)-1]
 | 
				
			||||||
 | 
						count := int(last)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if count == 0 || count > blockSize || count > len(buffer) {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid padding")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						padding := bytes.Repeat([]byte{last}, count)
 | 
				
			||||||
 | 
						if !bytes.HasSuffix(buffer, padding) {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid padding")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return buffer[:len(buffer)-count], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								vendor/github.com/square/go-jose/cipher/concat_kdf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								vendor/github.com/square/go-jose/cipher/concat_kdf.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package josecipher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"hash"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type concatKDF struct {
 | 
				
			||||||
 | 
						z, info []byte
 | 
				
			||||||
 | 
						i       uint32
 | 
				
			||||||
 | 
						cache   []byte
 | 
				
			||||||
 | 
						hasher  hash.Hash
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewConcatKDF builds a KDF reader based on the given inputs.
 | 
				
			||||||
 | 
					func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {
 | 
				
			||||||
 | 
						buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))
 | 
				
			||||||
 | 
						n := 0
 | 
				
			||||||
 | 
						n += copy(buffer, algID)
 | 
				
			||||||
 | 
						n += copy(buffer[n:], ptyUInfo)
 | 
				
			||||||
 | 
						n += copy(buffer[n:], ptyVInfo)
 | 
				
			||||||
 | 
						n += copy(buffer[n:], supPubInfo)
 | 
				
			||||||
 | 
						copy(buffer[n:], supPrivInfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hasher := hash.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &concatKDF{
 | 
				
			||||||
 | 
							z:      z,
 | 
				
			||||||
 | 
							info:   buffer,
 | 
				
			||||||
 | 
							hasher: hasher,
 | 
				
			||||||
 | 
							cache:  []byte{},
 | 
				
			||||||
 | 
							i:      1,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *concatKDF) Read(out []byte) (int, error) {
 | 
				
			||||||
 | 
						copied := copy(out, ctx.cache)
 | 
				
			||||||
 | 
						ctx.cache = ctx.cache[copied:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for copied < len(out) {
 | 
				
			||||||
 | 
							ctx.hasher.Reset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Write on a hash.Hash never fails
 | 
				
			||||||
 | 
							_ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i)
 | 
				
			||||||
 | 
							_, _ = ctx.hasher.Write(ctx.z)
 | 
				
			||||||
 | 
							_, _ = ctx.hasher.Write(ctx.info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							hash := ctx.hasher.Sum(nil)
 | 
				
			||||||
 | 
							chunkCopied := copy(out[copied:], hash)
 | 
				
			||||||
 | 
							copied += chunkCopied
 | 
				
			||||||
 | 
							ctx.cache = hash[chunkCopied:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ctx.i++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return copied, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										62
									
								
								vendor/github.com/square/go-jose/cipher/ecdh_es.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/square/go-jose/cipher/ecdh_es.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package josecipher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto"
 | 
				
			||||||
 | 
						"crypto/ecdsa"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.
 | 
				
			||||||
 | 
					// It is an error to call this function with a private/public key that are not on the same
 | 
				
			||||||
 | 
					// curve. Callers must ensure that the keys are valid before calling this function. Output
 | 
				
			||||||
 | 
					// size may be at most 1<<16 bytes (64 KiB).
 | 
				
			||||||
 | 
					func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {
 | 
				
			||||||
 | 
						if size > 1<<16 {
 | 
				
			||||||
 | 
							panic("ECDH-ES output size too large, must be less than 1<<16")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// algId, partyUInfo, partyVInfo inputs must be prefixed with the length
 | 
				
			||||||
 | 
						algID := lengthPrefixed([]byte(alg))
 | 
				
			||||||
 | 
						ptyUInfo := lengthPrefixed(apuData)
 | 
				
			||||||
 | 
						ptyVInfo := lengthPrefixed(apvData)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// suppPubInfo is the encoded length of the output size in bits
 | 
				
			||||||
 | 
						supPubInfo := make([]byte, 4)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {
 | 
				
			||||||
 | 
							panic("public key not on same curve as private key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						z, _ := priv.PublicKey.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
 | 
				
			||||||
 | 
						reader := NewConcatKDF(crypto.SHA256, z.Bytes(), algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						key := make([]byte, size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read on the KDF will never fail
 | 
				
			||||||
 | 
						_, _ = reader.Read(key)
 | 
				
			||||||
 | 
						return key
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func lengthPrefixed(data []byte) []byte {
 | 
				
			||||||
 | 
						out := make([]byte, len(data)+4)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint32(out, uint32(len(data)))
 | 
				
			||||||
 | 
						copy(out[4:], data)
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										109
									
								
								vendor/github.com/square/go-jose/cipher/key_wrap.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/square/go-jose/cipher/key_wrap.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package josecipher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/cipher"
 | 
				
			||||||
 | 
						"crypto/subtle"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher.
 | 
				
			||||||
 | 
					func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						if len(cek)%8 != 0 {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: key wrap input must be 8 byte blocks")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n := len(cek) / 8
 | 
				
			||||||
 | 
						r := make([][]byte, n)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := range r {
 | 
				
			||||||
 | 
							r[i] = make([]byte, 8)
 | 
				
			||||||
 | 
							copy(r[i], cek[i*8:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer := make([]byte, 16)
 | 
				
			||||||
 | 
						tBytes := make([]byte, 8)
 | 
				
			||||||
 | 
						copy(buffer, defaultIV)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for t := 0; t < 6*n; t++ {
 | 
				
			||||||
 | 
							copy(buffer[8:], r[t%n])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							block.Encrypt(buffer, buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint64(tBytes, uint64(t+1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for i := 0; i < 8; i++ {
 | 
				
			||||||
 | 
								buffer[i] = buffer[i] ^ tBytes[i]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							copy(r[t%n], buffer[8:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := make([]byte, (n+1)*8)
 | 
				
			||||||
 | 
						copy(out, buffer[:8])
 | 
				
			||||||
 | 
						for i := range r {
 | 
				
			||||||
 | 
							copy(out[(i+1)*8:], r[i])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return out, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher.
 | 
				
			||||||
 | 
					func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						if len(ciphertext)%8 != 0 {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: key wrap input must be 8 byte blocks")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						n := (len(ciphertext) / 8) - 1
 | 
				
			||||||
 | 
						r := make([][]byte, n)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := range r {
 | 
				
			||||||
 | 
							r[i] = make([]byte, 8)
 | 
				
			||||||
 | 
							copy(r[i], ciphertext[(i+1)*8:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						buffer := make([]byte, 16)
 | 
				
			||||||
 | 
						tBytes := make([]byte, 8)
 | 
				
			||||||
 | 
						copy(buffer[:8], ciphertext[:8])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for t := 6*n - 1; t >= 0; t-- {
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint64(tBytes, uint64(t+1))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for i := 0; i < 8; i++ {
 | 
				
			||||||
 | 
								buffer[i] = buffer[i] ^ tBytes[i]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							copy(buffer[8:], r[t%n])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							block.Decrypt(buffer, buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							copy(r[t%n], buffer[8:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: failed to unwrap key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						out := make([]byte, n*8)
 | 
				
			||||||
 | 
						for i := range r {
 | 
				
			||||||
 | 
							copy(out[i*8:], r[i])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return out, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										349
									
								
								vendor/github.com/square/go-jose/crypter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								vendor/github.com/square/go-jose/crypter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,349 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/ecdsa"
 | 
				
			||||||
 | 
						"crypto/rsa"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypter represents an encrypter which produces an encrypted JWE object.
 | 
				
			||||||
 | 
					type Encrypter interface {
 | 
				
			||||||
 | 
						Encrypt(plaintext []byte) (*JsonWebEncryption, error)
 | 
				
			||||||
 | 
						EncryptWithAuthData(plaintext []byte, aad []byte) (*JsonWebEncryption, error)
 | 
				
			||||||
 | 
						SetCompression(alg CompressionAlgorithm)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MultiEncrypter represents an encrypter which supports multiple recipients.
 | 
				
			||||||
 | 
					type MultiEncrypter interface {
 | 
				
			||||||
 | 
						Encrypt(plaintext []byte) (*JsonWebEncryption, error)
 | 
				
			||||||
 | 
						EncryptWithAuthData(plaintext []byte, aad []byte) (*JsonWebEncryption, error)
 | 
				
			||||||
 | 
						SetCompression(alg CompressionAlgorithm)
 | 
				
			||||||
 | 
						AddRecipient(alg KeyAlgorithm, encryptionKey interface{}) error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic content cipher
 | 
				
			||||||
 | 
					type contentCipher interface {
 | 
				
			||||||
 | 
						keySize() int
 | 
				
			||||||
 | 
						encrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error)
 | 
				
			||||||
 | 
						decrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A key generator (for generating/getting a CEK)
 | 
				
			||||||
 | 
					type keyGenerator interface {
 | 
				
			||||||
 | 
						keySize() int
 | 
				
			||||||
 | 
						genKey() ([]byte, rawHeader, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic key encrypter
 | 
				
			||||||
 | 
					type keyEncrypter interface {
 | 
				
			||||||
 | 
						encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic key decrypter
 | 
				
			||||||
 | 
					type keyDecrypter interface {
 | 
				
			||||||
 | 
						decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A generic encrypter based on the given key encrypter and content cipher.
 | 
				
			||||||
 | 
					type genericEncrypter struct {
 | 
				
			||||||
 | 
						contentAlg     ContentEncryption
 | 
				
			||||||
 | 
						compressionAlg CompressionAlgorithm
 | 
				
			||||||
 | 
						cipher         contentCipher
 | 
				
			||||||
 | 
						recipients     []recipientKeyInfo
 | 
				
			||||||
 | 
						keyGenerator   keyGenerator
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type recipientKeyInfo struct {
 | 
				
			||||||
 | 
						keyID        string
 | 
				
			||||||
 | 
						keyAlg       KeyAlgorithm
 | 
				
			||||||
 | 
						keyEncrypter keyEncrypter
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetCompression sets a compression algorithm to be applied before encryption.
 | 
				
			||||||
 | 
					func (ctx *genericEncrypter) SetCompression(compressionAlg CompressionAlgorithm) {
 | 
				
			||||||
 | 
						ctx.compressionAlg = compressionAlg
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewEncrypter creates an appropriate encrypter based on the key type
 | 
				
			||||||
 | 
					func NewEncrypter(alg KeyAlgorithm, enc ContentEncryption, encryptionKey interface{}) (Encrypter, error) {
 | 
				
			||||||
 | 
						encrypter := &genericEncrypter{
 | 
				
			||||||
 | 
							contentAlg:     enc,
 | 
				
			||||||
 | 
							compressionAlg: NONE,
 | 
				
			||||||
 | 
							recipients:     []recipientKeyInfo{},
 | 
				
			||||||
 | 
							cipher:         getContentCipher(enc),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if encrypter.cipher == nil {
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var keyID string
 | 
				
			||||||
 | 
						var rawKey interface{}
 | 
				
			||||||
 | 
						switch encryptionKey := encryptionKey.(type) {
 | 
				
			||||||
 | 
						case *JsonWebKey:
 | 
				
			||||||
 | 
							keyID = encryptionKey.KeyID
 | 
				
			||||||
 | 
							rawKey = encryptionKey.Key
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							rawKey = encryptionKey
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case DIRECT:
 | 
				
			||||||
 | 
							// Direct encryption mode must be treated differently
 | 
				
			||||||
 | 
							if reflect.TypeOf(rawKey) != reflect.TypeOf([]byte{}) {
 | 
				
			||||||
 | 
								return nil, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							encrypter.keyGenerator = staticKeyGenerator{
 | 
				
			||||||
 | 
								key: rawKey.([]byte),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							recipient, _ := newSymmetricRecipient(alg, rawKey.([]byte))
 | 
				
			||||||
 | 
							if keyID != "" {
 | 
				
			||||||
 | 
								recipient.keyID = keyID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							encrypter.recipients = []recipientKeyInfo{recipient}
 | 
				
			||||||
 | 
							return encrypter, nil
 | 
				
			||||||
 | 
						case ECDH_ES:
 | 
				
			||||||
 | 
							// ECDH-ES (w/o key wrapping) is similar to DIRECT mode
 | 
				
			||||||
 | 
							typeOf := reflect.TypeOf(rawKey)
 | 
				
			||||||
 | 
							if typeOf != reflect.TypeOf(&ecdsa.PublicKey{}) {
 | 
				
			||||||
 | 
								return nil, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							encrypter.keyGenerator = ecKeyGenerator{
 | 
				
			||||||
 | 
								size:      encrypter.cipher.keySize(),
 | 
				
			||||||
 | 
								algID:     string(enc),
 | 
				
			||||||
 | 
								publicKey: rawKey.(*ecdsa.PublicKey),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							recipient, _ := newECDHRecipient(alg, rawKey.(*ecdsa.PublicKey))
 | 
				
			||||||
 | 
							if keyID != "" {
 | 
				
			||||||
 | 
								recipient.keyID = keyID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							encrypter.recipients = []recipientKeyInfo{recipient}
 | 
				
			||||||
 | 
							return encrypter, nil
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							// Can just add a standard recipient
 | 
				
			||||||
 | 
							encrypter.keyGenerator = randomKeyGenerator{
 | 
				
			||||||
 | 
								size: encrypter.cipher.keySize(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := encrypter.AddRecipient(alg, encryptionKey)
 | 
				
			||||||
 | 
							return encrypter, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewMultiEncrypter creates a multi-encrypter based on the given parameters
 | 
				
			||||||
 | 
					func NewMultiEncrypter(enc ContentEncryption) (MultiEncrypter, error) {
 | 
				
			||||||
 | 
						cipher := getContentCipher(enc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if cipher == nil {
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						encrypter := &genericEncrypter{
 | 
				
			||||||
 | 
							contentAlg:     enc,
 | 
				
			||||||
 | 
							compressionAlg: NONE,
 | 
				
			||||||
 | 
							recipients:     []recipientKeyInfo{},
 | 
				
			||||||
 | 
							cipher:         cipher,
 | 
				
			||||||
 | 
							keyGenerator: randomKeyGenerator{
 | 
				
			||||||
 | 
								size: cipher.keySize(),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return encrypter, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *genericEncrypter) AddRecipient(alg KeyAlgorithm, encryptionKey interface{}) (err error) {
 | 
				
			||||||
 | 
						var recipient recipientKeyInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case DIRECT, ECDH_ES:
 | 
				
			||||||
 | 
							return fmt.Errorf("square/go-jose: key algorithm '%s' not supported in multi-recipient mode", alg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						recipient, err = makeJWERecipient(alg, encryptionKey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							ctx.recipients = append(ctx.recipients, recipient)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) {
 | 
				
			||||||
 | 
						switch encryptionKey := encryptionKey.(type) {
 | 
				
			||||||
 | 
						case *rsa.PublicKey:
 | 
				
			||||||
 | 
							return newRSARecipient(alg, encryptionKey)
 | 
				
			||||||
 | 
						case *ecdsa.PublicKey:
 | 
				
			||||||
 | 
							return newECDHRecipient(alg, encryptionKey)
 | 
				
			||||||
 | 
						case []byte:
 | 
				
			||||||
 | 
							return newSymmetricRecipient(alg, encryptionKey)
 | 
				
			||||||
 | 
						case *JsonWebKey:
 | 
				
			||||||
 | 
							recipient, err := makeJWERecipient(alg, encryptionKey.Key)
 | 
				
			||||||
 | 
							if err == nil && encryptionKey.KeyID != "" {
 | 
				
			||||||
 | 
								recipient.keyID = encryptionKey.KeyID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return recipient, err
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientKeyInfo{}, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newDecrypter creates an appropriate decrypter based on the key type
 | 
				
			||||||
 | 
					func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {
 | 
				
			||||||
 | 
						switch decryptionKey := decryptionKey.(type) {
 | 
				
			||||||
 | 
						case *rsa.PrivateKey:
 | 
				
			||||||
 | 
							return &rsaDecrypterSigner{
 | 
				
			||||||
 | 
								privateKey: decryptionKey,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case *ecdsa.PrivateKey:
 | 
				
			||||||
 | 
							return &ecDecrypterSigner{
 | 
				
			||||||
 | 
								privateKey: decryptionKey,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case []byte:
 | 
				
			||||||
 | 
							return &symmetricKeyCipher{
 | 
				
			||||||
 | 
								key: decryptionKey,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case *JsonWebKey:
 | 
				
			||||||
 | 
							return newDecrypter(decryptionKey.Key)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Implementation of encrypt method producing a JWE object.
 | 
				
			||||||
 | 
					func (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JsonWebEncryption, error) {
 | 
				
			||||||
 | 
						return ctx.EncryptWithAuthData(plaintext, nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Implementation of encrypt method producing a JWE object.
 | 
				
			||||||
 | 
					func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JsonWebEncryption, error) {
 | 
				
			||||||
 | 
						obj := &JsonWebEncryption{}
 | 
				
			||||||
 | 
						obj.aad = aad
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						obj.protected = &rawHeader{
 | 
				
			||||||
 | 
							Enc: ctx.contentAlg,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						obj.recipients = make([]recipientInfo, len(ctx.recipients))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(ctx.recipients) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: no recipients to encrypt to")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cek, headers, err := ctx.keyGenerator.genKey()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						obj.protected.merge(&headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, info := range ctx.recipients {
 | 
				
			||||||
 | 
							recipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							recipient.header.Alg = string(info.keyAlg)
 | 
				
			||||||
 | 
							if info.keyID != "" {
 | 
				
			||||||
 | 
								recipient.header.Kid = info.keyID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							obj.recipients[i] = recipient
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(ctx.recipients) == 1 {
 | 
				
			||||||
 | 
							// Move per-recipient headers into main protected header if there's
 | 
				
			||||||
 | 
							// only a single recipient.
 | 
				
			||||||
 | 
							obj.protected.merge(obj.recipients[0].header)
 | 
				
			||||||
 | 
							obj.recipients[0].header = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ctx.compressionAlg != NONE {
 | 
				
			||||||
 | 
							plaintext, err = compress(ctx.compressionAlg, plaintext)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							obj.protected.Zip = ctx.compressionAlg
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						authData := obj.computeAuthData()
 | 
				
			||||||
 | 
						parts, err := ctx.cipher.encrypt(cek, authData, plaintext)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						obj.iv = parts.iv
 | 
				
			||||||
 | 
						obj.ciphertext = parts.ciphertext
 | 
				
			||||||
 | 
						obj.tag = parts.tag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return obj, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decrypt and validate the object and return the plaintext.
 | 
				
			||||||
 | 
					func (obj JsonWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
 | 
				
			||||||
 | 
						headers := obj.mergedHeaders(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(headers.Crit) > 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: unsupported crit header")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						decrypter, err := newDecrypter(decryptionKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cipher := getContentCipher(headers.Enc)
 | 
				
			||||||
 | 
						if cipher == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: unsupported enc value '%s'", string(headers.Enc))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						generator := randomKeyGenerator{
 | 
				
			||||||
 | 
							size: cipher.keySize(),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parts := &aeadParts{
 | 
				
			||||||
 | 
							iv:         obj.iv,
 | 
				
			||||||
 | 
							ciphertext: obj.ciphertext,
 | 
				
			||||||
 | 
							tag:        obj.tag,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						authData := obj.computeAuthData()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var plaintext []byte
 | 
				
			||||||
 | 
						for _, recipient := range obj.recipients {
 | 
				
			||||||
 | 
							recipientHeaders := obj.mergedHeaders(&recipient)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								// Found a valid CEK -- let's try to decrypt.
 | 
				
			||||||
 | 
								plaintext, err = cipher.decrypt(cek, authData, parts)
 | 
				
			||||||
 | 
								if err == nil {
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if plaintext == nil {
 | 
				
			||||||
 | 
							return nil, ErrCryptoFailure
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The "zip" header parameter may only be present in the protected header.
 | 
				
			||||||
 | 
						if obj.protected.Zip != "" {
 | 
				
			||||||
 | 
							plaintext, err = decompress(obj.protected.Zip, plaintext)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return plaintext, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								vendor/github.com/square/go-jose/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/square/go-jose/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Package jose aims to provide an implementation of the Javascript Object Signing
 | 
				
			||||||
 | 
					and Encryption set of standards. For the moment, it mainly focuses on
 | 
				
			||||||
 | 
					encryption and signing based on the JSON Web Encryption and JSON Web Signature
 | 
				
			||||||
 | 
					standards.  The library supports both the compact and full serialization
 | 
				
			||||||
 | 
					formats, and has optional support for multiple recipients.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
							
								
								
									
										193
									
								
								vendor/github.com/square/go-jose/encoding.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								vendor/github.com/square/go-jose/encoding.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,193 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"compress/flate"
 | 
				
			||||||
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/square/go-jose/json"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var stripWhitespaceRegex = regexp.MustCompile("\\s")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Url-safe base64 encode that strips padding
 | 
				
			||||||
 | 
					func base64URLEncode(data []byte) string {
 | 
				
			||||||
 | 
						var result = base64.URLEncoding.EncodeToString(data)
 | 
				
			||||||
 | 
						return strings.TrimRight(result, "=")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Url-safe base64 decoder that adds padding
 | 
				
			||||||
 | 
					func base64URLDecode(data string) ([]byte, error) {
 | 
				
			||||||
 | 
						var missing = (4 - len(data)%4) % 4
 | 
				
			||||||
 | 
						data += strings.Repeat("=", missing)
 | 
				
			||||||
 | 
						return base64.URLEncoding.DecodeString(data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Helper function to serialize known-good objects.
 | 
				
			||||||
 | 
					// Precondition: value is not a nil pointer.
 | 
				
			||||||
 | 
					func mustSerializeJSON(value interface{}) []byte {
 | 
				
			||||||
 | 
						out, err := json.Marshal(value)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// We never want to serialize the top-level value "null," since it's not a
 | 
				
			||||||
 | 
						// valid JOSE message. But if a caller passes in a nil pointer to this method,
 | 
				
			||||||
 | 
						// MarshalJSON will happily serialize it as the top-level value "null". If
 | 
				
			||||||
 | 
						// that value is then embedded in another operation, for instance by being
 | 
				
			||||||
 | 
						// base64-encoded and fed as input to a signing algorithm
 | 
				
			||||||
 | 
						// (https://github.com/square/go-jose/issues/22), the result will be
 | 
				
			||||||
 | 
						// incorrect. Because this method is intended for known-good objects, and a nil
 | 
				
			||||||
 | 
						// pointer is not a known-good object, we are free to panic in this case.
 | 
				
			||||||
 | 
						// Note: It's not possible to directly check whether the data pointed at by an
 | 
				
			||||||
 | 
						// interface is a nil pointer, so we do this hacky workaround.
 | 
				
			||||||
 | 
						// https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I
 | 
				
			||||||
 | 
						if string(out) == "null" {
 | 
				
			||||||
 | 
							panic("Tried to serialize a nil pointer.")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Strip all newlines and whitespace
 | 
				
			||||||
 | 
					func stripWhitespace(data string) string {
 | 
				
			||||||
 | 
						return stripWhitespaceRegex.ReplaceAllString(data, "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Perform compression based on algorithm
 | 
				
			||||||
 | 
					func compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						switch algorithm {
 | 
				
			||||||
 | 
						case DEFLATE:
 | 
				
			||||||
 | 
							return deflate(input)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Perform decompression based on algorithm
 | 
				
			||||||
 | 
					func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						switch algorithm {
 | 
				
			||||||
 | 
						case DEFLATE:
 | 
				
			||||||
 | 
							return inflate(input)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compress with DEFLATE
 | 
				
			||||||
 | 
					func deflate(input []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						output := new(bytes.Buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Writing to byte buffer, err is always nil
 | 
				
			||||||
 | 
						writer, _ := flate.NewWriter(output, 1)
 | 
				
			||||||
 | 
						_, _ = io.Copy(writer, bytes.NewBuffer(input))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := writer.Close()
 | 
				
			||||||
 | 
						return output.Bytes(), err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decompress with DEFLATE
 | 
				
			||||||
 | 
					func inflate(input []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						output := new(bytes.Buffer)
 | 
				
			||||||
 | 
						reader := flate.NewReader(bytes.NewBuffer(input))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := io.Copy(output, reader)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = reader.Close()
 | 
				
			||||||
 | 
						return output.Bytes(), err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// byteBuffer represents a slice of bytes that can be serialized to url-safe base64.
 | 
				
			||||||
 | 
					type byteBuffer struct {
 | 
				
			||||||
 | 
						data []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newBuffer(data []byte) *byteBuffer {
 | 
				
			||||||
 | 
						if data == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &byteBuffer{
 | 
				
			||||||
 | 
							data: data,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newFixedSizeBuffer(data []byte, length int) *byteBuffer {
 | 
				
			||||||
 | 
						if len(data) > length {
 | 
				
			||||||
 | 
							panic("square/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						pad := make([]byte, length-len(data))
 | 
				
			||||||
 | 
						return newBuffer(append(pad, data...))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newBufferFromInt(num uint64) *byteBuffer {
 | 
				
			||||||
 | 
						data := make([]byte, 8)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint64(data, num)
 | 
				
			||||||
 | 
						return newBuffer(bytes.TrimLeft(data, "\x00"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *byteBuffer) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						return json.Marshal(b.base64())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *byteBuffer) UnmarshalJSON(data []byte) error {
 | 
				
			||||||
 | 
						var encoded string
 | 
				
			||||||
 | 
						err := json.Unmarshal(data, &encoded)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if encoded == "" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						decoded, err := base64URLDecode(encoded)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*b = *newBuffer(decoded)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *byteBuffer) base64() string {
 | 
				
			||||||
 | 
						return base64URLEncode(b.data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *byteBuffer) bytes() []byte {
 | 
				
			||||||
 | 
						// Handling nil here allows us to transparently handle nil slices when serializing.
 | 
				
			||||||
 | 
						if b == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return b.data
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b byteBuffer) bigInt() *big.Int {
 | 
				
			||||||
 | 
						return new(big.Int).SetBytes(b.data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b byteBuffer) toInt() int {
 | 
				
			||||||
 | 
						return int(b.bigInt().Int64())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								vendor/github.com/square/go-jose/json/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/square/go-jose/json/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					Copyright (c) 2012 The Go Authors. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					met:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					   * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					copyright notice, this list of conditions and the following disclaimer
 | 
				
			||||||
 | 
					in the documentation and/or other materials provided with the
 | 
				
			||||||
 | 
					distribution.
 | 
				
			||||||
 | 
					   * Neither the name of Google Inc. nor the names of its
 | 
				
			||||||
 | 
					contributors may be used to endorse or promote products derived from
 | 
				
			||||||
 | 
					this software without specific prior written permission.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
				
			||||||
 | 
					"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
				
			||||||
 | 
					A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
				
			||||||
 | 
					OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
				
			||||||
 | 
					SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
				
			||||||
 | 
					LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
				
			||||||
 | 
					OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
							
								
								
									
										13
									
								
								vendor/github.com/square/go-jose/json/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/square/go-jose/json/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					# Safe JSON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This repository contains a fork of the `encoding/json` package from Go 1.6.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following changes were made:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Object deserialization uses case-sensitive member name matching instead of
 | 
				
			||||||
 | 
					  [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).
 | 
				
			||||||
 | 
					  This is to avoid differences in the interpretation of JOSE messages between
 | 
				
			||||||
 | 
					  go-jose and libraries written in other languages.
 | 
				
			||||||
 | 
					* When deserializing a JSON object, we check for duplicate keys and reject the
 | 
				
			||||||
 | 
					  input whenever we detect a duplicate. Rather than trying to work with malformed
 | 
				
			||||||
 | 
					  data, we prefer to reject it right away.
 | 
				
			||||||
							
								
								
									
										1183
									
								
								vendor/github.com/square/go-jose/json/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1183
									
								
								vendor/github.com/square/go-jose/json/decode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1197
									
								
								vendor/github.com/square/go-jose/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1197
									
								
								vendor/github.com/square/go-jose/json/encode.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										141
									
								
								vendor/github.com/square/go-jose/json/indent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								vendor/github.com/square/go-jose/json/indent.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
				
			|||||||
 | 
					// Copyright 2010 The Go Authors.  All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a BSD-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "bytes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compact appends to dst the JSON-encoded src with
 | 
				
			||||||
 | 
					// insignificant space characters elided.
 | 
				
			||||||
 | 
					func Compact(dst *bytes.Buffer, src []byte) error {
 | 
				
			||||||
 | 
						return compact(dst, src, false)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func compact(dst *bytes.Buffer, src []byte, escape bool) error {
 | 
				
			||||||
 | 
						origLen := dst.Len()
 | 
				
			||||||
 | 
						var scan scanner
 | 
				
			||||||
 | 
						scan.reset()
 | 
				
			||||||
 | 
						start := 0
 | 
				
			||||||
 | 
						for i, c := range src {
 | 
				
			||||||
 | 
							if escape && (c == '<' || c == '>' || c == '&') {
 | 
				
			||||||
 | 
								if start < i {
 | 
				
			||||||
 | 
									dst.Write(src[start:i])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dst.WriteString(`\u00`)
 | 
				
			||||||
 | 
								dst.WriteByte(hex[c>>4])
 | 
				
			||||||
 | 
								dst.WriteByte(hex[c&0xF])
 | 
				
			||||||
 | 
								start = i + 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
 | 
				
			||||||
 | 
							if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
 | 
				
			||||||
 | 
								if start < i {
 | 
				
			||||||
 | 
									dst.Write(src[start:i])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dst.WriteString(`\u202`)
 | 
				
			||||||
 | 
								dst.WriteByte(hex[src[i+2]&0xF])
 | 
				
			||||||
 | 
								start = i + 3
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							v := scan.step(&scan, c)
 | 
				
			||||||
 | 
							if v >= scanSkipSpace {
 | 
				
			||||||
 | 
								if v == scanError {
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if start < i {
 | 
				
			||||||
 | 
									dst.Write(src[start:i])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								start = i + 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if scan.eof() == scanError {
 | 
				
			||||||
 | 
							dst.Truncate(origLen)
 | 
				
			||||||
 | 
							return scan.err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if start < len(src) {
 | 
				
			||||||
 | 
							dst.Write(src[start:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
 | 
				
			||||||
 | 
						dst.WriteByte('\n')
 | 
				
			||||||
 | 
						dst.WriteString(prefix)
 | 
				
			||||||
 | 
						for i := 0; i < depth; i++ {
 | 
				
			||||||
 | 
							dst.WriteString(indent)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Indent appends to dst an indented form of the JSON-encoded src.
 | 
				
			||||||
 | 
					// Each element in a JSON object or array begins on a new,
 | 
				
			||||||
 | 
					// indented line beginning with prefix followed by one or more
 | 
				
			||||||
 | 
					// copies of indent according to the indentation nesting.
 | 
				
			||||||
 | 
					// The data appended to dst does not begin with the prefix nor
 | 
				
			||||||
 | 
					// any indentation, to make it easier to embed inside other formatted JSON data.
 | 
				
			||||||
 | 
					// Although leading space characters (space, tab, carriage return, newline)
 | 
				
			||||||
 | 
					// at the beginning of src are dropped, trailing space characters
 | 
				
			||||||
 | 
					// at the end of src are preserved and copied to dst.
 | 
				
			||||||
 | 
					// For example, if src has no trailing spaces, neither will dst;
 | 
				
			||||||
 | 
					// if src ends in a trailing newline, so will dst.
 | 
				
			||||||
 | 
					func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
 | 
				
			||||||
 | 
						origLen := dst.Len()
 | 
				
			||||||
 | 
						var scan scanner
 | 
				
			||||||
 | 
						scan.reset()
 | 
				
			||||||
 | 
						needIndent := false
 | 
				
			||||||
 | 
						depth := 0
 | 
				
			||||||
 | 
						for _, c := range src {
 | 
				
			||||||
 | 
							scan.bytes++
 | 
				
			||||||
 | 
							v := scan.step(&scan, c)
 | 
				
			||||||
 | 
							if v == scanSkipSpace {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if v == scanError {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if needIndent && v != scanEndObject && v != scanEndArray {
 | 
				
			||||||
 | 
								needIndent = false
 | 
				
			||||||
 | 
								depth++
 | 
				
			||||||
 | 
								newline(dst, prefix, indent, depth)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Emit semantically uninteresting bytes
 | 
				
			||||||
 | 
							// (in particular, punctuation in strings) unmodified.
 | 
				
			||||||
 | 
							if v == scanContinue {
 | 
				
			||||||
 | 
								dst.WriteByte(c)
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Add spacing around real punctuation.
 | 
				
			||||||
 | 
							switch c {
 | 
				
			||||||
 | 
							case '{', '[':
 | 
				
			||||||
 | 
								// delay indent so that empty object and array are formatted as {} and [].
 | 
				
			||||||
 | 
								needIndent = true
 | 
				
			||||||
 | 
								dst.WriteByte(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case ',':
 | 
				
			||||||
 | 
								dst.WriteByte(c)
 | 
				
			||||||
 | 
								newline(dst, prefix, indent, depth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case ':':
 | 
				
			||||||
 | 
								dst.WriteByte(c)
 | 
				
			||||||
 | 
								dst.WriteByte(' ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case '}', ']':
 | 
				
			||||||
 | 
								if needIndent {
 | 
				
			||||||
 | 
									// suppress indent in empty object/array
 | 
				
			||||||
 | 
									needIndent = false
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									depth--
 | 
				
			||||||
 | 
									newline(dst, prefix, indent, depth)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dst.WriteByte(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								dst.WriteByte(c)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if scan.eof() == scanError {
 | 
				
			||||||
 | 
							dst.Truncate(origLen)
 | 
				
			||||||
 | 
							return scan.err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										623
									
								
								vendor/github.com/square/go-jose/json/scanner.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										623
									
								
								vendor/github.com/square/go-jose/json/scanner.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,623 @@
 | 
				
			|||||||
 | 
					// Copyright 2010 The Go Authors.  All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a BSD-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JSON value parser state machine.
 | 
				
			||||||
 | 
					// Just about at the limit of what is reasonable to write by hand.
 | 
				
			||||||
 | 
					// Some parts are a bit tedious, but overall it nicely factors out the
 | 
				
			||||||
 | 
					// otherwise common code from the multiple scanning functions
 | 
				
			||||||
 | 
					// in this package (Compact, Indent, checkValid, nextValue, etc).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file starts with two simple examples using the scanner
 | 
				
			||||||
 | 
					// before diving into the scanner itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// checkValid verifies that data is valid JSON-encoded data.
 | 
				
			||||||
 | 
					// scan is passed in for use by checkValid to avoid an allocation.
 | 
				
			||||||
 | 
					func checkValid(data []byte, scan *scanner) error {
 | 
				
			||||||
 | 
						scan.reset()
 | 
				
			||||||
 | 
						for _, c := range data {
 | 
				
			||||||
 | 
							scan.bytes++
 | 
				
			||||||
 | 
							if scan.step(scan, c) == scanError {
 | 
				
			||||||
 | 
								return scan.err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if scan.eof() == scanError {
 | 
				
			||||||
 | 
							return scan.err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// nextValue splits data after the next whole JSON value,
 | 
				
			||||||
 | 
					// returning that value and the bytes that follow it as separate slices.
 | 
				
			||||||
 | 
					// scan is passed in for use by nextValue to avoid an allocation.
 | 
				
			||||||
 | 
					func nextValue(data []byte, scan *scanner) (value, rest []byte, err error) {
 | 
				
			||||||
 | 
						scan.reset()
 | 
				
			||||||
 | 
						for i, c := range data {
 | 
				
			||||||
 | 
							v := scan.step(scan, c)
 | 
				
			||||||
 | 
							if v >= scanEndObject {
 | 
				
			||||||
 | 
								switch v {
 | 
				
			||||||
 | 
								// probe the scanner with a space to determine whether we will
 | 
				
			||||||
 | 
								// get scanEnd on the next character. Otherwise, if the next character
 | 
				
			||||||
 | 
								// is not a space, scanEndTop allocates a needless error.
 | 
				
			||||||
 | 
								case scanEndObject, scanEndArray:
 | 
				
			||||||
 | 
									if scan.step(scan, ' ') == scanEnd {
 | 
				
			||||||
 | 
										return data[:i+1], data[i+1:], nil
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								case scanError:
 | 
				
			||||||
 | 
									return nil, nil, scan.err
 | 
				
			||||||
 | 
								case scanEnd:
 | 
				
			||||||
 | 
									return data[:i], data[i:], nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if scan.eof() == scanError {
 | 
				
			||||||
 | 
							return nil, nil, scan.err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return data, nil, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A SyntaxError is a description of a JSON syntax error.
 | 
				
			||||||
 | 
					type SyntaxError struct {
 | 
				
			||||||
 | 
						msg    string // description of error
 | 
				
			||||||
 | 
						Offset int64  // error occurred after reading Offset bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *SyntaxError) Error() string { return e.msg }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A scanner is a JSON scanning state machine.
 | 
				
			||||||
 | 
					// Callers call scan.reset() and then pass bytes in one at a time
 | 
				
			||||||
 | 
					// by calling scan.step(&scan, c) for each byte.
 | 
				
			||||||
 | 
					// The return value, referred to as an opcode, tells the
 | 
				
			||||||
 | 
					// caller about significant parsing events like beginning
 | 
				
			||||||
 | 
					// and ending literals, objects, and arrays, so that the
 | 
				
			||||||
 | 
					// caller can follow along if it wishes.
 | 
				
			||||||
 | 
					// The return value scanEnd indicates that a single top-level
 | 
				
			||||||
 | 
					// JSON value has been completed, *before* the byte that
 | 
				
			||||||
 | 
					// just got passed in.  (The indication must be delayed in order
 | 
				
			||||||
 | 
					// to recognize the end of numbers: is 123 a whole value or
 | 
				
			||||||
 | 
					// the beginning of 12345e+6?).
 | 
				
			||||||
 | 
					type scanner struct {
 | 
				
			||||||
 | 
						// The step is a func to be called to execute the next transition.
 | 
				
			||||||
 | 
						// Also tried using an integer constant and a single func
 | 
				
			||||||
 | 
						// with a switch, but using the func directly was 10% faster
 | 
				
			||||||
 | 
						// on a 64-bit Mac Mini, and it's nicer to read.
 | 
				
			||||||
 | 
						step func(*scanner, byte) int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Reached end of top-level value.
 | 
				
			||||||
 | 
						endTop bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Stack of what we're in the middle of - array values, object keys, object values.
 | 
				
			||||||
 | 
						parseState []int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Error that happened, if any.
 | 
				
			||||||
 | 
						err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 1-byte redo (see undo method)
 | 
				
			||||||
 | 
						redo      bool
 | 
				
			||||||
 | 
						redoCode  int
 | 
				
			||||||
 | 
						redoState func(*scanner, byte) int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// total bytes consumed, updated by decoder.Decode
 | 
				
			||||||
 | 
						bytes int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// These values are returned by the state transition functions
 | 
				
			||||||
 | 
					// assigned to scanner.state and the method scanner.eof.
 | 
				
			||||||
 | 
					// They give details about the current state of the scan that
 | 
				
			||||||
 | 
					// callers might be interested to know about.
 | 
				
			||||||
 | 
					// It is okay to ignore the return value of any particular
 | 
				
			||||||
 | 
					// call to scanner.state: if one call returns scanError,
 | 
				
			||||||
 | 
					// every subsequent call will return scanError too.
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// Continue.
 | 
				
			||||||
 | 
						scanContinue     = iota // uninteresting byte
 | 
				
			||||||
 | 
						scanBeginLiteral        // end implied by next result != scanContinue
 | 
				
			||||||
 | 
						scanBeginObject         // begin object
 | 
				
			||||||
 | 
						scanObjectKey           // just finished object key (string)
 | 
				
			||||||
 | 
						scanObjectValue         // just finished non-last object value
 | 
				
			||||||
 | 
						scanEndObject           // end object (implies scanObjectValue if possible)
 | 
				
			||||||
 | 
						scanBeginArray          // begin array
 | 
				
			||||||
 | 
						scanArrayValue          // just finished array value
 | 
				
			||||||
 | 
						scanEndArray            // end array (implies scanArrayValue if possible)
 | 
				
			||||||
 | 
						scanSkipSpace           // space byte; can skip; known to be last "continue" result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Stop.
 | 
				
			||||||
 | 
						scanEnd   // top-level value ended *before* this byte; known to be first "stop" result
 | 
				
			||||||
 | 
						scanError // hit an error, scanner.err.
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// These values are stored in the parseState stack.
 | 
				
			||||||
 | 
					// They give the current state of a composite value
 | 
				
			||||||
 | 
					// being scanned.  If the parser is inside a nested value
 | 
				
			||||||
 | 
					// the parseState describes the nested state, outermost at entry 0.
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						parseObjectKey   = iota // parsing object key (before colon)
 | 
				
			||||||
 | 
						parseObjectValue        // parsing object value (after colon)
 | 
				
			||||||
 | 
						parseArrayValue         // parsing array value
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// reset prepares the scanner for use.
 | 
				
			||||||
 | 
					// It must be called before calling s.step.
 | 
				
			||||||
 | 
					func (s *scanner) reset() {
 | 
				
			||||||
 | 
						s.step = stateBeginValue
 | 
				
			||||||
 | 
						s.parseState = s.parseState[0:0]
 | 
				
			||||||
 | 
						s.err = nil
 | 
				
			||||||
 | 
						s.redo = false
 | 
				
			||||||
 | 
						s.endTop = false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// eof tells the scanner that the end of input has been reached.
 | 
				
			||||||
 | 
					// It returns a scan status just as s.step does.
 | 
				
			||||||
 | 
					func (s *scanner) eof() int {
 | 
				
			||||||
 | 
						if s.err != nil {
 | 
				
			||||||
 | 
							return scanError
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if s.endTop {
 | 
				
			||||||
 | 
							return scanEnd
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.step(s, ' ')
 | 
				
			||||||
 | 
						if s.endTop {
 | 
				
			||||||
 | 
							return scanEnd
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if s.err == nil {
 | 
				
			||||||
 | 
							s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return scanError
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// pushParseState pushes a new parse state p onto the parse stack.
 | 
				
			||||||
 | 
					func (s *scanner) pushParseState(p int) {
 | 
				
			||||||
 | 
						s.parseState = append(s.parseState, p)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// popParseState pops a parse state (already obtained) off the stack
 | 
				
			||||||
 | 
					// and updates s.step accordingly.
 | 
				
			||||||
 | 
					func (s *scanner) popParseState() {
 | 
				
			||||||
 | 
						n := len(s.parseState) - 1
 | 
				
			||||||
 | 
						s.parseState = s.parseState[0:n]
 | 
				
			||||||
 | 
						s.redo = false
 | 
				
			||||||
 | 
						if n == 0 {
 | 
				
			||||||
 | 
							s.step = stateEndTop
 | 
				
			||||||
 | 
							s.endTop = true
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							s.step = stateEndValue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func isSpace(c byte) bool {
 | 
				
			||||||
 | 
						return c == ' ' || c == '\t' || c == '\r' || c == '\n'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateBeginValueOrEmpty is the state after reading `[`.
 | 
				
			||||||
 | 
					func stateBeginValueOrEmpty(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c <= ' ' && isSpace(c) {
 | 
				
			||||||
 | 
							return scanSkipSpace
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == ']' {
 | 
				
			||||||
 | 
							return stateEndValue(s, c)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stateBeginValue(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateBeginValue is the state at the beginning of the input.
 | 
				
			||||||
 | 
					func stateBeginValue(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c <= ' ' && isSpace(c) {
 | 
				
			||||||
 | 
							return scanSkipSpace
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch c {
 | 
				
			||||||
 | 
						case '{':
 | 
				
			||||||
 | 
							s.step = stateBeginStringOrEmpty
 | 
				
			||||||
 | 
							s.pushParseState(parseObjectKey)
 | 
				
			||||||
 | 
							return scanBeginObject
 | 
				
			||||||
 | 
						case '[':
 | 
				
			||||||
 | 
							s.step = stateBeginValueOrEmpty
 | 
				
			||||||
 | 
							s.pushParseState(parseArrayValue)
 | 
				
			||||||
 | 
							return scanBeginArray
 | 
				
			||||||
 | 
						case '"':
 | 
				
			||||||
 | 
							s.step = stateInString
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						case '-':
 | 
				
			||||||
 | 
							s.step = stateNeg
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						case '0': // beginning of 0.123
 | 
				
			||||||
 | 
							s.step = state0
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						case 't': // beginning of true
 | 
				
			||||||
 | 
							s.step = stateT
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						case 'f': // beginning of false
 | 
				
			||||||
 | 
							s.step = stateF
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						case 'n': // beginning of null
 | 
				
			||||||
 | 
							s.step = stateN
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if '1' <= c && c <= '9' { // beginning of 1234.5
 | 
				
			||||||
 | 
							s.step = state1
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "looking for beginning of value")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateBeginStringOrEmpty is the state after reading `{`.
 | 
				
			||||||
 | 
					func stateBeginStringOrEmpty(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c <= ' ' && isSpace(c) {
 | 
				
			||||||
 | 
							return scanSkipSpace
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == '}' {
 | 
				
			||||||
 | 
							n := len(s.parseState)
 | 
				
			||||||
 | 
							s.parseState[n-1] = parseObjectValue
 | 
				
			||||||
 | 
							return stateEndValue(s, c)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stateBeginString(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateBeginString is the state after reading `{"key": value,`.
 | 
				
			||||||
 | 
					func stateBeginString(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c <= ' ' && isSpace(c) {
 | 
				
			||||||
 | 
							return scanSkipSpace
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == '"' {
 | 
				
			||||||
 | 
							s.step = stateInString
 | 
				
			||||||
 | 
							return scanBeginLiteral
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "looking for beginning of object key string")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateEndValue is the state after completing a value,
 | 
				
			||||||
 | 
					// such as after reading `{}` or `true` or `["x"`.
 | 
				
			||||||
 | 
					func stateEndValue(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						n := len(s.parseState)
 | 
				
			||||||
 | 
						if n == 0 {
 | 
				
			||||||
 | 
							// Completed top-level before the current byte.
 | 
				
			||||||
 | 
							s.step = stateEndTop
 | 
				
			||||||
 | 
							s.endTop = true
 | 
				
			||||||
 | 
							return stateEndTop(s, c)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c <= ' ' && isSpace(c) {
 | 
				
			||||||
 | 
							s.step = stateEndValue
 | 
				
			||||||
 | 
							return scanSkipSpace
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ps := s.parseState[n-1]
 | 
				
			||||||
 | 
						switch ps {
 | 
				
			||||||
 | 
						case parseObjectKey:
 | 
				
			||||||
 | 
							if c == ':' {
 | 
				
			||||||
 | 
								s.parseState[n-1] = parseObjectValue
 | 
				
			||||||
 | 
								s.step = stateBeginValue
 | 
				
			||||||
 | 
								return scanObjectKey
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return s.error(c, "after object key")
 | 
				
			||||||
 | 
						case parseObjectValue:
 | 
				
			||||||
 | 
							if c == ',' {
 | 
				
			||||||
 | 
								s.parseState[n-1] = parseObjectKey
 | 
				
			||||||
 | 
								s.step = stateBeginString
 | 
				
			||||||
 | 
								return scanObjectValue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c == '}' {
 | 
				
			||||||
 | 
								s.popParseState()
 | 
				
			||||||
 | 
								return scanEndObject
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return s.error(c, "after object key:value pair")
 | 
				
			||||||
 | 
						case parseArrayValue:
 | 
				
			||||||
 | 
							if c == ',' {
 | 
				
			||||||
 | 
								s.step = stateBeginValue
 | 
				
			||||||
 | 
								return scanArrayValue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c == ']' {
 | 
				
			||||||
 | 
								s.popParseState()
 | 
				
			||||||
 | 
								return scanEndArray
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return s.error(c, "after array element")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateEndTop is the state after finishing the top-level value,
 | 
				
			||||||
 | 
					// such as after reading `{}` or `[1,2,3]`.
 | 
				
			||||||
 | 
					// Only space characters should be seen now.
 | 
				
			||||||
 | 
					func stateEndTop(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
 | 
				
			||||||
 | 
							// Complain about non-space byte on next call.
 | 
				
			||||||
 | 
							s.error(c, "after top-level value")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return scanEnd
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateInString is the state after reading `"`.
 | 
				
			||||||
 | 
					func stateInString(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == '"' {
 | 
				
			||||||
 | 
							s.step = stateEndValue
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == '\\' {
 | 
				
			||||||
 | 
							s.step = stateInStringEsc
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c < 0x20 {
 | 
				
			||||||
 | 
							return s.error(c, "in string literal")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return scanContinue
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateInStringEsc is the state after reading `"\` during a quoted string.
 | 
				
			||||||
 | 
					func stateInStringEsc(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						switch c {
 | 
				
			||||||
 | 
						case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
 | 
				
			||||||
 | 
							s.step = stateInString
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						case 'u':
 | 
				
			||||||
 | 
							s.step = stateInStringEscU
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in string escape code")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateInStringEscU is the state after reading `"\u` during a quoted string.
 | 
				
			||||||
 | 
					func stateInStringEscU(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
				
			||||||
 | 
							s.step = stateInStringEscU1
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// numbers
 | 
				
			||||||
 | 
						return s.error(c, "in \\u hexadecimal character escape")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
 | 
				
			||||||
 | 
					func stateInStringEscU1(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
				
			||||||
 | 
							s.step = stateInStringEscU12
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// numbers
 | 
				
			||||||
 | 
						return s.error(c, "in \\u hexadecimal character escape")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
 | 
				
			||||||
 | 
					func stateInStringEscU12(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
				
			||||||
 | 
							s.step = stateInStringEscU123
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// numbers
 | 
				
			||||||
 | 
						return s.error(c, "in \\u hexadecimal character escape")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
 | 
				
			||||||
 | 
					func stateInStringEscU123(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
 | 
				
			||||||
 | 
							s.step = stateInString
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// numbers
 | 
				
			||||||
 | 
						return s.error(c, "in \\u hexadecimal character escape")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateNeg is the state after reading `-` during a number.
 | 
				
			||||||
 | 
					func stateNeg(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == '0' {
 | 
				
			||||||
 | 
							s.step = state0
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if '1' <= c && c <= '9' {
 | 
				
			||||||
 | 
							s.step = state1
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in numeric literal")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// state1 is the state after reading a non-zero integer during a number,
 | 
				
			||||||
 | 
					// such as after reading `1` or `100` but not `0`.
 | 
				
			||||||
 | 
					func state1(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' {
 | 
				
			||||||
 | 
							s.step = state1
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return state0(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// state0 is the state after reading `0` during a number.
 | 
				
			||||||
 | 
					func state0(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == '.' {
 | 
				
			||||||
 | 
							s.step = stateDot
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == 'e' || c == 'E' {
 | 
				
			||||||
 | 
							s.step = stateE
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stateEndValue(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateDot is the state after reading the integer and decimal point in a number,
 | 
				
			||||||
 | 
					// such as after reading `1.`.
 | 
				
			||||||
 | 
					func stateDot(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' {
 | 
				
			||||||
 | 
							s.step = stateDot0
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "after decimal point in numeric literal")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateDot0 is the state after reading the integer, decimal point, and subsequent
 | 
				
			||||||
 | 
					// digits of a number, such as after reading `3.14`.
 | 
				
			||||||
 | 
					func stateDot0(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' {
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == 'e' || c == 'E' {
 | 
				
			||||||
 | 
							s.step = stateE
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stateEndValue(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateE is the state after reading the mantissa and e in a number,
 | 
				
			||||||
 | 
					// such as after reading `314e` or `0.314e`.
 | 
				
			||||||
 | 
					func stateE(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == '+' || c == '-' {
 | 
				
			||||||
 | 
							s.step = stateESign
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stateESign(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateESign is the state after reading the mantissa, e, and sign in a number,
 | 
				
			||||||
 | 
					// such as after reading `314e-` or `0.314e+`.
 | 
				
			||||||
 | 
					func stateESign(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' {
 | 
				
			||||||
 | 
							s.step = stateE0
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in exponent of numeric literal")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateE0 is the state after reading the mantissa, e, optional sign,
 | 
				
			||||||
 | 
					// and at least one digit of the exponent in a number,
 | 
				
			||||||
 | 
					// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
 | 
				
			||||||
 | 
					func stateE0(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if '0' <= c && c <= '9' {
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stateEndValue(s, c)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateT is the state after reading `t`.
 | 
				
			||||||
 | 
					func stateT(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'r' {
 | 
				
			||||||
 | 
							s.step = stateTr
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal true (expecting 'r')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateTr is the state after reading `tr`.
 | 
				
			||||||
 | 
					func stateTr(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'u' {
 | 
				
			||||||
 | 
							s.step = stateTru
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal true (expecting 'u')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateTru is the state after reading `tru`.
 | 
				
			||||||
 | 
					func stateTru(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'e' {
 | 
				
			||||||
 | 
							s.step = stateEndValue
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal true (expecting 'e')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateF is the state after reading `f`.
 | 
				
			||||||
 | 
					func stateF(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'a' {
 | 
				
			||||||
 | 
							s.step = stateFa
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal false (expecting 'a')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateFa is the state after reading `fa`.
 | 
				
			||||||
 | 
					func stateFa(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'l' {
 | 
				
			||||||
 | 
							s.step = stateFal
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal false (expecting 'l')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateFal is the state after reading `fal`.
 | 
				
			||||||
 | 
					func stateFal(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 's' {
 | 
				
			||||||
 | 
							s.step = stateFals
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal false (expecting 's')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateFals is the state after reading `fals`.
 | 
				
			||||||
 | 
					func stateFals(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'e' {
 | 
				
			||||||
 | 
							s.step = stateEndValue
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal false (expecting 'e')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateN is the state after reading `n`.
 | 
				
			||||||
 | 
					func stateN(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'u' {
 | 
				
			||||||
 | 
							s.step = stateNu
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal null (expecting 'u')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateNu is the state after reading `nu`.
 | 
				
			||||||
 | 
					func stateNu(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'l' {
 | 
				
			||||||
 | 
							s.step = stateNul
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal null (expecting 'l')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateNul is the state after reading `nul`.
 | 
				
			||||||
 | 
					func stateNul(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						if c == 'l' {
 | 
				
			||||||
 | 
							s.step = stateEndValue
 | 
				
			||||||
 | 
							return scanContinue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s.error(c, "in literal null (expecting 'l')")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateError is the state after reaching a syntax error,
 | 
				
			||||||
 | 
					// such as after reading `[1}` or `5.1.2`.
 | 
				
			||||||
 | 
					func stateError(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						return scanError
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// error records an error and switches to the error state.
 | 
				
			||||||
 | 
					func (s *scanner) error(c byte, context string) int {
 | 
				
			||||||
 | 
						s.step = stateError
 | 
				
			||||||
 | 
						s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
 | 
				
			||||||
 | 
						return scanError
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// quoteChar formats c as a quoted character literal
 | 
				
			||||||
 | 
					func quoteChar(c byte) string {
 | 
				
			||||||
 | 
						// special cases - different from quoted strings
 | 
				
			||||||
 | 
						if c == '\'' {
 | 
				
			||||||
 | 
							return `'\''`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if c == '"' {
 | 
				
			||||||
 | 
							return `'"'`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// use quoted string with different quotation marks
 | 
				
			||||||
 | 
						s := strconv.Quote(string(c))
 | 
				
			||||||
 | 
						return "'" + s[1:len(s)-1] + "'"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// undo causes the scanner to return scanCode from the next state transition.
 | 
				
			||||||
 | 
					// This gives callers a simple 1-byte undo mechanism.
 | 
				
			||||||
 | 
					func (s *scanner) undo(scanCode int) {
 | 
				
			||||||
 | 
						if s.redo {
 | 
				
			||||||
 | 
							panic("json: invalid use of scanner")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s.redoCode = scanCode
 | 
				
			||||||
 | 
						s.redoState = s.step
 | 
				
			||||||
 | 
						s.step = stateRedo
 | 
				
			||||||
 | 
						s.redo = true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// stateRedo helps implement the scanner's 1-byte undo.
 | 
				
			||||||
 | 
					func stateRedo(s *scanner, c byte) int {
 | 
				
			||||||
 | 
						s.redo = false
 | 
				
			||||||
 | 
						s.step = s.redoState
 | 
				
			||||||
 | 
						return s.redoCode
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										480
									
								
								vendor/github.com/square/go-jose/json/stream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										480
									
								
								vendor/github.com/square/go-jose/json/stream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,480 @@
 | 
				
			|||||||
 | 
					// Copyright 2010 The Go Authors.  All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a BSD-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Decoder reads and decodes JSON objects from an input stream.
 | 
				
			||||||
 | 
					type Decoder struct {
 | 
				
			||||||
 | 
						r     io.Reader
 | 
				
			||||||
 | 
						buf   []byte
 | 
				
			||||||
 | 
						d     decodeState
 | 
				
			||||||
 | 
						scanp int // start of unread data in buf
 | 
				
			||||||
 | 
						scan  scanner
 | 
				
			||||||
 | 
						err   error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tokenState int
 | 
				
			||||||
 | 
						tokenStack []int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewDecoder returns a new decoder that reads from r.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The decoder introduces its own buffering and may
 | 
				
			||||||
 | 
					// read data from r beyond the JSON values requested.
 | 
				
			||||||
 | 
					func NewDecoder(r io.Reader) *Decoder {
 | 
				
			||||||
 | 
						return &Decoder{r: r}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
 | 
				
			||||||
 | 
					// Number instead of as a float64.
 | 
				
			||||||
 | 
					func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decode reads the next JSON-encoded value from its
 | 
				
			||||||
 | 
					// input and stores it in the value pointed to by v.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// See the documentation for Unmarshal for details about
 | 
				
			||||||
 | 
					// the conversion of JSON into a Go value.
 | 
				
			||||||
 | 
					func (dec *Decoder) Decode(v interface{}) error {
 | 
				
			||||||
 | 
						if dec.err != nil {
 | 
				
			||||||
 | 
							return dec.err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := dec.tokenPrepareForDecode(); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !dec.tokenValueAllowed() {
 | 
				
			||||||
 | 
							return &SyntaxError{msg: "not at beginning of value"}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read whole value into buffer.
 | 
				
			||||||
 | 
						n, err := dec.readValue()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
 | 
				
			||||||
 | 
						dec.scanp += n
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Don't save err from unmarshal into dec.err:
 | 
				
			||||||
 | 
						// the connection is still usable since we read a complete JSON
 | 
				
			||||||
 | 
						// object from it before the error happened.
 | 
				
			||||||
 | 
						err = dec.d.unmarshal(v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// fixup token streaming state
 | 
				
			||||||
 | 
						dec.tokenValueEnd()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Buffered returns a reader of the data remaining in the Decoder's
 | 
				
			||||||
 | 
					// buffer. The reader is valid until the next call to Decode.
 | 
				
			||||||
 | 
					func (dec *Decoder) Buffered() io.Reader {
 | 
				
			||||||
 | 
						return bytes.NewReader(dec.buf[dec.scanp:])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// readValue reads a JSON value into dec.buf.
 | 
				
			||||||
 | 
					// It returns the length of the encoding.
 | 
				
			||||||
 | 
					func (dec *Decoder) readValue() (int, error) {
 | 
				
			||||||
 | 
						dec.scan.reset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scanp := dec.scanp
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					Input:
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							// Look in the buffer for a new value.
 | 
				
			||||||
 | 
							for i, c := range dec.buf[scanp:] {
 | 
				
			||||||
 | 
								dec.scan.bytes++
 | 
				
			||||||
 | 
								v := dec.scan.step(&dec.scan, c)
 | 
				
			||||||
 | 
								if v == scanEnd {
 | 
				
			||||||
 | 
									scanp += i
 | 
				
			||||||
 | 
									break Input
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// scanEnd is delayed one byte.
 | 
				
			||||||
 | 
								// We might block trying to get that byte from src,
 | 
				
			||||||
 | 
								// so instead invent a space byte.
 | 
				
			||||||
 | 
								if (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {
 | 
				
			||||||
 | 
									scanp += i + 1
 | 
				
			||||||
 | 
									break Input
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if v == scanError {
 | 
				
			||||||
 | 
									dec.err = dec.scan.err
 | 
				
			||||||
 | 
									return 0, dec.scan.err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							scanp = len(dec.buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Did the last read have an error?
 | 
				
			||||||
 | 
							// Delayed until now to allow buffer scan.
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								if err == io.EOF {
 | 
				
			||||||
 | 
									if dec.scan.step(&dec.scan, ' ') == scanEnd {
 | 
				
			||||||
 | 
										break Input
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if nonSpace(dec.buf) {
 | 
				
			||||||
 | 
										err = io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.err = err
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							n := scanp - dec.scanp
 | 
				
			||||||
 | 
							err = dec.refill()
 | 
				
			||||||
 | 
							scanp = dec.scanp + n
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return scanp - dec.scanp, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dec *Decoder) refill() error {
 | 
				
			||||||
 | 
						// Make room to read more into the buffer.
 | 
				
			||||||
 | 
						// First slide down data already consumed.
 | 
				
			||||||
 | 
						if dec.scanp > 0 {
 | 
				
			||||||
 | 
							n := copy(dec.buf, dec.buf[dec.scanp:])
 | 
				
			||||||
 | 
							dec.buf = dec.buf[:n]
 | 
				
			||||||
 | 
							dec.scanp = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Grow buffer if not large enough.
 | 
				
			||||||
 | 
						const minRead = 512
 | 
				
			||||||
 | 
						if cap(dec.buf)-len(dec.buf) < minRead {
 | 
				
			||||||
 | 
							newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
 | 
				
			||||||
 | 
							copy(newBuf, dec.buf)
 | 
				
			||||||
 | 
							dec.buf = newBuf
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Read.  Delay error for next iteration (after scan).
 | 
				
			||||||
 | 
						n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
 | 
				
			||||||
 | 
						dec.buf = dec.buf[0 : len(dec.buf)+n]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func nonSpace(b []byte) bool {
 | 
				
			||||||
 | 
						for _, c := range b {
 | 
				
			||||||
 | 
							if !isSpace(c) {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An Encoder writes JSON objects to an output stream.
 | 
				
			||||||
 | 
					type Encoder struct {
 | 
				
			||||||
 | 
						w   io.Writer
 | 
				
			||||||
 | 
						err error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewEncoder returns a new encoder that writes to w.
 | 
				
			||||||
 | 
					func NewEncoder(w io.Writer) *Encoder {
 | 
				
			||||||
 | 
						return &Encoder{w: w}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode writes the JSON encoding of v to the stream,
 | 
				
			||||||
 | 
					// followed by a newline character.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// See the documentation for Marshal for details about the
 | 
				
			||||||
 | 
					// conversion of Go values to JSON.
 | 
				
			||||||
 | 
					func (enc *Encoder) Encode(v interface{}) error {
 | 
				
			||||||
 | 
						if enc.err != nil {
 | 
				
			||||||
 | 
							return enc.err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						e := newEncodeState()
 | 
				
			||||||
 | 
						err := e.marshal(v)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Terminate each value with a newline.
 | 
				
			||||||
 | 
						// This makes the output look a little nicer
 | 
				
			||||||
 | 
						// when debugging, and some kind of space
 | 
				
			||||||
 | 
						// is required if the encoded value was a number,
 | 
				
			||||||
 | 
						// so that the reader knows there aren't more
 | 
				
			||||||
 | 
						// digits coming.
 | 
				
			||||||
 | 
						e.WriteByte('\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if _, err = enc.w.Write(e.Bytes()); err != nil {
 | 
				
			||||||
 | 
							enc.err = err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						encodeStatePool.Put(e)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RawMessage is a raw encoded JSON object.
 | 
				
			||||||
 | 
					// It implements Marshaler and Unmarshaler and can
 | 
				
			||||||
 | 
					// be used to delay JSON decoding or precompute a JSON encoding.
 | 
				
			||||||
 | 
					type RawMessage []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MarshalJSON returns *m as the JSON encoding of m.
 | 
				
			||||||
 | 
					func (m *RawMessage) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						return *m, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnmarshalJSON sets *m to a copy of data.
 | 
				
			||||||
 | 
					func (m *RawMessage) UnmarshalJSON(data []byte) error {
 | 
				
			||||||
 | 
						if m == nil {
 | 
				
			||||||
 | 
							return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						*m = append((*m)[0:0], data...)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _ Marshaler = (*RawMessage)(nil)
 | 
				
			||||||
 | 
					var _ Unmarshaler = (*RawMessage)(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Token holds a value of one of these types:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//	Delim, for the four JSON delimiters [ ] { }
 | 
				
			||||||
 | 
					//	bool, for JSON booleans
 | 
				
			||||||
 | 
					//	float64, for JSON numbers
 | 
				
			||||||
 | 
					//	Number, for JSON numbers
 | 
				
			||||||
 | 
					//	string, for JSON string literals
 | 
				
			||||||
 | 
					//	nil, for JSON null
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					type Token interface{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						tokenTopValue = iota
 | 
				
			||||||
 | 
						tokenArrayStart
 | 
				
			||||||
 | 
						tokenArrayValue
 | 
				
			||||||
 | 
						tokenArrayComma
 | 
				
			||||||
 | 
						tokenObjectStart
 | 
				
			||||||
 | 
						tokenObjectKey
 | 
				
			||||||
 | 
						tokenObjectColon
 | 
				
			||||||
 | 
						tokenObjectValue
 | 
				
			||||||
 | 
						tokenObjectComma
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// advance tokenstate from a separator state to a value state
 | 
				
			||||||
 | 
					func (dec *Decoder) tokenPrepareForDecode() error {
 | 
				
			||||||
 | 
						// Note: Not calling peek before switch, to avoid
 | 
				
			||||||
 | 
						// putting peek into the standard Decode path.
 | 
				
			||||||
 | 
						// peek is only called when using the Token API.
 | 
				
			||||||
 | 
						switch dec.tokenState {
 | 
				
			||||||
 | 
						case tokenArrayComma:
 | 
				
			||||||
 | 
							c, err := dec.peek()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c != ',' {
 | 
				
			||||||
 | 
								return &SyntaxError{"expected comma after array element", 0}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dec.scanp++
 | 
				
			||||||
 | 
							dec.tokenState = tokenArrayValue
 | 
				
			||||||
 | 
						case tokenObjectColon:
 | 
				
			||||||
 | 
							c, err := dec.peek()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if c != ':' {
 | 
				
			||||||
 | 
								return &SyntaxError{"expected colon after object key", 0}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dec.scanp++
 | 
				
			||||||
 | 
							dec.tokenState = tokenObjectValue
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dec *Decoder) tokenValueAllowed() bool {
 | 
				
			||||||
 | 
						switch dec.tokenState {
 | 
				
			||||||
 | 
						case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dec *Decoder) tokenValueEnd() {
 | 
				
			||||||
 | 
						switch dec.tokenState {
 | 
				
			||||||
 | 
						case tokenArrayStart, tokenArrayValue:
 | 
				
			||||||
 | 
							dec.tokenState = tokenArrayComma
 | 
				
			||||||
 | 
						case tokenObjectValue:
 | 
				
			||||||
 | 
							dec.tokenState = tokenObjectComma
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Delim is a JSON array or object delimiter, one of [ ] { or }.
 | 
				
			||||||
 | 
					type Delim rune
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d Delim) String() string {
 | 
				
			||||||
 | 
						return string(d)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Token returns the next JSON token in the input stream.
 | 
				
			||||||
 | 
					// At the end of the input stream, Token returns nil, io.EOF.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Token guarantees that the delimiters [ ] { } it returns are
 | 
				
			||||||
 | 
					// properly nested and matched: if Token encounters an unexpected
 | 
				
			||||||
 | 
					// delimiter in the input, it will return an error.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The input stream consists of basic JSON values—bool, string,
 | 
				
			||||||
 | 
					// number, and null—along with delimiters [ ] { } of type Delim
 | 
				
			||||||
 | 
					// to mark the start and end of arrays and objects.
 | 
				
			||||||
 | 
					// Commas and colons are elided.
 | 
				
			||||||
 | 
					func (dec *Decoder) Token() (Token, error) {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							c, err := dec.peek()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch c {
 | 
				
			||||||
 | 
							case '[':
 | 
				
			||||||
 | 
								if !dec.tokenValueAllowed() {
 | 
				
			||||||
 | 
									return dec.tokenError(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.scanp++
 | 
				
			||||||
 | 
								dec.tokenStack = append(dec.tokenStack, dec.tokenState)
 | 
				
			||||||
 | 
								dec.tokenState = tokenArrayStart
 | 
				
			||||||
 | 
								return Delim('['), nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case ']':
 | 
				
			||||||
 | 
								if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
 | 
				
			||||||
 | 
									return dec.tokenError(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.scanp++
 | 
				
			||||||
 | 
								dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
 | 
				
			||||||
 | 
								dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
 | 
				
			||||||
 | 
								dec.tokenValueEnd()
 | 
				
			||||||
 | 
								return Delim(']'), nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case '{':
 | 
				
			||||||
 | 
								if !dec.tokenValueAllowed() {
 | 
				
			||||||
 | 
									return dec.tokenError(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.scanp++
 | 
				
			||||||
 | 
								dec.tokenStack = append(dec.tokenStack, dec.tokenState)
 | 
				
			||||||
 | 
								dec.tokenState = tokenObjectStart
 | 
				
			||||||
 | 
								return Delim('{'), nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case '}':
 | 
				
			||||||
 | 
								if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
 | 
				
			||||||
 | 
									return dec.tokenError(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.scanp++
 | 
				
			||||||
 | 
								dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
 | 
				
			||||||
 | 
								dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
 | 
				
			||||||
 | 
								dec.tokenValueEnd()
 | 
				
			||||||
 | 
								return Delim('}'), nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case ':':
 | 
				
			||||||
 | 
								if dec.tokenState != tokenObjectColon {
 | 
				
			||||||
 | 
									return dec.tokenError(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.scanp++
 | 
				
			||||||
 | 
								dec.tokenState = tokenObjectValue
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case ',':
 | 
				
			||||||
 | 
								if dec.tokenState == tokenArrayComma {
 | 
				
			||||||
 | 
									dec.scanp++
 | 
				
			||||||
 | 
									dec.tokenState = tokenArrayValue
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if dec.tokenState == tokenObjectComma {
 | 
				
			||||||
 | 
									dec.scanp++
 | 
				
			||||||
 | 
									dec.tokenState = tokenObjectKey
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return dec.tokenError(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							case '"':
 | 
				
			||||||
 | 
								if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
 | 
				
			||||||
 | 
									var x string
 | 
				
			||||||
 | 
									old := dec.tokenState
 | 
				
			||||||
 | 
									dec.tokenState = tokenTopValue
 | 
				
			||||||
 | 
									err := dec.Decode(&x)
 | 
				
			||||||
 | 
									dec.tokenState = old
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										clearOffset(err)
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									dec.tokenState = tokenObjectColon
 | 
				
			||||||
 | 
									return x, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								fallthrough
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								if !dec.tokenValueAllowed() {
 | 
				
			||||||
 | 
									return dec.tokenError(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var x interface{}
 | 
				
			||||||
 | 
								if err := dec.Decode(&x); err != nil {
 | 
				
			||||||
 | 
									clearOffset(err)
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return x, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func clearOffset(err error) {
 | 
				
			||||||
 | 
						if s, ok := err.(*SyntaxError); ok {
 | 
				
			||||||
 | 
							s.Offset = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dec *Decoder) tokenError(c byte) (Token, error) {
 | 
				
			||||||
 | 
						var context string
 | 
				
			||||||
 | 
						switch dec.tokenState {
 | 
				
			||||||
 | 
						case tokenTopValue:
 | 
				
			||||||
 | 
							context = " looking for beginning of value"
 | 
				
			||||||
 | 
						case tokenArrayStart, tokenArrayValue, tokenObjectValue:
 | 
				
			||||||
 | 
							context = " looking for beginning of value"
 | 
				
			||||||
 | 
						case tokenArrayComma:
 | 
				
			||||||
 | 
							context = " after array element"
 | 
				
			||||||
 | 
						case tokenObjectKey:
 | 
				
			||||||
 | 
							context = " looking for beginning of object key string"
 | 
				
			||||||
 | 
						case tokenObjectColon:
 | 
				
			||||||
 | 
							context = " after object key"
 | 
				
			||||||
 | 
						case tokenObjectComma:
 | 
				
			||||||
 | 
							context = " after object key:value pair"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, &SyntaxError{"invalid character " + quoteChar(c) + " " + context, 0}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// More reports whether there is another element in the
 | 
				
			||||||
 | 
					// current array or object being parsed.
 | 
				
			||||||
 | 
					func (dec *Decoder) More() bool {
 | 
				
			||||||
 | 
						c, err := dec.peek()
 | 
				
			||||||
 | 
						return err == nil && c != ']' && c != '}'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dec *Decoder) peek() (byte, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							for i := dec.scanp; i < len(dec.buf); i++ {
 | 
				
			||||||
 | 
								c := dec.buf[i]
 | 
				
			||||||
 | 
								if isSpace(c) {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dec.scanp = i
 | 
				
			||||||
 | 
								return c, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// buffer has been scanned, now report any error
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = dec.refill()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EncodeToken writes the given JSON token to the stream.
 | 
				
			||||||
 | 
					// It returns an error if the delimiters [ ] { } are not properly used.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// EncodeToken does not call Flush, because usually it is part of
 | 
				
			||||||
 | 
					// a larger operation such as Encode, and those will call Flush when finished.
 | 
				
			||||||
 | 
					// Callers that create an Encoder and then invoke EncodeToken directly,
 | 
				
			||||||
 | 
					// without using Encode, need to call Flush when finished to ensure that
 | 
				
			||||||
 | 
					// the JSON is written to the underlying writer.
 | 
				
			||||||
 | 
					func (e *Encoder) EncodeToken(t Token) error  {
 | 
				
			||||||
 | 
						...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
							
								
								
									
										44
									
								
								vendor/github.com/square/go-jose/json/tags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/square/go-jose/json/tags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					// Copyright 2011 The Go Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a BSD-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// tagOptions is the string following a comma in a struct field's "json"
 | 
				
			||||||
 | 
					// tag, or the empty string. It does not include the leading comma.
 | 
				
			||||||
 | 
					type tagOptions string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseTag splits a struct field's json tag into its name and
 | 
				
			||||||
 | 
					// comma-separated options.
 | 
				
			||||||
 | 
					func parseTag(tag string) (string, tagOptions) {
 | 
				
			||||||
 | 
						if idx := strings.Index(tag, ","); idx != -1 {
 | 
				
			||||||
 | 
							return tag[:idx], tagOptions(tag[idx+1:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return tag, tagOptions("")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Contains reports whether a comma-separated list of options
 | 
				
			||||||
 | 
					// contains a particular substr flag. substr must be surrounded by a
 | 
				
			||||||
 | 
					// string boundary or commas.
 | 
				
			||||||
 | 
					func (o tagOptions) Contains(optionName string) bool {
 | 
				
			||||||
 | 
						if len(o) == 0 {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						s := string(o)
 | 
				
			||||||
 | 
						for s != "" {
 | 
				
			||||||
 | 
							var next string
 | 
				
			||||||
 | 
							i := strings.Index(s, ",")
 | 
				
			||||||
 | 
							if i >= 0 {
 | 
				
			||||||
 | 
								s, next = s[:i], s[i+1:]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if s == optionName {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							s = next
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										280
									
								
								vendor/github.com/square/go-jose/jwe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								vendor/github.com/square/go-jose/jwe.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,280 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/square/go-jose/json"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawJsonWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
 | 
				
			||||||
 | 
					type rawJsonWebEncryption struct {
 | 
				
			||||||
 | 
						Protected    *byteBuffer        `json:"protected,omitempty"`
 | 
				
			||||||
 | 
						Unprotected  *rawHeader         `json:"unprotected,omitempty"`
 | 
				
			||||||
 | 
						Header       *rawHeader         `json:"header,omitempty"`
 | 
				
			||||||
 | 
						Recipients   []rawRecipientInfo `json:"recipients,omitempty"`
 | 
				
			||||||
 | 
						Aad          *byteBuffer        `json:"aad,omitempty"`
 | 
				
			||||||
 | 
						EncryptedKey *byteBuffer        `json:"encrypted_key,omitempty"`
 | 
				
			||||||
 | 
						Iv           *byteBuffer        `json:"iv,omitempty"`
 | 
				
			||||||
 | 
						Ciphertext   *byteBuffer        `json:"ciphertext,omitempty"`
 | 
				
			||||||
 | 
						Tag          *byteBuffer        `json:"tag,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawRecipientInfo represents a raw JWE Per-Recipient header JSON object. Used for parsing/serializing.
 | 
				
			||||||
 | 
					type rawRecipientInfo struct {
 | 
				
			||||||
 | 
						Header       *rawHeader `json:"header,omitempty"`
 | 
				
			||||||
 | 
						EncryptedKey string     `json:"encrypted_key,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JsonWebEncryption represents an encrypted JWE object after parsing.
 | 
				
			||||||
 | 
					type JsonWebEncryption struct {
 | 
				
			||||||
 | 
						Header                   JoseHeader
 | 
				
			||||||
 | 
						protected, unprotected   *rawHeader
 | 
				
			||||||
 | 
						recipients               []recipientInfo
 | 
				
			||||||
 | 
						aad, iv, ciphertext, tag []byte
 | 
				
			||||||
 | 
						original                 *rawJsonWebEncryption
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// recipientInfo represents a raw JWE Per-Recipient header JSON object after parsing.
 | 
				
			||||||
 | 
					type recipientInfo struct {
 | 
				
			||||||
 | 
						header       *rawHeader
 | 
				
			||||||
 | 
						encryptedKey []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetAuthData retrieves the (optional) authenticated data attached to the object.
 | 
				
			||||||
 | 
					func (obj JsonWebEncryption) GetAuthData() []byte {
 | 
				
			||||||
 | 
						if obj.aad != nil {
 | 
				
			||||||
 | 
							out := make([]byte, len(obj.aad))
 | 
				
			||||||
 | 
							copy(out, obj.aad)
 | 
				
			||||||
 | 
							return out
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get the merged header values
 | 
				
			||||||
 | 
					func (obj JsonWebEncryption) mergedHeaders(recipient *recipientInfo) rawHeader {
 | 
				
			||||||
 | 
						out := rawHeader{}
 | 
				
			||||||
 | 
						out.merge(obj.protected)
 | 
				
			||||||
 | 
						out.merge(obj.unprotected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if recipient != nil {
 | 
				
			||||||
 | 
							out.merge(recipient.header)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get the additional authenticated data from a JWE object.
 | 
				
			||||||
 | 
					func (obj JsonWebEncryption) computeAuthData() []byte {
 | 
				
			||||||
 | 
						var protected string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if obj.original != nil {
 | 
				
			||||||
 | 
							protected = obj.original.Protected.base64()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							protected = base64URLEncode(mustSerializeJSON((obj.protected)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						output := []byte(protected)
 | 
				
			||||||
 | 
						if obj.aad != nil {
 | 
				
			||||||
 | 
							output = append(output, '.')
 | 
				
			||||||
 | 
							output = append(output, []byte(base64URLEncode(obj.aad))...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return output
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseEncrypted parses an encrypted message in compact or full serialization format.
 | 
				
			||||||
 | 
					func ParseEncrypted(input string) (*JsonWebEncryption, error) {
 | 
				
			||||||
 | 
						input = stripWhitespace(input)
 | 
				
			||||||
 | 
						if strings.HasPrefix(input, "{") {
 | 
				
			||||||
 | 
							return parseEncryptedFull(input)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return parseEncryptedCompact(input)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseEncryptedFull parses a message in compact format.
 | 
				
			||||||
 | 
					func parseEncryptedFull(input string) (*JsonWebEncryption, error) {
 | 
				
			||||||
 | 
						var parsed rawJsonWebEncryption
 | 
				
			||||||
 | 
						err := json.Unmarshal([]byte(input), &parsed)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return parsed.sanitized()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sanitized produces a cleaned-up JWE object from the raw JSON.
 | 
				
			||||||
 | 
					func (parsed *rawJsonWebEncryption) sanitized() (*JsonWebEncryption, error) {
 | 
				
			||||||
 | 
						obj := &JsonWebEncryption{
 | 
				
			||||||
 | 
							original:    parsed,
 | 
				
			||||||
 | 
							unprotected: parsed.Unprotected,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check that there is not a nonce in the unprotected headers
 | 
				
			||||||
 | 
						if (parsed.Unprotected != nil && parsed.Unprotected.Nonce != "") ||
 | 
				
			||||||
 | 
							(parsed.Header != nil && parsed.Header.Nonce != "") {
 | 
				
			||||||
 | 
							return nil, ErrUnprotectedNonce
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
 | 
				
			||||||
 | 
							err := json.Unmarshal(parsed.Protected.bytes(), &obj.protected)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("square/go-jose: invalid protected header: %s, %s", err, parsed.Protected.base64())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Note: this must be called _after_ we parse the protected header,
 | 
				
			||||||
 | 
						// otherwise fields from the protected header will not get picked up.
 | 
				
			||||||
 | 
						obj.Header = obj.mergedHeaders(nil).sanitized()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(parsed.Recipients) == 0 {
 | 
				
			||||||
 | 
							obj.recipients = []recipientInfo{
 | 
				
			||||||
 | 
								recipientInfo{
 | 
				
			||||||
 | 
									header:       parsed.Header,
 | 
				
			||||||
 | 
									encryptedKey: parsed.EncryptedKey.bytes(),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							obj.recipients = make([]recipientInfo, len(parsed.Recipients))
 | 
				
			||||||
 | 
							for r := range parsed.Recipients {
 | 
				
			||||||
 | 
								encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Check that there is not a nonce in the unprotected header
 | 
				
			||||||
 | 
								if parsed.Recipients[r].Header != nil && parsed.Recipients[r].Header.Nonce != "" {
 | 
				
			||||||
 | 
									return nil, ErrUnprotectedNonce
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								obj.recipients[r].header = parsed.Recipients[r].Header
 | 
				
			||||||
 | 
								obj.recipients[r].encryptedKey = encryptedKey
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, recipient := range obj.recipients {
 | 
				
			||||||
 | 
							headers := obj.mergedHeaders(&recipient)
 | 
				
			||||||
 | 
							if headers.Alg == "" || headers.Enc == "" {
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("square/go-jose: message is missing alg/enc headers")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						obj.iv = parsed.Iv.bytes()
 | 
				
			||||||
 | 
						obj.ciphertext = parsed.Ciphertext.bytes()
 | 
				
			||||||
 | 
						obj.tag = parsed.Tag.bytes()
 | 
				
			||||||
 | 
						obj.aad = parsed.Aad.bytes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return obj, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseEncryptedCompact parses a message in compact format.
 | 
				
			||||||
 | 
					func parseEncryptedCompact(input string) (*JsonWebEncryption, error) {
 | 
				
			||||||
 | 
						parts := strings.Split(input, ".")
 | 
				
			||||||
 | 
						if len(parts) != 5 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: compact JWE format must have five parts")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rawProtected, err := base64URLDecode(parts[0])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						encryptedKey, err := base64URLDecode(parts[1])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iv, err := base64URLDecode(parts[2])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ciphertext, err := base64URLDecode(parts[3])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tag, err := base64URLDecode(parts[4])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						raw := &rawJsonWebEncryption{
 | 
				
			||||||
 | 
							Protected:    newBuffer(rawProtected),
 | 
				
			||||||
 | 
							EncryptedKey: newBuffer(encryptedKey),
 | 
				
			||||||
 | 
							Iv:           newBuffer(iv),
 | 
				
			||||||
 | 
							Ciphertext:   newBuffer(ciphertext),
 | 
				
			||||||
 | 
							Tag:          newBuffer(tag),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return raw.sanitized()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CompactSerialize serializes an object using the compact serialization format.
 | 
				
			||||||
 | 
					func (obj JsonWebEncryption) CompactSerialize() (string, error) {
 | 
				
			||||||
 | 
						if len(obj.recipients) != 1 || obj.unprotected != nil ||
 | 
				
			||||||
 | 
							obj.protected == nil || obj.recipients[0].header != nil {
 | 
				
			||||||
 | 
							return "", ErrNotSupported
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						serializedProtected := mustSerializeJSON(obj.protected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"%s.%s.%s.%s.%s",
 | 
				
			||||||
 | 
							base64URLEncode(serializedProtected),
 | 
				
			||||||
 | 
							base64URLEncode(obj.recipients[0].encryptedKey),
 | 
				
			||||||
 | 
							base64URLEncode(obj.iv),
 | 
				
			||||||
 | 
							base64URLEncode(obj.ciphertext),
 | 
				
			||||||
 | 
							base64URLEncode(obj.tag)), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FullSerialize serializes an object using the full JSON serialization format.
 | 
				
			||||||
 | 
					func (obj JsonWebEncryption) FullSerialize() string {
 | 
				
			||||||
 | 
						raw := rawJsonWebEncryption{
 | 
				
			||||||
 | 
							Unprotected:  obj.unprotected,
 | 
				
			||||||
 | 
							Iv:           newBuffer(obj.iv),
 | 
				
			||||||
 | 
							Ciphertext:   newBuffer(obj.ciphertext),
 | 
				
			||||||
 | 
							EncryptedKey: newBuffer(obj.recipients[0].encryptedKey),
 | 
				
			||||||
 | 
							Tag:          newBuffer(obj.tag),
 | 
				
			||||||
 | 
							Aad:          newBuffer(obj.aad),
 | 
				
			||||||
 | 
							Recipients:   []rawRecipientInfo{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj.recipients) > 1 {
 | 
				
			||||||
 | 
							for _, recipient := range obj.recipients {
 | 
				
			||||||
 | 
								info := rawRecipientInfo{
 | 
				
			||||||
 | 
									Header:       recipient.header,
 | 
				
			||||||
 | 
									EncryptedKey: base64URLEncode(recipient.encryptedKey),
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								raw.Recipients = append(raw.Recipients, info)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							// Use flattened serialization
 | 
				
			||||||
 | 
							raw.Header = obj.recipients[0].header
 | 
				
			||||||
 | 
							raw.EncryptedKey = newBuffer(obj.recipients[0].encryptedKey)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if obj.protected != nil {
 | 
				
			||||||
 | 
							raw.Protected = newBuffer(mustSerializeJSON(obj.protected))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return string(mustSerializeJSON(raw))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										447
									
								
								vendor/github.com/square/go-jose/jwk.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								vendor/github.com/square/go-jose/jwk.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,447 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto"
 | 
				
			||||||
 | 
						"crypto/ecdsa"
 | 
				
			||||||
 | 
						"crypto/elliptic"
 | 
				
			||||||
 | 
						"crypto/rsa"
 | 
				
			||||||
 | 
						"crypto/x509"
 | 
				
			||||||
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/square/go-jose/json"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawJsonWebKey represents a public or private key in JWK format, used for parsing/serializing.
 | 
				
			||||||
 | 
					type rawJsonWebKey struct {
 | 
				
			||||||
 | 
						Use string      `json:"use,omitempty"`
 | 
				
			||||||
 | 
						Kty string      `json:"kty,omitempty"`
 | 
				
			||||||
 | 
						Kid string      `json:"kid,omitempty"`
 | 
				
			||||||
 | 
						Crv string      `json:"crv,omitempty"`
 | 
				
			||||||
 | 
						Alg string      `json:"alg,omitempty"`
 | 
				
			||||||
 | 
						K   *byteBuffer `json:"k,omitempty"`
 | 
				
			||||||
 | 
						X   *byteBuffer `json:"x,omitempty"`
 | 
				
			||||||
 | 
						Y   *byteBuffer `json:"y,omitempty"`
 | 
				
			||||||
 | 
						N   *byteBuffer `json:"n,omitempty"`
 | 
				
			||||||
 | 
						E   *byteBuffer `json:"e,omitempty"`
 | 
				
			||||||
 | 
						// -- Following fields are only used for private keys --
 | 
				
			||||||
 | 
						// RSA uses D, P and Q, while ECDSA uses only D. Fields Dp, Dq, and Qi are
 | 
				
			||||||
 | 
						// completely optional. Therefore for RSA/ECDSA, D != nil is a contract that
 | 
				
			||||||
 | 
						// we have a private key whereas D == nil means we have only a public key.
 | 
				
			||||||
 | 
						D  *byteBuffer `json:"d,omitempty"`
 | 
				
			||||||
 | 
						P  *byteBuffer `json:"p,omitempty"`
 | 
				
			||||||
 | 
						Q  *byteBuffer `json:"q,omitempty"`
 | 
				
			||||||
 | 
						Dp *byteBuffer `json:"dp,omitempty"`
 | 
				
			||||||
 | 
						Dq *byteBuffer `json:"dq,omitempty"`
 | 
				
			||||||
 | 
						Qi *byteBuffer `json:"qi,omitempty"`
 | 
				
			||||||
 | 
						// Certificates
 | 
				
			||||||
 | 
						X5c []string `json:"x5c,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JsonWebKey represents a public or private key in JWK format.
 | 
				
			||||||
 | 
					type JsonWebKey struct {
 | 
				
			||||||
 | 
						Key          interface{}
 | 
				
			||||||
 | 
						Certificates []*x509.Certificate
 | 
				
			||||||
 | 
						KeyID        string
 | 
				
			||||||
 | 
						Algorithm    string
 | 
				
			||||||
 | 
						Use          string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MarshalJSON serializes the given key to its JSON representation.
 | 
				
			||||||
 | 
					func (k JsonWebKey) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						var raw *rawJsonWebKey
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch key := k.Key.(type) {
 | 
				
			||||||
 | 
						case *ecdsa.PublicKey:
 | 
				
			||||||
 | 
							raw, err = fromEcPublicKey(key)
 | 
				
			||||||
 | 
						case *rsa.PublicKey:
 | 
				
			||||||
 | 
							raw = fromRsaPublicKey(key)
 | 
				
			||||||
 | 
						case *ecdsa.PrivateKey:
 | 
				
			||||||
 | 
							raw, err = fromEcPrivateKey(key)
 | 
				
			||||||
 | 
						case *rsa.PrivateKey:
 | 
				
			||||||
 | 
							raw, err = fromRsaPrivateKey(key)
 | 
				
			||||||
 | 
						case []byte:
 | 
				
			||||||
 | 
							raw, err = fromSymmetricKey(key)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: unknown key type '%s'", reflect.TypeOf(key))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						raw.Kid = k.KeyID
 | 
				
			||||||
 | 
						raw.Alg = k.Algorithm
 | 
				
			||||||
 | 
						raw.Use = k.Use
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, cert := range k.Certificates {
 | 
				
			||||||
 | 
							raw.X5c = append(raw.X5c, base64.StdEncoding.EncodeToString(cert.Raw))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return json.Marshal(raw)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnmarshalJSON reads a key from its JSON representation.
 | 
				
			||||||
 | 
					func (k *JsonWebKey) UnmarshalJSON(data []byte) (err error) {
 | 
				
			||||||
 | 
						var raw rawJsonWebKey
 | 
				
			||||||
 | 
						err = json.Unmarshal(data, &raw)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var key interface{}
 | 
				
			||||||
 | 
						switch raw.Kty {
 | 
				
			||||||
 | 
						case "EC":
 | 
				
			||||||
 | 
							if raw.D != nil {
 | 
				
			||||||
 | 
								key, err = raw.ecPrivateKey()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								key, err = raw.ecPublicKey()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case "RSA":
 | 
				
			||||||
 | 
							if raw.D != nil {
 | 
				
			||||||
 | 
								key, err = raw.rsaPrivateKey()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								key, err = raw.rsaPublicKey()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case "oct":
 | 
				
			||||||
 | 
							key, err = raw.symmetricKey()
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							err = fmt.Errorf("square/go-jose: unknown json web key type '%s'", raw.Kty)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							*k = JsonWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						k.Certificates = make([]*x509.Certificate, len(raw.X5c))
 | 
				
			||||||
 | 
						for i, cert := range raw.X5c {
 | 
				
			||||||
 | 
							raw, err := base64.StdEncoding.DecodeString(cert)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							k.Certificates[i], err = x509.ParseCertificate(raw)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JsonWebKeySet represents a JWK Set object.
 | 
				
			||||||
 | 
					type JsonWebKeySet struct {
 | 
				
			||||||
 | 
						Keys []JsonWebKey `json:"keys"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key convenience method returns keys by key ID. Specification states
 | 
				
			||||||
 | 
					// that a JWK Set "SHOULD" use distinct key IDs, but allows for some
 | 
				
			||||||
 | 
					// cases where they are not distinct. Hence method returns a slice
 | 
				
			||||||
 | 
					// of JsonWebKeys.
 | 
				
			||||||
 | 
					func (s *JsonWebKeySet) Key(kid string) []JsonWebKey {
 | 
				
			||||||
 | 
						var keys []JsonWebKey
 | 
				
			||||||
 | 
						for _, key := range s.Keys {
 | 
				
			||||||
 | 
							if key.KeyID == kid {
 | 
				
			||||||
 | 
								keys = append(keys, key)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return keys
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const rsaThumbprintTemplate = `{"e":"%s","kty":"RSA","n":"%s"}`
 | 
				
			||||||
 | 
					const ecThumbprintTemplate = `{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ecThumbprintInput(curve elliptic.Curve, x, y *big.Int) (string, error) {
 | 
				
			||||||
 | 
						coordLength := curveSize(curve)
 | 
				
			||||||
 | 
						crv, err := curveName(curve)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf(ecThumbprintTemplate, crv,
 | 
				
			||||||
 | 
							newFixedSizeBuffer(x.Bytes(), coordLength).base64(),
 | 
				
			||||||
 | 
							newFixedSizeBuffer(y.Bytes(), coordLength).base64()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func rsaThumbprintInput(n *big.Int, e int) (string, error) {
 | 
				
			||||||
 | 
						return fmt.Sprintf(rsaThumbprintTemplate,
 | 
				
			||||||
 | 
							newBufferFromInt(uint64(e)).base64(),
 | 
				
			||||||
 | 
							newBuffer(n.Bytes()).base64()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Thumbprint computes the JWK Thumbprint of a key using the
 | 
				
			||||||
 | 
					// indicated hash algorithm.
 | 
				
			||||||
 | 
					func (k *JsonWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
 | 
				
			||||||
 | 
						var input string
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						switch key := k.Key.(type) {
 | 
				
			||||||
 | 
						case *ecdsa.PublicKey:
 | 
				
			||||||
 | 
							input, err = ecThumbprintInput(key.Curve, key.X, key.Y)
 | 
				
			||||||
 | 
						case *ecdsa.PrivateKey:
 | 
				
			||||||
 | 
							input, err = ecThumbprintInput(key.Curve, key.X, key.Y)
 | 
				
			||||||
 | 
						case *rsa.PublicKey:
 | 
				
			||||||
 | 
							input, err = rsaThumbprintInput(key.N, key.E)
 | 
				
			||||||
 | 
						case *rsa.PrivateKey:
 | 
				
			||||||
 | 
							input, err = rsaThumbprintInput(key.N, key.E)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: unknown key type '%s'", reflect.TypeOf(key))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h := hash.New()
 | 
				
			||||||
 | 
						h.Write([]byte(input))
 | 
				
			||||||
 | 
						return h.Sum(nil), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Valid checks that the key contains the expected parameters
 | 
				
			||||||
 | 
					func (k *JsonWebKey) Valid() bool {
 | 
				
			||||||
 | 
						if k.Key == nil {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch key := k.Key.(type) {
 | 
				
			||||||
 | 
						case *ecdsa.PublicKey:
 | 
				
			||||||
 | 
							if key.Curve == nil || key.X == nil || key.Y == nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case *ecdsa.PrivateKey:
 | 
				
			||||||
 | 
							if key.Curve == nil || key.X == nil || key.Y == nil || key.D == nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case *rsa.PublicKey:
 | 
				
			||||||
 | 
							if key.N == nil || key.E == 0 {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case *rsa.PrivateKey:
 | 
				
			||||||
 | 
							if key.N == nil || key.E == 0 || key.D == nil || len(key.Primes) < 2 {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (key rawJsonWebKey) rsaPublicKey() (*rsa.PublicKey, error) {
 | 
				
			||||||
 | 
						if key.N == nil || key.E == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid RSA key, missing n/e values")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &rsa.PublicKey{
 | 
				
			||||||
 | 
							N: key.N.bigInt(),
 | 
				
			||||||
 | 
							E: key.E.toInt(),
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func fromRsaPublicKey(pub *rsa.PublicKey) *rawJsonWebKey {
 | 
				
			||||||
 | 
						return &rawJsonWebKey{
 | 
				
			||||||
 | 
							Kty: "RSA",
 | 
				
			||||||
 | 
							N:   newBuffer(pub.N.Bytes()),
 | 
				
			||||||
 | 
							E:   newBufferFromInt(uint64(pub.E)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (key rawJsonWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
 | 
				
			||||||
 | 
						var curve elliptic.Curve
 | 
				
			||||||
 | 
						switch key.Crv {
 | 
				
			||||||
 | 
						case "P-256":
 | 
				
			||||||
 | 
							curve = elliptic.P256()
 | 
				
			||||||
 | 
						case "P-384":
 | 
				
			||||||
 | 
							curve = elliptic.P384()
 | 
				
			||||||
 | 
						case "P-521":
 | 
				
			||||||
 | 
							curve = elliptic.P521()
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: unsupported elliptic curve '%s'", key.Crv)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if key.X == nil || key.Y == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid EC key, missing x/y values")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						x := key.X.bigInt()
 | 
				
			||||||
 | 
						y := key.Y.bigInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !curve.IsOnCurve(x, y) {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &ecdsa.PublicKey{
 | 
				
			||||||
 | 
							Curve: curve,
 | 
				
			||||||
 | 
							X:     x,
 | 
				
			||||||
 | 
							Y:     y,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJsonWebKey, error) {
 | 
				
			||||||
 | 
						if pub == nil || pub.X == nil || pub.Y == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid EC key (nil, or X/Y missing)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name, err := curveName(pub.Curve)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size := curveSize(pub.Curve)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xBytes := pub.X.Bytes()
 | 
				
			||||||
 | 
						yBytes := pub.Y.Bytes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(xBytes) > size || len(yBytes) > size {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid EC key (X/Y too large)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						key := &rawJsonWebKey{
 | 
				
			||||||
 | 
							Kty: "EC",
 | 
				
			||||||
 | 
							Crv: name,
 | 
				
			||||||
 | 
							X:   newFixedSizeBuffer(xBytes, size),
 | 
				
			||||||
 | 
							Y:   newFixedSizeBuffer(yBytes, size),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return key, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (key rawJsonWebKey) rsaPrivateKey() (*rsa.PrivateKey, error) {
 | 
				
			||||||
 | 
						var missing []string
 | 
				
			||||||
 | 
						switch {
 | 
				
			||||||
 | 
						case key.N == nil:
 | 
				
			||||||
 | 
							missing = append(missing, "N")
 | 
				
			||||||
 | 
						case key.E == nil:
 | 
				
			||||||
 | 
							missing = append(missing, "E")
 | 
				
			||||||
 | 
						case key.D == nil:
 | 
				
			||||||
 | 
							missing = append(missing, "D")
 | 
				
			||||||
 | 
						case key.P == nil:
 | 
				
			||||||
 | 
							missing = append(missing, "P")
 | 
				
			||||||
 | 
						case key.Q == nil:
 | 
				
			||||||
 | 
							missing = append(missing, "Q")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(missing) > 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid RSA private key, missing %s value(s)", strings.Join(missing, ", "))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rv := &rsa.PrivateKey{
 | 
				
			||||||
 | 
							PublicKey: rsa.PublicKey{
 | 
				
			||||||
 | 
								N: key.N.bigInt(),
 | 
				
			||||||
 | 
								E: key.E.toInt(),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							D: key.D.bigInt(),
 | 
				
			||||||
 | 
							Primes: []*big.Int{
 | 
				
			||||||
 | 
								key.P.bigInt(),
 | 
				
			||||||
 | 
								key.Q.bigInt(),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if key.Dp != nil {
 | 
				
			||||||
 | 
							rv.Precomputed.Dp = key.Dp.bigInt()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if key.Dq != nil {
 | 
				
			||||||
 | 
							rv.Precomputed.Dq = key.Dq.bigInt()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if key.Qi != nil {
 | 
				
			||||||
 | 
							rv.Precomputed.Qinv = key.Qi.bigInt()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := rv.Validate()
 | 
				
			||||||
 | 
						return rv, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func fromRsaPrivateKey(rsa *rsa.PrivateKey) (*rawJsonWebKey, error) {
 | 
				
			||||||
 | 
						if len(rsa.Primes) != 2 {
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						raw := fromRsaPublicKey(&rsa.PublicKey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						raw.D = newBuffer(rsa.D.Bytes())
 | 
				
			||||||
 | 
						raw.P = newBuffer(rsa.Primes[0].Bytes())
 | 
				
			||||||
 | 
						raw.Q = newBuffer(rsa.Primes[1].Bytes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return raw, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (key rawJsonWebKey) ecPrivateKey() (*ecdsa.PrivateKey, error) {
 | 
				
			||||||
 | 
						var curve elliptic.Curve
 | 
				
			||||||
 | 
						switch key.Crv {
 | 
				
			||||||
 | 
						case "P-256":
 | 
				
			||||||
 | 
							curve = elliptic.P256()
 | 
				
			||||||
 | 
						case "P-384":
 | 
				
			||||||
 | 
							curve = elliptic.P384()
 | 
				
			||||||
 | 
						case "P-521":
 | 
				
			||||||
 | 
							curve = elliptic.P521()
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: unsupported elliptic curve '%s'", key.Crv)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if key.X == nil || key.Y == nil || key.D == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid EC private key, missing x/y/d values")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						x := key.X.bigInt()
 | 
				
			||||||
 | 
						y := key.Y.bigInt()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !curve.IsOnCurve(x, y) {
 | 
				
			||||||
 | 
							return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &ecdsa.PrivateKey{
 | 
				
			||||||
 | 
							PublicKey: ecdsa.PublicKey{
 | 
				
			||||||
 | 
								Curve: curve,
 | 
				
			||||||
 | 
								X:     x,
 | 
				
			||||||
 | 
								Y:     y,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							D: key.D.bigInt(),
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func fromEcPrivateKey(ec *ecdsa.PrivateKey) (*rawJsonWebKey, error) {
 | 
				
			||||||
 | 
						raw, err := fromEcPublicKey(&ec.PublicKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ec.D == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid EC private key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						raw.D = newBuffer(ec.D.Bytes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return raw, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func fromSymmetricKey(key []byte) (*rawJsonWebKey, error) {
 | 
				
			||||||
 | 
						return &rawJsonWebKey{
 | 
				
			||||||
 | 
							Kty: "oct",
 | 
				
			||||||
 | 
							K:   newBuffer(key),
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (key rawJsonWebKey) symmetricKey() ([]byte, error) {
 | 
				
			||||||
 | 
						if key.K == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: invalid OCT (symmetric) key, missing k value")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return key.K.bytes(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										254
									
								
								vendor/github.com/square/go-jose/jws.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								vendor/github.com/square/go-jose/jws.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,254 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/square/go-jose/json"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawJsonWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
 | 
				
			||||||
 | 
					type rawJsonWebSignature struct {
 | 
				
			||||||
 | 
						Payload    *byteBuffer        `json:"payload,omitempty"`
 | 
				
			||||||
 | 
						Signatures []rawSignatureInfo `json:"signatures,omitempty"`
 | 
				
			||||||
 | 
						Protected  *byteBuffer        `json:"protected,omitempty"`
 | 
				
			||||||
 | 
						Header     *rawHeader         `json:"header,omitempty"`
 | 
				
			||||||
 | 
						Signature  *byteBuffer        `json:"signature,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawSignatureInfo represents a single JWS signature over the JWS payload and protected header.
 | 
				
			||||||
 | 
					type rawSignatureInfo struct {
 | 
				
			||||||
 | 
						Protected *byteBuffer `json:"protected,omitempty"`
 | 
				
			||||||
 | 
						Header    *rawHeader  `json:"header,omitempty"`
 | 
				
			||||||
 | 
						Signature *byteBuffer `json:"signature,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JsonWebSignature represents a signed JWS object after parsing.
 | 
				
			||||||
 | 
					type JsonWebSignature struct {
 | 
				
			||||||
 | 
						payload    []byte
 | 
				
			||||||
 | 
						Signatures []Signature
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Signature represents a single signature over the JWS payload and protected header.
 | 
				
			||||||
 | 
					type Signature struct {
 | 
				
			||||||
 | 
						// Header fields, such as the signature algorithm
 | 
				
			||||||
 | 
						Header JoseHeader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The actual signature value
 | 
				
			||||||
 | 
						Signature []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						protected *rawHeader
 | 
				
			||||||
 | 
						header    *rawHeader
 | 
				
			||||||
 | 
						original  *rawSignatureInfo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseSigned parses a signed message in compact or full serialization format.
 | 
				
			||||||
 | 
					func ParseSigned(input string) (*JsonWebSignature, error) {
 | 
				
			||||||
 | 
						input = stripWhitespace(input)
 | 
				
			||||||
 | 
						if strings.HasPrefix(input, "{") {
 | 
				
			||||||
 | 
							return parseSignedFull(input)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return parseSignedCompact(input)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get a header value
 | 
				
			||||||
 | 
					func (sig Signature) mergedHeaders() rawHeader {
 | 
				
			||||||
 | 
						out := rawHeader{}
 | 
				
			||||||
 | 
						out.merge(sig.protected)
 | 
				
			||||||
 | 
						out.merge(sig.header)
 | 
				
			||||||
 | 
						return out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compute data to be signed
 | 
				
			||||||
 | 
					func (obj JsonWebSignature) computeAuthData(signature *Signature) []byte {
 | 
				
			||||||
 | 
						var serializedProtected string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if signature.original != nil && signature.original.Protected != nil {
 | 
				
			||||||
 | 
							serializedProtected = signature.original.Protected.base64()
 | 
				
			||||||
 | 
						} else if signature.protected != nil {
 | 
				
			||||||
 | 
							serializedProtected = base64URLEncode(mustSerializeJSON(signature.protected))
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							serializedProtected = ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return []byte(fmt.Sprintf("%s.%s",
 | 
				
			||||||
 | 
							serializedProtected,
 | 
				
			||||||
 | 
							base64URLEncode(obj.payload)))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseSignedFull parses a message in full format.
 | 
				
			||||||
 | 
					func parseSignedFull(input string) (*JsonWebSignature, error) {
 | 
				
			||||||
 | 
						var parsed rawJsonWebSignature
 | 
				
			||||||
 | 
						err := json.Unmarshal([]byte(input), &parsed)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return parsed.sanitized()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sanitized produces a cleaned-up JWS object from the raw JSON.
 | 
				
			||||||
 | 
					func (parsed *rawJsonWebSignature) sanitized() (*JsonWebSignature, error) {
 | 
				
			||||||
 | 
						if parsed.Payload == nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: missing payload in JWS message")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						obj := &JsonWebSignature{
 | 
				
			||||||
 | 
							payload:    parsed.Payload.bytes(),
 | 
				
			||||||
 | 
							Signatures: make([]Signature, len(parsed.Signatures)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(parsed.Signatures) == 0 {
 | 
				
			||||||
 | 
							// No signatures array, must be flattened serialization
 | 
				
			||||||
 | 
							signature := Signature{}
 | 
				
			||||||
 | 
							if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
 | 
				
			||||||
 | 
								signature.protected = &rawHeader{}
 | 
				
			||||||
 | 
								err := json.Unmarshal(parsed.Protected.bytes(), signature.protected)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if parsed.Header != nil && parsed.Header.Nonce != "" {
 | 
				
			||||||
 | 
								return nil, ErrUnprotectedNonce
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							signature.header = parsed.Header
 | 
				
			||||||
 | 
							signature.Signature = parsed.Signature.bytes()
 | 
				
			||||||
 | 
							// Make a fake "original" rawSignatureInfo to store the unprocessed
 | 
				
			||||||
 | 
							// Protected header. This is necessary because the Protected header can
 | 
				
			||||||
 | 
							// contain arbitrary fields not registered as part of the spec. See
 | 
				
			||||||
 | 
							// https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4
 | 
				
			||||||
 | 
							// If we unmarshal Protected into a rawHeader with its explicit list of fields,
 | 
				
			||||||
 | 
							// we cannot marshal losslessly. So we have to keep around the original bytes.
 | 
				
			||||||
 | 
							// This is used in computeAuthData, which will first attempt to use
 | 
				
			||||||
 | 
							// the original bytes of a protected header, and fall back on marshaling the
 | 
				
			||||||
 | 
							// header struct only if those bytes are not available.
 | 
				
			||||||
 | 
							signature.original = &rawSignatureInfo{
 | 
				
			||||||
 | 
								Protected: parsed.Protected,
 | 
				
			||||||
 | 
								Header:    parsed.Header,
 | 
				
			||||||
 | 
								Signature: parsed.Signature,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							signature.Header = signature.mergedHeaders().sanitized()
 | 
				
			||||||
 | 
							obj.Signatures = append(obj.Signatures, signature)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, sig := range parsed.Signatures {
 | 
				
			||||||
 | 
							if sig.Protected != nil && len(sig.Protected.bytes()) > 0 {
 | 
				
			||||||
 | 
								obj.Signatures[i].protected = &rawHeader{}
 | 
				
			||||||
 | 
								err := json.Unmarshal(sig.Protected.bytes(), obj.Signatures[i].protected)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check that there is not a nonce in the unprotected header
 | 
				
			||||||
 | 
							if sig.Header != nil && sig.Header.Nonce != "" {
 | 
				
			||||||
 | 
								return nil, ErrUnprotectedNonce
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							obj.Signatures[i].Signature = sig.Signature.bytes()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Copy value of sig
 | 
				
			||||||
 | 
							original := sig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							obj.Signatures[i].header = sig.Header
 | 
				
			||||||
 | 
							obj.Signatures[i].original = &original
 | 
				
			||||||
 | 
							obj.Signatures[i].Header = obj.Signatures[i].mergedHeaders().sanitized()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return obj, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseSignedCompact parses a message in compact format.
 | 
				
			||||||
 | 
					func parseSignedCompact(input string) (*JsonWebSignature, error) {
 | 
				
			||||||
 | 
						parts := strings.Split(input, ".")
 | 
				
			||||||
 | 
						if len(parts) != 3 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("square/go-jose: compact JWS format must have three parts")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rawProtected, err := base64URLDecode(parts[0])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						payload, err := base64URLDecode(parts[1])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						signature, err := base64URLDecode(parts[2])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						raw := &rawJsonWebSignature{
 | 
				
			||||||
 | 
							Payload:   newBuffer(payload),
 | 
				
			||||||
 | 
							Protected: newBuffer(rawProtected),
 | 
				
			||||||
 | 
							Signature: newBuffer(signature),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return raw.sanitized()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CompactSerialize serializes an object using the compact serialization format.
 | 
				
			||||||
 | 
					func (obj JsonWebSignature) CompactSerialize() (string, error) {
 | 
				
			||||||
 | 
						if len(obj.Signatures) != 1 || obj.Signatures[0].header != nil || obj.Signatures[0].protected == nil {
 | 
				
			||||||
 | 
							return "", ErrNotSupported
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						serializedProtected := mustSerializeJSON(obj.Signatures[0].protected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"%s.%s.%s",
 | 
				
			||||||
 | 
							base64URLEncode(serializedProtected),
 | 
				
			||||||
 | 
							base64URLEncode(obj.payload),
 | 
				
			||||||
 | 
							base64URLEncode(obj.Signatures[0].Signature)), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FullSerialize serializes an object using the full JSON serialization format.
 | 
				
			||||||
 | 
					func (obj JsonWebSignature) FullSerialize() string {
 | 
				
			||||||
 | 
						raw := rawJsonWebSignature{
 | 
				
			||||||
 | 
							Payload: newBuffer(obj.payload),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj.Signatures) == 1 {
 | 
				
			||||||
 | 
							if obj.Signatures[0].protected != nil {
 | 
				
			||||||
 | 
								serializedProtected := mustSerializeJSON(obj.Signatures[0].protected)
 | 
				
			||||||
 | 
								raw.Protected = newBuffer(serializedProtected)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							raw.Header = obj.Signatures[0].header
 | 
				
			||||||
 | 
							raw.Signature = newBuffer(obj.Signatures[0].Signature)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							raw.Signatures = make([]rawSignatureInfo, len(obj.Signatures))
 | 
				
			||||||
 | 
							for i, signature := range obj.Signatures {
 | 
				
			||||||
 | 
								raw.Signatures[i] = rawSignatureInfo{
 | 
				
			||||||
 | 
									Header:    signature.header,
 | 
				
			||||||
 | 
									Signature: newBuffer(signature.Signature),
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if signature.protected != nil {
 | 
				
			||||||
 | 
									raw.Signatures[i].Protected = newBuffer(mustSerializeJSON(signature.protected))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return string(mustSerializeJSON(raw))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										224
									
								
								vendor/github.com/square/go-jose/shared.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								vendor/github.com/square/go-jose/shared.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,224 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/elliptic"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// KeyAlgorithm represents a key management algorithm.
 | 
				
			||||||
 | 
					type KeyAlgorithm string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SignatureAlgorithm represents a signature (or MAC) algorithm.
 | 
				
			||||||
 | 
					type SignatureAlgorithm string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ContentEncryption represents a content encryption algorithm.
 | 
				
			||||||
 | 
					type ContentEncryption string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CompressionAlgorithm represents an algorithm used for plaintext compression.
 | 
				
			||||||
 | 
					type CompressionAlgorithm string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// ErrCryptoFailure represents an error in cryptographic primitive. This
 | 
				
			||||||
 | 
						// occurs when, for example, a message had an invalid authentication tag or
 | 
				
			||||||
 | 
						// could not be decrypted.
 | 
				
			||||||
 | 
						ErrCryptoFailure = errors.New("square/go-jose: error in cryptographic primitive")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ErrUnsupportedAlgorithm indicates that a selected algorithm is not
 | 
				
			||||||
 | 
						// supported. This occurs when trying to instantiate an encrypter for an
 | 
				
			||||||
 | 
						// algorithm that is not yet implemented.
 | 
				
			||||||
 | 
						ErrUnsupportedAlgorithm = errors.New("square/go-jose: unknown/unsupported algorithm")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ErrUnsupportedKeyType indicates that the given key type/format is not
 | 
				
			||||||
 | 
						// supported. This occurs when trying to instantiate an encrypter and passing
 | 
				
			||||||
 | 
						// it a key of an unrecognized type or with unsupported parameters, such as
 | 
				
			||||||
 | 
						// an RSA private key with more than two primes.
 | 
				
			||||||
 | 
						ErrUnsupportedKeyType = errors.New("square/go-jose: unsupported key type/format")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ErrNotSupported serialization of object is not supported. This occurs when
 | 
				
			||||||
 | 
						// trying to compact-serialize an object which can't be represented in
 | 
				
			||||||
 | 
						// compact form.
 | 
				
			||||||
 | 
						ErrNotSupported = errors.New("square/go-jose: compact serialization not supported for object")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
 | 
				
			||||||
 | 
						// nonce header parameter was included in an unprotected header object.
 | 
				
			||||||
 | 
						ErrUnprotectedNonce = errors.New("square/go-jose: Nonce parameter included in unprotected header")
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key management algorithms
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						RSA1_5             = KeyAlgorithm("RSA1_5")             // RSA-PKCS1v1.5
 | 
				
			||||||
 | 
						RSA_OAEP           = KeyAlgorithm("RSA-OAEP")           // RSA-OAEP-SHA1
 | 
				
			||||||
 | 
						RSA_OAEP_256       = KeyAlgorithm("RSA-OAEP-256")       // RSA-OAEP-SHA256
 | 
				
			||||||
 | 
						A128KW             = KeyAlgorithm("A128KW")             // AES key wrap (128)
 | 
				
			||||||
 | 
						A192KW             = KeyAlgorithm("A192KW")             // AES key wrap (192)
 | 
				
			||||||
 | 
						A256KW             = KeyAlgorithm("A256KW")             // AES key wrap (256)
 | 
				
			||||||
 | 
						DIRECT             = KeyAlgorithm("dir")                // Direct encryption
 | 
				
			||||||
 | 
						ECDH_ES            = KeyAlgorithm("ECDH-ES")            // ECDH-ES
 | 
				
			||||||
 | 
						ECDH_ES_A128KW     = KeyAlgorithm("ECDH-ES+A128KW")     // ECDH-ES + AES key wrap (128)
 | 
				
			||||||
 | 
						ECDH_ES_A192KW     = KeyAlgorithm("ECDH-ES+A192KW")     // ECDH-ES + AES key wrap (192)
 | 
				
			||||||
 | 
						ECDH_ES_A256KW     = KeyAlgorithm("ECDH-ES+A256KW")     // ECDH-ES + AES key wrap (256)
 | 
				
			||||||
 | 
						A128GCMKW          = KeyAlgorithm("A128GCMKW")          // AES-GCM key wrap (128)
 | 
				
			||||||
 | 
						A192GCMKW          = KeyAlgorithm("A192GCMKW")          // AES-GCM key wrap (192)
 | 
				
			||||||
 | 
						A256GCMKW          = KeyAlgorithm("A256GCMKW")          // AES-GCM key wrap (256)
 | 
				
			||||||
 | 
						PBES2_HS256_A128KW = KeyAlgorithm("PBES2-HS256+A128KW") // PBES2 + HMAC-SHA256 + AES key wrap (128)
 | 
				
			||||||
 | 
						PBES2_HS384_A192KW = KeyAlgorithm("PBES2-HS384+A192KW") // PBES2 + HMAC-SHA384 + AES key wrap (192)
 | 
				
			||||||
 | 
						PBES2_HS512_A256KW = KeyAlgorithm("PBES2-HS512+A256KW") // PBES2 + HMAC-SHA512 + AES key wrap (256)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Signature algorithms
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						HS256 = SignatureAlgorithm("HS256") // HMAC using SHA-256
 | 
				
			||||||
 | 
						HS384 = SignatureAlgorithm("HS384") // HMAC using SHA-384
 | 
				
			||||||
 | 
						HS512 = SignatureAlgorithm("HS512") // HMAC using SHA-512
 | 
				
			||||||
 | 
						RS256 = SignatureAlgorithm("RS256") // RSASSA-PKCS-v1.5 using SHA-256
 | 
				
			||||||
 | 
						RS384 = SignatureAlgorithm("RS384") // RSASSA-PKCS-v1.5 using SHA-384
 | 
				
			||||||
 | 
						RS512 = SignatureAlgorithm("RS512") // RSASSA-PKCS-v1.5 using SHA-512
 | 
				
			||||||
 | 
						ES256 = SignatureAlgorithm("ES256") // ECDSA using P-256 and SHA-256
 | 
				
			||||||
 | 
						ES384 = SignatureAlgorithm("ES384") // ECDSA using P-384 and SHA-384
 | 
				
			||||||
 | 
						ES512 = SignatureAlgorithm("ES512") // ECDSA using P-521 and SHA-512
 | 
				
			||||||
 | 
						PS256 = SignatureAlgorithm("PS256") // RSASSA-PSS using SHA256 and MGF1-SHA256
 | 
				
			||||||
 | 
						PS384 = SignatureAlgorithm("PS384") // RSASSA-PSS using SHA384 and MGF1-SHA384
 | 
				
			||||||
 | 
						PS512 = SignatureAlgorithm("PS512") // RSASSA-PSS using SHA512 and MGF1-SHA512
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Content encryption algorithms
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						A128CBC_HS256 = ContentEncryption("A128CBC-HS256") // AES-CBC + HMAC-SHA256 (128)
 | 
				
			||||||
 | 
						A192CBC_HS384 = ContentEncryption("A192CBC-HS384") // AES-CBC + HMAC-SHA384 (192)
 | 
				
			||||||
 | 
						A256CBC_HS512 = ContentEncryption("A256CBC-HS512") // AES-CBC + HMAC-SHA512 (256)
 | 
				
			||||||
 | 
						A128GCM       = ContentEncryption("A128GCM")       // AES-GCM (128)
 | 
				
			||||||
 | 
						A192GCM       = ContentEncryption("A192GCM")       // AES-GCM (192)
 | 
				
			||||||
 | 
						A256GCM       = ContentEncryption("A256GCM")       // AES-GCM (256)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compression algorithms
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						NONE    = CompressionAlgorithm("")    // No compression
 | 
				
			||||||
 | 
						DEFLATE = CompressionAlgorithm("DEF") // DEFLATE (RFC 1951)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// rawHeader represents the JOSE header for JWE/JWS objects (used for parsing).
 | 
				
			||||||
 | 
					type rawHeader struct {
 | 
				
			||||||
 | 
						Alg   string               `json:"alg,omitempty"`
 | 
				
			||||||
 | 
						Enc   ContentEncryption    `json:"enc,omitempty"`
 | 
				
			||||||
 | 
						Zip   CompressionAlgorithm `json:"zip,omitempty"`
 | 
				
			||||||
 | 
						Crit  []string             `json:"crit,omitempty"`
 | 
				
			||||||
 | 
						Apu   *byteBuffer          `json:"apu,omitempty"`
 | 
				
			||||||
 | 
						Apv   *byteBuffer          `json:"apv,omitempty"`
 | 
				
			||||||
 | 
						Epk   *JsonWebKey          `json:"epk,omitempty"`
 | 
				
			||||||
 | 
						Iv    *byteBuffer          `json:"iv,omitempty"`
 | 
				
			||||||
 | 
						Tag   *byteBuffer          `json:"tag,omitempty"`
 | 
				
			||||||
 | 
						Jwk   *JsonWebKey          `json:"jwk,omitempty"`
 | 
				
			||||||
 | 
						Kid   string               `json:"kid,omitempty"`
 | 
				
			||||||
 | 
						Nonce string               `json:"nonce,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JoseHeader represents the read-only JOSE header for JWE/JWS objects.
 | 
				
			||||||
 | 
					type JoseHeader struct {
 | 
				
			||||||
 | 
						KeyID      string
 | 
				
			||||||
 | 
						JsonWebKey *JsonWebKey
 | 
				
			||||||
 | 
						Algorithm  string
 | 
				
			||||||
 | 
						Nonce      string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sanitized produces a cleaned-up header object from the raw JSON.
 | 
				
			||||||
 | 
					func (parsed rawHeader) sanitized() JoseHeader {
 | 
				
			||||||
 | 
						return JoseHeader{
 | 
				
			||||||
 | 
							KeyID:      parsed.Kid,
 | 
				
			||||||
 | 
							JsonWebKey: parsed.Jwk,
 | 
				
			||||||
 | 
							Algorithm:  parsed.Alg,
 | 
				
			||||||
 | 
							Nonce:      parsed.Nonce,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Merge headers from src into dst, giving precedence to headers from l.
 | 
				
			||||||
 | 
					func (dst *rawHeader) merge(src *rawHeader) {
 | 
				
			||||||
 | 
						if src == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if dst.Alg == "" {
 | 
				
			||||||
 | 
							dst.Alg = src.Alg
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Enc == "" {
 | 
				
			||||||
 | 
							dst.Enc = src.Enc
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Zip == "" {
 | 
				
			||||||
 | 
							dst.Zip = src.Zip
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Crit == nil {
 | 
				
			||||||
 | 
							dst.Crit = src.Crit
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Crit == nil {
 | 
				
			||||||
 | 
							dst.Crit = src.Crit
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Apu == nil {
 | 
				
			||||||
 | 
							dst.Apu = src.Apu
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Apv == nil {
 | 
				
			||||||
 | 
							dst.Apv = src.Apv
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Epk == nil {
 | 
				
			||||||
 | 
							dst.Epk = src.Epk
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Iv == nil {
 | 
				
			||||||
 | 
							dst.Iv = src.Iv
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Tag == nil {
 | 
				
			||||||
 | 
							dst.Tag = src.Tag
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Kid == "" {
 | 
				
			||||||
 | 
							dst.Kid = src.Kid
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Jwk == nil {
 | 
				
			||||||
 | 
							dst.Jwk = src.Jwk
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if dst.Nonce == "" {
 | 
				
			||||||
 | 
							dst.Nonce = src.Nonce
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get JOSE name of curve
 | 
				
			||||||
 | 
					func curveName(crv elliptic.Curve) (string, error) {
 | 
				
			||||||
 | 
						switch crv {
 | 
				
			||||||
 | 
						case elliptic.P256():
 | 
				
			||||||
 | 
							return "P-256", nil
 | 
				
			||||||
 | 
						case elliptic.P384():
 | 
				
			||||||
 | 
							return "P-384", nil
 | 
				
			||||||
 | 
						case elliptic.P521():
 | 
				
			||||||
 | 
							return "P-521", nil
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return "", fmt.Errorf("square/go-jose: unsupported/unknown elliptic curve")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get size of curve in bytes
 | 
				
			||||||
 | 
					func curveSize(crv elliptic.Curve) int {
 | 
				
			||||||
 | 
						bits := crv.Params().BitSize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						div := bits / 8
 | 
				
			||||||
 | 
						mod := bits % 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if mod == 0 {
 | 
				
			||||||
 | 
							return div
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return div + 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										218
									
								
								vendor/github.com/square/go-jose/signing.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								vendor/github.com/square/go-jose/signing.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/ecdsa"
 | 
				
			||||||
 | 
						"crypto/rsa"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NonceSource represents a source of random nonces to go into JWS objects
 | 
				
			||||||
 | 
					type NonceSource interface {
 | 
				
			||||||
 | 
						Nonce() (string, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Signer represents a signer which takes a payload and produces a signed JWS object.
 | 
				
			||||||
 | 
					type Signer interface {
 | 
				
			||||||
 | 
						Sign(payload []byte) (*JsonWebSignature, error)
 | 
				
			||||||
 | 
						SetNonceSource(source NonceSource)
 | 
				
			||||||
 | 
						SetEmbedJwk(embed bool)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MultiSigner represents a signer which supports multiple recipients.
 | 
				
			||||||
 | 
					type MultiSigner interface {
 | 
				
			||||||
 | 
						Sign(payload []byte) (*JsonWebSignature, error)
 | 
				
			||||||
 | 
						SetNonceSource(source NonceSource)
 | 
				
			||||||
 | 
						SetEmbedJwk(embed bool)
 | 
				
			||||||
 | 
						AddRecipient(alg SignatureAlgorithm, signingKey interface{}) error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type payloadSigner interface {
 | 
				
			||||||
 | 
						signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type payloadVerifier interface {
 | 
				
			||||||
 | 
						verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type genericSigner struct {
 | 
				
			||||||
 | 
						recipients  []recipientSigInfo
 | 
				
			||||||
 | 
						nonceSource NonceSource
 | 
				
			||||||
 | 
						embedJwk    bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type recipientSigInfo struct {
 | 
				
			||||||
 | 
						sigAlg    SignatureAlgorithm
 | 
				
			||||||
 | 
						keyID     string
 | 
				
			||||||
 | 
						publicKey *JsonWebKey
 | 
				
			||||||
 | 
						signer    payloadSigner
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewSigner creates an appropriate signer based on the key type
 | 
				
			||||||
 | 
					func NewSigner(alg SignatureAlgorithm, signingKey interface{}) (Signer, error) {
 | 
				
			||||||
 | 
						// NewMultiSigner never fails (currently)
 | 
				
			||||||
 | 
						signer := NewMultiSigner()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := signer.AddRecipient(alg, signingKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return signer, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewMultiSigner creates a signer for multiple recipients
 | 
				
			||||||
 | 
					func NewMultiSigner() MultiSigner {
 | 
				
			||||||
 | 
						return &genericSigner{
 | 
				
			||||||
 | 
							recipients: []recipientSigInfo{},
 | 
				
			||||||
 | 
							embedJwk:   true,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newVerifier creates a verifier based on the key type
 | 
				
			||||||
 | 
					func newVerifier(verificationKey interface{}) (payloadVerifier, error) {
 | 
				
			||||||
 | 
						switch verificationKey := verificationKey.(type) {
 | 
				
			||||||
 | 
						case *rsa.PublicKey:
 | 
				
			||||||
 | 
							return &rsaEncrypterVerifier{
 | 
				
			||||||
 | 
								publicKey: verificationKey,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case *ecdsa.PublicKey:
 | 
				
			||||||
 | 
							return &ecEncrypterVerifier{
 | 
				
			||||||
 | 
								publicKey: verificationKey,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case []byte:
 | 
				
			||||||
 | 
							return &symmetricMac{
 | 
				
			||||||
 | 
								key: verificationKey,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case *JsonWebKey:
 | 
				
			||||||
 | 
							return newVerifier(verificationKey.Key)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *genericSigner) AddRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
 | 
				
			||||||
 | 
						recipient, err := makeJWSRecipient(alg, signingKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctx.recipients = append(ctx.recipients, recipient)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipientSigInfo, error) {
 | 
				
			||||||
 | 
						switch signingKey := signingKey.(type) {
 | 
				
			||||||
 | 
						case *rsa.PrivateKey:
 | 
				
			||||||
 | 
							return newRSASigner(alg, signingKey)
 | 
				
			||||||
 | 
						case *ecdsa.PrivateKey:
 | 
				
			||||||
 | 
							return newECDSASigner(alg, signingKey)
 | 
				
			||||||
 | 
						case []byte:
 | 
				
			||||||
 | 
							return newSymmetricSigner(alg, signingKey)
 | 
				
			||||||
 | 
						case *JsonWebKey:
 | 
				
			||||||
 | 
							recipient, err := makeJWSRecipient(alg, signingKey.Key)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return recipientSigInfo{}, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							recipient.keyID = signingKey.KeyID
 | 
				
			||||||
 | 
							return recipient, nil
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientSigInfo{}, ErrUnsupportedKeyType
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctx *genericSigner) Sign(payload []byte) (*JsonWebSignature, error) {
 | 
				
			||||||
 | 
						obj := &JsonWebSignature{}
 | 
				
			||||||
 | 
						obj.payload = payload
 | 
				
			||||||
 | 
						obj.Signatures = make([]Signature, len(ctx.recipients))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, recipient := range ctx.recipients {
 | 
				
			||||||
 | 
							protected := &rawHeader{
 | 
				
			||||||
 | 
								Alg: string(recipient.sigAlg),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if recipient.publicKey != nil && ctx.embedJwk {
 | 
				
			||||||
 | 
								protected.Jwk = recipient.publicKey
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if recipient.keyID != "" {
 | 
				
			||||||
 | 
								protected.Kid = recipient.keyID
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ctx.nonceSource != nil {
 | 
				
			||||||
 | 
								nonce, err := ctx.nonceSource.Nonce()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, fmt.Errorf("square/go-jose: Error generating nonce: %v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								protected.Nonce = nonce
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							serializedProtected := mustSerializeJSON(protected)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							input := []byte(fmt.Sprintf("%s.%s",
 | 
				
			||||||
 | 
								base64URLEncode(serializedProtected),
 | 
				
			||||||
 | 
								base64URLEncode(payload)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							signatureInfo, err := recipient.signer.signPayload(input, recipient.sigAlg)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							signatureInfo.protected = protected
 | 
				
			||||||
 | 
							obj.Signatures[i] = signatureInfo
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return obj, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetNonceSource provides or updates a nonce pool to the first recipients.
 | 
				
			||||||
 | 
					// After this method is called, the signer will consume one nonce per
 | 
				
			||||||
 | 
					// signature, returning an error it is unable to get a nonce.
 | 
				
			||||||
 | 
					func (ctx *genericSigner) SetNonceSource(source NonceSource) {
 | 
				
			||||||
 | 
						ctx.nonceSource = source
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetEmbedJwk specifies if the signing key should be embedded in the protected header,
 | 
				
			||||||
 | 
					// if any. It defaults to 'true'.
 | 
				
			||||||
 | 
					func (ctx *genericSigner) SetEmbedJwk(embed bool) {
 | 
				
			||||||
 | 
						ctx.embedJwk = embed
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Verify validates the signature on the object and returns the payload.
 | 
				
			||||||
 | 
					func (obj JsonWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
 | 
				
			||||||
 | 
						verifier, err := newVerifier(verificationKey)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, signature := range obj.Signatures {
 | 
				
			||||||
 | 
							headers := signature.mergedHeaders()
 | 
				
			||||||
 | 
							if len(headers.Crit) > 0 {
 | 
				
			||||||
 | 
								// Unsupported crit header
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							input := obj.computeAuthData(&signature)
 | 
				
			||||||
 | 
							alg := SignatureAlgorithm(headers.Alg)
 | 
				
			||||||
 | 
							err := verifier.verifyPayload(input, signature.Signature, alg)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								return obj.payload, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, ErrCryptoFailure
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										349
									
								
								vendor/github.com/square/go-jose/symmetric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								vendor/github.com/square/go-jose/symmetric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,349 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/aes"
 | 
				
			||||||
 | 
						"crypto/cipher"
 | 
				
			||||||
 | 
						"crypto/hmac"
 | 
				
			||||||
 | 
						"crypto/rand"
 | 
				
			||||||
 | 
						"crypto/sha256"
 | 
				
			||||||
 | 
						"crypto/sha512"
 | 
				
			||||||
 | 
						"crypto/subtle"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"hash"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/square/go-jose/cipher"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Random reader (stubbed out in tests)
 | 
				
			||||||
 | 
					var randReader = rand.Reader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Dummy key cipher for shared symmetric key mode
 | 
				
			||||||
 | 
					type symmetricKeyCipher struct {
 | 
				
			||||||
 | 
						key []byte // Pre-shared content-encryption key
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Signer/verifier for MAC modes
 | 
				
			||||||
 | 
					type symmetricMac struct {
 | 
				
			||||||
 | 
						key []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Input/output from an AEAD operation
 | 
				
			||||||
 | 
					type aeadParts struct {
 | 
				
			||||||
 | 
						iv, ciphertext, tag []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A content cipher based on an AEAD construction
 | 
				
			||||||
 | 
					type aeadContentCipher struct {
 | 
				
			||||||
 | 
						keyBytes     int
 | 
				
			||||||
 | 
						authtagBytes int
 | 
				
			||||||
 | 
						getAead      func(key []byte) (cipher.AEAD, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Random key generator
 | 
				
			||||||
 | 
					type randomKeyGenerator struct {
 | 
				
			||||||
 | 
						size int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Static key generator
 | 
				
			||||||
 | 
					type staticKeyGenerator struct {
 | 
				
			||||||
 | 
						key []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new content cipher based on AES-GCM
 | 
				
			||||||
 | 
					func newAESGCM(keySize int) contentCipher {
 | 
				
			||||||
 | 
						return &aeadContentCipher{
 | 
				
			||||||
 | 
							keyBytes:     keySize,
 | 
				
			||||||
 | 
							authtagBytes: 16,
 | 
				
			||||||
 | 
							getAead: func(key []byte) (cipher.AEAD, error) {
 | 
				
			||||||
 | 
								aes, err := aes.NewCipher(key)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return cipher.NewGCM(aes)
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create a new content cipher based on AES-CBC+HMAC
 | 
				
			||||||
 | 
					func newAESCBC(keySize int) contentCipher {
 | 
				
			||||||
 | 
						return &aeadContentCipher{
 | 
				
			||||||
 | 
							keyBytes:     keySize * 2,
 | 
				
			||||||
 | 
							authtagBytes: 16,
 | 
				
			||||||
 | 
							getAead: func(key []byte) (cipher.AEAD, error) {
 | 
				
			||||||
 | 
								return josecipher.NewCBCHMAC(key, aes.NewCipher)
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get an AEAD cipher object for the given content encryption algorithm
 | 
				
			||||||
 | 
					func getContentCipher(alg ContentEncryption) contentCipher {
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case A128GCM:
 | 
				
			||||||
 | 
							return newAESGCM(16)
 | 
				
			||||||
 | 
						case A192GCM:
 | 
				
			||||||
 | 
							return newAESGCM(24)
 | 
				
			||||||
 | 
						case A256GCM:
 | 
				
			||||||
 | 
							return newAESGCM(32)
 | 
				
			||||||
 | 
						case A128CBC_HS256:
 | 
				
			||||||
 | 
							return newAESCBC(16)
 | 
				
			||||||
 | 
						case A192CBC_HS384:
 | 
				
			||||||
 | 
							return newAESCBC(24)
 | 
				
			||||||
 | 
						case A256CBC_HS512:
 | 
				
			||||||
 | 
							return newAESCBC(32)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newSymmetricRecipient creates a JWE encrypter based on AES-GCM key wrap.
 | 
				
			||||||
 | 
					func newSymmetricRecipient(keyAlg KeyAlgorithm, key []byte) (recipientKeyInfo, error) {
 | 
				
			||||||
 | 
						switch keyAlg {
 | 
				
			||||||
 | 
						case DIRECT, A128GCMKW, A192GCMKW, A256GCMKW, A128KW, A192KW, A256KW:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientKeyInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientKeyInfo{
 | 
				
			||||||
 | 
							keyAlg: keyAlg,
 | 
				
			||||||
 | 
							keyEncrypter: &symmetricKeyCipher{
 | 
				
			||||||
 | 
								key: key,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// newSymmetricSigner creates a recipientSigInfo based on the given key.
 | 
				
			||||||
 | 
					func newSymmetricSigner(sigAlg SignatureAlgorithm, key []byte) (recipientSigInfo, error) {
 | 
				
			||||||
 | 
						// Verify that key management algorithm is supported by this encrypter
 | 
				
			||||||
 | 
						switch sigAlg {
 | 
				
			||||||
 | 
						case HS256, HS384, HS512:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return recipientSigInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientSigInfo{
 | 
				
			||||||
 | 
							sigAlg: sigAlg,
 | 
				
			||||||
 | 
							signer: &symmetricMac{
 | 
				
			||||||
 | 
								key: key,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generate a random key for the given content cipher
 | 
				
			||||||
 | 
					func (ctx randomKeyGenerator) genKey() ([]byte, rawHeader, error) {
 | 
				
			||||||
 | 
						key := make([]byte, ctx.size)
 | 
				
			||||||
 | 
						_, err := io.ReadFull(randReader, key)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, rawHeader{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return key, rawHeader{}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key size for random generator
 | 
				
			||||||
 | 
					func (ctx randomKeyGenerator) keySize() int {
 | 
				
			||||||
 | 
						return ctx.size
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generate a static key (for direct mode)
 | 
				
			||||||
 | 
					func (ctx staticKeyGenerator) genKey() ([]byte, rawHeader, error) {
 | 
				
			||||||
 | 
						cek := make([]byte, len(ctx.key))
 | 
				
			||||||
 | 
						copy(cek, ctx.key)
 | 
				
			||||||
 | 
						return cek, rawHeader{}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Key size for static generator
 | 
				
			||||||
 | 
					func (ctx staticKeyGenerator) keySize() int {
 | 
				
			||||||
 | 
						return len(ctx.key)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get key size for this cipher
 | 
				
			||||||
 | 
					func (ctx aeadContentCipher) keySize() int {
 | 
				
			||||||
 | 
						return ctx.keyBytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypt some data
 | 
				
			||||||
 | 
					func (ctx aeadContentCipher) encrypt(key, aad, pt []byte) (*aeadParts, error) {
 | 
				
			||||||
 | 
						// Get a new AEAD instance
 | 
				
			||||||
 | 
						aead, err := ctx.getAead(key)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Initialize a new nonce
 | 
				
			||||||
 | 
						iv := make([]byte, aead.NonceSize())
 | 
				
			||||||
 | 
						_, err = io.ReadFull(randReader, iv)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ciphertextAndTag := aead.Seal(nil, iv, pt, aad)
 | 
				
			||||||
 | 
						offset := len(ciphertextAndTag) - ctx.authtagBytes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &aeadParts{
 | 
				
			||||||
 | 
							iv:         iv,
 | 
				
			||||||
 | 
							ciphertext: ciphertextAndTag[:offset],
 | 
				
			||||||
 | 
							tag:        ciphertextAndTag[offset:],
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decrypt some data
 | 
				
			||||||
 | 
					func (ctx aeadContentCipher) decrypt(key, aad []byte, parts *aeadParts) ([]byte, error) {
 | 
				
			||||||
 | 
						aead, err := ctx.getAead(key)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return aead.Open(nil, parts.iv, append(parts.ciphertext, parts.tag...), aad)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encrypt the content encryption key.
 | 
				
			||||||
 | 
					func (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case DIRECT:
 | 
				
			||||||
 | 
							return recipientInfo{
 | 
				
			||||||
 | 
								header: &rawHeader{},
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case A128GCMKW, A192GCMKW, A256GCMKW:
 | 
				
			||||||
 | 
							aead := newAESGCM(len(ctx.key))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							parts, err := aead.encrypt(ctx.key, []byte{}, cek)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return recipientInfo{}, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return recipientInfo{
 | 
				
			||||||
 | 
								header: &rawHeader{
 | 
				
			||||||
 | 
									Iv:  newBuffer(parts.iv),
 | 
				
			||||||
 | 
									Tag: newBuffer(parts.tag),
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								encryptedKey: parts.ciphertext,
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						case A128KW, A192KW, A256KW:
 | 
				
			||||||
 | 
							block, err := aes.NewCipher(ctx.key)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return recipientInfo{}, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							jek, err := josecipher.KeyWrap(block, cek)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return recipientInfo{}, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return recipientInfo{
 | 
				
			||||||
 | 
								encryptedKey: jek,
 | 
				
			||||||
 | 
								header:       &rawHeader{},
 | 
				
			||||||
 | 
							}, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return recipientInfo{}, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Decrypt the content encryption key.
 | 
				
			||||||
 | 
					func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
 | 
				
			||||||
 | 
						switch KeyAlgorithm(headers.Alg) {
 | 
				
			||||||
 | 
						case DIRECT:
 | 
				
			||||||
 | 
							cek := make([]byte, len(ctx.key))
 | 
				
			||||||
 | 
							copy(cek, ctx.key)
 | 
				
			||||||
 | 
							return cek, nil
 | 
				
			||||||
 | 
						case A128GCMKW, A192GCMKW, A256GCMKW:
 | 
				
			||||||
 | 
							aead := newAESGCM(len(ctx.key))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							parts := &aeadParts{
 | 
				
			||||||
 | 
								iv:         headers.Iv.bytes(),
 | 
				
			||||||
 | 
								ciphertext: recipient.encryptedKey,
 | 
				
			||||||
 | 
								tag:        headers.Tag.bytes(),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cek, err := aead.decrypt(ctx.key, []byte{}, parts)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return cek, nil
 | 
				
			||||||
 | 
						case A128KW, A192KW, A256KW:
 | 
				
			||||||
 | 
							block, err := aes.NewCipher(ctx.key)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return cek, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Sign the given payload
 | 
				
			||||||
 | 
					func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
 | 
				
			||||||
 | 
						mac, err := ctx.hmac(payload, alg)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return Signature{}, errors.New("square/go-jose: failed to compute hmac")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Signature{
 | 
				
			||||||
 | 
							Signature: mac,
 | 
				
			||||||
 | 
							protected: &rawHeader{},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Verify the given payload
 | 
				
			||||||
 | 
					func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureAlgorithm) error {
 | 
				
			||||||
 | 
						expected, err := ctx.hmac(payload, alg)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return errors.New("square/go-jose: failed to compute hmac")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(mac) != len(expected) {
 | 
				
			||||||
 | 
							return errors.New("square/go-jose: invalid hmac")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						match := subtle.ConstantTimeCompare(mac, expected)
 | 
				
			||||||
 | 
						if match != 1 {
 | 
				
			||||||
 | 
							return errors.New("square/go-jose: invalid hmac")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Compute the HMAC based on the given alg value
 | 
				
			||||||
 | 
					func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) {
 | 
				
			||||||
 | 
						var hash func() hash.Hash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch alg {
 | 
				
			||||||
 | 
						case HS256:
 | 
				
			||||||
 | 
							hash = sha256.New
 | 
				
			||||||
 | 
						case HS384:
 | 
				
			||||||
 | 
							hash = sha512.New384
 | 
				
			||||||
 | 
						case HS512:
 | 
				
			||||||
 | 
							hash = sha512.New
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrUnsupportedAlgorithm
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hmac := hmac.New(hash, ctx.key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// According to documentation, Write() on hash never fails
 | 
				
			||||||
 | 
						_, _ = hmac.Write(payload)
 | 
				
			||||||
 | 
						return hmac.Sum(nil), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										74
									
								
								vendor/github.com/square/go-jose/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/square/go-jose/utils.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					/*-
 | 
				
			||||||
 | 
					 * Copyright 2014 Square Inc.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package jose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"crypto/x509"
 | 
				
			||||||
 | 
						"encoding/pem"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LoadPublicKey loads a public key from PEM/DER-encoded data.
 | 
				
			||||||
 | 
					func LoadPublicKey(data []byte) (interface{}, error) {
 | 
				
			||||||
 | 
						input := data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block, _ := pem.Decode(data)
 | 
				
			||||||
 | 
						if block != nil {
 | 
				
			||||||
 | 
							input = block.Bytes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Try to load SubjectPublicKeyInfo
 | 
				
			||||||
 | 
						pub, err0 := x509.ParsePKIXPublicKey(input)
 | 
				
			||||||
 | 
						if err0 == nil {
 | 
				
			||||||
 | 
							return pub, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cert, err1 := x509.ParseCertificate(input)
 | 
				
			||||||
 | 
						if err1 == nil {
 | 
				
			||||||
 | 
							return cert.PublicKey, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, fmt.Errorf("square/go-jose: parse error, got '%s' and '%s'", err0, err1)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// LoadPrivateKey loads a private key from PEM/DER-encoded data.
 | 
				
			||||||
 | 
					func LoadPrivateKey(data []byte) (interface{}, error) {
 | 
				
			||||||
 | 
						input := data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block, _ := pem.Decode(data)
 | 
				
			||||||
 | 
						if block != nil {
 | 
				
			||||||
 | 
							input = block.Bytes
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var priv interface{}
 | 
				
			||||||
 | 
						priv, err0 := x509.ParsePKCS1PrivateKey(input)
 | 
				
			||||||
 | 
						if err0 == nil {
 | 
				
			||||||
 | 
							return priv, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv, err1 := x509.ParsePKCS8PrivateKey(input)
 | 
				
			||||||
 | 
						if err1 == nil {
 | 
				
			||||||
 | 
							return priv, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						priv, err2 := x509.ParseECPrivateKey(input)
 | 
				
			||||||
 | 
						if err2 == nil {
 | 
				
			||||||
 | 
							return priv, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, fmt.Errorf("square/go-jose: parse error, got '%s', '%s' and '%s'", err0, err1, err2)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user