summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ct/ct_vfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ct/ct_vfy.c')
-rw-r--r--src/lib/libcrypto/ct/ct_vfy.c222
1 files changed, 112 insertions, 110 deletions
diff --git a/src/lib/libcrypto/ct/ct_vfy.c b/src/lib/libcrypto/ct/ct_vfy.c
index 74fd34f415..74642a9304 100644
--- a/src/lib/libcrypto/ct/ct_vfy.c
+++ b/src/lib/libcrypto/ct/ct_vfy.c
@@ -17,124 +17,126 @@
17#include "ct_local.h" 17#include "ct_local.h"
18 18
19typedef enum sct_signature_type_t { 19typedef enum sct_signature_type_t {
20 SIGNATURE_TYPE_NOT_SET = -1, 20 SIGNATURE_TYPE_NOT_SET = -1,
21 SIGNATURE_TYPE_CERT_TIMESTAMP, 21 SIGNATURE_TYPE_CERT_TIMESTAMP,
22 SIGNATURE_TYPE_TREE_HASH 22 SIGNATURE_TYPE_TREE_HASH
23} SCT_SIGNATURE_TYPE; 23} SCT_SIGNATURE_TYPE;
24 24
25/* 25/*
26 * Update encoding for SCT signature verification/generation to supplied 26 * Update encoding for SCT signature verification/generation to supplied
27 * EVP_MD_CTX. 27 * EVP_MD_CTX.
28 */ 28 */
29static int sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct) 29static int
30sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
30{ 31{
31 unsigned char tmpbuf[12]; 32 unsigned char tmpbuf[12];
32 unsigned char *p, *der; 33 unsigned char *p, *der;
33 size_t derlen; 34 size_t derlen;
34 /*+ 35 /*+
35 * digitally-signed struct { 36 * digitally-signed struct {
36 * (1 byte) Version sct_version; 37 * (1 byte) Version sct_version;
37 * (1 byte) SignatureType signature_type = certificate_timestamp; 38 * (1 byte) SignatureType signature_type = certificate_timestamp;
38 * (8 bytes) uint64 timestamp; 39 * (8 bytes) uint64 timestamp;
39 * (2 bytes) LogEntryType entry_type; 40 * (2 bytes) LogEntryType entry_type;
40 * (? bytes) select(entry_type) { 41 * (? bytes) select(entry_type) {
41 * case x509_entry: ASN.1Cert; 42 * case x509_entry: ASN.1Cert;
42 * case precert_entry: PreCert; 43 * case precert_entry: PreCert;
43 * } signed_entry; 44 * } signed_entry;
44 * (2 bytes + sct->ext_len) CtExtensions extensions; 45 * (2 bytes + sct->ext_len) CtExtensions extensions;
45 * } 46 * }
46 */ 47 */
47 if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET) 48 if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
48 return 0; 49 return 0;
49 if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL) 50 if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
50 return 0; 51 return 0;
51 52
52 p = tmpbuf; 53 p = tmpbuf;
53 *p++ = sct->version; 54 *p++ = sct->version;
54 *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP; 55 *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP;
55 l2n8(sct->timestamp, p); 56 l2n8(sct->timestamp, p);
56 s2n(sct->entry_type, p); 57 s2n(sct->entry_type, p);
57 58
58 if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf)) 59 if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf))
59 return 0; 60 return 0;
60 61
61 if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) { 62 if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) {
62 der = sctx->certder; 63 der = sctx->certder;
63 derlen = sctx->certderlen; 64 derlen = sctx->certderlen;
64 } else { 65 } else {
65 if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen)) 66 if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen))
66 return 0; 67 return 0;
67 der = sctx->preder; 68 der = sctx->preder;
68 derlen = sctx->prederlen; 69 derlen = sctx->prederlen;
69 } 70 }
70 71
71 /* If no encoding available, fatal error */ 72 /* If no encoding available, fatal error */
72 if (der == NULL) 73 if (der == NULL)
73 return 0; 74 return 0;
74 75
75 /* Include length first */ 76 /* Include length first */
76 p = tmpbuf; 77 p = tmpbuf;
77 l2n3(derlen, p); 78 l2n3(derlen, p);
78 79
79 if (!EVP_DigestUpdate(ctx, tmpbuf, 3)) 80 if (!EVP_DigestUpdate(ctx, tmpbuf, 3))
80 return 0; 81 return 0;
81 if (!EVP_DigestUpdate(ctx, der, derlen)) 82 if (!EVP_DigestUpdate(ctx, der, derlen))
82 return 0; 83 return 0;
83 84
84 /* Add any extensions */ 85 /* Add any extensions */
85 p = tmpbuf; 86 p = tmpbuf;
86 s2n(sct->ext_len, p); 87 s2n(sct->ext_len, p);
87 if (!EVP_DigestUpdate(ctx, tmpbuf, 2)) 88 if (!EVP_DigestUpdate(ctx, tmpbuf, 2))
88 return 0; 89 return 0;
89 90
90 if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len)) 91 if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len))
91 return 0; 92 return 0;
92 93
93 return 1; 94 return 1;
94} 95}
95 96
96int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) 97int
98SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
97{ 99{
98 EVP_MD_CTX *ctx = NULL; 100 EVP_MD_CTX *ctx = NULL;
99 int ret = 0; 101 int ret = 0;
100 102
101 if (!SCT_is_complete(sct) || sctx->pkey == NULL || 103 if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
102 sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET || 104 sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
103 (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) { 105 (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) {
104 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET); 106 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET);
105 return 0; 107 return 0;
106 } 108 }
107 if (sct->version != SCT_VERSION_V1) { 109 if (sct->version != SCT_VERSION_V1) {
108 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION); 110 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION);
109 return 0; 111 return 0;
110 } 112 }
111 if (sct->log_id_len != sctx->pkeyhashlen || 113 if (sct->log_id_len != sctx->pkeyhashlen ||
112 memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) { 114 memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
113 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH); 115 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH);
114 return 0; 116 return 0;
115 } 117 }
116 if (sct->timestamp > sctx->epoch_time_in_ms) { 118 if (sct->timestamp > sctx->epoch_time_in_ms) {
117 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP); 119 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP);
118 return 0; 120 return 0;
119 } 121 }
120 122
121 ctx = EVP_MD_CTX_new(); 123 ctx = EVP_MD_CTX_new();
122 if (ctx == NULL) 124 if (ctx == NULL)
123 goto end; 125 goto end;
124 126
125 if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey)) 127 if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
126 goto end; 128 goto end;
127 129
128 if (!sct_ctx_update(ctx, sctx, sct)) 130 if (!sct_ctx_update(ctx, sctx, sct))
129 goto end; 131 goto end;
130 132
131 /* Verify signature */ 133 /* Verify signature */
132 ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len); 134 ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len);
133 /* If ret < 0 some other error: fall through without setting error */ 135 /* If ret < 0 some other error: fall through without setting error */
134 if (ret == 0) 136 if (ret == 0)
135 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE); 137 CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE);
136 138
137end: 139 end:
138 EVP_MD_CTX_free(ctx); 140 EVP_MD_CTX_free(ctx);
139 return ret; 141 return ret;
140} 142}