/* crypto/ecdsa/ecs_lib.c */ /* ==================================================================== * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ #include #include "ecs_locl.h" #ifndef OPENSSL_NO_ENGINE #include #endif #include #include const char *ECDSA_version="ECDSA" OPENSSL_VERSION_PTEXT; static const ECDSA_METHOD *default_ECDSA_method = NULL; static void *ecdsa_data_new(void); static void *ecdsa_data_dup(void *); static void ecdsa_data_free(void *); void ECDSA_set_default_method(const ECDSA_METHOD *meth) { default_ECDSA_method = meth; } const ECDSA_METHOD *ECDSA_get_default_method(void) { if(!default_ECDSA_method) default_ECDSA_method = ECDSA_OpenSSL(); return default_ECDSA_method; } int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) { const ECDSA_METHOD *mtmp; ECDSA_DATA *ecdsa; ecdsa = ecdsa_check(eckey); if (ecdsa == NULL) return 0; mtmp = ecdsa->meth; #ifndef OPENSSL_NO_ENGINE if (ecdsa->engine) { ENGINE_finish(ecdsa->engine); ecdsa->engine = NULL; } #endif ecdsa->meth = meth; return 1; } static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) { ECDSA_DATA *ret; ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); if (ret == NULL) { ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); return(NULL); } ret->init = NULL; ret->meth = ECDSA_get_default_method(); ret->engine = engine; #ifndef OPENSSL_NO_ENGINE if (!ret->engine) ret->engine = ENGINE_get_default_ECDSA(); if (ret->engine) { ret->meth = ENGINE_get_ECDSA(ret->engine); if (!ret->meth) { ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); ENGINE_finish(ret->engine); OPENSSL_free(ret); return NULL; } } #endif ret->flags = ret->meth->flags; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); #if 0 if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; } #endif return(ret); } static void *ecdsa_data_new(void) { return (void *)ECDSA_DATA_new_method(NULL); } static void *ecdsa_data_dup(void *data) { ECDSA_DATA *r = (ECDSA_DATA *)data; /* XXX: dummy operation */ if (r == NULL) return NULL; return ecdsa_data_new(); } static void ecdsa_data_free(void *data) { ECDSA_DATA *r = (ECDSA_DATA *)data; #ifndef OPENSSL_NO_ENGINE if (r->engine) ENGINE_finish(r->engine); #endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); OPENSSL_free(r); } ECDSA_DATA *ecdsa_check(EC_KEY *key) { ECDSA_DATA *ecdsa_data; void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free); if (data == NULL) { ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); if (ecdsa_data == NULL) return NULL; EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free); } else ecdsa_data = (ECDSA_DATA *)data; return ecdsa_data; } int ECDSA_size(const EC_KEY *r) { int ret,i; ASN1_INTEGER bs; BIGNUM *order=NULL; unsigned char buf[4]; const EC_GROUP *group; if (r == NULL) return 0; group = EC_KEY_get0_group(r); if (group == NULL) return 0; if ((order = BN_new()) == NULL) return 0; if (!EC_GROUP_get_order(group,order,NULL)) { BN_clear_free(order); return 0; } i=BN_num_bits(order); bs.length=(i+7)/8; bs.data=buf; bs.type=V_ASN1_INTEGER; /* If the top bit is set the asn1 encoding is 1 larger. */ buf[0]=0xff; i=i2d_ASN1_INTEGER(&bs,NULL); i+=i; /* r and s */ ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE); BN_clear_free(order); return(ret); } int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, new_func, dup_func, free_func); } int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) { ECDSA_DATA *ecdsa; ecdsa = ecdsa_check(d); if (ecdsa == NULL) return 0; return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg)); } void *ECDSA_get_ex_data(EC_KEY *d, int idx) { ECDSA_DATA *ecdsa; ecdsa = ecdsa_check(d); if (ecdsa == NULL) return NULL; return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx)); } 9e9ab4109d8'>edf891be
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                                             






























































                                                                                                                            




                                                                             


                                      

                                                                          









                                              
                                                             















































































































































                                                                                                                                         
# Copyright (C) 2012  SPARTA, Inc. a Parsons Company
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS.  IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.

__version__ = '$Id$'

import bisect
import unittest

class RangeList(list):
    """A sorted list of ranges, which automatically merges adjacent ranges.

    Items in the list are expected to have ".min" and ".max" attributes."""

    def __init__(self, ini=None):
        list.__init__(self)
        if ini:
            self.extend(ini)

    def append(self, v):
        keys = [x.min for x in self]

        # lower bound
        i = bisect.bisect_left(keys, v.min)

        # upper bound
        j = bisect.bisect_right(keys, v.max, lo=i)

        # if the max value for the previous item is greater than v.min, include the previous item in the range to replace
        # and use its min value.  also include the previous item if the max value is 1 less than the min value for the
        # inserted item
        if i > 0 and self[i-1].max >= v.min - 1:
            i = i - 1
            vmin = self[i].min
        else:
            vmin = v.min

        # if the max value for the previous item is greater than the max value for the new item, use the previous item's max
        if j > 0 and self[j-1].max > v.max:
            vmax = self[j-1].max
        else:
            vmax = v.max

        # if the max value for the new item is 1 less than the min value for the next item, combine into a single item
        if j < len(self) and vmax+1 == self[j].min:
            vmax = self[j].max
            j = j+1

        # replace the range with a new object covering the entire range
        self[i:j] = [v.__class__(min=vmin, max=vmax)]

    def extend(self, args):
        for x in args:
            self.append(x)

    def difference(self, other):
        """Return a RangeList object which contains ranges in this object which are not in "other"."""
        it = iter(other)

        try:
            cur = it.next()
        except StopIteration:
            return self

        r = RangeList()

        for x in self:
            xmin = x.min

            def V(v):
                """convert the integer value to the appropriate type for this
                range"""
                return x.__class__.datum_type(v)

            try:
                while xmin <= x.max:
                    if xmin < cur.min:
                        r.append(x.__class__(min=V(xmin),
                                             max=V(min(x.max,cur.min-1))))
                        xmin = cur.max+1
                    elif xmin == cur.min:
                        xmin = cur.max+1
                    else: # xmin > cur.min
                        if xmin <= cur.max:
                            xmin = cur.max+1
                        else: # xmin > cur.max
                            cur = it.next()

            except StopIteration:
                r.append(x.__class__(min=V(xmin), max=x.max))

        return r

class TestRangeList(unittest.TestCase):
    class MinMax(object):
        def __init__(self, min, max):
            self.min = min
            self.max = max

        def __str__(self):
            return '(%d, %d)' % (self.min, self.max)

        def __repr__(self):
            return '<MinMax: (%d, %d)>' % (self.min, self.max)

        def __eq__(self, other):
            return self.min == other.min and self.max == other.max

    def setUp(self):
        self.v1 = TestRangeList.MinMax(1,2)
        self.v2 = TestRangeList.MinMax(4,5)
        self.v3 = TestRangeList.MinMax(7,8)
        self.v4 = TestRangeList.MinMax(3,4)
        self.v5 = TestRangeList.MinMax(2,3)
        self.v6 = TestRangeList.MinMax(1,10)

    def test_empty_append(self):
        s = RangeList()
        s.append(self.v1)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], self.v1)

    def test_no_overlap(self):
        s = RangeList()
        s.append(self.v1)
        s.append(self.v2)
        self.assertTrue(len(s) == 2)
        self.assertEqual(s[0], self.v1)
        self.assertEqual(s[1], self.v2)

    def test_no_overlap_prepend(self):
        s = RangeList()
        s.append(self.v2)
        s.append(self.v1)
        self.assertTrue(len(s) == 2)
        self.assertEqual(s[0], self.v1)
        self.assertEqual(s[1], self.v2)

    def test_insert_middle(self):
        s = RangeList()
        s.append(self.v1)
        s.append(self.v3)
        s.append(self.v2)
        self.assertTrue(len(s) == 3)
        self.assertEqual(s[0], self.v1)
        self.assertEqual(s[1], self.v2)
        self.assertEqual(s[2], self.v3)

    def test_append_overlap(self):
        s = RangeList()
        s.append(self.v1)
        s.append(self.v5)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], TestRangeList.MinMax(1,3))

    def test_combine_range(self):
        s = RangeList()
        s.append(self.v1)
        s.append(self.v4)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], TestRangeList.MinMax(1,4))

    def test_append_subset(self):
        s = RangeList()
        s.append(self.v6)
        s.append(self.v3)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], self.v6)

    def test_append_equal(self):
        s = RangeList()
        s.append(self.v6)
        s.append(self.v6)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], self.v6)

    def test_prepend_combine(self):
        s = RangeList()
        s.append(self.v4)
        s.append(self.v1)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], TestRangeList.MinMax(1,4))

    def test_append_aggregate(self):
        s = RangeList()
        s.append(self.v1)
        s.append(self.v2)
        s.append(self.v3)
        s.append(self.v6)
        self.assertTrue(len(s) == 1)
        self.assertEqual(s[0], self.v6)

    def test_diff_empty(self):
        s = RangeList()
        s.append(self.v1)
        self.assertEqual(s, s.difference([]))

    def test_diff_self(self):
        s = RangeList()
        s.append(self.v1)
        self.assertEqual(s.difference(s), [])

    def test_diff_middle(self):
        s1 = RangeList([self.v6])
        s2 = RangeList([self.v3])
        self.assertEqual(s1.difference(s2), RangeList([TestRangeList.MinMax(1,6), TestRangeList.MinMax(9, 10)]))

    def test_diff_overlap(self):
        s1 = RangeList([self.v2])
        s2 = RangeList([self.v4])
        self.assertEqual(s1.difference(s2), RangeList([TestRangeList.MinMax(5,5)]))

    def test_diff_overlap2(self):
        s1 = RangeList([self.v2])
        s2 = RangeList([self.v4])
        self.assertEqual(s2.difference(s1), RangeList([TestRangeList.MinMax(3,3)]))

    def test_diff_multi(self):
        s1 = RangeList([TestRangeList.MinMax(1,2), TestRangeList.MinMax(4,5)]) 
        s2 = RangeList([TestRangeList.MinMax(4,4)]) 
        self.assertEqual(s1.difference(s2), RangeList([TestRangeList.MinMax(1,2), TestRangeList.MinMax(5,5)]))

    def test_diff_multi_overlap(self):
        s1 = RangeList([TestRangeList.MinMax(1,2), TestRangeList.MinMax(3,4)])
        s2 = RangeList([TestRangeList.MinMax(2,3)])
        self.assertEqual(s1.difference(s2), RangeList([TestRangeList.MinMax(1,1), TestRangeList.MinMax(4,4)]))

    def test_diff_multi_overlap2(self):
        s1 = RangeList([TestRangeList.MinMax(1,2), TestRangeList.MinMax(3,4), TestRangeList.MinMax(6,7)])
        s2 = RangeList([TestRangeList.MinMax(2,3), TestRangeList.MinMax(6,6)])
        self.assertEqual(s1.difference(s2), RangeList([TestRangeList.MinMax(1,1), TestRangeList.MinMax(4,4), TestRangeList.MinMax(7,7)]))

if __name__ == '__main__':
    unittest.main()