> On Mar 18, 2019, at 4:02 PM, Dave Coombs <dcoombs@xxxxxxxxxxx> 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. -- Viktor.