SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
                             int type, const char *key_passwd)
{
  int ret = 0;
  X509 *x = NULL;
  /* the typecast of blob->len is fine since it is guaranteed to never be
     larger than CURL_MAX_INPUT_LENGTH */
  BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
  if(!in)
    return CURLE_OUT_OF_MEMORY;

  if(type == SSL_FILETYPE_ASN1) {
    /* j = ERR_R_ASN1_LIB; */
    x = d2i_X509_bio(in, NULL);
  }
  else if(type == SSL_FILETYPE_PEM) {
    /* ERR_R_PEM_LIB; */
    x = PEM_read_bio_X509(in, NULL,
                          passwd_callback, (void *)key_passwd);
  }
  else {
    ret = 0;
    goto end;
  }

  if(!x) {
    ret = 0;
    goto end;
  }

  ret = SSL_CTX_use_certificate(ctx, x);
 end:
  X509_free(x);
  BIO_free(in);
  return ret;
}
SSL_CTX_use_certificate_blob(SSL_CTX *ctx, const struct curl_blob *blob,
                             int type, const char *key_passwd)
{
  int ret = 0;
  X509 *x = NULL;
   
  BIO *in = BIO_new_mem_buf(blob->data, (int)(blob->len));
  if(!in)
    return CURLE_OUT_OF_MEMORY;

  if(type == SSL_FILETYPE_ASN1) {
     
    x = d2i_X509_bio(in, NULL);
  }
  else if(type == SSL_FILETYPE_PEM) {
     
    x = PEM_read_bio_X509(in, NULL,
                          passwd_callback, (void *)key_passwd);
  }
  else {
    ret = 0;
    goto end;
  }

  if(!x) {
    ret = 0;
    goto end;
  }

  ret = SSL_CTX_use_certificate(ctx, x);
 end:
  X509_free(x);
  BIO_free(in);
  return ret;
}