Annotation of qemu/roms/ipxe/src/crypto/x509.c, revision 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.