+{
+ static const unsigned char map[17] = "0123456789ABCDEF";
+ long i;
+ int j;
+
+ BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
+ BUF_strlcat(buf, type, PEM_BUFSIZE);
+ BUF_strlcat(buf, ",", PEM_BUFSIZE);
+ j = strlen(buf);
+ if (j + (len * 2) + 1 > PEM_BUFSIZE)
+ return;
+ for (i = 0; i < len; i++) {
+ buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
+ buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
+ }
+ buf[j + i * 2] = '\n';
+ buf[j + i * 2 + 1] = '\0';
+}
+
+#ifndef OPENSSL_NO_STDIO
+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+ pem_password_cb *cb, void *u)
+{
+ BIO *b;
+ void *ret;
+
+ if ((b = BIO_new(BIO_s_file())) == NULL) {
+ PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB);
+ return (0);
+ }
+ BIO_set_fp(b, fp, BIO_NOCLOSE);
+ ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
+ BIO_free(b);
+ return (ret);
+}
+#endif
+
+static int check_pem(const char *nm, const char *name)
+{
+ /* Normal matching nm and name */
+ if (strcmp(nm, name) == 0)
+ return 1;
+
+ /* Make PEM_STRING_EVP_PKEY match any private key */
+
+ if (strcmp(name, PEM_STRING_EVP_PKEY) == 0) {
+ int slen;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if (strcmp(nm, PEM_STRING_PKCS8) == 0)
+ return 1;
+ if (strcmp(nm, PEM_STRING_PKCS8INF) == 0)
+ return 1;
+ slen = pem_check_suffix(nm, "PRIVATE KEY");
+ if (slen > 0) {
+ /*
+ * NB: ENGINE implementations wont contain a deprecated old
+ * private key decode function so don't look for them.
+ */
+ ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+ if (ameth && ameth->old_priv_decode)
+ return 1;
+ }
+ return 0;
+ }
+
+ if (strcmp(name, PEM_STRING_PARAMETERS) == 0) {
+ int slen;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ slen = pem_check_suffix(nm, "PARAMETERS");
+ if (slen > 0) {
+ ENGINE *e;
+ ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
+ if (ameth) {
+ int r;
+ if (ameth->param_decode)
+ r = 1;
+ else
+ r = 0;
+#ifndef OPENSSL_NO_ENGINE
+ if (e)
+ ENGINE_finish(e);
+#endif
+ return r;
+ }
+ }
+ return 0;
+ }
+ /* If reading DH parameters handle X9.42 DH format too */
+ if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0
+ && strcmp(name, PEM_STRING_DHPARAMS) == 0)
+ return 1;
+
+ /* Permit older strings */
+
+ if (strcmp(nm, PEM_STRING_X509_OLD) == 0
+ && strcmp(name, PEM_STRING_X509) == 0)
+ return 1;
+
+ if (strcmp(nm, PEM_STRING_X509_REQ_OLD) == 0
+ && strcmp(name, PEM_STRING_X509_REQ) == 0)
+ return 1;
+
+ /* Allow normal certs to be read as trusted certs */
+ if (strcmp(nm, PEM_STRING_X509) == 0
+ && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
+ return 1;
+
+ if (strcmp(nm, PEM_STRING_X509_OLD) == 0
+ && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
+ return 1;
+
+ /* Some CAs use PKCS#7 with CERTIFICATE headers */
+ if (strcmp(nm, PEM_STRING_X509) == 0
+ && strcmp(name, PEM_STRING_PKCS7) == 0)
+ return 1;
+
+ if (strcmp(nm, PEM_STRING_PKCS7_SIGNED) == 0
+ && strcmp(name, PEM_STRING_PKCS7) == 0)
+ return 1;
+
+#ifndef OPENSSL_NO_CMS
+ if (strcmp(nm, PEM_STRING_X509) == 0
+ && strcmp(name, PEM_STRING_CMS) == 0)
+ return 1;
+ /* Allow CMS to be read from PKCS#7 headers */
+ if (strcmp(nm, PEM_STRING_PKCS7) == 0
+ && strcmp(name, PEM_STRING_CMS) == 0)
+ return 1;