acme-client/src/mimik_acme_client.c
int mk_post_acme_finalize_resource(mk_acme_info *actx)
{
    int rc = 0;
    char *res_url = NULL;
    mk_mbedtls_key_params *pmtls = NULL;

    if ((!actx) || (!actx->order_resp.finalize)) {
       return -1;
    }

    rc = mk_acme_create_csr_from_key(actx);
    if (rc < 0) {
       MK_LOG(LOG_ERR, "%s(): mk_acme_create_csr_from_key Error rc=%d \n",__func__,rc);
       return -1;
    }

    pmtls = &actx->mtlsc;
    if ((!pmtls->pcsr) || (!pmtls->csr_len)) {
       MK_LOG(LOG_ERR, "%s(): mk_acme_create_csr_from_key Error rc=%d \n",__func__,rc);
       return -1;
    }

    res_url = actx->order_resp.finalize;
    actx->hCfg.http_url = res_url;

    actx->hCfg.http_method = MK_HTTP_METHOD_POST;
    actx->hCfg.set_Content_Type = MK_HTTP_SET_CONTENT_TYPE_JOSE_JSON;
    actx->hCfg.set_Host = MK_HTTP_SET_HOST_LOCALHOST;
    actx->hCfg.set_UserAgent = MK_HTTP_SET_USER_AGENT_MIMIK;
    actx->hCfg.set_Accept = NULL;

    //"protected" section
    snprintf(actx->tx_msg.protected_str, MAX_PROTECTED_SZ, ACME_PROTECTED_SPRINTF_FORMAT, 
               res_url, actx->mkrspdata.Replay_Nonce, actx->kid_KeyId);

    //"payload": section
    //convert CSR into base64(CSR)
    memset(pmtls->csr_base64,0,CSR_DATA_SZ);
    rc = mk_convert_to_base64((char *)pmtls->pcsr, pmtls->csr_len, (char *)pmtls->csr_base64, CSR_DATA_SZ);
    if ( rc < 0) {
      MK_LOG(LOG_ERR, "%s(): Error mk_convert_to_base64 for csr\n",__func__);
       return -1;
    }
    MK_LOG(LOG_DEBUG,"%s() converted csr to csr_base64 strlen(csr_base64)=%d rc=%d \n",
                       __func__,strlen((char *)pmtls->csr_base64),rc);

    snprintf(actx->tx_msg.payload_str, MAX_PAYLOAD_SZ, ACME_PAYLOAD_FINALIZE_CSR_SPRINTF_FORMAT , pmtls->csr_base64);

    rc = mk_prepare_acme_resource_msg(actx, res_url);
    if ( rc < 0 ) {
        MK_LOG(LOG_ERR, "%s(): mk_prepare_acme_resource_msg Error rc=%d \n",__func__,rc);
        return -1;
    }

    actx->hCfg.post_msg = actx->tx_msg.txbuf;
    actx->hCfg.post_msg_len = actx->tx_msg.txlen;

    actx->mkrspdata.rsp_buff = actx->rxbuf;
    actx->mkrspdata.rsp_max_buff_sz = RXBUFSZ;
    memset(actx->rxbuf,0,RXBUFSZ);
    rc = mk_esp_http_acme_req_rsp(&actx->hCfg, &actx->mkrspdata);
    if ( rc < 0 ) {
        MK_LOG(LOG_ERR, "%s(): Error rc=%d \n",__func__,rc);
        return -1;
    }

    actx->mkrspdata.rsp_buff[actx->mkrspdata.rsp_rx_bytes] = 0; //NULL terminate, just in case, to be used as a string buffer
    MK_LOG(LOG_INFO, "%s(): recvd rc=%d mkrspdata[rsp_rx_bytes=%d content_length=%d] \n",
                      __func__, rc, actx->mkrspdata.rsp_rx_bytes, actx->mkrspdata.content_length);

    //Parse directory resource JSON object and the obtain the values of certificate resource url
    rc = mk_json_parse_finalize_response(actx->mkrspdata.rsp_buff, &actx->finalize_resp);
    if ( rc < 0 ) {
        MK_LOG(LOG_ERR, "%s(): Error rc=%d \n",__func__,rc);
        return -1;
    }
    
    return 0;
}
//POST finalize
/* comments from rfc8555:

   "Once the client believes it has fulfilled the server's requirements,
   it should send a POST request to the order resource's finalize URL.
   The POST body MUST include a CSR:

   csr (required, string):  A CSR encoding the parameters for the
      certificate being requested [RFC2986].  The CSR is sent in the
      base64url-encoded version of the DER format.  (Note: Because this
      field uses base64url, and does not include headers, it is
      different from PEM.)

   POST /acme/order/TOlocE8rfgo/finalize HTTP/1.1
   Host: example.com
   Content-Type: application/jose+json

   {
     "protected": base64url({
       "alg": "ES256",
       "kid": "https://example.com/acme/acct/evOfKhNU60wg",
       "nonce": "MSF2j2nawWHPxxkE3ZJtKQ",
       "url": "https://example.com/acme/order/TOlocE8rfgo/finalize"
     }),
     "payload": base64url({
       "csr": "MIIBPTCBxAIBADBFMQ...FS6aKdZeGsysoCo4H9P",
     }),
     "signature": "uOrUfIIk5RyQ...nw62Ay1cl6AB"
   }

   The CSR encodes the client's requests with regard to the content of
   the certificate to be issued.  The CSR MUST indicate the exact same
   set of requested identifiers as the initial newOrder request.
   Identifiers of type "dns" MUST appear either in the commonName
   portion of the requested subject name or in an extensionRequest
   attribute [RFC2985] requesting a subjectAltName extension, or both.
   (These identifiers may appear in any sort order.)  Specifications
   that define new identifier types must specify where in the
   certificate signing request these identifiers can appear."
*/
POST finalize
comments from rfc8555.

