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 43 /** 44 * RSASSA-PSS with SHA2-512 digest, SHA2-512 MGF1, 64 bytes of salt, trailer: 0xbc, content 45 * digested using SHA2-512 in 1 MB chunks. 46 */ 47 RSA_PSS_WITH_SHA512( 48 0x0102, 49 ContentDigestAlgorithm.CHUNKED_SHA512, 50 "RSA", 51 Pair.of( 52 "SHA512withRSA/PSS", 53 new PSSParameterSpec( 54 "SHA-512", "MGF1", MGF1ParameterSpec.SHA512, 512 / 8, 1)), 55 AndroidSdkVersion.N), 56 57 /** RSASSA-PKCS1-v1_5 with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */ 58 RSA_PKCS1_V1_5_WITH_SHA256( 59 0x0103, 60 ContentDigestAlgorithm.CHUNKED_SHA256, 61 "RSA", 62 Pair.of("SHA256withRSA", null), 63 AndroidSdkVersion.N), 64 65 /** RSASSA-PKCS1-v1_5 with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */ 66 RSA_PKCS1_V1_5_WITH_SHA512( 67 0x0104, 68 ContentDigestAlgorithm.CHUNKED_SHA512, 69 "RSA", 70 Pair.of("SHA512withRSA", null), 71 AndroidSdkVersion.N), 72 73 /** ECDSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */ 74 ECDSA_WITH_SHA256( 75 0x0201, 76 ContentDigestAlgorithm.CHUNKED_SHA256, 77 "EC", 78 Pair.of("SHA256withECDSA", null), 79 AndroidSdkVersion.N), 80 81 /** ECDSA with SHA2-512 digest, content digested using SHA2-512 in 1 MB chunks. */ 82 ECDSA_WITH_SHA512( 83 0x0202, 84 ContentDigestAlgorithm.CHUNKED_SHA512, 85 "EC", 86 Pair.of("SHA512withECDSA", null), 87 AndroidSdkVersion.N), 88 89 /** DSA with SHA2-256 digest, content digested using SHA2-256 in 1 MB chunks. */ 90 DSA_WITH_SHA256( 91 0x0301, 92 ContentDigestAlgorithm.CHUNKED_SHA256, 93 "DSA", 94 Pair.of("SHA256withDSA", null), 95 AndroidSdkVersion.N), 96 97 /** 98 * RSASSA-PKCS1-v1_5 with SHA2-256 digest, content digested using SHA2-256 in 4 KB chunks, in 99 * the same way fsverity operates. This digest and the content length (before digestion, 8 bytes 100 * in little endian) construct the final digest. 101 */ 102 VERITY_RSA_PKCS1_V1_5_WITH_SHA256( 103 0x0421, 104 ContentDigestAlgorithm.VERITY_CHUNKED_SHA256, 105 "RSA", 106 Pair.of("SHA256withRSA", null), 107 AndroidSdkVersion.P), 108 109 /** 110 * ECDSA with SHA2-256 digest, content digested using SHA2-256 in 4 KB chunks, in the same way 111 * fsverity operates. This digest and the content length (before digestion, 8 bytes in little 112 * endian) construct the final digest. 113 */ 114 VERITY_ECDSA_WITH_SHA256( 115 0x0423, 116 ContentDigestAlgorithm.VERITY_CHUNKED_SHA256, 117 "EC", 118 Pair.of("SHA256withECDSA", null), 119 AndroidSdkVersion.P), 120 121 /** 122 * DSA with SHA2-256 digest, content digested using SHA2-256 in 4 KB chunks, in the same way 123 * fsverity operates. This digest and the content length (before digestion, 8 bytes in little 124 * endian) construct the final digest. 125 */ 126 VERITY_DSA_WITH_SHA256( 127 0x0425, 128 ContentDigestAlgorithm.VERITY_CHUNKED_SHA256, 129 "DSA", 130 Pair.of("SHA256withDSA", null), 131 AndroidSdkVersion.P); 132 133 private final int mId; 134 private final String mJcaKeyAlgorithm; 135 private final ContentDigestAlgorithm mContentDigestAlgorithm; 136 private final Pair<String, ? extends AlgorithmParameterSpec> mJcaSignatureAlgAndParams; 137 private final int mMinSdkVersion; 138 SignatureAlgorithm(int id, ContentDigestAlgorithm contentDigestAlgorithm, String jcaKeyAlgorithm, Pair<String, ? extends AlgorithmParameterSpec> jcaSignatureAlgAndParams, int minSdkVersion)139 SignatureAlgorithm(int id, 140 ContentDigestAlgorithm contentDigestAlgorithm, 141 String jcaKeyAlgorithm, 142 Pair<String, ? extends AlgorithmParameterSpec> jcaSignatureAlgAndParams, 143 int minSdkVersion) { 144 mId = id; 145 mContentDigestAlgorithm = contentDigestAlgorithm; 146 mJcaKeyAlgorithm = jcaKeyAlgorithm; 147 mJcaSignatureAlgAndParams = jcaSignatureAlgAndParams; 148 mMinSdkVersion = minSdkVersion; 149 } 150 151 /** 152 * Returns the ID of this signature algorithm as used in APK Signature Scheme v2 wire format. 153 */ getId()154 public int getId() { 155 return mId; 156 } 157 158 /** 159 * Returns the content digest algorithm associated with this signature algorithm. 160 */ getContentDigestAlgorithm()161 public ContentDigestAlgorithm getContentDigestAlgorithm() { 162 return mContentDigestAlgorithm; 163 } 164 165 /** 166 * Returns the JCA {@link java.security.Key} algorithm used by this signature scheme. 167 */ getJcaKeyAlgorithm()168 public String getJcaKeyAlgorithm() { 169 return mJcaKeyAlgorithm; 170 } 171 172 /** 173 * Returns the {@link java.security.Signature} algorithm and the {@link AlgorithmParameterSpec} 174 * (or null if not needed) to parameterize the {@code Signature}. 175 */ getJcaSignatureAlgorithmAndParams()176 public Pair<String, ? extends AlgorithmParameterSpec> getJcaSignatureAlgorithmAndParams() { 177 return mJcaSignatureAlgAndParams; 178 } 179 getMinSdkVersion()180 public int getMinSdkVersion() { 181 return mMinSdkVersion; 182 } 183 findById(int id)184 public static SignatureAlgorithm findById(int id) { 185 for (SignatureAlgorithm alg : SignatureAlgorithm.values()) { 186 if (alg.getId() == id) { 187 return alg; 188 } 189 } 190 191 return null; 192 } 193 } 194