Return to pem_encoder.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / pem |
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: }