• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.apksig.internal.apk;
18 
19 import com.android.apksig.internal.util.AndroidSdkVersion;
20 import com.android.apksig.internal.util.Pair;
21 import java.security.spec.AlgorithmParameterSpec;
22 import java.security.spec.MGF1ParameterSpec;
23 import java.security.spec.PSSParameterSpec;
24 
25 /**
26  * APK Signing Block signature algorithm.
27  */
28 public enum SignatureAlgorithm {
29     // TODO reserve the 0x0000 ID to mean null
30     /**
31      * RSASSA-PSS with SHA2-256 digest, SHA2-256 MGF1, 32 bytes of salt, trailer: 0xbc, content
32      * digested using SHA2-256 in 1 MB chunks.
33      */
34     RSA_PSS_WITH_SHA256(
35             0x0101,
36             ContentDigestAlgorithm.CHUNKED_SHA256,
37             "RSA",
38             Pair.of("SHA256withRSA/PSS",
39                     new PSSParameterSpec(
40                             "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 256 / 8, 1)),
41             AndroidSdkVersion.N,
42             AndroidSdkVersion.M),
43 
44     /**
45      * RSASSA-PSS with SHA2-512 digest, SHA2-512 MGF1, 64 bytes of salt, trailer: 0xbc, content
46      * digested using SHA2-512 in 1 MB chunks.
47      */
48     RSA_PSS_WITH_SHA512(
49             0x0102,
50             ContentDigestAlgorithm.CHUNKED_SHA512,
51             "RSA",
52             Pair.of(
53                     "SHA512withRSA/PSS",
54                     new PSSParameterSpec(
55                             "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1)),
56             AndroidSdkVersion.N,
57             AndroidSdkVersion.M),
58 
59     /** RSASSA-PKCS1-v1_5 with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */
60     RSA_PKCS1_V1_5_WITH_SHA256(
61             0x0103,
62             ContentDigestAlgorithm.CHUNKED_SHA256,
63             "RSA",
64             Pair.of("SHA256withRSA", null),
65             AndroidSdkVersion.N,
66             AndroidSdkVersion.INITIAL_RELEASE),
67 
68     /** RSASSA-PKCS1-v1_5 with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */
69     RSA_PKCS1_V1_5_WITH_SHA512(
70             0x0104,
71             ContentDigestAlgorithm.CHUNKED_SHA512,
72             "RSA",
73             Pair.of("SHA512withRSA", null),
74             AndroidSdkVersion.N,
75             AndroidSdkVersion.INITIAL_RELEASE),
76 
77     /** ECDSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */
78     ECDSA_WITH_SHA256(
79             0x0201,
80             ContentDigestAlgorithm.CHUNKED_SHA256,
81             "EC",
82             Pair.of("SHA256withECDSA", null),
83             AndroidSdkVersion.N,
84             AndroidSdkVersion.HONEYCOMB),
85 
86     /** ECDSA with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */
87     ECDSA_WITH_SHA512(
88             0x0202,
89             ContentDigestAlgorithm.CHUNKED_SHA512,
90             "EC",
91             Pair.of("SHA512withECDSA", null),
92             AndroidSdkVersion.N,
93             AndroidSdkVersion.HONEYCOMB),
94 
95     /** DSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */
96     DSA_WITH_SHA256(
97             0x0301,
98             ContentDigestAlgorithm.CHUNKED_SHA256,
99             "DSA",
100             Pair.of("SHA256withDSA", null),
101             AndroidSdkVersion.N,
102             AndroidSdkVersion.INITIAL_RELEASE),
103 
104     /**
105      * DSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. Signing is done
106      * deterministically according to RFC 6979.
107      */
108     DETDSA_WITH_SHA256(
109             0x0301,
110             ContentDigestAlgorithm.CHUNKED_SHA256,
111             "DSA",
112             Pair.of("SHA256withDetDSA", null),
113             AndroidSdkVersion.N,
114             AndroidSdkVersion.INITIAL_RELEASE),
115 
116     /**
117      * RSASSA-PKCS1-v1_5 with SHA2-256 digest, content digested using SHA2-256 in 4 KB chunks, in
118      * the same way fsverity operates. This digest and the content length (before digestion, 8 bytes
119      * in little endian) construct the final digest.
120      */
121     VERITY_RSA_PKCS1_V1_5_WITH_SHA256(
122             0x0421,
123             ContentDigestAlgorithm.VERITY_CHUNKED_SHA256,
124             "RSA",
125             Pair.of("SHA256withRSA", null),
126             AndroidSdkVersion.P,
127             AndroidSdkVersion.INITIAL_RELEASE),
128 
129     /**
130      * ECDSA with SHA2-256 digest, content digested using SHA2-256 in 4 KB chunks, in the same way
131      * fsverity operates. This digest and the content length (before digestion, 8 bytes in little
132      * endian) construct the final digest.
133      */
134     VERITY_ECDSA_WITH_SHA256(
135             0x0423,
136             ContentDigestAlgorithm.VERITY_CHUNKED_SHA256,
137             "EC",
138             Pair.of("SHA256withECDSA", null),
139             AndroidSdkVersion.P,
140             AndroidSdkVersion.HONEYCOMB),
141 
142     /**
143      * DSA with SHA2-256 digest, content digested using SHA2-256 in 4 KB chunks, in the same way
144      * fsverity operates. This digest and the content length (before digestion, 8 bytes in little
145      * endian) construct the final digest.
146      */
147     VERITY_DSA_WITH_SHA256(
148             0x0425,
149             ContentDigestAlgorithm.VERITY_CHUNKED_SHA256,
150             "DSA",
151             Pair.of("SHA256withDSA", null),
152             AndroidSdkVersion.P,
153             AndroidSdkVersion.INITIAL_RELEASE);
154 
155     private final int mId;
156     private final String mJcaKeyAlgorithm;
157     private final ContentDigestAlgorithm mContentDigestAlgorithm;
158     private final Pair<String, ? extends AlgorithmParameterSpec> mJcaSignatureAlgAndParams;
159     private final int mMinSdkVersion;
160     private final int mJcaSigAlgMinSdkVersion;
161 
SignatureAlgorithm(int id, ContentDigestAlgorithm contentDigestAlgorithm, String jcaKeyAlgorithm, Pair<String, ? extends AlgorithmParameterSpec> jcaSignatureAlgAndParams, int minSdkVersion, int jcaSigAlgMinSdkVersion)162     SignatureAlgorithm(int id,
163             ContentDigestAlgorithm contentDigestAlgorithm,
164             String jcaKeyAlgorithm,
165             Pair<String, ? extends AlgorithmParameterSpec> jcaSignatureAlgAndParams,
166             int minSdkVersion,
167             int jcaSigAlgMinSdkVersion) {
168         mId = id;
169         mContentDigestAlgorithm = contentDigestAlgorithm;
170         mJcaKeyAlgorithm = jcaKeyAlgorithm;
171         mJcaSignatureAlgAndParams = jcaSignatureAlgAndParams;
172         mMinSdkVersion = minSdkVersion;
173         mJcaSigAlgMinSdkVersion = jcaSigAlgMinSdkVersion;
174     }
175 
176     /**
177      * Returns the ID of this signature algorithm as used in APK Signature Scheme v2 wire format.
178      */
getId()179     public int getId() {
180         return mId;
181     }
182 
183     /**
184      * Returns the content digest algorithm associated with this signature algorithm.
185      */
getContentDigestAlgorithm()186     public ContentDigestAlgorithm getContentDigestAlgorithm() {
187         return mContentDigestAlgorithm;
188     }
189 
190     /**
191      * Returns the JCA {@link java.security.Key} algorithm used by this signature scheme.
192      */
getJcaKeyAlgorithm()193     public String getJcaKeyAlgorithm() {
194         return mJcaKeyAlgorithm;
195     }
196 
197     /**
198      * Returns the {@link java.security.Signature} algorithm and the {@link AlgorithmParameterSpec}
199      * (or null if not needed) to parameterize the {@code Signature}.
200      */
getJcaSignatureAlgorithmAndParams()201     public Pair<String, ? extends AlgorithmParameterSpec> getJcaSignatureAlgorithmAndParams() {
202         return mJcaSignatureAlgAndParams;
203     }
204 
getMinSdkVersion()205     public int getMinSdkVersion() {
206         return mMinSdkVersion;
207     }
208 
209     /**
210      * Returns the minimum SDK version that supports the JCA signature algorithm.
211      */
getJcaSigAlgMinSdkVersion()212     public int getJcaSigAlgMinSdkVersion() {
213         return mJcaSigAlgMinSdkVersion;
214     }
215 
findById(int id)216     public static SignatureAlgorithm findById(int id) {
217         for (SignatureAlgorithm alg : SignatureAlgorithm.values()) {
218             if (alg.getId() == id) {
219                 return alg;
220             }
221         }
222 
223         return null;
224     }
225 }
226