summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Nissler2016-03-31 09:31:42 -0500
committerElliott Hughes2016-04-12 17:08:01 -0500
commitb62146dcabedcacf99349793c1947797a173f0e6 (patch)
treebe19fb1ff38584708cf4ed4058a1718b18fb5f7b /libcrypto_utils
parent979ce0e33827a9c5bb2b76b2e2557544f8eb0cce (diff)
downloadplatform-system-core-b62146dcabedcacf99349793c1947797a173f0e6.tar.gz
platform-system-core-b62146dcabedcacf99349793c1947797a173f0e6.tar.xz
platform-system-core-b62146dcabedcacf99349793c1947797a173f0e6.zip
Add libcrypto_utils.
This provides a tiny library implementing encode/decode functionality for Android's custom RSA public key binary format. Keys are encoded from and decoded to BoringSSL RSA key objects. Change-Id: I55e5522d557e0e9f35927a87b6581f020ee34e7a
Diffstat (limited to 'libcrypto_utils')
-rw-r--r--libcrypto_utils/Android.mk56
-rw-r--r--libcrypto_utils/android_pubkey.c167
-rw-r--r--libcrypto_utils/include/crypto_utils/android_pubkey.h61
-rw-r--r--libcrypto_utils/tests/Android.mk24
-rw-r--r--libcrypto_utils/tests/android_pubkey_test.cpp129
5 files changed, 437 insertions, 0 deletions
diff --git a/libcrypto_utils/Android.mk b/libcrypto_utils/Android.mk
new file mode 100644
index 000000000..5e9763fe5
--- /dev/null
+++ b/libcrypto_utils/Android.mk
@@ -0,0 +1,56 @@
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
17LOCAL_PATH := $(call my-dir)
18
19include $(CLEAR_VARS)
20LOCAL_MODULE := libcrypto_utils
21LOCAL_SRC_FILES := android_pubkey.c
22LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
23LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
24LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
25LOCAL_SHARED_LIBRARIES := libcrypto
26include $(BUILD_SHARED_LIBRARY)
27
28include $(CLEAR_VARS)
29LOCAL_MODULE := libcrypto_utils
30LOCAL_SRC_FILES := android_pubkey.c
31LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
32LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
33LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
34LOCAL_SHARED_LIBRARIES := libcrypto-host
35include $(BUILD_HOST_SHARED_LIBRARY)
36
37include $(CLEAR_VARS)
38LOCAL_MODULE := libcrypto_utils_static
39LOCAL_SRC_FILES := android_pubkey.c
40LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
41LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
42LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
43LOCAL_STATIC_LIBRARIES := libcrypto_static
44include $(BUILD_STATIC_LIBRARY)
45
46include $(CLEAR_VARS)
47LOCAL_MODULE := libcrypto_utils_static
48LOCAL_MODULE_HOST_OS := darwin linux windows
49LOCAL_SRC_FILES := android_pubkey.c
50LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c99
51LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
52LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
53LOCAL_STATIC_LIBRARIES := libcrypto_static
54include $(BUILD_HOST_STATIC_LIBRARY)
55
56include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libcrypto_utils/android_pubkey.c b/libcrypto_utils/android_pubkey.c
new file mode 100644
index 000000000..9cd9aabe1
--- /dev/null
+++ b/libcrypto_utils/android_pubkey.c
@@ -0,0 +1,167 @@
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#include <crypto_utils/android_pubkey.h>
18
19#include <assert.h>
20#include <stdlib.h>
21#include <string.h>
22
23// Better safe than sorry.
24#if (ANDROID_PUBKEY_MODULUS_SIZE % 4) != 0
25#error RSA modulus size must be multiple of the word size!
26#endif
27
28// Size of the RSA modulus in words.
29#define ANDROID_PUBKEY_MODULUS_SIZE_WORDS (ANDROID_PUBKEY_MODULUS_SIZE / 4)
30
31// This file implements encoding and decoding logic for Android's custom RSA
32// public key binary format. Public keys are stored as a sequence of
33// little-endian 32 bit words. Note that Android only supports little-endian
34// processors, so we don't do any byte order conversions when parsing the binary
35// struct.
36typedef struct RSAPublicKey {
37 // Modulus length. This must be ANDROID_PUBKEY_MODULUS_SIZE.
38 uint32_t modulus_size_words;
39
40 // Precomputed montgomery parameter: -1 / n[0] mod 2^32
41 uint32_t n0inv;
42
43 // RSA modulus as a little-endian array.
44 uint8_t modulus[ANDROID_PUBKEY_MODULUS_SIZE];
45
46 // Montgomery parameter R^2 as a little-endian array of little-endian words.
47 uint8_t rr[ANDROID_PUBKEY_MODULUS_SIZE];
48
49 // RSA modulus: 3 or 65537
50 uint32_t exponent;
51} RSAPublicKey;
52
53// Reverses byte order in |buffer|.
54static void reverse_bytes(uint8_t* buffer, size_t size) {
55 for (size_t i = 0; i < (size + 1) / 2; ++i) {
56 uint8_t tmp = buffer[i];
57 buffer[i] = buffer[size - i - 1];
58 buffer[size - i - 1] = tmp;
59 }
60}
61
62bool android_pubkey_decode(const uint8_t* key_buffer, size_t size, RSA** key) {
63 const RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer;
64 bool ret = false;
65 uint8_t modulus_buffer[ANDROID_PUBKEY_MODULUS_SIZE];
66 RSA* new_key = RSA_new();
67 if (!new_key) {
68 goto cleanup;
69 }
70
71 // Check |size| is large enough and the modulus size is correct.
72 if (size < sizeof(RSAPublicKey)) {
73 goto cleanup;
74 }
75 if (key_struct->modulus_size_words != ANDROID_PUBKEY_MODULUS_SIZE_WORDS) {
76 goto cleanup;
77 }
78
79 // Convert the modulus to big-endian byte order as expected by BN_bin2bn.
80 memcpy(modulus_buffer, key_struct->modulus, sizeof(modulus_buffer));
81 reverse_bytes(modulus_buffer, sizeof(modulus_buffer));
82 new_key->n = BN_bin2bn(modulus_buffer, sizeof(modulus_buffer), NULL);
83 if (!new_key->n) {
84 goto cleanup;
85 }
86
87 // Read the exponent.
88 new_key->e = BN_new();
89 if (!new_key->e || !BN_set_word(new_key->e, key_struct->exponent)) {
90 goto cleanup;
91 }
92
93 // Note that we don't extract the montgomery parameters n0inv and rr from
94 // the RSAPublicKey structure. They assume a word size of 32 bits, but
95 // BoringSSL may use a word size of 64 bits internally, so we're lacking the
96 // top 32 bits of n0inv in general. For now, we just ignore the parameters
97 // and have BoringSSL recompute them internally. More sophisticated logic can
98 // be added here if/when we want the additional speedup from using the
99 // pre-computed montgomery parameters.
100
101 *key = new_key;
102 ret = true;
103
104cleanup:
105 if (!ret && new_key) {
106 RSA_free(new_key);
107 }
108 return ret;
109}
110
111static bool android_pubkey_encode_bignum(const BIGNUM* num, uint8_t* buffer) {
112 if (!BN_bn2bin_padded(buffer, ANDROID_PUBKEY_MODULUS_SIZE, num)) {
113 return false;
114 }
115
116 reverse_bytes(buffer, ANDROID_PUBKEY_MODULUS_SIZE);
117 return true;
118}
119
120bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size) {
121 RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer;
122 bool ret = false;
123 BN_CTX* ctx = BN_CTX_new();
124 BIGNUM* r32 = BN_new();
125 BIGNUM* n0inv = BN_new();
126 BIGNUM* rr = BN_new();
127
128 if (sizeof(RSAPublicKey) > size ||
129 RSA_size(key) != ANDROID_PUBKEY_MODULUS_SIZE) {
130 goto cleanup;
131 }
132
133 // Store the modulus size.
134 key_struct->modulus_size_words = ANDROID_PUBKEY_MODULUS_SIZE_WORDS;
135
136 // Compute and store n0inv = -1 / N[0] mod 2^32.
137 if (!ctx || !r32 || !n0inv || !BN_set_bit(r32, 32) ||
138 !BN_mod(n0inv, key->n, r32, ctx) ||
139 !BN_mod_inverse(n0inv, n0inv, r32, ctx) || !BN_sub(n0inv, r32, n0inv)) {
140 goto cleanup;
141 }
142 key_struct->n0inv = (uint32_t)BN_get_word(n0inv);
143
144 // Store the modulus.
145 if (!android_pubkey_encode_bignum(key->n, key_struct->modulus)) {
146 goto cleanup;
147 }
148
149 // Compute and store rr = (2^(rsa_size)) ^ 2 mod N.
150 if (!ctx || !rr || !BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) ||
151 !BN_mod_sqr(rr, rr, key->n, ctx) ||
152 !android_pubkey_encode_bignum(rr, key_struct->rr)) {
153 goto cleanup;
154 }
155
156 // Store the exponent.
157 key_struct->exponent = (uint32_t)BN_get_word(key->e);
158
159 ret = true;
160
161cleanup:
162 BN_free(rr);
163 BN_free(n0inv);
164 BN_free(r32);
165 BN_CTX_free(ctx);
166 return ret;
167}
diff --git a/libcrypto_utils/include/crypto_utils/android_pubkey.h b/libcrypto_utils/include/crypto_utils/android_pubkey.h
new file mode 100644
index 000000000..1045eba0f
--- /dev/null
+++ b/libcrypto_utils/include/crypto_utils/android_pubkey.h
@@ -0,0 +1,61 @@
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#ifndef CRYPTO_UTILS_ANDROID_PUBKEY_H
18#define CRYPTO_UTILS_ANDROID_PUBKEY_H
19
20#include <stdbool.h>
21#include <stddef.h>
22#include <stdint.h>
23
24#include <openssl/rsa.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30// Size of an RSA modulus such as an encrypted block or a signature.
31#define ANDROID_PUBKEY_MODULUS_SIZE (2048 / 8)
32
33// Size of an encoded RSA key.
34#define ANDROID_PUBKEY_ENCODED_SIZE \
35 (3 * sizeof(uint32_t) + 2 * ANDROID_PUBKEY_MODULUS_SIZE)
36
37/* Allocates a new RSA |key| object, decodes a public RSA key stored in
38 * Android's custom binary format from |key_buffer| and sets the key parameters
39 * in |key|. |size| specifies the size of the key buffer and must be at least
40 * |ANDROID_PUBKEY_ENCODED_SIZE|. The resulting |*key| can be used with the
41 * standard BoringSSL API to perform public operations.
42 *
43 * Returns true if successful, in which case the caller receives ownership of
44 * the |*key| object, i.e. needs to call RSA_free() when done with it. If there
45 * is an error, |key| is left untouched and the return value will be false.
46 */
47bool android_pubkey_decode(const uint8_t* key_buffer, size_t size, RSA** key);
48
49/* Encodes |key| in the Android RSA public key binary format and stores the
50 * bytes in |key_buffer|. |key_buffer| should be of size at least
51 * |ANDROID_PUBKEY_ENCODED_SIZE|.
52 *
53 * Returns true if successful, false on error.
54 */
55bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size);
56
57#ifdef __cplusplus
58} // extern "C"
59#endif
60
61#endif // CRYPTO_UTILS_ANDROID_PUBKEY_H
diff --git a/libcrypto_utils/tests/Android.mk b/libcrypto_utils/tests/Android.mk
new file mode 100644
index 000000000..dad82f70f
--- /dev/null
+++ b/libcrypto_utils/tests/Android.mk
@@ -0,0 +1,24 @@
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
17LOCAL_PATH := $(call my-dir)
18
19include $(CLEAR_VARS)
20LOCAL_MODULE := libcrypto_utils_test
21LOCAL_SRC_FILES := android_pubkey_test.cpp
22LOCAL_CFLAGS := -Wall -Werror -Wextra -std=c++11
23LOCAL_SHARED_LIBRARIES := libcrypto_utils libcrypto-host
24include $(BUILD_HOST_NATIVE_TEST)
diff --git a/libcrypto_utils/tests/android_pubkey_test.cpp b/libcrypto_utils/tests/android_pubkey_test.cpp
new file mode 100644
index 000000000..f8c2e0cae
--- /dev/null
+++ b/libcrypto_utils/tests/android_pubkey_test.cpp
@@ -0,0 +1,129 @@
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#include <crypto_utils/android_pubkey.h>
18
19#include <string.h>
20
21#include <memory>
22
23#include <openssl/obj_mac.h>
24#include <openssl/rsa.h>
25
26#include <gtest/gtest.h>
27
28// Test digest to verify.
29const uint8_t kDigest[] = {
30 0x31, 0x5f, 0x5b, 0xdb, 0x76, 0xd0, 0x78, 0xc4, 0x3b, 0x8a, 0xc0,
31 0x06, 0x4e, 0x4a, 0x01, 0x64, 0x61, 0x2b, 0x1f, 0xce, 0x77, 0xc8,
32 0x69, 0x34, 0x5b, 0xfc, 0x94, 0xc7, 0x58, 0x94, 0xed, 0xd3,
33};
34
35// 2048 RSA test key.
36const uint8_t kKey2048[ANDROID_PUBKEY_ENCODED_SIZE] = {
37 0x40, 0x00, 0x00, 0x00, 0x05, 0x75, 0x61, 0xd1, 0x33, 0xf0, 0x2d, 0x12,
38 0x45, 0xfb, 0xae, 0x07, 0x02, 0x15, 0x4f, 0x3a, 0x2b, 0xa3, 0xbc, 0x49,
39 0xbd, 0x14, 0x07, 0xa0, 0xc0, 0x9f, 0x0c, 0x52, 0x60, 0x77, 0x9f, 0xa2,
40 0x31, 0xd0, 0xa7, 0xfb, 0x7e, 0xde, 0xfb, 0xc9, 0x05, 0xc0, 0x97, 0xf7,
41 0x74, 0x99, 0xe6, 0xd1, 0x08, 0xa6, 0xc2, 0x59, 0x5a, 0xd8, 0x37, 0x1d,
42 0xe0, 0x48, 0x5e, 0x63, 0x44, 0x04, 0x8b, 0x05, 0x20, 0xf6, 0x25, 0x67,
43 0x38, 0xb2, 0xb6, 0xf9, 0xbe, 0xb6, 0x1d, 0x7f, 0x1b, 0x71, 0x8a, 0xeb,
44 0xb7, 0xf8, 0x01, 0xc1, 0x5e, 0xf7, 0xfe, 0x48, 0x08, 0x27, 0x0f, 0x27,
45 0x2a, 0x64, 0x1a, 0x43, 0x8d, 0xcf, 0x5a, 0x33, 0x5c, 0x18, 0xc5, 0xf4,
46 0xe7, 0xfe, 0xee, 0xd3, 0x12, 0x62, 0xad, 0x61, 0x78, 0x9a, 0x03, 0xb0,
47 0xaf, 0xab, 0x91, 0x57, 0x46, 0xbf, 0x18, 0xc6, 0xbc, 0x0c, 0x6b, 0x55,
48 0xcd, 0xda, 0xc4, 0xcc, 0x98, 0x46, 0x91, 0x99, 0xbc, 0xa3, 0xca, 0x6c,
49 0x86, 0xa6, 0x1c, 0x8f, 0xca, 0xf8, 0xf6, 0x8a, 0x00, 0x8e, 0x05, 0xd7,
50 0x13, 0x43, 0xe2, 0xf2, 0x1a, 0x13, 0xf3, 0x50, 0x13, 0xa4, 0xf2, 0x4e,
51 0x41, 0xb1, 0x36, 0x78, 0x55, 0x4c, 0x5e, 0x27, 0xc5, 0xc0, 0x4b, 0xd8,
52 0x93, 0xaa, 0x7e, 0xf0, 0x90, 0x08, 0x10, 0x26, 0x72, 0x6d, 0xb9, 0x21,
53 0xae, 0x4d, 0x01, 0x4b, 0x55, 0x1d, 0xe7, 0x1e, 0x5e, 0x31, 0x6e, 0x62,
54 0xd1, 0x33, 0x26, 0xcb, 0xdb, 0xfe, 0x72, 0x98, 0xc8, 0x06, 0x1c, 0x12,
55 0xdf, 0xfc, 0x74, 0xe5, 0x7a, 0x6f, 0xf5, 0xa3, 0x63, 0x08, 0xe3, 0x02,
56 0x68, 0x4d, 0x7c, 0x70, 0x05, 0xec, 0x95, 0x7e, 0x24, 0xa4, 0xbc, 0x4c,
57 0xcd, 0x39, 0x14, 0xb5, 0x2a, 0x8f, 0xc1, 0xe3, 0x4e, 0xfa, 0xf8, 0x70,
58 0x50, 0x8f, 0xd5, 0x8e, 0xc7, 0xb5, 0x32, 0x89, 0x4d, 0xbb, 0x6a, 0xc1,
59 0xc1, 0xa2, 0x42, 0x57, 0x57, 0xbd, 0x2a, 0xdc, 0xa6, 0xfd, 0xc8, 0x86,
60 0x44, 0x6a, 0x03, 0x5d, 0x4d, 0x28, 0xe1, 0xde, 0xb4, 0xa9, 0xa5, 0x03,
61 0x61, 0x7a, 0x5f, 0xb1, 0x09, 0x17, 0x2b, 0x9c, 0xa2, 0x54, 0x28, 0xad,
62 0x34, 0xc9, 0x5f, 0x6c, 0x9f, 0xb8, 0xd2, 0xa9, 0x78, 0xa7, 0xaa, 0xb3,
63 0x11, 0x2f, 0x65, 0x9b, 0x4e, 0x67, 0x0c, 0xcc, 0x20, 0x36, 0xbf, 0x26,
64 0x2b, 0x4e, 0xc0, 0xd4, 0xbd, 0x22, 0x64, 0xc4, 0x1c, 0x56, 0x69, 0xdb,
65 0x5f, 0x89, 0xe1, 0x75, 0x68, 0x8d, 0x0e, 0xab, 0x1c, 0x10, 0x1a, 0xc0,
66 0x12, 0x5d, 0x6f, 0xbd, 0x09, 0xbb, 0x47, 0xcb, 0xe7, 0x34, 0xef, 0x56,
67 0xab, 0xea, 0xc3, 0xe9, 0x7f, 0x9a, 0x3d, 0xe9, 0x2d, 0x14, 0x61, 0x25,
68 0x37, 0x5c, 0x3b, 0x4b, 0xaf, 0x5a, 0x4b, 0xc8, 0x99, 0x1a, 0x32, 0x8f,
69 0x54, 0x07, 0xd3, 0x57, 0x8a, 0x3d, 0x2a, 0xf7, 0x9e, 0x7e, 0x92, 0x2a,
70 0x50, 0xe9, 0xd8, 0xdb, 0xd6, 0x03, 0xd3, 0x8e, 0x54, 0x32, 0xce, 0x87,
71 0x93, 0x92, 0xe7, 0x75, 0xe1, 0x6b, 0x78, 0x1a, 0x85, 0xc2, 0x46, 0xa1,
72 0x31, 0xbb, 0xc7, 0xb9, 0x1d, 0xd1, 0x71, 0xe0, 0xe2, 0x9b, 0x9c, 0x0d,
73 0xa3, 0xcf, 0x93, 0x4d, 0x87, 0x7b, 0x65, 0xd9, 0xda, 0x4c, 0xd9, 0x6a,
74 0xa6, 0x36, 0xc2, 0xc7, 0xe3, 0x33, 0xe2, 0xc3, 0x83, 0xd1, 0x72, 0x54,
75 0x30, 0x81, 0x5e, 0x34, 0x2c, 0x61, 0xee, 0xf4, 0x48, 0x97, 0xb6, 0xaa,
76 0x47, 0x6a, 0x05, 0x09, 0xd8, 0x4d, 0x90, 0xaf, 0xa8, 0x4e, 0x82, 0xe4,
77 0x8e, 0xb5, 0xe2, 0x65, 0x86, 0x67, 0xe9, 0x5b, 0x4b, 0x9a, 0x68, 0x08,
78 0x30, 0xf6, 0x25, 0x8b, 0x20, 0xda, 0x26, 0x6f, 0xbd, 0x0d, 0xa5, 0xd8,
79 0x6a, 0x7b, 0x01, 0x2f, 0xab, 0x7b, 0xb5, 0xfe, 0x62, 0x37, 0x2d, 0x94,
80 0x43, 0x2f, 0x4d, 0x16, 0x01, 0x00, 0x01, 0x00,
81};
82
83// 2048 bit RSA signature.
84const uint8_t kSignature2048[ANDROID_PUBKEY_MODULUS_SIZE] = {
85 0x3a, 0x11, 0x84, 0x40, 0xc1, 0x2f, 0x13, 0x8c, 0xde, 0xb0, 0xc3, 0x89,
86 0x8a, 0x63, 0xb2, 0x50, 0x93, 0x58, 0xc0, 0x0c, 0xb7, 0x08, 0xe7, 0x6c,
87 0x52, 0x87, 0x4e, 0x78, 0x89, 0xa3, 0x9a, 0x47, 0xeb, 0x11, 0x57, 0xbc,
88 0xb3, 0x97, 0xf8, 0x34, 0xf1, 0xf7, 0xbf, 0x3a, 0xfa, 0x1c, 0x6b, 0xdc,
89 0xd1, 0x02, 0xde, 0x9a, 0x0d, 0x72, 0xe7, 0x19, 0x63, 0x81, 0x46, 0x68,
90 0x1e, 0x63, 0x64, 0xc6, 0x59, 0xe7, 0x7c, 0x39, 0xed, 0x32, 0xd2, 0xd1,
91 0xd5, 0x1f, 0x13, 0x9b, 0x52, 0xdf, 0x34, 0xa3, 0xc0, 0xc4, 0x9a, 0x63,
92 0x9b, 0x9c, 0xbe, 0x22, 0xc8, 0xd8, 0x14, 0x2f, 0x4c, 0x78, 0x36, 0xdb,
93 0x16, 0x41, 0x67, 0xc1, 0x21, 0x8a, 0x73, 0xb2, 0xe5, 0xb0, 0xd3, 0x80,
94 0x91, 0x7a, 0xbf, 0xf9, 0x59, 0x4a, 0x4d, 0x78, 0x45, 0x44, 0xa1, 0x52,
95 0x86, 0x29, 0x48, 0x4d, 0xf0, 0x5d, 0xf2, 0x55, 0xa7, 0xcd, 0xc5, 0x2b,
96 0x7b, 0xe0, 0xb1, 0xf6, 0x2a, 0xd5, 0x61, 0xba, 0x1e, 0x1e, 0x3a, 0xf0,
97 0x55, 0xbc, 0x8c, 0x44, 0x41, 0xfc, 0xb8, 0x8c, 0x76, 0xbf, 0x80, 0x58,
98 0x82, 0x35, 0x4b, 0x0c, 0xfd, 0xef, 0xd5, 0x70, 0xd1, 0x64, 0xcb, 0x46,
99 0x58, 0x37, 0xbc, 0xa9, 0x7d, 0xd4, 0x70, 0xac, 0xce, 0xec, 0xca, 0x48,
100 0xcb, 0x0a, 0x40, 0x77, 0x04, 0x59, 0xca, 0x9c, 0x7d, 0x1a, 0x0b, 0xf0,
101 0xb5, 0xdd, 0xde, 0x71, 0x18, 0xb8, 0xef, 0x90, 0x2a, 0x09, 0x42, 0x39,
102 0x74, 0xff, 0x45, 0xa1, 0x39, 0x17, 0x50, 0x89, 0xa6, 0x5f, 0xbc, 0x9c,
103 0x0c, 0x9b, 0x47, 0x25, 0x79, 0x3e, 0xe3, 0xaa, 0xaf, 0xbe, 0x73, 0x6b,
104 0xcb, 0xe7, 0x35, 0xc1, 0x27, 0x09, 0xcd, 0xeb, 0xd7, 0xcf, 0x63, 0x83,
105 0x64, 0x8c, 0x45, 0x1c, 0x1d, 0x58, 0xcc, 0xd2, 0xf8, 0x2b, 0x4c, 0x4e,
106 0x14, 0x89, 0x2d, 0x70,
107};
108
109struct AndroidPubkeyTest : public ::testing::Test {
110 void SetUp() override {
111 RSA* new_key = nullptr;
112 ASSERT_TRUE(android_pubkey_decode(kKey2048, sizeof(kKey2048), &new_key));
113 key_.reset(new_key);
114 }
115
116 std::unique_ptr<RSA, void(*)(RSA*)> key_ = {nullptr, RSA_free};
117};
118
119TEST_F(AndroidPubkeyTest, Decode) {
120 // Make sure the decoded key successfully verifies a valid signature.
121 EXPECT_TRUE(RSA_verify(NID_sha256, kDigest, sizeof(kDigest), kSignature2048,
122 sizeof(kSignature2048), key_.get()));
123}
124
125TEST_F(AndroidPubkeyTest, Encode) {
126 uint8_t key_data[ANDROID_PUBKEY_ENCODED_SIZE];
127 ASSERT_TRUE(android_pubkey_encode(key_.get(), key_data, sizeof(key_data)));
128 ASSERT_EQ(0, memcmp(kKey2048, key_data, sizeof(kKey2048)));
129}