On 18 Mar 2019, at 22:27, Viktor Dukhovni <openssl-us...@dukhovni.org> wrote:
>> (Even in the 1.1 API, where they are opaque, i2d_re_X509_REQ_tbs will encode >> a given X509_REQ's X509_REQ_INFO for you.) > > Yes, i2d_re_X509_REQ_tbs is the key function for constructing the > "to be signed" (tbs) request: > > int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) > { > req->req_info.enc.modified = 1; > return i2d_X509_REQ_INFO(&req->req_info, pp); > } > > By setting the "modified" bit, it ensures that the DER representation > will be re-generated with any changes made to the object. > > So the OP can create the "partially filled in" X509_REQ and then call > i2d_re_X509_REQ_tbs() function to generate the DER CRI blob to sign. > This removes any temptation to "cheat" by just casting the (X509_REQ *) > as an (X509_REQ_INFO *) and calling i2d_X509_REQ_INFO() on that (first > member of the X509_REQ structure). The i2d_re_X509_REQ_tbs() function > achieves the same effect in a type safe supported manner. Can you confirm what structure is being encoded by i2d_re_X509_REQ_tbs, is this a X509_REQ_INFO? The man page doesn’t explicitly specify the output formats of any of the related functions: https://www.openssl.org/docs/man1.1.1/man3/i2d_re_X509_REQ_tbs.html Looking at the source, we have X509_REQ_INFO being returned: int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp) { req->req_info.enc.modified = 1; return i2d_X509_REQ_INFO(&req->req_info, pp); } What would the corresponding functions need to be in the openssl v1.0.x world to achieve the same output as i2d_re_X509_REQ_tbs? Would it just be to copy the above code in? Regards, Graham —