Annotation of qemu/roms/ipxe/src/crypto/x509.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 <stdlib.h>
                     22: #include <string.h>
                     23: #include <errno.h>
                     24: #include <ipxe/asn1.h>
                     25: #include <ipxe/x509.h>
                     26: 
                     27: /** @file
                     28:  *
                     29:  * X.509 certificates
                     30:  *
                     31:  * The structure of X.509v3 certificates is concisely documented in
                     32:  * RFC5280 section 4.1.  The structure of RSA public keys is
                     33:  * documented in RFC2313.
                     34:  */
                     35: 
                     36: /** Object Identifier for "rsaEncryption" (1.2.840.113549.1.1.1) */
                     37: static const uint8_t oid_rsa_encryption[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7,
                     38:                                              0x0d, 0x01, 0x01, 0x01 };
                     39: 
                     40: /**
                     41:  * Identify X.509 certificate public key
                     42:  *
                     43:  * @v certificate      Certificate
                     44:  * @v algorithm                Public key algorithm to fill in
                     45:  * @v pubkey           Public key value to fill in
                     46:  * @ret rc             Return status code
                     47:  */
                     48: static int x509_public_key ( const struct asn1_cursor *certificate,
                     49:                             struct asn1_cursor *algorithm,
                     50:                             struct asn1_cursor *pubkey ) {
                     51:        struct asn1_cursor cursor;
                     52:        int rc;
                     53: 
                     54:        /* Locate subjectPublicKeyInfo */
                     55:        memcpy ( &cursor, certificate, sizeof ( cursor ) );
                     56:        rc = ( asn1_enter ( &cursor, ASN1_SEQUENCE ), /* Certificate */
                     57:               asn1_enter ( &cursor, ASN1_SEQUENCE ), /* tbsCertificate */
                     58:               asn1_skip ( &cursor, ASN1_EXPLICIT_TAG ), /* version */
                     59:               asn1_skip ( &cursor, ASN1_INTEGER ), /* serialNumber */
                     60:               asn1_skip ( &cursor, ASN1_SEQUENCE ), /* signature */
                     61:               asn1_skip ( &cursor, ASN1_SEQUENCE ), /* issuer */
                     62:               asn1_skip ( &cursor, ASN1_SEQUENCE ), /* validity */
                     63:               asn1_skip ( &cursor, ASN1_SEQUENCE ), /* name */
                     64:               asn1_enter ( &cursor, ASN1_SEQUENCE )/* subjectPublicKeyInfo*/);
                     65:        if ( rc != 0 ) {
                     66:                DBG ( "Cannot locate subjectPublicKeyInfo in:\n" );
                     67:                DBG_HDA ( 0, certificate->data, certificate->len );
                     68:                return rc;
                     69:        }
                     70: 
                     71:        /* Locate algorithm */
                     72:        memcpy ( algorithm, &cursor, sizeof ( *algorithm ) );
                     73:        rc = ( asn1_enter ( algorithm, ASN1_SEQUENCE ) /* algorithm */ );
                     74:        if ( rc != 0 ) {
                     75:                DBG ( "Cannot locate algorithm in:\n" );
                     76:                DBG_HDA ( 0, certificate->data, certificate->len );
                     77:                return rc;
                     78:        }
                     79: 
                     80:        /* Locate subjectPublicKey */
                     81:        memcpy ( pubkey, &cursor, sizeof ( *pubkey ) );
                     82:        rc = ( asn1_skip ( pubkey, ASN1_SEQUENCE ), /* algorithm */
                     83:               asn1_enter ( pubkey, ASN1_BIT_STRING ) /* subjectPublicKey*/ );
                     84:        if ( rc != 0 ) {
                     85:                DBG ( "Cannot locate subjectPublicKey in:\n" );
                     86:                DBG_HDA ( 0, certificate->data, certificate->len );
                     87:                return rc;
                     88:        }
                     89: 
                     90:        return 0;
                     91: }
                     92: 
                     93: /**
                     94:  * Identify X.509 certificate RSA modulus and public exponent
                     95:  *
                     96:  * @v certificate      Certificate
                     97:  * @v rsa              RSA public key to fill in
                     98:  * @ret rc             Return status code
                     99:  *
                    100:  * The caller is responsible for eventually calling
                    101:  * x509_free_rsa_public_key() to free the storage allocated to hold
                    102:  * the RSA modulus and exponent.
                    103:  */
                    104: int x509_rsa_public_key ( const struct asn1_cursor *certificate,
                    105:                          struct x509_rsa_public_key *rsa_pubkey ) {
                    106:        struct asn1_cursor algorithm;
                    107:        struct asn1_cursor pubkey;
                    108:        struct asn1_cursor modulus;
                    109:        struct asn1_cursor exponent;
                    110:        int rc;
                    111: 
                    112:        /* First, extract the public key algorithm and key data */
                    113:        if ( ( rc = x509_public_key ( certificate, &algorithm,
                    114:                                      &pubkey ) ) != 0 )
                    115:                return rc;
                    116: 
                    117:        /* Check that algorithm is RSA */
                    118:        rc = ( asn1_enter ( &algorithm, ASN1_OID ) /* algorithm */ );
                    119:        if ( rc != 0 ) {
                    120:                DBG ( "Cannot locate algorithm:\n" );
                    121:                DBG_HDA ( 0, certificate->data, certificate->len );
                    122:        return rc;
                    123:        }
                    124:        if ( ( algorithm.len != sizeof ( oid_rsa_encryption ) ) ||
                    125:             ( memcmp ( algorithm.data, &oid_rsa_encryption,
                    126:                        sizeof ( oid_rsa_encryption ) ) != 0 ) ) {
                    127:                DBG ( "algorithm is not rsaEncryption in:\n" );
                    128:                DBG_HDA ( 0, certificate->data, certificate->len );
                    129:                return -ENOTSUP;
                    130:        }
                    131: 
                    132:        /* Check that public key is a byte string, i.e. that the
                    133:         * "unused bits" byte contains zero.
                    134:         */
                    135:        if ( ( pubkey.len < 1 ) ||
                    136:             ( ( *( uint8_t * ) pubkey.data ) != 0 ) ) {
                    137:                DBG ( "subjectPublicKey is not a byte string in:\n" );
                    138:                DBG_HDA ( 0, certificate->data, certificate->len );
                    139:                return -ENOTSUP;
                    140:        }
                    141:        pubkey.data++;
                    142:        pubkey.len--;
                    143: 
                    144:        /* Pick out the modulus and exponent */
                    145:        rc = ( asn1_enter ( &pubkey, ASN1_SEQUENCE ) /* RSAPublicKey */ );
                    146:        if ( rc != 0 ) {
                    147:                DBG ( "Cannot locate RSAPublicKey in:\n" );
                    148:                DBG_HDA ( 0, certificate->data, certificate->len );
                    149:                return -ENOTSUP;
                    150:        }
                    151:        memcpy ( &modulus, &pubkey, sizeof ( modulus ) );
                    152:        rc = ( asn1_enter ( &modulus, ASN1_INTEGER ) /* modulus */ );
                    153:        if ( rc != 0 ) {
                    154:                DBG ( "Cannot locate modulus in:\n" );
                    155:                DBG_HDA ( 0, certificate->data, certificate->len );
                    156:                return -ENOTSUP;
                    157:        }
                    158:        memcpy ( &exponent, &pubkey, sizeof ( exponent ) );
                    159:        rc = ( asn1_skip ( &exponent, ASN1_INTEGER ), /* modulus */
                    160:               asn1_enter ( &exponent, ASN1_INTEGER ) /* publicExponent */ );
                    161:        if ( rc != 0 ) {
                    162:                DBG ( "Cannot locate publicExponent in:\n" );
                    163:                DBG_HDA ( 0, certificate->data, certificate->len );
                    164:                return -ENOTSUP;
                    165:        }
                    166: 
                    167:        /* Allocate space and copy out modulus and exponent */
                    168:        rsa_pubkey->modulus = malloc ( modulus.len + exponent.len );
                    169:        if ( ! rsa_pubkey->modulus )
                    170:                return -ENOMEM;
                    171:        rsa_pubkey->exponent = ( rsa_pubkey->modulus + modulus.len );
                    172:        memcpy ( rsa_pubkey->modulus, modulus.data, modulus.len );
                    173:        rsa_pubkey->modulus_len = modulus.len;
                    174:        memcpy ( rsa_pubkey->exponent, exponent.data, exponent.len );
                    175:        rsa_pubkey->exponent_len = exponent.len;
                    176: 
                    177:        DBG2 ( "RSA modulus:\n" );
                    178:        DBG2_HDA ( 0, rsa_pubkey->modulus, rsa_pubkey->modulus_len );
                    179:        DBG2 ( "RSA exponent:\n" );
                    180:        DBG2_HDA ( 0, rsa_pubkey->exponent, rsa_pubkey->exponent_len );
                    181: 
                    182:        return 0;
                    183: }

unix.superglobalmegacorp.com

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