"Once the client believes it has fulfilled the server's requirements,
it should send a POST request to the order resource's finalize URL.
The POST body MUST include a CSR.

csr (required, string):  A CSR encoding the parameters for the
certificate being requested [RFC2986].  The CSR is sent in the
base64url-encoded version of the DER format.  (Note: Because this
field uses base64url, and does not include headers, it is
different from PEM.)





The CSR encodes the client's requests with regard to the content of
the certificate to be issued.  The CSR MUST indicate the exact same
set of requested identifiers as the initial newOrder request.
Identifiers of type "dns" MUST appear either in the commonName
portion of the requested subject name or in an extensionRequest
attribute [RFC2985] requesting a subjectAltName extension, or both.
(These identifiers may appear in any sort order.)  Specifications
that define new identifier types must specify where in the
certificate signing request these identifiers can appear."
POST finalize comments from rfc8555 . " Once the client believes it has fulfilled the server ' s requirements it should send a POST request to the order resource ' s finalize URL . The POST body MUST include a CSR . csr ( required string ) : A CSR encoding the parameters for the certificate being requested [ RFC2986 ] . The CSR is sent in the base64url - encoded version of the DER format . ( Note : Because this field uses base64url and does not include headers it is different from PEM . ) The CSR encodes the client ' s requests with regard to the content of the certificate to be issued . The CSR MUST indicate the exact same set of requested identifiers as the initial newOrder request . Identifiers of type " dns " MUST appear either in the commonName portion of the requested subject name or in an extensionRequest attribute [ RFC2985 ] requesting a subjectAltName extension or both . ( These identifiers may appear in any sort order . ) Specifications that define new identifier types must specify where in the certificate signing request these identifiers can appear . "
int mk_post_acme_finalize_resource(mk_acme_info *actx)
{
    int rc = 0;
    char *res_url = NULL;
    mk_mbedtls_key_params *pmtls = NULL;
    if ((!actx) || (!actx->order_resp.finalize)) {
       return -1;
    }
    rc = mk_acme_create_csr_from_key(actx);
    if (rc < 0) {
       MK_LOG(LOG_ERR, "%s(): mk_acme_create_csr_from_key Error rc=%d \n",__func__,rc);
       return -1;
    }
    pmtls = &actx->mtlsc;
    if ((!pmtls->pcsr) || (!pmtls->csr_len)) {
       MK_LOG(LOG_ERR, "%s(): mk_acme_create_csr_from_key Error rc=%d \n",__func__,rc);
       return -1;
    }
    res_url = actx->order_resp.finalize;
    actx->hCfg.http_url = res_url;
    actx->hCfg.http_method = MK_HTTP_METHOD_POST;
    actx->hCfg.set_Content_Type = MK_HTTP_SET_CONTENT_TYPE_JOSE_JSON;
    actx->hCfg.set_Host = MK_HTTP_SET_HOST_LOCALHOST;
    actx->hCfg.set_UserAgent = MK_HTTP_SET_USER_AGENT_MIMIK;
    actx->hCfg.set_Accept = NULL;
    snprintf(actx->tx_msg.protected_str, MAX_PROTECTED_SZ, ACME_PROTECTED_SPRINTF_FORMAT, 
               res_url, actx->mkrspdata.Replay_Nonce, actx->kid_KeyId);
    memset(pmtls->csr_base64,0,CSR_DATA_SZ);
    rc = mk_convert_to_base64((char *)pmtls->pcsr, pmtls->csr_len, (char *)pmtls->csr_base64, CSR_DATA_SZ);
    if ( rc < 0) {
      MK_LOG(LOG_ERR, "%s(): Error mk_convert_to_base64 for csr\n",__func__);
       return -1;
    }
    MK_LOG(LOG_DEBUG,"%s() converted csr to csr_base64 strlen(csr_base64)=%d rc=%d \n",
                       __func__,strlen((char *)pmtls->csr_base64),rc);
    snprintf(actx->tx_msg.payload_str, MAX_PAYLOAD_SZ, ACME_PAYLOAD_FINALIZE_CSR_SPRINTF_FORMAT , pmtls->csr_base64);
    rc = mk_prepare_acme_resource_msg(actx, res_url);
    if ( rc < 0 ) {
        MK_LOG(LOG_ERR, "%s(): mk_prepare_acme_resource_msg Error rc=%d \n",__func__,rc);
        return -1;
    }
    actx->hCfg.post_msg = actx->tx_msg.txbuf;
    actx->hCfg.post_msg_len = actx->tx_msg.txlen;
    actx->mkrspdata.rsp_buff = actx->rxbuf;
    actx->mkrspdata.rsp_max_buff_sz = RXBUFSZ;
    memset(actx->rxbuf,0,RXBUFSZ);
    rc = mk_esp_http_acme_req_rsp(&actx->hCfg, &actx->mkrspdata);
    if ( rc < 0 ) {
        MK_LOG(LOG_ERR, "%s(): Error rc=%d \n",__func__,rc);
        return -1;
    }
    actx->mkrspdata.rsp_buff[actx->mkrspdata.rsp_rx_bytes] = 0; 
    MK_LOG(LOG_INFO, "%s(): recvd rc=%d mkrspdata[rsp_rx_bytes=%d content_length=%d] \n",
                      __func__, rc, actx->mkrspdata.rsp_rx_bytes, actx->mkrspdata.content_length);
    rc = mk_json_parse_finalize_response(actx->mkrspdata.rsp_buff, &actx->finalize_resp);
    if ( rc < 0 ) {
        MK_LOG(LOG_ERR, "%s(): Error rc=%d \n",__func__,rc);
        return -1;
    }
    return 0;
}
int mk_post_acme_finalize_resource ( mk_acme_info * actx ) { int rc = 0 ; char * res_url = NULL ; mk_mbedtls_key_params * pmtls = NULL ; if ( ( ! actx ) || ( ! actx -> order_resp . finalize ) ) { return -1 ; } rc = mk_acme_create_csr_from_key ( actx ) ; if ( rc < 0 ) { MK_LOG ( LOG_ERR , " \n " , __func__ , rc ) ; return -1 ; } pmtls = & actx -> mtlsc ; if ( ( ! pmtls -> pcsr ) || ( ! pmtls -> csr_len ) ) { MK_LOG ( LOG_ERR , " \n " , __func__ , rc ) ; return -1 ; } res_url = actx -> order_resp . finalize ; actx -> hCfg . http_url = res_url ; actx -> hCfg . http_method = MK_HTTP_METHOD_POST ; actx -> hCfg . set_Content_Type = MK_HTTP_SET_CONTENT_TYPE_JOSE_JSON ; actx -> hCfg . set_Host = MK_HTTP_SET_HOST_LOCALHOST ; actx -> hCfg . set_UserAgent = MK_HTTP_SET_USER_AGENT_MIMIK ; actx -> hCfg . set_Accept = NULL ; snprintf ( actx -> tx_msg . protected_str , MAX_PROTECTED_SZ , ACME_PROTECTED_SPRINTF_FORMAT , res_url , actx -> mkrspdata . Replay_Nonce , actx -> kid_KeyId ) ; memset ( pmtls -> csr_base64 , 0 , CSR_DATA_SZ ) ; rc = mk_convert_to_base64 ( ( char * ) pmtls -> pcsr , pmtls -> csr_len , ( char * ) pmtls -> csr_base64 , CSR_DATA_SZ ) ; if ( rc < 0 ) { MK_LOG ( LOG_ERR , " \n " , __func__ ) ; return -1 ; } MK_LOG ( LOG_DEBUG , " \n " , __func__ , strlen ( ( char * ) pmtls -> csr_base64 ) , rc ) ; snprintf ( actx -> tx_msg . payload_str , MAX_PAYLOAD_SZ , ACME_PAYLOAD_FINALIZE_CSR_SPRINTF_FORMAT , pmtls -> csr_base64 ) ; rc = mk_prepare_acme_resource_msg ( actx , res_url ) ; if ( rc < 0 ) { MK_LOG ( LOG_ERR , " \n " , __func__ , rc ) ; return -1 ; } actx -> hCfg . post_msg = actx -> tx_msg . txbuf ; actx -> hCfg . post_msg_len = actx -> tx_msg . txlen ; actx -> mkrspdata . rsp_buff = actx -> rxbuf ; actx -> mkrspdata . rsp_max_buff_sz = RXBUFSZ ; memset ( actx -> rxbuf , 0 , RXBUFSZ ) ; rc = mk_esp_http_acme_req_rsp ( & actx -> hCfg , & actx -> mkrspdata ) ; if ( rc < 0 ) { MK_LOG ( LOG_ERR , " \n " , __func__ , rc ) ; return -1 ; } actx -> mkrspdata . rsp_buff [ actx -> mkrspdata . rsp_rx_bytes ] = 0 ; MK_LOG ( LOG_INFO , " \n " , __func__ , rc , actx -> mkrspdata . rsp_rx_bytes , actx -> mkrspdata . content_length ) ; rc = mk_json_parse_finalize_response ( actx -> mkrspdata . rsp_buff , & actx -> finalize_resp ) ; if ( rc < 0 ) { MK_LOG ( LOG_ERR , " \n " , __func__ , rc ) ; return -1 ; } return 0 ; }
POST finalize
comments from rfc8555:
POST finalize comments from rfc8555 :
//"protected" section //"payload": section //convert CSR into base64(CSR) //NULL terminate, just in case, to be used as a string buffer //Parse directory resource JSON object and the obtain the values of certificate resource url