Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/lib/util/asn1.c

    r597 r740  
    215215}
    216216
    217 bool ber_write_OID_String(DATA_BLOB *blob, const char *OID)
    218 {
    219         uint_t v, v2;
     217bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
     218{
     219        unsigned int v, v2;
    220220        const char *p = (const char *)OID;
    221221        char *newp;
    222222        int i;
    223223
     224        if (!isdigit(*p)) return false;
    224225        v = strtoul(p, &newp, 10);
    225226        if (newp[0] != '.') return false;
    226227        p = newp + 1;
    227228
     229        if (!isdigit(*p)) return false;
    228230        v2 = strtoul(p, &newp, 10);
    229231        if (newp[0] != '.') return false;
     
    231233
    232234        /*the ber representation can't use more space then the string one */
    233         *blob = data_blob(NULL, strlen(OID));
     235        *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID));
    234236        if (!blob->data) return false;
    235237
     
    238240        i = 1;
    239241        while (*p) {
     242                if (!isdigit(*p)) return false;
    240243                v = strtoul(p, &newp, 10);
    241244                if (newp[0] == '.') {
    242245                        p = newp + 1;
     246                        /* check for empty last component */
     247                        if (!*p) return false;
    243248                } else if (newp[0] == '\0') {
    244249                        p = newp;
     
    259264}
    260265
     266/**
     267 * Serialize partial OID string.
     268 * Partial OIDs are in the form:
     269 *   1:2.5.6:0x81
     270 *   1:2.5.6:0x8182
     271 */
     272bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid)
     273{
     274        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     275        char *oid = talloc_strdup(tmp_ctx, partial_oid);
     276        char *p;
     277
     278        /* truncate partial part so ber_write_OID_String() works */
     279        p = strchr(oid, ':');
     280        if (p) {
     281                *p = '\0';
     282                p++;
     283        }
     284
     285        if (!ber_write_OID_String(mem_ctx, blob, oid)) {
     286                talloc_free(tmp_ctx);
     287                return false;
     288        }
     289
     290        /* Add partially encoded sub-identifier */
     291        if (p) {
     292                DATA_BLOB tmp_blob = strhex_to_data_blob(tmp_ctx, p);
     293                if (!data_blob_append(mem_ctx, blob, tmp_blob.data,
     294                                      tmp_blob.length)) {
     295                        talloc_free(tmp_ctx);
     296                        return false;
     297                }
     298        }
     299
     300        talloc_free(tmp_ctx);
     301
     302        return true;
     303}
     304
    261305/* write an object ID to a ASN1 buffer */
    262306bool asn1_write_OID(struct asn1_data *data, const char *OID)
     
    266310        if (!asn1_push_tag(data, ASN1_OID)) return false;
    267311
    268         if (!ber_write_OID_String(&blob, OID)) {
     312        if (!ber_write_OID_String(NULL, &blob, OID)) {
    269313                data->has_error = true;
    270314                return false;
     
    453497
    454498        return (b == tag);
     499}
     500
     501/*
     502 * just get the needed size the tag would consume
     503 */
     504bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag, size_t *size)
     505{
     506        off_t start_ofs = data->ofs;
     507        uint8_t b;
     508        size_t taglen = 0;
     509
     510        if (data->has_error) {
     511                return false;
     512        }
     513
     514        if (!asn1_read_uint8(data, &b)) {
     515                data->ofs = start_ofs;
     516                data->has_error = false;
     517                return false;
     518        }
     519
     520        if (b != tag) {
     521                data->ofs = start_ofs;
     522                data->has_error = false;
     523                return false;
     524        }
     525
     526        if (!asn1_read_uint8(data, &b)) {
     527                data->ofs = start_ofs;
     528                data->has_error = false;
     529                return false;
     530        }
     531
     532        if (b & 0x80) {
     533                int n = b & 0x7f;
     534                if (!asn1_read_uint8(data, &b)) {
     535                        data->ofs = start_ofs;
     536                        data->has_error = false;
     537                        return false;
     538                }
     539                if (n > 4) {
     540                        /*
     541                         * We should not allow more than 4 bytes
     542                         * for the encoding of the tag length.
     543                         *
     544                         * Otherwise we'd overflow the taglen
     545                         * variable on 32 bit systems.
     546                         */
     547                        data->ofs = start_ofs;
     548                        data->has_error = false;
     549                        return false;
     550                }
     551                taglen = b;
     552                while (n > 1) {
     553                        if (!asn1_read_uint8(data, &b)) {
     554                                data->ofs = start_ofs;
     555                                data->has_error = false;
     556                                return false;
     557                        }
     558                        taglen = (taglen << 8) | b;
     559                        n--;
     560                }
     561        } else {
     562                taglen = b;
     563        }
     564
     565        *size = (data->ofs - start_ofs) + taglen;
     566
     567        data->ofs = start_ofs;
     568        data->has_error = false;
     569        return true;
    455570}
    456571
     
    544659}
    545660
    546 /* read an object ID from a data blob */
    547 bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID)
     661/**
     662 * Internal implementation for reading binary OIDs
     663 * Reading is done as far in the buffer as valid OID
     664 * till buffer ends or not valid sub-identifier is found.
     665 */
     666static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
     667                                      char **OID, size_t *bytes_eaten)
    548668{
    549669        int i;
    550670        uint8_t *b;
    551         uint_t v;
     671        unsigned int v;
    552672        char *tmp_oid = NULL;
    553673
     
    560680        tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  b[0]%40);
    561681        if (!tmp_oid) goto nomem;
     682
     683        if (bytes_eaten != NULL) {
     684                *bytes_eaten = 0;
     685        }
    562686
    563687        for(i = 1, v = 0; i < blob.length; i++) {
     
    566690                        tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u",  v);
    567691                        v = 0;
     692                        if (bytes_eaten)
     693                                *bytes_eaten = i+1;
    568694                }
    569695                if (!tmp_oid) goto nomem;
    570696        }
    571697
    572         if (v != 0) {
    573                 talloc_free(tmp_oid);
    574                 return false;
    575         }
    576 
    577698        *OID = tmp_oid;
    578699        return true;
    579700
    580 nomem: 
     701nomem:
    581702        return false;
    582703}
    583704
     705/* read an object ID from a data blob */
     706bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID)
     707{
     708        size_t bytes_eaten;
     709
     710        if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
     711                return false;
     712
     713        return (bytes_eaten == blob.length);
     714}
     715
     716/**
     717 * Deserialize partial OID string.
     718 * Partial OIDs are in the form:
     719 *   1:2.5.6:0x81
     720 *   1:2.5.6:0x8182
     721 */
     722bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
     723                                 char **partial_oid)
     724{
     725        size_t bytes_left;
     726        size_t bytes_eaten;
     727        char *identifier = NULL;
     728        char *tmp_oid = NULL;
     729
     730        if (!_ber_read_OID_String_impl(mem_ctx, blob, &tmp_oid, &bytes_eaten))
     731                return false;
     732
     733        if (bytes_eaten < blob.length) {
     734                bytes_left = blob.length - bytes_eaten;
     735                identifier = hex_encode_talloc(mem_ctx, &blob.data[bytes_eaten], bytes_left);
     736                if (!identifier)        goto nomem;
     737
     738                *partial_oid = talloc_asprintf_append_buffer(tmp_oid, ":0x%s", identifier);
     739                if (!*partial_oid)      goto nomem;
     740                TALLOC_FREE(identifier);
     741        } else {
     742                *partial_oid = tmp_oid;
     743        }
     744
     745        return true;
     746
     747nomem:
     748        TALLOC_FREE(identifier);
     749        TALLOC_FREE(tmp_oid);
     750        return false;
     751}
     752
    584753/* read an object ID from a ASN1 buffer */
    585 bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, const char **OID)
     754bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID)
    586755{
    587756        DATA_BLOB blob;
     
    622791bool asn1_check_OID(struct asn1_data *data, const char *OID)
    623792{
    624         const char *id;
     793        char *id;
    625794
    626795        if (!asn1_read_OID(data, data, &id)) return false;
    627796
    628797        if (strcmp(id, OID) != 0) {
    629                 talloc_free(discard_const(id));
    630                 data->has_error = true;
    631                 return false;
    632         }
    633         talloc_free(discard_const(id));
     798                talloc_free(id);
     799                data->has_error = true;
     800                return false;
     801        }
     802        talloc_free(id);
    634803        return true;
    635804}
     
    8651034        if (size > blob.length) {
    8661035                return STATUS_MORE_ENTRIES;
    867         }               
     1036        }
    8681037
    8691038        *packet_size = size;
    8701039        return NT_STATUS_OK;
    8711040}
     1041
     1042NTSTATUS asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
     1043{
     1044        struct asn1_data asn1;
     1045        size_t size;
     1046        bool ok;
     1047
     1048        ZERO_STRUCT(asn1);
     1049        asn1.data = blob.data;
     1050        asn1.length = blob.length;
     1051
     1052        ok = asn1_peek_tag_needed_size(&asn1, tag, &size);
     1053        if (!ok) {
     1054                return NT_STATUS_INVALID_BUFFER_SIZE;
     1055        }
     1056
     1057        if (size > blob.length) {
     1058                *packet_size = size;
     1059                return STATUS_MORE_ENTRIES;
     1060        }               
     1061
     1062        *packet_size = size;
     1063        return NT_STATUS_OK;
     1064}
Note: See TracChangeset for help on using the changeset viewer.