Topic: my god,who can help me?
i want to change the openssl code to wolfssl embedded ssl,who can help me?
lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t public_key, key_data_t *odevice_cert,
                                       key_data_t * ohost_cert, key_data_t * oroot_cert)
{
    if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert)
        return LOCKDOWN_E_INVALID_ARG;
    lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
    userpref_error_t uret = USERPREF_E_UNKNOWN_ERROR;
    ///个人理解 下面这一段代码是将 public 方式 转换成 rsa 方式
    BIO *membio = BIO_new_mem_buf(public_key.data, public_key.size);
    RSA *pubkey = NULL;
    if (!PEM_read_bio_RSAPublicKey(membio, &pubkey, NULL, NULL)) {
        debug_info("Could not read public key");
    }
    BIO_free(membio);
    /* now generate certificates */
    key_data_t root_privkey, host_privkey;
    key_data_t root_cert, host_cert;
    X509* dev_cert;
    root_cert.data = NULL;
    root_cert.size = 0;
    host_cert.data = NULL;
    host_cert.size = 0;
dev_cert = X509_new();
    root_privkey.data = NULL;
    root_privkey.size = 0;
    host_privkey.data = NULL;
    host_privkey.size = 0;
   //// 下面这一部分是根据X509的方式添加信息   
    uret = userpref_device_record_get_keys_and_certs(udid, &root_privkey, &root_cert, &host_privkey, &host_cert);
    if (USERPREF_E_SUCCESS == uret) {
        /* generate device certificate */
        //// 串号
        ASN1_INTEGER* sn = ASN1_INTEGER_new();
        ASN1_INTEGER_set(sn, 0);
        X509_set_serialNumber( dev_cert ,  sn );
        ASN1_INTEGER_free(sn);
        /////版本号
        X509_set_version(dev_cert, 2);
         ////x509V3 扩展信息
        X509_EXTENSION* ext;
        if (!(ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, (char*)"critical,CA:FALSE"))) {
            debug_info("ERROR: X509V3_EXT_conf_nid failed??for Basic Constraints");
        }
        X509_add_ext(dev_cert, ext, -1);
        X509_EXTENSION_free(ext);
        ////当前时间往后10年时间
        ASN1_TIME* asn1time = ASN1_TIME_new();
        ASN1_TIME_set(asn1time, time(NULL));
        X509_set_notBefore(dev_cert, asn1time);
        ASN1_TIME_set(asn1time, time(NULL) + (60 * 60 * 24 * 365 * 10));
        X509_set_notAfter(dev_cert, asn1time);
        ASN1_TIME_free(asn1time);
        
        BIO* membp;
        X509* rootCert = NULL;
        membp = BIO_new_mem_buf(root_cert.data, root_cert.size);
        PEM_read_bio_X509(membp, &rootCert, NULL, NULL);
        BIO_free(membp);
        if (!rootCert) {
            debug_info("Could not read RootCertificate");
        } else {
            debug_info("RootCertificate loaded");
            EVP_PKEY* pkey = EVP_PKEY_new();
            EVP_PKEY_assign_RSA(pkey, pubkey);
            X509_set_pubkey(dev_cert, pkey);
            EVP_PKEY_free(pkey);
            X509_free(rootCert);
        }
        X509V3_CTX ctx;
        X509V3_set_ctx_nodb(&ctx);
        X509V3_set_ctx(&ctx, NULL, dev_cert, NULL, NULL, 0);
        if (!(ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
            debug_info("ERROR: X509V3_EXT_conf_nid failed for Subject Key identifier");
        }
        X509_add_ext(dev_cert, ext, -1);
        X509_EXTENSION_free(ext);
        if (!(ext = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, (char*)"critical,digitalSignature,keyEncipherment"))) {
            debug_info("ERROR: X509V3_EXT_conf_nid failed for Key Usage");
        }
        X509_add_ext(dev_cert, ext, -1);
        X509_EXTENSION_free(ext);
        EVP_PKEY* rootPriv = NULL;
        membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
        PEM_read_bio_PrivateKey(membp, &rootPriv, NULL, NULL);
        BIO_free(membp);
        if (!rootPriv) {
            debug_info("Could not read RootPrivateKey");
        } else {
            debug_info("RootPrivateKey loaded");
            if (X509_sign(dev_cert, rootPriv, EVP_sha1())) {
                ret = LOCKDOWN_E_SUCCESS;
            } else {
                debug_info("signing failed");
            }
            EVP_PKEY_free(rootPriv);
        }
        if (LOCKDOWN_E_SUCCESS == ret) {
            /* if everything went well, export in PEM format */
            key_data_t pem_root_cert = { NULL, 0 };
            key_data_t pem_host_cert = { NULL, 0 };
            uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert, NULL);
            if (USERPREF_E_SUCCESS == uret) {
                /* copy buffer for output */
                membp = BIO_new(BIO_s_mem());
                if (membp && PEM_write_bio_X509(membp, dev_cert) > 0) {
                    void *datap;
                    odevice_cert->size = BIO_get_mem_data(membp, &datap);
                    odevice_cert->data = malloc(odevice_cert->size);
                    memcpy(odevice_cert->data, datap, odevice_cert->size);
                }
                if (membp)
                    BIO_free(membp);
                ohost_cert->data = malloc(pem_host_cert.size);
                memcpy(ohost_cert->data, pem_host_cert.data, pem_host_cert.size);
                ohost_cert->size = pem_host_cert.size;
                oroot_cert->data = malloc(pem_root_cert.size);
                memcpy(oroot_cert->data, pem_root_cert.data, pem_root_cert.size);
                oroot_cert->size = pem_root_cert.size;
                free(pem_root_cert.data);
                free(pem_host_cert.data);
            }
        }
    }
    X509V3_EXT_cleanup();
    X509_free(dev_cert);
    switch(uret) {
    case USERPREF_E_INVALID_ARG:
        ret = LOCKDOWN_E_INVALID_ARG;
        break;
    case USERPREF_E_INVALID_CONF:
        ret = LOCKDOWN_E_INVALID_CONF;
        break;
    case USERPREF_E_SSL_ERROR:
        ret = LOCKDOWN_E_SSL_ERROR;
    default:
        break;
    }
    if (root_cert.data)
        free(root_cert.data);
    if (host_cert.data)
        free(host_cert.data);
    if (root_privkey.data)
        free(root_privkey.data);
    if (host_privkey.data)
        free(host_privkey.data);
    return ret;
}