Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/clispnego.c

    r746 r988  
    2727
    2828/*
    29   generate a negTokenInit packet given a list of supported
    30   OIDs (the mechanisms) a blob, and a principal name string
    31 */
    32 
    33 DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
    34                                   const char *OIDs[],
    35                                   DATA_BLOB *psecblob,
    36                                   const char *principal)
    37 {
    38         int i;
    39         ASN1_DATA *data;
    40         DATA_BLOB ret;
    41 
    42         data = asn1_init(talloc_tos());
    43         if (data == NULL) {
    44                 return data_blob_null;
    45         }
    46 
    47         asn1_push_tag(data,ASN1_APPLICATION(0));
    48         asn1_write_OID(data,OID_SPNEGO);
    49         asn1_push_tag(data,ASN1_CONTEXT(0));
    50         asn1_push_tag(data,ASN1_SEQUENCE(0));
    51 
    52         asn1_push_tag(data,ASN1_CONTEXT(0));
    53         asn1_push_tag(data,ASN1_SEQUENCE(0));
    54         for (i=0; OIDs[i]; i++) {
    55                 asn1_write_OID(data,OIDs[i]);
    56         }
    57         asn1_pop_tag(data);
    58         asn1_pop_tag(data);
    59 
    60         if (psecblob && psecblob->length && psecblob->data) {
    61                 asn1_push_tag(data, ASN1_CONTEXT(2));
    62                 asn1_write_OctetString(data,psecblob->data,
    63                         psecblob->length);
    64                 asn1_pop_tag(data);
    65         }
    66 
    67         if (principal) {
    68                 asn1_push_tag(data, ASN1_CONTEXT(3));
    69                 asn1_push_tag(data, ASN1_SEQUENCE(0));
    70                 asn1_push_tag(data, ASN1_CONTEXT(0));
    71                 asn1_write_GeneralString(data,principal);
    72                 asn1_pop_tag(data);
    73                 asn1_pop_tag(data);
    74                 asn1_pop_tag(data);
    75         }
    76 
    77         asn1_pop_tag(data);
    78         asn1_pop_tag(data);
    79 
    80         asn1_pop_tag(data);
    81 
    82         if (data->has_error) {
    83                 DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs));
    84         }
    85 
    86         ret = data_blob_talloc(ctx, data->data, data->length);
    87         asn1_free(data);
    88 
    89         return ret;
    90 }
    91 
    92 /*
    9329  parse a negTokenInit packet giving a GUID, a list of supported
    9430  OIDs (the mechanisms) and a principal name string
     
    10137{
    10238        int i;
    103         bool ret;
     39        bool ret = false;
    10440        ASN1_DATA *data;
    10541
    10642        for (i = 0; i < ASN1_MAX_OIDS; i++) {
    10743                OIDs[i] = NULL;
     44        }
     45
     46        if (principal) {
     47                *principal = NULL;
     48        }
     49        if (secblob) {
     50                *secblob = data_blob_null;
    10851        }
    10952
     
    11356        }
    11457
    115         asn1_load(data, blob);
    116 
    117         asn1_start_tag(data,ASN1_APPLICATION(0));
    118 
    119         asn1_check_OID(data,OID_SPNEGO);
     58        if (!asn1_load(data, blob)) goto err;
     59
     60        if (!asn1_start_tag(data,ASN1_APPLICATION(0))) goto err;
     61
     62        if (!asn1_check_OID(data,OID_SPNEGO)) goto err;
    12063
    12164        /* negTokenInit  [0]  NegTokenInit */
    122         asn1_start_tag(data,ASN1_CONTEXT(0));
    123         asn1_start_tag(data,ASN1_SEQUENCE(0));
     65        if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err;
     66        if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err;
    12467
    12568        /* mechTypes [0] MechTypeList  OPTIONAL */
     
    12871         * what mechanisms we have to work with. */
    12972
    130         asn1_start_tag(data,ASN1_CONTEXT(0));
    131         asn1_start_tag(data,ASN1_SEQUENCE(0));
     73        if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err;
     74        if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err;
    13275        for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
    133                 asn1_read_OID(data,ctx, &OIDs[i]);
    134                 if (data->has_error) {
    135                         break;
     76                if (!asn1_read_OID(data,ctx, &OIDs[i])) {
     77                        goto err;
     78                }
     79                if (asn1_has_error(data)) {
     80                        goto err;
    13681                }
    13782        }
    13883        OIDs[i] = NULL;
    139         asn1_end_tag(data);
    140         asn1_end_tag(data);
    141 
    142         if (principal) {
    143                 *principal = NULL;
    144         }
    145         if (secblob) {
    146                 *secblob = data_blob_null;
    147         }
     84        if (!asn1_end_tag(data)) goto err;
     85        if (!asn1_end_tag(data)) goto err;
    14886
    14987        /*
     
    15593
    15694        if (asn1_peek_tag(data, ASN1_CONTEXT(1))) {
    157                 uint8 flags;
     95                uint8_t flags;
    15896
    15997                /* reqFlags [1] ContextFlags  OPTIONAL */
    160                 asn1_start_tag(data, ASN1_CONTEXT(1));
    161                 asn1_start_tag(data, ASN1_BIT_STRING);
     98                if (!asn1_start_tag(data, ASN1_CONTEXT(1))) goto err;
     99                if (!asn1_start_tag(data, ASN1_BIT_STRING)) goto err;
    162100                while (asn1_tag_remaining(data) > 0) {
    163                         asn1_read_uint8(data, &flags);
    164                 }
    165                 asn1_end_tag(data);
    166                 asn1_end_tag(data);
     101                        if (!asn1_read_uint8(data, &flags)) goto err;
     102                }
     103                if (!asn1_end_tag(data)) goto err;
     104                if (!asn1_end_tag(data)) goto err;
    167105        }
    168106
     
    170108                DATA_BLOB sblob = data_blob_null;
    171109                /* mechToken [2] OCTET STRING  OPTIONAL */
    172                 asn1_start_tag(data, ASN1_CONTEXT(2));
    173                 asn1_read_OctetString(data, ctx, &sblob);
    174                 asn1_end_tag(data);
     110                if (!asn1_start_tag(data, ASN1_CONTEXT(2))) goto err;
     111                if (!asn1_read_OctetString(data, ctx, &sblob)) goto err;
     112                if (!asn1_end_tag(data)) {
     113                        data_blob_free(&sblob);
     114                        goto err;
     115                }
    175116                if (secblob) {
    176117                        *secblob = sblob;
     
    183124                char *princ = NULL;
    184125                /* mechListMIC [3] OCTET STRING  OPTIONAL */
    185                 asn1_start_tag(data, ASN1_CONTEXT(3));
    186                 asn1_start_tag(data, ASN1_SEQUENCE(0));
    187                 asn1_start_tag(data, ASN1_CONTEXT(0));
    188                 asn1_read_GeneralString(data, ctx, &princ);
    189                 asn1_end_tag(data);
    190                 asn1_end_tag(data);
    191                 asn1_end_tag(data);
     126                if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto err;
     127                if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto err;
     128                if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto err;
     129                if (!asn1_read_GeneralString(data, ctx, &princ)) goto err;
     130                if (!asn1_end_tag(data)) goto err;
     131                if (!asn1_end_tag(data)) goto err;
     132                if (!asn1_end_tag(data)) goto err;
    192133                if (principal) {
    193134                        *principal = princ;
     
    197138        }
    198139
    199         asn1_end_tag(data);
    200         asn1_end_tag(data);
    201 
    202         asn1_end_tag(data);
    203 
    204         ret = !data->has_error;
    205         if (data->has_error) {
     140        if (!asn1_end_tag(data)) goto err;
     141        if (!asn1_end_tag(data)) goto err;
     142
     143        if (!asn1_end_tag(data)) goto err;
     144
     145        ret = !asn1_has_error(data);
     146
     147  err:
     148
     149        if (asn1_has_error(data)) {
    206150                int j;
    207151                if (principal) {
     
    223167  generate a krb5 GSS-API wrapper packet given a ticket
    224168*/
    225 DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2])
     169DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8_t tok_id[2])
    226170{
    227171        ASN1_DATA *data;
    228         DATA_BLOB ret;
     172        DATA_BLOB ret = data_blob_null;
    229173
    230174        data = asn1_init(talloc_tos());
     
    233177        }
    234178
    235         asn1_push_tag(data, ASN1_APPLICATION(0));
    236         asn1_write_OID(data, OID_KERBEROS5);
    237 
    238         asn1_write(data, tok_id, 2);
    239         asn1_write(data, ticket.data, ticket.length);
    240         asn1_pop_tag(data);
    241 
    242         if (data->has_error) {
    243                 DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
    244         }
    245 
    246         ret = data_blob_talloc(ctx, data->data, data->length);
     179        if (!asn1_push_tag(data, ASN1_APPLICATION(0))) goto err;
     180        if (!asn1_write_OID(data, OID_KERBEROS5)) goto err;
     181
     182        if (!asn1_write(data, tok_id, 2)) goto err;
     183        if (!asn1_write(data, ticket.data, ticket.length)) goto err;
     184        if (!asn1_pop_tag(data)) goto err;
     185
     186        if (!asn1_extract_blob(data, ctx, &ret)) {
     187                goto err;
     188        }
     189
    247190        asn1_free(data);
     191        data = NULL;
     192
     193  err:
     194
     195        if (data != NULL) {
     196                if (asn1_has_error(data)) {
     197                        DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n",
     198                                  (int)asn1_current_ofs(data)));
     199                }
     200
     201                asn1_free(data);
     202        }
    248203
    249204        return ret;
    250205}
    251 
    252 /*
    253   parse a krb5 GSS-API wrapper packet giving a ticket
    254 */
    255 bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
    256 {
    257         bool ret;
    258         ASN1_DATA *data;
    259         int data_remaining;
    260         *ticket = data_blob_null;
    261 
    262         data = asn1_init(talloc_tos());
    263         if (data == NULL) {
    264                 return false;
    265         }
    266 
    267         asn1_load(data, blob);
    268         asn1_start_tag(data, ASN1_APPLICATION(0));
    269         asn1_check_OID(data, OID_KERBEROS5);
    270 
    271         data_remaining = asn1_tag_remaining(data);
    272 
    273         if (data_remaining < 3) {
    274                 data->has_error = True;
    275         } else {
    276                 asn1_read(data, tok_id, 2);
    277                 data_remaining -= 2;
    278                 *ticket = data_blob_talloc(ctx, NULL, data_remaining);
    279                 asn1_read(data, ticket->data, ticket->length);
    280         }
    281 
    282         asn1_end_tag(data);
    283 
    284         ret = !data->has_error;
    285 
    286         if (data->has_error) {
    287                 data_blob_free(ticket);
    288         }
    289 
    290         asn1_free(data);
    291 
    292         return ret;
    293 }
    294 
    295 
    296 /*
    297    generate a SPNEGO krb5 negTokenInit packet, ready for a EXTENDED_SECURITY
    298    kerberos session setup
    299 */
    300 int spnego_gen_krb5_negTokenInit(TALLOC_CTX *ctx,
    301                             const char *principal, int time_offset,
    302                             DATA_BLOB *targ,
    303                             DATA_BLOB *session_key_krb5, uint32 extra_ap_opts,
    304                             time_t *expire_time)
    305 {
    306         int retval;
    307         DATA_BLOB tkt, tkt_wrapped;
    308         const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL};
    309 
    310         /* get a kerberos ticket for the service and extract the session key */
    311         retval = cli_krb5_get_ticket(ctx, principal, time_offset,
    312                                           &tkt, session_key_krb5,
    313                                           extra_ap_opts, NULL,
    314                                           expire_time, NULL);
    315         if (retval) {
    316                 return retval;
    317         }
    318 
    319         /* wrap that up in a nice GSS-API wrapping */
    320         tkt_wrapped = spnego_gen_krb5_wrap(ctx, tkt, TOK_ID_KRB_AP_REQ);
    321 
    322         /* and wrap that in a shiny SPNEGO wrapper */
    323         *targ = spnego_gen_negTokenInit(ctx, krb_mechs, &tkt_wrapped, NULL);
    324 
    325         data_blob_free(&tkt_wrapped);
    326         data_blob_free(&tkt);
    327 
    328         return retval;
    329 }
    330 
    331 
    332 /*
    333   parse a spnego NTLMSSP challenge packet giving two security blobs
    334 */
    335 bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
    336                             DATA_BLOB *chal1, DATA_BLOB *chal2)
    337 {
    338         bool ret;
    339         ASN1_DATA *data;
    340 
    341         ZERO_STRUCTP(chal1);
    342         ZERO_STRUCTP(chal2);
    343 
    344         data = asn1_init(talloc_tos());
    345         if (data == NULL) {
    346                 return false;
    347         }
    348 
    349         asn1_load(data, blob);
    350         asn1_start_tag(data,ASN1_CONTEXT(1));
    351         asn1_start_tag(data,ASN1_SEQUENCE(0));
    352 
    353         asn1_start_tag(data,ASN1_CONTEXT(0));
    354         asn1_check_enumerated(data,1);
    355         asn1_end_tag(data);
    356 
    357         asn1_start_tag(data,ASN1_CONTEXT(1));
    358         asn1_check_OID(data, OID_NTLMSSP);
    359         asn1_end_tag(data);
    360 
    361         asn1_start_tag(data,ASN1_CONTEXT(2));
    362         asn1_read_OctetString(data, ctx, chal1);
    363         asn1_end_tag(data);
    364 
    365         /* the second challenge is optional (XP doesn't send it) */
    366         if (asn1_tag_remaining(data)) {
    367                 asn1_start_tag(data,ASN1_CONTEXT(3));
    368                 asn1_read_OctetString(data, ctx, chal2);
    369                 asn1_end_tag(data);
    370         }
    371 
    372         asn1_end_tag(data);
    373         asn1_end_tag(data);
    374 
    375         ret = !data->has_error;
    376 
    377         if (data->has_error) {
    378                 data_blob_free(chal1);
    379                 data_blob_free(chal2);
    380         }
    381 
    382         asn1_free(data);
    383         return ret;
    384 }
    385 
    386 
    387 /*
    388  generate a SPNEGO auth packet. This will contain the encrypted passwords
    389 */
    390 DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
    391 {
    392         ASN1_DATA *data;
    393         DATA_BLOB ret;
    394 
    395         data = asn1_init(talloc_tos());
    396         if (data == NULL) {
    397                 return data_blob_null;
    398         }
    399 
    400         asn1_push_tag(data, ASN1_CONTEXT(1));
    401         asn1_push_tag(data, ASN1_SEQUENCE(0));
    402         asn1_push_tag(data, ASN1_CONTEXT(2));
    403         asn1_write_OctetString(data,blob.data,blob.length);
    404         asn1_pop_tag(data);
    405         asn1_pop_tag(data);
    406         asn1_pop_tag(data);
    407 
    408         ret = data_blob_talloc(ctx, data->data, data->length);
    409 
    410         asn1_free(data);
    411 
    412         return ret;
    413 }
    414 
    415 /*
    416  parse a SPNEGO auth packet. This contains the encrypted passwords
    417 */
    418 bool spnego_parse_auth_and_mic(TALLOC_CTX *ctx, DATA_BLOB blob,
    419                                 DATA_BLOB *auth, DATA_BLOB *signature)
    420 {
    421         ssize_t len;
    422         struct spnego_data token;
    423 
    424         len = spnego_read_data(talloc_tos(), blob, &token);
    425         if (len == -1) {
    426                 DEBUG(3,("spnego_parse_auth: spnego_read_data failed\n"));
    427                 return false;
    428         }
    429 
    430         if (token.type != SPNEGO_NEG_TOKEN_TARG) {
    431                 DEBUG(3,("spnego_parse_auth: wrong token type: %d\n",
    432                         token.type));
    433                 spnego_free_data(&token);
    434                 return false;
    435         }
    436 
    437         *auth = data_blob_talloc(ctx,
    438                                  token.negTokenTarg.responseToken.data,
    439                                  token.negTokenTarg.responseToken.length);
    440 
    441         if (!signature) {
    442                 goto done;
    443         }
    444 
    445         *signature = data_blob_talloc(ctx,
    446                                  token.negTokenTarg.mechListMIC.data,
    447                                  token.negTokenTarg.mechListMIC.length);
    448 
    449 done:
    450         spnego_free_data(&token);
    451 
    452         return true;
    453 }
    454 
    455 bool spnego_parse_auth(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *auth)
    456 {
    457         return spnego_parse_auth_and_mic(ctx, blob, auth, NULL);
    458 }
    459 
    460 /*
    461   generate a minimal SPNEGO response packet.  Doesn't contain much.
    462 */
    463 DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx,
    464                                            NTSTATUS nt_status,
    465                                            const char *mechOID,
    466                                            DATA_BLOB *reply,
    467                                            DATA_BLOB *mechlistMIC)
    468 {
    469         ASN1_DATA *data;
    470         DATA_BLOB ret;
    471         uint8 negResult;
    472 
    473         if (NT_STATUS_IS_OK(nt_status)) {
    474                 negResult = SPNEGO_ACCEPT_COMPLETED;
    475         } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    476                 negResult = SPNEGO_ACCEPT_INCOMPLETE;
    477         } else {
    478                 negResult = SPNEGO_REJECT;
    479         }
    480 
    481         data = asn1_init(talloc_tos());
    482         if (data == NULL) {
    483                 return data_blob_null;
    484         }
    485 
    486         asn1_push_tag(data, ASN1_CONTEXT(1));
    487         asn1_push_tag(data, ASN1_SEQUENCE(0));
    488         asn1_push_tag(data, ASN1_CONTEXT(0));
    489         asn1_write_enumerated(data, negResult);
    490         asn1_pop_tag(data);
    491 
    492         if (mechOID) {
    493                 asn1_push_tag(data,ASN1_CONTEXT(1));
    494                 asn1_write_OID(data, mechOID);
    495                 asn1_pop_tag(data);
    496         }
    497 
    498         if (reply && reply->data != NULL) {
    499                 asn1_push_tag(data,ASN1_CONTEXT(2));
    500                 asn1_write_OctetString(data, reply->data, reply->length);
    501                 asn1_pop_tag(data);
    502         }
    503 
    504         if (mechlistMIC && mechlistMIC->data != NULL) {
    505                 asn1_push_tag(data, ASN1_CONTEXT(3));
    506                 asn1_write_OctetString(data,
    507                                         mechlistMIC->data,
    508                                         mechlistMIC->length);
    509                 asn1_pop_tag(data);
    510         }
    511 
    512         asn1_pop_tag(data);
    513         asn1_pop_tag(data);
    514 
    515         ret = data_blob_talloc(ctx, data->data, data->length);
    516         asn1_free(data);
    517         return ret;
    518 }
    519 
    520 DATA_BLOB spnego_gen_auth_response(TALLOC_CTX *ctx, DATA_BLOB *reply,
    521                                    NTSTATUS nt_status, const char *mechOID)
    522 {
    523         return spnego_gen_auth_response_and_mic(ctx, nt_status,
    524                                                 mechOID, reply, NULL);
    525 }
    526 
    527 /*
    528  parse a SPNEGO auth packet. This contains the encrypted passwords
    529 */
    530 bool spnego_parse_auth_response(TALLOC_CTX *ctx,
    531                                 DATA_BLOB blob, NTSTATUS nt_status,
    532                                 const char *mechOID,
    533                                 DATA_BLOB *auth)
    534 {
    535         ASN1_DATA *data;
    536         uint8 negResult;
    537 
    538         if (NT_STATUS_IS_OK(nt_status)) {
    539                 negResult = SPNEGO_ACCEPT_COMPLETED;
    540         } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    541                 negResult = SPNEGO_ACCEPT_INCOMPLETE;
    542         } else {
    543                 negResult = SPNEGO_REJECT;
    544         }
    545 
    546         data = asn1_init(talloc_tos());
    547         if (data == NULL) {
    548                 return false;
    549         }
    550 
    551         asn1_load(data, blob);
    552         asn1_start_tag(data, ASN1_CONTEXT(1));
    553         asn1_start_tag(data, ASN1_SEQUENCE(0));
    554         asn1_start_tag(data, ASN1_CONTEXT(0));
    555         asn1_check_enumerated(data, negResult);
    556         asn1_end_tag(data);
    557 
    558         *auth = data_blob_null;
    559 
    560         if (asn1_tag_remaining(data)) {
    561                 asn1_start_tag(data,ASN1_CONTEXT(1));
    562                 asn1_check_OID(data, mechOID);
    563                 asn1_end_tag(data);
    564 
    565                 if (asn1_tag_remaining(data)) {
    566                         asn1_start_tag(data,ASN1_CONTEXT(2));
    567                         asn1_read_OctetString(data, ctx, auth);
    568                         asn1_end_tag(data);
    569                 }
    570         } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) {
    571                 data->has_error = 1;
    572         }
    573 
    574         /* Binding against Win2K DC returns a duplicate of the responseToken in
    575          * the optional mechListMIC field. This is a bug in Win2K. We ignore
    576          * this field if it exists. Win2K8 may return a proper mechListMIC at
    577          * which point we need to implement the integrity checking. */
    578         if (asn1_tag_remaining(data)) {
    579                 DATA_BLOB mechList = data_blob_null;
    580                 asn1_start_tag(data, ASN1_CONTEXT(3));
    581                 asn1_read_OctetString(data, ctx, &mechList);
    582                 asn1_end_tag(data);
    583                 data_blob_free(&mechList);
    584                 DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
    585                     "ignoring.\n"));
    586         }
    587 
    588         asn1_end_tag(data);
    589         asn1_end_tag(data);
    590 
    591         if (data->has_error) {
    592                 DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data->ofs));
    593                 asn1_free(data);
    594                 data_blob_free(auth);
    595                 return False;
    596         }
    597 
    598         asn1_free(data);
    599         return True;
    600 }
    601 
    602 bool spnego_mech_list_blob(TALLOC_CTX *mem_ctx,
    603                            char **oid_list, DATA_BLOB *raw_data)
    604 {
    605         ASN1_DATA *data;
    606         unsigned int idx;
    607 
    608         if (!oid_list || !oid_list[0] || !raw_data) {
    609                 return false;
    610         }
    611 
    612         data = asn1_init(talloc_tos());
    613         if (data == NULL) {
    614                 return false;
    615         }
    616 
    617         asn1_push_tag(data, ASN1_SEQUENCE(0));
    618         for (idx = 0; oid_list[idx]; idx++) {
    619                 asn1_write_OID(data, oid_list[idx]);
    620         }
    621         asn1_pop_tag(data);
    622 
    623         if (data->has_error) {
    624                 DEBUG(3, (__location__ " failed at %d\n", (int)data->ofs));
    625                 asn1_free(data);
    626                 return false;
    627         }
    628 
    629         *raw_data = data_blob_talloc(mem_ctx, data->data, data->length);
    630         if (!raw_data->data) {
    631                 DEBUG(3, (__location__": data_blob_talloc() failed!\n"));
    632                 asn1_free(data);
    633                 return false;
    634         }
    635 
    636         asn1_free(data);
    637         return true;
    638 }
Note: See TracChangeset for help on using the changeset viewer.