pem.h (21979B)
1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef OPENSSL_HEADER_PEM_H 16 #define OPENSSL_HEADER_PEM_H 17 18 #include <openssl/base64.h> 19 #include <openssl/bio.h> 20 #include <openssl/cipher.h> 21 #include <openssl/digest.h> 22 #include <openssl/evp.h> 23 #include <openssl/pkcs7.h> 24 #include <openssl/stack.h> 25 #include <openssl/x509.h> 26 27 // For compatibility with open-iscsi, which assumes that it can get 28 // |OPENSSL_malloc| from pem.h or err.h 29 #include <openssl/crypto.h> 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 36 #define PEM_BUFSIZE 1024 37 38 #define PEM_STRING_X509_OLD "X509 CERTIFICATE" 39 #define PEM_STRING_X509 "CERTIFICATE" 40 #define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" 41 #define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" 42 #define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" 43 #define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" 44 #define PEM_STRING_X509_CRL "X509 CRL" 45 #define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" 46 #define PEM_STRING_PUBLIC "PUBLIC KEY" 47 #define PEM_STRING_RSA "RSA PRIVATE KEY" 48 #define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" 49 #define PEM_STRING_DSA "DSA PRIVATE KEY" 50 #define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" 51 #define PEM_STRING_EC "EC PRIVATE KEY" 52 #define PEM_STRING_PKCS7 "PKCS7" 53 #define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" 54 #define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" 55 #define PEM_STRING_PKCS8INF "PRIVATE KEY" 56 #define PEM_STRING_DHPARAMS "DH PARAMETERS" 57 #define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" 58 #define PEM_STRING_DSAPARAMS "DSA PARAMETERS" 59 #define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" 60 #define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" 61 #define PEM_STRING_CMS "CMS" 62 63 // enc_type is one off 64 #define PEM_TYPE_ENCRYPTED 10 65 #define PEM_TYPE_MIC_ONLY 20 66 #define PEM_TYPE_MIC_CLEAR 30 67 #define PEM_TYPE_CLEAR 40 68 69 // These macros make the PEM_read/PEM_write functions easier to maintain and 70 // write. Now they are all implemented with either: 71 // IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...) 72 73 74 #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ 75 static void *pem_read_##name##_d2i(void **x, const unsigned char **inp, \ 76 long len) { \ 77 return d2i_##asn1((type **)x, inp, len); \ 78 } \ 79 OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, \ 80 pem_password_cb *cb, void *u) { \ 81 return (type *)PEM_ASN1_read(pem_read_##name##_d2i, str, fp, (void **)x, \ 82 cb, u); \ 83 } 84 85 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ 86 static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ 87 return i2d_##asn1((type *)x, outp); \ 88 } \ 89 OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x) { \ 90 return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, x, NULL, NULL, 0, \ 91 NULL, NULL); \ 92 } 93 94 #define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ 95 static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ 96 return i2d_##asn1((const type *)x, outp); \ 97 } \ 98 OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x) { \ 99 return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, (void *)x, NULL, \ 100 NULL, 0, NULL, NULL); \ 101 } 102 103 #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ 104 static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ 105 return i2d_##asn1((type *)x, outp); \ 106 } \ 107 OPENSSL_EXPORT int PEM_write_##name( \ 108 FILE *fp, type *x, const EVP_CIPHER *enc, const unsigned char *pass, \ 109 int pass_len, pem_password_cb *cb, void *u) { \ 110 return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, x, enc, pass, \ 111 pass_len, cb, u); \ 112 } 113 114 #define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ 115 static int pem_write_##name##_i2d(const void *x, unsigned char **outp) { \ 116 return i2d_##asn1((const type *)x, outp); \ 117 } \ 118 OPENSSL_EXPORT int PEM_write_##name( \ 119 FILE *fp, type *x, const EVP_CIPHER *enc, const unsigned char *pass, \ 120 int pass_len, pem_password_cb *cb, void *u) { \ 121 return PEM_ASN1_write(pem_write_##name##_i2d, str, fp, x, enc, pass, \ 122 pass_len, cb, u); \ 123 } 124 125 126 #define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ 127 static void *pem_read_bio_##name##_d2i(void **x, const unsigned char **inp, \ 128 long len) { \ 129 return d2i_##asn1((type **)x, inp, len); \ 130 } \ 131 OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, \ 132 pem_password_cb *cb, void *u) { \ 133 return (type *)PEM_ASN1_read_bio(pem_read_bio_##name##_d2i, str, bp, \ 134 (void **)x, cb, u); \ 135 } 136 137 #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ 138 static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ 139 return i2d_##asn1((type *)x, outp); \ 140 } \ 141 OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x) { \ 142 return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, x, NULL, \ 143 NULL, 0, NULL, NULL); \ 144 } 145 146 #define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ 147 static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ 148 return i2d_##asn1((const type *)x, outp); \ 149 } \ 150 OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x) { \ 151 return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, (void *)x, \ 152 NULL, NULL, 0, NULL, NULL); \ 153 } 154 155 #define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ 156 static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ 157 return i2d_##asn1((type *)x, outp); \ 158 } \ 159 OPENSSL_EXPORT int PEM_write_bio_##name( \ 160 BIO *bp, type *x, const EVP_CIPHER *enc, const unsigned char *pass, \ 161 int pass_len, pem_password_cb *cb, void *u) { \ 162 return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, x, enc, \ 163 pass, pass_len, cb, u); \ 164 } 165 166 #define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ 167 static int pem_write_bio_##name##_i2d(const void *x, unsigned char **outp) { \ 168 return i2d_##asn1((const type *)x, outp); \ 169 } \ 170 OPENSSL_EXPORT int PEM_write_bio_##name( \ 171 BIO *bp, type *x, const EVP_CIPHER *enc, const unsigned char *pass, \ 172 int pass_len, pem_password_cb *cb, void *u) { \ 173 return PEM_ASN1_write_bio(pem_write_bio_##name##_i2d, str, bp, (void *)x, \ 174 enc, pass, pass_len, cb, u); \ 175 } 176 177 #define IMPLEMENT_PEM_write(name, type, str, asn1) \ 178 IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ 179 IMPLEMENT_PEM_write_fp(name, type, str, asn1) 180 181 #define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ 182 IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ 183 IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) 184 185 #define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ 186 IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ 187 IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) 188 189 #define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ 190 IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ 191 IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) 192 193 #define IMPLEMENT_PEM_read(name, type, str, asn1) \ 194 IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ 195 IMPLEMENT_PEM_read_fp(name, type, str, asn1) 196 197 #define IMPLEMENT_PEM_rw(name, type, str, asn1) \ 198 IMPLEMENT_PEM_read(name, type, str, asn1) \ 199 IMPLEMENT_PEM_write(name, type, str, asn1) 200 201 #define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ 202 IMPLEMENT_PEM_read(name, type, str, asn1) \ 203 IMPLEMENT_PEM_write_const(name, type, str, asn1) 204 205 #define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ 206 IMPLEMENT_PEM_read(name, type, str, asn1) \ 207 IMPLEMENT_PEM_write_cb(name, type, str, asn1) 208 209 // These are the same except they are for the declarations 210 211 #define DECLARE_PEM_read_fp(name, type) \ 212 OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, \ 213 pem_password_cb *cb, void *u); 214 215 #define DECLARE_PEM_write_fp(name, type) \ 216 OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x); 217 218 #define DECLARE_PEM_write_fp_const(name, type) \ 219 OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x); 220 221 #define DECLARE_PEM_write_cb_fp(name, type) \ 222 OPENSSL_EXPORT int PEM_write_##name( \ 223 FILE *fp, type *x, const EVP_CIPHER *enc, const unsigned char *pass, \ 224 int pass_len, pem_password_cb *cb, void *u); 225 226 #define DECLARE_PEM_read_bio(name, type) \ 227 OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, \ 228 pem_password_cb *cb, void *u); 229 230 #define DECLARE_PEM_write_bio(name, type) \ 231 OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x); 232 233 #define DECLARE_PEM_write_bio_const(name, type) \ 234 OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x); 235 236 #define DECLARE_PEM_write_cb_bio(name, type) \ 237 OPENSSL_EXPORT int PEM_write_bio_##name( \ 238 BIO *bp, type *x, const EVP_CIPHER *enc, const unsigned char *pass, \ 239 int pass_len, pem_password_cb *cb, void *u); 240 241 242 #define DECLARE_PEM_write(name, type) \ 243 DECLARE_PEM_write_bio(name, type) \ 244 DECLARE_PEM_write_fp(name, type) 245 246 #define DECLARE_PEM_write_const(name, type) \ 247 DECLARE_PEM_write_bio_const(name, type) \ 248 DECLARE_PEM_write_fp_const(name, type) 249 250 #define DECLARE_PEM_write_cb(name, type) \ 251 DECLARE_PEM_write_cb_bio(name, type) \ 252 DECLARE_PEM_write_cb_fp(name, type) 253 254 #define DECLARE_PEM_read(name, type) \ 255 DECLARE_PEM_read_bio(name, type) \ 256 DECLARE_PEM_read_fp(name, type) 257 258 #define DECLARE_PEM_rw(name, type) \ 259 DECLARE_PEM_read(name, type) \ 260 DECLARE_PEM_write(name, type) 261 262 #define DECLARE_PEM_rw_const(name, type) \ 263 DECLARE_PEM_read(name, type) \ 264 DECLARE_PEM_write_const(name, type) 265 266 #define DECLARE_PEM_rw_cb(name, type) \ 267 DECLARE_PEM_read(name, type) \ 268 DECLARE_PEM_write_cb(name, type) 269 270 // "userdata": new with OpenSSL 0.9.4 271 typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); 272 273 // PEM_read_bio reads from |bp|, until the next PEM block. If one is found, it 274 // returns one and sets |*name|, |*header|, and |*data| to newly-allocated 275 // buffers containing the PEM type, the header block, and the decoded data, 276 // respectively. |*name| and |*header| are NUL-terminated C strings, while 277 // |*data| has |*len| bytes. The caller must release each of |*name|, |*header|, 278 // and |*data| with |OPENSSL_free| when done. If no PEM block is found, this 279 // function returns zero and pushes |PEM_R_NO_START_LINE| to the error queue. If 280 // one is found, but there is an error decoding it, it returns zero and pushes 281 // some other error to the error queue. 282 OPENSSL_EXPORT int PEM_read_bio(BIO *bp, char **name, char **header, 283 unsigned char **data, long *len); 284 285 // PEM_write_bio writes a PEM block to |bp|, containing |len| bytes from |data| 286 // as data. |name| and |hdr| are NUL-terminated C strings containing the PEM 287 // type and header block, respectively. This function returns zero on error and 288 // the number of bytes written on success. 289 OPENSSL_EXPORT int PEM_write_bio(BIO *bp, const char *name, const char *hdr, 290 const unsigned char *data, long len); 291 292 OPENSSL_EXPORT int PEM_bytes_read_bio(unsigned char **pdata, long *plen, 293 char **pnm, const char *name, BIO *bp, 294 pem_password_cb *cb, void *u); 295 OPENSSL_EXPORT void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, 296 BIO *bp, void **x, pem_password_cb *cb, 297 void *u); 298 OPENSSL_EXPORT int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, 299 BIO *bp, void *x, const EVP_CIPHER *enc, 300 const unsigned char *pass, int pass_len, 301 pem_password_cb *cb, void *u); 302 303 // PEM_X509_INFO_read_bio reads PEM blocks from |bp| and decodes any 304 // certificates, CRLs, and private keys found. It returns a 305 // |STACK_OF(X509_INFO)| structure containing the results, or NULL on error. 306 // 307 // If |sk| is NULL, the result on success will be a newly-allocated 308 // |STACK_OF(X509_INFO)| structure which should be released with 309 // |sk_X509_INFO_pop_free| and |X509_INFO_free| when done. 310 // 311 // If |sk| is non-NULL, it appends the results to |sk| instead and returns |sk| 312 // on success. In this case, the caller retains ownership of |sk| in both 313 // success and failure. 314 // 315 // This function will decrypt any encrypted certificates in |bp|, using |cb|, 316 // but it will not decrypt encrypted private keys. Encrypted private keys are 317 // instead represented as placeholder |X509_INFO| objects with an empty |x_pkey| 318 // field. This allows this function to be used with inputs with unencrypted 319 // certificates, but encrypted passwords, without knowing the password. However, 320 // it also means that this function cannot be used to decrypt the private key 321 // when the password is known. 322 // 323 // WARNING: If the input contains "TRUSTED CERTIFICATE" PEM blocks, this 324 // function parses auxiliary properties as in |d2i_X509_AUX|. Passing untrusted 325 // input to this function allows an attacker to influence those properties. See 326 // |d2i_X509_AUX| for details. 327 OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio( 328 BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); 329 330 // PEM_X509_INFO_read behaves like |PEM_X509_INFO_read_bio| but reads from a 331 // |FILE|. 332 OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, 333 STACK_OF(X509_INFO) *sk, 334 pem_password_cb *cb, 335 void *u); 336 337 OPENSSL_EXPORT int PEM_read(FILE *fp, char **name, char **header, 338 unsigned char **data, long *len); 339 OPENSSL_EXPORT int PEM_write(FILE *fp, const char *name, const char *hdr, 340 const unsigned char *data, long len); 341 OPENSSL_EXPORT void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, 342 void **x, pem_password_cb *cb, void *u); 343 OPENSSL_EXPORT int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, 344 void *x, const EVP_CIPHER *enc, 345 const unsigned char *pass, int pass_len, 346 pem_password_cb *callback, void *u); 347 348 // PEM_def_callback treats |userdata| as a string and copies it into |buf|, 349 // assuming its |size| is sufficient. Returns the length of the string, or -1 on 350 // error. Error cases the buffer being too small, or |buf| and |userdata| being 351 // NULL. Note that this is different from OpenSSL, which prompts for a password. 352 OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, 353 void *userdata); 354 355 356 DECLARE_PEM_rw(X509, X509) 357 358 // TODO(crbug.com/boringssl/426): When documenting these, copy the warning 359 // about auxiliary properties from |PEM_X509_INFO_read_bio|. 360 DECLARE_PEM_rw(X509_AUX, X509) 361 362 DECLARE_PEM_rw(X509_REQ, X509_REQ) 363 DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) 364 365 DECLARE_PEM_rw(X509_CRL, X509_CRL) 366 367 DECLARE_PEM_rw(PKCS7, PKCS7) 368 DECLARE_PEM_rw(PKCS8, X509_SIG) 369 370 DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) 371 372 DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) 373 374 DECLARE_PEM_rw_const(RSAPublicKey, RSA) 375 DECLARE_PEM_rw(RSA_PUBKEY, RSA) 376 377 #ifndef OPENSSL_NO_DSA 378 379 DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) 380 381 DECLARE_PEM_rw(DSA_PUBKEY, DSA) 382 383 DECLARE_PEM_rw_const(DSAparams, DSA) 384 385 #endif 386 387 DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) 388 DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) 389 390 391 DECLARE_PEM_rw_const(DHparams, DH) 392 393 394 DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) 395 396 DECLARE_PEM_rw(PUBKEY, EVP_PKEY) 397 398 OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, 399 int nid, const char *pass, 400 int pass_len, 401 pem_password_cb *cb, 402 void *u); 403 OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, 404 const EVP_CIPHER *enc, 405 const char *pass, int pass_len, 406 pem_password_cb *cb, void *u); 407 OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, const EVP_PKEY *x, 408 const EVP_CIPHER *enc, 409 const char *pass, int pass_len, 410 pem_password_cb *cb, void *u); 411 OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, const EVP_PKEY *x, 412 int nid, const char *pass, 413 int pass_len, 414 pem_password_cb *cb, void *u); 415 OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, 416 pem_password_cb *cb, void *u); 417 418 OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, const EVP_PKEY *x, 419 const EVP_CIPHER *enc, 420 const char *pass, int pass_len, 421 pem_password_cb *cb, void *u); 422 OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, const EVP_PKEY *x, 423 int nid, const char *pass, 424 int pass_len, pem_password_cb *cb, 425 void *u); 426 OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, const EVP_PKEY *x, 427 int nid, const char *pass, 428 int pass_len, 429 pem_password_cb *cb, void *u); 430 431 OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, 432 pem_password_cb *cb, void *u); 433 434 OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, 435 const EVP_CIPHER *enc, 436 const char *pass, int pass_len, 437 pem_password_cb *cd, void *u); 438 439 440 #ifdef __cplusplus 441 } // extern "C" 442 #endif 443 444 #define PEM_R_BAD_BASE64_DECODE 100 445 #define PEM_R_BAD_DECRYPT 101 446 #define PEM_R_BAD_END_LINE 102 447 #define PEM_R_BAD_IV_CHARS 103 448 #define PEM_R_BAD_PASSWORD_READ 104 449 #define PEM_R_CIPHER_IS_NULL 105 450 #define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 106 451 #define PEM_R_NOT_DEK_INFO 107 452 #define PEM_R_NOT_ENCRYPTED 108 453 #define PEM_R_NOT_PROC_TYPE 109 454 #define PEM_R_NO_START_LINE 110 455 #define PEM_R_READ_KEY 111 456 #define PEM_R_SHORT_HEADER 112 457 #define PEM_R_UNSUPPORTED_CIPHER 113 458 #define PEM_R_UNSUPPORTED_ENCRYPTION 114 459 #define PEM_R_UNSUPPORTED_PROC_TYPE_VERSION 115 460 461 #endif // OPENSSL_HEADER_PEM_H