00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stddef.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 #include <openssl/evp.h>
00024 #include <openssl/rand.h>
00025 #include <openssl/x509.h>
00026 #include <ccn/merklepathasn1.h>
00027 #include <ccn/ccn.h>
00028 #include <ccn/signing.h>
00029 #include <ccn/random.h>
00030
00031 struct ccn_sigc {
00032 EVP_MD_CTX context;
00033 };
00034
00035 #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) && defined(NID_ecdsa_with_SHA256)
00036 static int init256(EVP_MD_CTX *ctx)
00037 { return SHA256_Init(ctx->md_data); }
00038 static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
00039 { return SHA256_Update(ctx->md_data,data,count); }
00040 static int final256(EVP_MD_CTX *ctx,unsigned char *md)
00041 { return SHA256_Final(md,ctx->md_data); }
00042
00043 static const EVP_MD sha256ec_md=
00044 {
00045 NID_sha256,
00046 NID_ecdsa_with_SHA256,
00047 SHA256_DIGEST_LENGTH,
00048 0,
00049 init256,
00050 update256,
00051 final256,
00052 NULL,
00053 NULL,
00054 EVP_PKEY_ECDSA_method,
00055 SHA256_CBLOCK,
00056 sizeof(EVP_MD *)+sizeof(SHA256_CTX),
00057 };
00058 #endif
00059
00060 static const EVP_MD *
00061 md_from_digest_and_pkey(const char *digest, const struct ccn_pkey *pkey)
00062 {
00063 int md_nid;
00064 int pkey_type;
00065
00066
00067
00068
00069
00070
00071
00072 if (digest == NULL) {
00073 md_nid = NID_sha256;
00074 }
00075 else {
00076
00077 md_nid = OBJ_txt2nid(digest);
00078 if (md_nid == NID_undef) {
00079 fprintf(stderr, "not a DigestAlgorithm I understand right now: %s\n", digest);
00080 return (NULL);
00081 }
00082 }
00083 pkey_type = EVP_PKEY_type(((EVP_PKEY *)pkey)->type);
00084 switch (pkey_type) {
00085 case EVP_PKEY_RSA:
00086 case EVP_PKEY_DSA:
00087 #if !defined(OPENSSL_NO_EC)
00088 case EVP_PKEY_EC:
00089 #endif
00090 break;
00091 default:
00092 fprintf(stderr, "not a Key type I understand right now: NID %d\n", pkey_type);
00093 return(NULL);
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 switch (md_nid) {
00109 #ifndef OPENSSL_NO_SHA
00110 case NID_sha1:
00111 switch (pkey_type) {
00112 case EVP_PKEY_RSA:
00113 return(EVP_sha1());
00114 case EVP_PKEY_DSA:
00115 return(EVP_dss1());
00116 #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
00117 case EVP_PKEY_EC:
00118 return(EVP_ecdsa());
00119 #endif
00120 }
00121 break;
00122 #endif
00123 case NID_sha256:
00124 if (pkey_type == EVP_PKEY_RSA)
00125 return(EVP_sha256());
00126 #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) && defined(NID_ecdsa_with_SHA256)
00127 else if (pkey_type == EVP_PKEY_EC) {
00128 return(&sha256ec_md);
00129 }
00130 #endif
00131 break;
00132 case NID_sha512:
00133 if (pkey_type == EVP_PKEY_RSA)
00134 return(EVP_sha512());
00135 default:
00136 break;
00137 }
00138 fprintf(stderr, "not a Digest+Signature algorithm I understand right now: %s with NID %d\n",
00139 digest, pkey_type);
00140 return (NULL);
00141 }
00142
00143
00144 struct ccn_sigc *
00145 ccn_sigc_create(void)
00146 {
00147 return (calloc(1, sizeof(struct ccn_sigc)));
00148 }
00149
00150 void
00151 ccn_sigc_destroy(struct ccn_sigc **ctx)
00152 {
00153 if (*ctx) {
00154
00155 EVP_MD_CTX_cleanup(&(*ctx)->context);
00156 free(*ctx);
00157 *ctx = NULL;
00158 }
00159 }
00160
00161 int
00162 ccn_sigc_init(struct ccn_sigc *ctx, const char *digest, const struct ccn_pkey *priv_key)
00163 {
00164 const EVP_MD *md;
00165
00166 EVP_MD_CTX_init(&ctx->context);
00167 md = md_from_digest_and_pkey(digest, priv_key);
00168 if (0 == EVP_SignInit_ex(&ctx->context, md, NULL))
00169 return (-1);
00170 return (0);
00171 }
00172
00173 int
00174 ccn_sigc_update(struct ccn_sigc *ctx, const void *data, size_t size)
00175 {
00176 if (0 == EVP_SignUpdate(&ctx->context, (unsigned char *)data, size))
00177 return (-1);
00178 return (0);
00179 }
00180
00181 int
00182 ccn_sigc_final(struct ccn_sigc *ctx, struct ccn_signature *signature, size_t *size, const struct ccn_pkey *priv_key)
00183 {
00184 unsigned int sig_size;
00185
00186 if (0 == EVP_SignFinal(&ctx->context, (unsigned char *)signature, &sig_size, (EVP_PKEY *)priv_key))
00187 return (-1);
00188 *size = sig_size;
00189 return (0);
00190 }
00191
00192 size_t
00193 ccn_sigc_signature_max_size(struct ccn_sigc *ctx, const struct ccn_pkey *priv_key)
00194 {
00195 return (EVP_PKEY_size((EVP_PKEY *)priv_key));
00196 }
00197
00198 #define is_left(x) (0 == (x & 1))
00199 #define node_lr(x) (x & 1)
00200 #define sibling_of(x) (x ^ 1)
00201 #define parent_of(x) (x >> 1)
00202
00203 int ccn_merkle_root_hash(const unsigned char *msg, size_t size,
00204 const struct ccn_parsed_ContentObject *co,
00205 const EVP_MD *digest_type,
00206 MP_info *merkle_path_info,
00207 unsigned char *result, int result_size)
00208 {
00209 int node = ASN1_INTEGER_get(merkle_path_info->node);
00210 EVP_MD_CTX digest_context;
00211 EVP_MD_CTX *digest_contextp = &digest_context;
00212 size_t data_size;
00213 unsigned char *input_hash[2] = {NULL, NULL};
00214
00215 int hash_index = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes) - 1;
00216
00217 int res;
00218
00219 if (result_size != EVP_MD_size(digest_type))
00220 return -1;
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 EVP_MD_CTX_init(digest_contextp);
00231 EVP_DigestInit_ex(digest_contextp, digest_type, NULL);
00232 data_size = co->offset[CCN_PCO_E_Content] - co->offset[CCN_PCO_B_Name];
00233 res = EVP_DigestUpdate(digest_contextp, msg + co->offset[CCN_PCO_B_Name], data_size);
00234 res &= EVP_DigestFinal_ex(digest_contextp, result, NULL);
00235 EVP_MD_CTX_cleanup(digest_contextp);
00236 if (res != 1)
00237 return(-1);
00238
00239
00240 while (node != 1) {
00241 input_hash[node & 1] = result;
00242 input_hash[(node & 1) ^ 1] = sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, hash_index)->data;
00243 if (sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, hash_index)->length != result_size)
00244 return (-1);
00245 hash_index -= 1;
00246 #ifdef DEBUG
00247 fprintf(stderr, "node[%d].lefthash = ", parent_of(node));
00248 for (int x = 0; x < result_size; x++) {
00249 fprintf(stderr, "%02x", input_hash[0][x]);
00250 }
00251 fprintf(stderr, "\n");
00252
00253 fprintf(stderr, "node[%d].righthash = ", parent_of(node));
00254 for (int x = 0; x < result_size; x++) {
00255 fprintf(stderr, "%02x", input_hash[1][x]);
00256 }
00257 fprintf(stderr, "\n");
00258 #endif
00259 EVP_MD_CTX_init(digest_contextp);
00260 res = EVP_DigestInit_ex(digest_contextp, digest_type, NULL);
00261 res &= EVP_DigestUpdate(digest_contextp, input_hash[0], result_size);
00262 res &= EVP_DigestUpdate(digest_contextp, input_hash[1], result_size);
00263 res &= EVP_DigestFinal_ex(digest_contextp, result, NULL);
00264 EVP_MD_CTX_cleanup(digest_contextp);
00265 if (res != 1)
00266 return(-1);
00267 node = parent_of(node);
00268
00269 #ifdef DEBUG
00270 fprintf(stderr, "yielding node[%d] hash = ", node);
00271 for (int x = 0; x < result_size; x++) {
00272 fprintf(stderr, "%02x", result[x]);
00273 }
00274 fprintf(stderr, "\n");
00275 #endif
00276 }
00277 return (0);
00278 }
00279
00280 int ccn_verify_signature(const unsigned char *msg,
00281 size_t size,
00282 const struct ccn_parsed_ContentObject *co,
00283 const struct ccn_pkey *verification_pubkey)
00284 {
00285 EVP_MD_CTX verc;
00286 EVP_MD_CTX *ver_ctx = &verc;
00287 X509_SIG *digest_info = NULL;
00288 const unsigned char *dd = NULL;
00289 MP_info *merkle_path_info = NULL;
00290 unsigned char *root_hash = NULL;
00291 size_t root_hash_size;
00292
00293 int res;
00294
00295 const EVP_MD *digest = NULL;
00296 const EVP_MD *merkle_path_digest = NULL;
00297
00298 const unsigned char *signature_bits = NULL;
00299 size_t signature_bits_size = 0;
00300 const unsigned char *witness = NULL;
00301 size_t witness_size = 0;
00302 const unsigned char *digest_algorithm = NULL;
00303 size_t digest_algorithm_size;
00304
00305 EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey;
00306
00307 res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, msg,
00308 co->offset[CCN_PCO_B_SignatureBits],
00309 co->offset[CCN_PCO_E_SignatureBits],
00310 &signature_bits,
00311 &signature_bits_size);
00312 if (res < 0)
00313 return (-1);
00314
00315 if (co->offset[CCN_PCO_B_DigestAlgorithm] == co->offset[CCN_PCO_E_DigestAlgorithm]) {
00316 digest_algorithm = (const unsigned char *)CCN_SIGNING_DEFAULT_DIGEST_ALGORITHM;
00317 }
00318 else {
00319
00320 res = ccn_ref_tagged_string(CCN_DTAG_DigestAlgorithm, msg,
00321 co->offset[CCN_PCO_B_DigestAlgorithm],
00322 co->offset[CCN_PCO_E_DigestAlgorithm],
00323 &digest_algorithm,
00324 &digest_algorithm_size);
00325 if (res < 0)
00326 return (-1);
00327
00328
00329
00330 }
00331 digest = md_from_digest_and_pkey((const char *)digest_algorithm, verification_pubkey);
00332 EVP_MD_CTX_init(ver_ctx);
00333 res = EVP_VerifyInit_ex(ver_ctx, digest, NULL);
00334 if (!res) {
00335 EVP_MD_CTX_cleanup(ver_ctx);
00336 return (-1);
00337 }
00338 if (co->offset[CCN_PCO_B_Witness] != co->offset[CCN_PCO_E_Witness]) {
00339
00340
00341
00342
00343 res = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, msg,
00344 co->offset[CCN_PCO_B_Witness],
00345 co->offset[CCN_PCO_E_Witness],
00346 &witness,
00347 &witness_size);
00348 if (res < 0) {
00349 EVP_MD_CTX_cleanup(ver_ctx);
00350 return (-1);
00351 }
00352
00353 digest_info = d2i_X509_SIG(NULL, &witness, witness_size);
00354
00355
00356
00357
00358 ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1);
00359 if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) {
00360 fprintf(stderr, "A witness is present without an MHT OID!\n");
00361 EVP_MD_CTX_cleanup(ver_ctx);
00362 ASN1_OBJECT_free(merkle_hash_tree_oid);
00363 return (-1);
00364 }
00365
00366 ASN1_OBJECT_free(merkle_hash_tree_oid);
00367 merkle_path_digest = EVP_sha256();
00368
00369 dd = digest_info->digest->data;
00370 merkle_path_info = d2i_MP_info(NULL, &dd, digest_info->digest->length);
00371 X509_SIG_free(digest_info);
00372 #ifdef DEBUG
00373 int x,h;
00374 int node = ASN1_INTEGER_get(merkle_path_info->node);
00375 int hash_count = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes);
00376 ASN1_OCTET_STRING *hash;
00377 fprintf(stderr, "A witness is present with an MHT OID\n");
00378 fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count);
00379 for (h = 0; h < hash_count; h++) {
00380 hash = sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, h);
00381 fprintf(stderr, " hashes[%d] len = %d data = ", h, hash->length);
00382 for (x = 0; x < hash->length; x++) {
00383 fprintf(stderr, "%02x", hash->data[x]);
00384 }
00385 fprintf(stderr, "\n");
00386 }
00387 #endif
00388
00389 root_hash_size = EVP_MD_size(merkle_path_digest);
00390 root_hash = calloc(1, root_hash_size);
00391 res = ccn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size);
00392 MP_info_free(merkle_path_info);
00393 if (res < 0) {
00394 EVP_MD_CTX_cleanup(ver_ctx);
00395 free(root_hash);
00396 return(-1);
00397 }
00398 res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size);
00399 free(root_hash);
00400 if (res == 0) {
00401 EVP_MD_CTX_cleanup(ver_ctx);
00402 return(-1);
00403 }
00404 res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
00405 EVP_MD_CTX_cleanup(ver_ctx);
00406 } else {
00407
00408
00409
00410
00411 size_t signed_size = co->offset[CCN_PCO_E_Content] - co->offset[CCN_PCO_B_Name];
00412 res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[CCN_PCO_B_Name], signed_size);
00413 if (res == 0) {
00414 EVP_MD_CTX_cleanup(ver_ctx);
00415 return(-1);
00416 }
00417 res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
00418 EVP_MD_CTX_cleanup(ver_ctx);
00419 }
00420 return (res);
00421 }
00422
00423 struct ccn_pkey *
00424 ccn_d2i_pubkey(const unsigned char *p, size_t size)
00425 {
00426 const unsigned char *q = p;
00427 EVP_PKEY *ans;
00428 ans = d2i_PUBKEY(NULL, &q, size);
00429 return ((struct ccn_pkey *)ans);
00430 }
00431
00432 void
00433 ccn_pubkey_free(struct ccn_pkey *i_pubkey)
00434 {
00435 EVP_PKEY *pkey = (EVP_PKEY *)i_pubkey;
00436 EVP_PKEY_free(pkey);
00437 }
00438
00439 size_t
00440 ccn_pubkey_size(const struct ccn_pkey *i_pubkey)
00441 {
00442 size_t ans;
00443 EVP_PKEY *pkey = (EVP_PKEY *)i_pubkey;
00444 ans = EVP_PKEY_size(pkey);
00445 return (ans);
00446 }
00447
00448 int
00449 ccn_append_pubkey_blob(struct ccn_charbuf *c, const struct ccn_pkey *i_pubkey)
00450 {
00451 int res;
00452 size_t bytes;
00453 unsigned char *p = NULL;
00454 res = i2d_PUBKEY((EVP_PKEY *)i_pubkey, NULL);
00455 if (res < 0)
00456 return(-1);
00457 bytes = res;
00458 res = ccn_charbuf_append_tt(c, bytes, CCN_BLOB);
00459 if (res < 0)
00460 return(-1);
00461 p = ccn_charbuf_reserve(c, bytes);
00462 if (p == NULL)
00463 return(-1);
00464 res = i2d_PUBKEY((EVP_PKEY *)i_pubkey, &p);
00465 if (res != (int)bytes)
00466 return(-1);
00467 c->length += bytes;
00468 return(bytes);
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 void
00480 ccn_random_bytes(unsigned char *buf, size_t size)
00481 {
00482 int num = size;
00483
00484 if (num < 0 || num != size)
00485 abort();
00486 RAND_bytes(buf, num);
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496 void
00497 ccn_add_entropy(const void *buf, size_t size, int bits_of_entropy)
00498 {
00499 int num = size;
00500
00501 if (num < 0 || num != size)
00502 abort();
00503
00504 if (bits_of_entropy <= 0)
00505 bits_of_entropy = (num < 32) ? 1 : num / 32;
00506 RAND_add((unsigned char *)buf, num, bits_of_entropy * 0.125);
00507 }