ccn_signing.c

Go to the documentation of this file.
00001 /**
00002  * @file ccn_signing.c
00003  * @brief Support for signing.
00004  * 
00005  * Part of the CCNx C Library.
00006  *
00007  * Copyright (C) 2009-2010 Palo Alto Research Center, Inc.
00008  *
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Lesser General Public License version 2.1
00011  * as published by the Free Software Foundation.
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * Lesser General Public License for more details. You should have received
00016  * a copy of the GNU Lesser General Public License along with this library;
00017  * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
00018  * Fifth Floor, Boston, MA 02110-1301 USA.
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     /* This encapsulates knowledge that the default digest algorithm for
00067      * signing is SHA256.  See also CCN_SIGNING_DEFAULT_DIGEST_ALGORITHM
00068      * in ccn/ccn.h.  We could call OBJ_txt2nid(), but this would be rather
00069      * inefficient.  If there were a place to stand for overall signing
00070      * initialization then that would be an appropriate place to do so.
00071      */
00072     if (digest == NULL) {
00073         md_nid = NID_sha256;
00074     }
00075     else {
00076         /* figure out what algorithm the OID represents */
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      * In OpenSSL 0.9.8 the digest algorithm and key type determine the
00097      * digest and signature methods that are in the staticly defined
00098      * EVP_MD structures, so we need to get the correct predefined one, or
00099      * create our own.
00100      * In OpenSSL 1.0.0 the EVP_MD structure allows for the key that is passed
00101      * in the signature finalization step to determine the signature algorithm
00102      * applied to the digest, so we would be able to use a single SHA256 context
00103      * independent of the key type (assuming size compatability).
00104      * At the point that 1.0.0 or later is the default provider we could simplify
00105      * this code.   The Java code (OIDLookup.java) uses a much more elaborate
00106      * set of hash maps to perform a similar function.
00107      */
00108     switch (md_nid) {
00109 #ifndef OPENSSL_NO_SHA
00110         case NID_sha1:      // supported for RSA/DSA/EC key types
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:    // supported for RSA/EC key types
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             } /* our own md */
00130 #endif
00131             break;
00132         case NID_sha512:     // supported for RSA
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         // XXX - is it OK to call cleanup unconditionally?
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     //int hash_count = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes);
00215     int hash_index = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes) - 1;
00216     //ASN1_OCTET_STRING *sibling_hash;
00217     int res;
00218     
00219     if (result_size != EVP_MD_size(digest_type))
00220         return -1;
00221 
00222     /*
00223      * This is the calculation for the node we're starting from
00224      *
00225      * The digest type for the leaf node we'll take from the MHT OID
00226      * We can assume that, since we're using the same digest function, the
00227      * result size will always be the same.
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     /* input_hash[0, 1] = address of hash for (left,right) node of parent
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         /* figure out what algorithm the OID represents */
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         /* NOTE: since the element closer is a 0, and the element is well formed,
00328          * the string will be null terminated 
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         /* The witness is a DigestInfo, where the octet-string therein encapsulates
00340          * a sequence of [integer (origin 1 node#), sequence of [octet-string]]
00341          * where the inner octet-string is the concatenated hashes on the merkle-path
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         /* digest_info->algor->algorithm->{length, data}
00355          * digest_info->digest->{length, type, data}
00356          */
00357         /* ...2.2 is an MHT w/ SHA256 */
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         /* we're doing an MHT */
00366         ASN1_OBJECT_free(merkle_hash_tree_oid);
00367         merkle_path_digest = EVP_sha256();
00368         /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */
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         /* In the MHT signature case, we signed/verify the root hash */
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          * In the simple signature case, we signed/verify from the name through
00409          * the end of the content.
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 /* PRNG */
00472 
00473 /**
00474  * Generate pseudo-random bytes.
00475  *
00476  * @param buf is the destination buffer
00477  * @param size is in bytes
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  * Feed some entropy to the random number generator.
00491  * 
00492  * @param buf is the source buffer
00493  * @param size is in bytes
00494  * @param bits_of_entropy is an estimate; use 0 to make me guess
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     /* Supply a hopefully conservative estimate of entropy. */
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 }
Generated on Tue Aug 21 14:54:18 2012 for Content-Centric Networking in C by  doxygen 1.6.3