Annotation of qemu/roms/ipxe/src/crypto/asn1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2007 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: #include <stdint.h>
                     22: #include <stddef.h>
                     23: #include <errno.h>
                     24: #include <ipxe/asn1.h>
                     25: 
                     26: /** @file
                     27:  *
                     28:  * ASN.1 encoding
                     29:  *
                     30:  */
                     31: 
                     32: /**
                     33:  * Start parsing ASN.1 object
                     34:  *
                     35:  * @v cursor           ASN.1 object cursor
                     36:  * @v type             Expected type
                     37:  * @ret len            Length of object body, or negative error
                     38:  *
                     39:  * The object cursor will be updated to point to the start of the
                     40:  * object body (i.e. the first byte following the length byte(s)), and
                     41:  * the length of the object body (i.e. the number of bytes until the
                     42:  * following object tag, if any) is returned.
                     43:  *
                     44:  * If any error occurs (i.e. if the object is not of the expected
                     45:  * type, or if we overflow beyond the end of the ASN.1 object), then
                     46:  * the cursor will be invalidated and a negative value will be
                     47:  * returned.
                     48:  */
                     49: static int asn1_start ( struct asn1_cursor *cursor,
                     50:                               unsigned int type ) {
                     51:        unsigned int len_len;
                     52:        unsigned int len;
                     53:        int rc;
                     54: 
                     55:        /* Sanity check */
                     56:        if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
                     57:                if ( cursor->len )
                     58:                        DBGC ( cursor, "ASN1 %p too short\n", cursor );
                     59:                rc = -EINVAL;
                     60:                goto notfound;
                     61:        }
                     62: 
                     63:        /* Check the tag byte */
                     64:        if ( *( ( uint8_t * ) cursor->data ) != type ) {
                     65:                DBGC ( cursor, "ASN1 %p type mismatch (expected %d, got %d)\n",
                     66:                       cursor, type, *( ( uint8_t * ) cursor->data ) );
                     67:                rc = -ENXIO;
                     68:                goto notfound;
                     69:        }
                     70:        cursor->data++;
                     71:        cursor->len--;
                     72: 
                     73:        /* Extract length of the length field and sanity check */
                     74:        len_len = *( ( uint8_t * ) cursor->data );
                     75:        if ( len_len & 0x80 ) {
                     76:                len_len = ( len_len & 0x7f );
                     77:                cursor->data++;
                     78:                cursor->len--;
                     79:        } else {
                     80:                len_len = 1;
                     81:        }
                     82:        if ( cursor->len < len_len ) {
                     83:                DBGC ( cursor, "ASN1 %p bad length field length %d (max "
                     84:                       "%zd)\n", cursor, len_len, cursor->len );
                     85:                rc = -EINVAL;
                     86:                goto notfound;
                     87:        }
                     88: 
                     89:        /* Extract the length and sanity check */
                     90:        for ( len = 0 ; len_len ; len_len-- ) {
                     91:                len <<= 8;
                     92:                len |= *( ( uint8_t * ) cursor->data );
                     93:                cursor->data++;
                     94:                cursor->len--;
                     95:        }
                     96:        if ( cursor->len < len ) {
                     97:                DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
                     98:                       cursor, len, cursor->len );
                     99:                rc = -EINVAL;
                    100:                goto notfound;
                    101:        }
                    102: 
                    103:        return len;
                    104: 
                    105:  notfound:
                    106:        cursor->data = NULL;
                    107:        cursor->len = 0;
                    108:        return rc;
                    109: }
                    110: 
                    111: /**
                    112:  * Enter ASN.1 object
                    113:  *
                    114:  * @v cursor           ASN.1 object cursor
                    115:  * @v type             Expected type
                    116:  * @ret rc             Return status code
                    117:  *
                    118:  * The object cursor will be updated to point to the body of the
                    119:  * current ASN.1 object.  If any error occurs, the object cursor will
                    120:  * be invalidated.
                    121:  */
                    122: int asn1_enter ( struct asn1_cursor *cursor, unsigned int type ) {
                    123:        int len;
                    124: 
                    125:        len = asn1_start ( cursor, type );
                    126:        if ( len < 0 )
                    127:                return len;
                    128: 
                    129:        cursor->len = len;
                    130:        DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n",
                    131:               cursor, type, len );
                    132: 
                    133:        return 0;
                    134: }
                    135: 
                    136: /**
                    137:  * Skip ASN.1 object
                    138:  *
                    139:  * @v cursor           ASN.1 object cursor
                    140:  * @v type             Expected type
                    141:  * @ret rc             Return status code
                    142:  *
                    143:  * The object cursor will be updated to point to the next ASN.1
                    144:  * object.  If any error occurs, the object cursor will be
                    145:  * invalidated.
                    146:  */
                    147: int asn1_skip ( struct asn1_cursor *cursor, unsigned int type ) {
                    148:        int len;
                    149: 
                    150:        len = asn1_start ( cursor, type );
                    151:        if ( len < 0 )
                    152:                return len;
                    153: 
                    154:        cursor->data += len;
                    155:        cursor->len -= len;
                    156:        DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n",
                    157:               cursor, type, len );
                    158: 
                    159:        if ( ! cursor->len ) {
                    160:                DBGC ( cursor, "ASN1 %p reached end of object\n", cursor );
                    161:                cursor->data = NULL;
                    162:                return -ENOENT;
                    163:        }
                    164: 
                    165:        return 0;
                    166: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.