2013-03-08 76 views
2

我正在使用OpenSSL C API构建CSR。代码如下:Windows 2008R2 CA&OpenSSL CSR:解析CSR ASN1错误值时遇到错误

static void seedPRNG() { 

const int openSSLseedsize = 128; 

uint8_t *openSSLseed = NULL; 
openSSLseed = malloc(openSSLseedsize * sizeof(uint8_t)); 
//printf("%d\n\n", openSSLseedsize); 


// random number generator 
SecRandomCopyBytes(kSecRandomDefault, openSSLseedsize, openSSLseed); 

for (unsigned i = 0; i < openSSLseedsize; i++) { 
    printf("%d", openSSLseed[i]); 
} 
printf("\n\n\n\n"); 
//seed openSSL random 
RAND_seed(openSSLseed, 128); 


} 

// Parameter settings for this cert 
// 
#define RSA_KEY_SIZE (2048) 
#define ENTRIES 3 

// array of entries to assign to cert 
struct entry { 
char *key; 
char *value; 
}; 

struct entry entries[ENTRIES] = 
{ 
{"emailAddress", "[email protected]"}, 
{"commonName", "internal.example.com"}, 
{"countryName", "GB"}, 
}; 

// Generate CSR 

int generateCSR() { 

int i; 
RSA *rsakey; 
X509_REQ *req; 
X509_NAME *subj; 
EVP_PKEY *pkey; 
EVP_MD *digest; 
FILE *fp; 

// set up OpenSSl 
OpenSSL_add_all_algorithms(); 
ERR_load_CRYPTO_strings(); 

// seed oppenssl's prng 
seedPRNG(); 

// generate RSA key (no callback for progress - it's quick enough) 
// RSA_F4 is 0x10001 (or 65537) for the exponent. 
// RSA docs say exponent should be either 3, 5, 17, 257 or 65537 i.e. prime numbers. See here for further info: 
// http://security.stackexchange.com/questions/2335/should-rsa-public-exponent-be-only-in-3-5-17-257-or-65537-due-to-security-c 

rsakey = RSA_generate_key(RSA_KEY_SIZE, RSA_F4, NULL, NULL); 



if (rsakey == NULL) { 
    fatal("Could not create RSA key"); 
} 

// Create EVP ("Envelope Encryption" apparently...) object to hold our rsakey 
// generate private key 
if (!(pkey = EVP_PKEY_new())) 
    fatal("Could not create EVP object"); 
// assign the rsa key to EVP object 
if (!(EVP_PKEY_set1_RSA(pkey, rsakey))) 
    fatal("Could not assign RSA key to EVP object"); 

// create request object 
if (!(req = X509_REQ_new())) 
    fatal("Failed to create X509_REQ object"); 

// set the public key 
X509_REQ_set_pubkey(req, pkey); 


// create and fill in subject object 
if (!(subj = X509_NAME_new())) 
    fatal("Failed to create X509_NAME object"); 


for (i = 0; i < ENTRIES; i++) 
{ 
    // create nid for every entry 
    int nid; // ASN.1 numeric ID - ASN.1 = Abstract Syntax Notation One. Formal notation used to describe data transmitted by telecommunications protocols. 
      // The NID is a unique internal ID assigned to every object. 

    X509_NAME_ENTRY *ent; 

    if ((nid = OBJ_txt2nid(entries[i].key)) == NID_undef) 
    { 
     fprintf(stderr, "Error finding NID for %s\n", entries[i].key); 
     fatal("Error on lookup"); 
    } 
    if (!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, (unsigned char*)entries[i].value, -1))) 
     fatal("Error creating Name entry from NID"); 

    if (X509_NAME_add_entry(subj, ent, -1, 0) != 1) 
     fatal("Error adding entry to Name"); 

} 


if (X509_REQ_set_subject_name(req, subj) != 1) 
    fatal("Error adding subject to request"); 

// request is filled in and contains our generated public key 
// now sign it 
digest = (EVP_MD *)EVP_sha1(); 

if (!(X509_REQ_sign(req, pkey, digest))) 
    fatal("Error signing request"); 

// write output files 
// 
NSString *docDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
// append file name 
NSString *crtPath = [docDirectory stringByAppendingString:@"/example.crt"]; 
NSLog(@"crtPath = %@", crtPath); 

if (!(fp = fopen([crtPath UTF8String], "w"))) 
    fatal("Error writing to request file"); 
if (PEM_write_X509_REQ(fp, req) != 1) 
    fatal("Error writing request"); 
fclose(fp); 

NSString *keyPath = [docDirectory stringByAppendingString:@"/example.key"]; 
NSLog(@"keyPath = %@", keyPath); 
if (!(fp = fopen([keyPath UTF8String], "w"))) 
    fatal("Error writing to private key file"); 
if (PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, 0, NULL) != 1) 
    fatal("Error while writing private key"); 
fclose(fp); 

X509_REQ_print_fp(stdout, req); 


EVP_PKEY_free(pkey); 
X509_REQ_free(req); 



return 0; 

} 

这创建了一个CSR并输出私钥。我可以使用一个在线CSR检查器来验证CSR,并且它会全面发出滴答声,说它是正确的。我正在使用Windows 2008R2 CA来粘贴base64 CSR。但是,当我提交请求时,Windows框会抛出以下错误:

您的请求ID为0.处理消息为“Error Parsing Request ASN1 bad tag value met。0x8009310b(ASN:267)”。

使用开放式SSL附带的mkreq.c示例代码生成CSR时,也会发生这种情况。

有没有人遇到过这个?我在网上的研究只是想出人们从CA(GoDaddy等)发布的时髦证书中得到这个错误。

任何帮助将不胜感激!

回答

1

(通过在编辑OP回答见Question with no answers, but issue solved in the comments (or extended in chat)

的OP写道:

Well - my colleague and I FINALLY found a solution.

Looking at the ASN.1 representation (using openssl asn1parse), we noticed the BAD CSR had this representation:

8:d=2 hl=2 l= 0 prim: INTEGER   :00 

Notice the l = 0 (I guess this means length). Then a GOOD CSR:

8:d=2 hl=2 l= 1 prim: INTEGER   :00 

Notice l = 1

This is fixed by setting the version number of the CSR (the RFP says it should be set to 0).

So - using X509_REQ_set_version(req, 0); has fixed things and server 2008R2 gives me my beloved identity!