… | |
… | |
263 | if (!(c & 0x80)) |
263 | if (!(c & 0x80)) |
264 | return res; |
264 | return res; |
265 | } |
265 | } |
266 | } |
266 | } |
267 | |
267 | |
|
|
268 | // get_w, but disallow padding |
|
|
269 | static UV |
|
|
270 | get_w_nopad (void) |
|
|
271 | { |
|
|
272 | U8 first = get_u8 (); |
|
|
273 | |
|
|
274 | if (first == 0x80) |
|
|
275 | error ("illegal BER padding"); |
|
|
276 | |
|
|
277 | --cur; |
|
|
278 | |
|
|
279 | return get_w (); |
|
|
280 | } |
|
|
281 | |
268 | static UV |
282 | static UV |
269 | get_length (void) |
283 | get_length (void) |
270 | { |
284 | { |
271 | UV res = get_u8 (); |
285 | UV res = get_u8 (); |
272 | |
286 | |
… | |
… | |
279 | { |
293 | { |
280 | case 0: |
294 | case 0: |
281 | error ("indefinite ASN.1 lengths not supported"); |
295 | error ("indefinite ASN.1 lengths not supported"); |
282 | return 0; |
296 | return 0; |
283 | |
297 | |
|
|
298 | //case 0x80: // indefinite length |
|
|
299 | |
|
|
300 | //case 0xff: reserved |
284 | default: |
301 | default: |
285 | error ("ASN.1 length too long"); |
302 | error ("ASN.1 length too long"); |
286 | return 0; |
303 | return 0; |
287 | |
304 | |
288 | case 8: res = (res << 8) | get_u8 (); |
305 | case 8: res = (res << 8) | get_u8 (); |
… | |
… | |
375 | error ("OBJECT IDENTIFIER length equal to zero"); |
392 | error ("OBJECT IDENTIFIER length equal to zero"); |
376 | return &PL_sv_undef; |
393 | return &PL_sv_undef; |
377 | } |
394 | } |
378 | |
395 | |
379 | U8 *end = cur + len; |
396 | U8 *end = cur + len; |
380 | UV w = get_w (); |
397 | UV w = get_w_nopad (); |
381 | |
398 | |
382 | static char oid[MAX_OID_STRLEN]; // static, becaueds too large for stack |
399 | static char oid[MAX_OID_STRLEN]; // static, becaueds too large for stack |
383 | char *app = oid; |
400 | char *app = oid; |
384 | |
401 | |
385 | if (relative) |
402 | if (relative) |
386 | app = write_uv (app, w); |
403 | app = write_uv (app, w); |
387 | else |
404 | else if (w < 2 * 40) |
388 | { |
405 | { |
389 | app = write_uv (app, (U8)w / 40); |
406 | app = write_uv (app, (U8)w / 40); |
390 | *app++ = '.'; |
407 | *app++ = '.'; |
391 | app = write_uv (app, (U8)w % 40); |
408 | app = write_uv (app, (U8)w % 40); |
392 | } |
409 | } |
|
|
410 | else |
|
|
411 | { |
|
|
412 | app = write_uv (app, 2); |
|
|
413 | *app++ = '.'; |
|
|
414 | app = write_uv (app, w - 2 * 40); |
|
|
415 | } |
393 | |
416 | |
394 | while (cur < end) |
417 | while (cur < end) |
395 | { |
418 | { |
396 | // we assume an oid component is never > 64 digits |
419 | // we assume an oid component is never > 64 digits |
397 | if (oid + sizeof (oid) - app < 64) |
420 | if (oid + sizeof (oid) - app < 64) |
398 | croak ("BER_TYPE_OID to long to decode"); |
421 | croak ("BER_TYPE_OID to long to decode"); |
399 | |
422 | |
400 | w = get_w (); |
423 | w = get_w_nopad (); |
401 | *app++ = '.'; |
424 | *app++ = '.'; |
402 | app = write_uv (app, w); |
425 | app = write_uv (app, w); |
403 | } |
426 | } |
404 | |
427 | |
405 | return newSVpvn (oid, app - oid); |
428 | return newSVpvn (oid, app - oid); |