Annotation of embedaddon/strongswan/src/libstrongswan/plugins/pem/pem_encoder.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2010-2016 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "pem_encoder.h"
                     17: 
                     18: #include <library.h>
                     19: 
                     20: #define BYTES_PER_LINE 48
                     21: 
                     22: /**
                     23:  * See header.
                     24:  */
                     25: bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
                     26:                                                va_list args)
                     27: {
                     28:        chunk_t asn1;
                     29:        char *label;
                     30:        u_char *pos;
                     31:        size_t len, written, pem_chars, pem_lines;
                     32:        chunk_t n, e, d, p, q, exp1, exp2, coeff, to_free = chunk_empty;
                     33: 
                     34:        switch (type)
                     35:        {
                     36:                case PUBKEY_PEM:
                     37:                        label ="PUBLIC KEY";
                     38:                        /* direct PKCS#1 PEM encoding */
                     39:                        if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER,
                     40:                                                                        &asn1, CRED_PART_END) ||
                     41:                                cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER,
                     42:                                                                        &asn1, CRED_PART_END) ||
                     43:                                cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER,
                     44:                                                                        &asn1, CRED_PART_END) ||
                     45:                                cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER,
                     46:                                                                   &asn1, CRED_PART_END))
                     47:                        {
                     48:                                break;
                     49:                        }
                     50:                        /* indirect PEM encoding from components */
                     51:                        if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n,
                     52:                                                                        CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END))
                     53:                        {
                     54:                                if (lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER,
                     55:                                                                        NULL, &asn1, CRED_PART_RSA_MODULUS, n,
                     56:                                                                        CRED_PART_RSA_PUB_EXP, e, CRED_PART_END))
                     57:                                {
                     58:                                        to_free = asn1;
                     59:                                        break;
                     60:                                }
                     61:                        }
                     62:                        return FALSE;
                     63:                case PRIVKEY_PEM:
                     64:                        label ="RSA PRIVATE KEY";
                     65:                        /* direct PKCS#1 PEM encoding */
                     66:                        if (cred_encoding_args(args, CRED_PART_RSA_PRIV_ASN1_DER,
                     67:                                                                        &asn1, CRED_PART_END))
                     68:                        {
                     69:                                break;
                     70:                        }
                     71:                        /* indirect PEM encoding from components */
                     72:                        if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n,
                     73:                                                CRED_PART_RSA_PUB_EXP, &e, CRED_PART_RSA_PRIV_EXP, &d,
                     74:                                                CRED_PART_RSA_PRIME1, &p, CRED_PART_RSA_PRIME2, &q,
                     75:                                                CRED_PART_RSA_EXP1, &exp1, CRED_PART_RSA_EXP2, &exp2,
                     76:                                                CRED_PART_RSA_COEFF, &coeff, CRED_PART_END))
                     77:                        {
                     78:                                if (lib->encoding->encode(lib->encoding, PRIVKEY_ASN1_DER, NULL,
                     79:                                                &asn1, CRED_PART_RSA_MODULUS, n,
                     80:                                                CRED_PART_RSA_PUB_EXP, e, CRED_PART_RSA_PRIV_EXP, d,
                     81:                                                CRED_PART_RSA_PRIME1, p, CRED_PART_RSA_PRIME2, q,
                     82:                                                CRED_PART_RSA_EXP1, exp1, CRED_PART_RSA_EXP2, exp2,
                     83:                                                CRED_PART_RSA_COEFF, coeff, CRED_PART_END))
                     84:                                {
                     85:                                        to_free = asn1;
                     86:                                        break;
                     87:                                }
                     88:                        }
                     89:                        if (cred_encoding_args(args, CRED_PART_ECDSA_PRIV_ASN1_DER,
                     90:                                                                   &asn1, CRED_PART_END))
                     91:                        {
                     92:                                label ="EC PRIVATE KEY";
                     93:                                break;
                     94:                        }
                     95:                        if (cred_encoding_args(args, CRED_PART_BLISS_PRIV_ASN1_DER,
                     96:                                                                   &asn1, CRED_PART_END))
                     97:                        {
                     98:                                label ="BLISS PRIVATE KEY";
                     99:                                break;
                    100:                        }
                    101:                        if (cred_encoding_args(args, CRED_PART_EDDSA_PRIV_ASN1_DER,
                    102:                                                                   &asn1, CRED_PART_END))
                    103:                        {
                    104:                                label ="PRIVATE KEY";
                    105:                                break;
                    106:                        }
                    107:                        return FALSE;
                    108:                case CERT_PEM:
                    109:                        if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER,
                    110:                                                                   &asn1, CRED_PART_END))
                    111:                        {       /* PEM encode x509 certificate */
                    112:                                label = "CERTIFICATE";
                    113:                                break;
                    114:                        }
                    115:                        if (cred_encoding_args(args, CRED_PART_X509_CRL_ASN1_DER,
                    116:                                                                   &asn1, CRED_PART_END))
                    117:                        {       /* PEM encode CRL */
                    118:                                label = "X509 CRL";
                    119:                                break;
                    120:                        }
                    121:                        if (cred_encoding_args(args, CRED_PART_PKCS10_ASN1_DER,
                    122:                                                                   &asn1, CRED_PART_END))
                    123:                        {       /* PEM encode PKCS10 certificate request */
                    124:                                label = "CERTIFICATE REQUEST";
                    125:                                break;
                    126:                        }
                    127:                        if (cred_encoding_args(args, CRED_PART_X509_AC_ASN1_DER,
                    128:                                                                   &asn1, CRED_PART_END))
                    129:                        {
                    130:                                label = "ATTRIBUTE CERTIFICATE";
                    131:                                break;
                    132:                        }
                    133:                default:
                    134:                        return FALSE;
                    135:        }
                    136: 
                    137:        /* compute and allocate maximum size of PEM object */
                    138:        pem_chars = 4 * ((asn1.len + 2) / 3);
                    139:        pem_lines = (asn1.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE;
                    140:        *encoding = chunk_alloc(5 + 2*(6 + strlen(label) + 6) + 3 + pem_chars + pem_lines);
                    141:        pos = encoding->ptr;
                    142:        len = encoding->len;
                    143: 
                    144:        /* write PEM header */
                    145:        written = snprintf(pos, len, "-----BEGIN %s-----\n", label);
                    146:        pos += written;
                    147:        len -= written;
                    148: 
                    149:        /* write PEM body */
                    150:        while (pem_lines--)
                    151:        {
                    152:                chunk_t asn1_line, pem_line;
                    153: 
                    154:                asn1_line = chunk_create(asn1.ptr, min(asn1.len, BYTES_PER_LINE));
                    155:                asn1.ptr += asn1_line.len;
                    156:                asn1.len -= asn1_line.len;
                    157:                pem_line =  chunk_to_base64(asn1_line, pos);
                    158:                pos += pem_line.len;
                    159:                len -= pem_line.len;
                    160:                *pos = '\n';
                    161:                pos++;
                    162:                len--;
                    163:        }
                    164: 
                    165:        chunk_clear(&to_free);
                    166: 
                    167:        /* write PEM trailer */
                    168:        written = snprintf(pos, len, "-----END %s-----", label);
                    169:        pos += written;
                    170:        len -= written;
                    171: 
                    172:        /* replace termination null character with newline */
                    173:        *pos = '\n';
                    174:        pos++;
                    175:        len--;
                    176: 
                    177:        /* compute effective length of PEM object */
                    178:        encoding->len = pos - encoding->ptr;
                    179:        return TRUE;
                    180: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>