📄 rsapki.c
字号:
mp_clear(&(key->N)); mp_clear(&(key->e)); mp_clear(&(key->d)); mp_clear(&(key->p)); mp_clear(&(key->q)); mp_clear(&(key->dP)); mp_clear(&(key->dQ)); mp_clear(&(key->qP)); psFree(key);}/******************************************************************************//* Parse a a private key structure in DER formatted ASN.1 Per ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf RSAPrivateKey ::= SEQUENCE { version Version, modulus INTEGER, -- n publicExponent INTEGER, -- e privateExponent INTEGER, -- d prime1 INTEGER, -- p prime2 INTEGER, -- q exponent1 INTEGER, -- d mod (p-1) exponent2 INTEGER, -- d mod (q-1) coefficient INTEGER, -- (inverse of q) mod p otherPrimeInfos OtherPrimeInfos OPTIONAL } Version ::= INTEGER { two-prime(0), multi(1) } (CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --}) Which should look something like this in hex (pipe character is used as a delimiter): ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc 30 Tag in binary: 00|1|10000 -> UNIVERSAL | CONSTRUCTED | SEQUENCE (16) 82 Length in binary: 1 | 0000010 -> LONG LENGTH | LENGTH BYTES (2) 04 A4 Length Bytes (1188) 02 Tag in binary: 00|0|00010 -> UNIVERSAL | PRIMITIVE | INTEGER (2) 01 Length in binary: 0|0000001 -> SHORT LENGTH | LENGTH (1) 00 INTEGER value (0) - RSAPrivateKey.version 02 Tag in binary: 00|0|00010 -> UNIVERSAL | PRIMITIVE | INTEGER (2) 82 Length in binary: 1 | 0000010 -> LONG LENGTH | LENGTH BYTES (2) 01 01 Length Bytes (257) [] 257 Bytes of data - RSAPrivateKey.modulus (2048 bit key) 02 Tag in binary: 00|0|00010 -> UNIVERSAL | PRIMITIVE | INTEGER (2) 03 Length in binary: 0|0000011 -> SHORT LENGTH | LENGTH (3) 01 00 01 INTEGER value (65537) - RSAPrivateKey.publicExponent ... OtherPrimeInfos is not supported in this routine, and an error will be returned if they are present*/static int32 psAsnParsePrivateKey(psPool_t *pool, unsigned char **pp, int32 size, sslRsaKey_t *key){ unsigned char *p, *end, *seq; int32 version, seqlen; key->optimized = 0; p = *pp; end = p + size; if (getSequence(&p, size, &seqlen) < 0) { matrixStrDebugMsg("ASN sequence parse error\n", NULL); return -1; } seq = p; if (getInteger(&p, (int32)(end - p), &version) < 0 || version != 0 || getBig(pool, &p, (int32)(end - p), &(key->N)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->e)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->d)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->p)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->q)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->dP)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->dQ)) < 0 || getBig(pool, &p, (int32)(end - p), &(key->qP)) < 0 || (int32)(p - seq) != seqlen) { matrixStrDebugMsg("ASN key extract parse error\n", NULL); return -1; } if (mp_shrink(&key->e) != MP_OKAY) { goto done; } if (mp_shrink(&key->d) != MP_OKAY) { goto done; } if (mp_shrink(&key->N) != MP_OKAY) { goto done; } if (mp_shrink(&key->p) != MP_OKAY) { goto done; } if (mp_shrink(&key->q) != MP_OKAY) { goto done; } if (mp_shrink(&key->dQ) != MP_OKAY) { goto done; } if (mp_shrink(&key->dP) != MP_OKAY) { goto done; } if (mp_shrink(&key->qP) != MP_OKAY) { goto done; }/* If we made it here, the key is ready for optimized decryption*/ key->optimized = 1;done: *pp = p;/* Set the key length of the key*/ key->size = mp_unsigned_bin_size(&key->N); return 0;}/******************************************************************************//* Implementations of this specification MUST be prepared to receive the following standard attribute types in issuer names: country, organization, organizational-unit, distinguished name qualifier, state or province name, and common name */int32 getDNAttributes(psPool_t *pool, unsigned char **pp, int32 len, DNattributes_t *attribs){ sslSha1Context_t hash; unsigned char *p = *pp; unsigned char *dnEnd, *dnStart; int32 llen, setlen, arcLen, id, stringType; char *stringOut; dnStart = p; if (getSequence(&p, len, &llen) < 0) { return -1; } dnEnd = p + llen; matrixSha1Init(&hash); while (p < dnEnd) { if (getSet(&p, (int32)(dnEnd - p), &setlen) < 0) { return -1; } if (getSequence(&p, (int32)(dnEnd - p), &llen) < 0) { return -1; } if (dnEnd <= p || (*(p++) != ASN_OID) || asnParseLength(&p, (int32)(dnEnd - p), &arcLen) < 0 || (dnEnd - p) < arcLen) { return -1; }/* id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} id-at-commonName OBJECT IDENTIFIER ::= {id-at 3} id-at-countryName OBJECT IDENTIFIER ::= {id-at 6} id-at-localityName OBJECT IDENTIFIER ::= {id-at 7} id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8} id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10} id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}*/ *pp = p;/* FUTURE: Currently skipping OIDs not of type {joint-iso-ccitt(2) ds(5) 4} However, we could be dealing with an OID we MUST support per RFC. domainComponent is one such example.*/ if (dnEnd - p < 2) { return -1; } if ((*p++ != 85) || (*p++ != 4) ) { p = *pp;/* Move past the OID and string type, get data size, and skip it. NOTE: Have had problems parsing older certs in this area.*/ if (dnEnd - p < arcLen + 1) { return -1; } p += arcLen + 1; if (asnParseLength(&p, (int32)(dnEnd - p), &llen) < 0 || dnEnd - p < llen) { return -1; } p = p + llen; continue; }/* Next are the id of the attribute type and the ASN string type*/ if (arcLen != 3 || dnEnd - p < 2) { return -1; } id = (int32)*p++;/* Done with OID parsing*/ stringType = (int32)*p++; asnParseLength(&p, (int32)(dnEnd - p), &llen); if (dnEnd - p < llen) { return -1; } switch (stringType) { case ASN_PRINTABLESTRING: case ASN_UTF8STRING: case ASN_IA5STRING: case ASN_T61STRING: stringOut = psMalloc(pool, llen + 1); if (stringOut == NULL) { return -8; /* SSL_MEM_ERROR */ } memcpy(stringOut, p, llen); stringOut[llen] = '\0'; p = p + llen; break; default: matrixStrDebugMsg("Parsing untested DN attrib type\n", NULL); return -1; } switch (id) { case ATTRIB_COUNTRY_NAME: if (attribs->country) { psFree(attribs->country); } attribs->country = stringOut; break; case ATTRIB_STATE_PROVINCE: if (attribs->state) { psFree(attribs->state); } attribs->state = stringOut; break; case ATTRIB_LOCALITY: if (attribs->locality) { psFree(attribs->locality); } attribs->locality = stringOut; break; case ATTRIB_ORGANIZATION: if (attribs->organization) { psFree(attribs->organization); } attribs->organization = stringOut; break; case ATTRIB_ORG_UNIT: if (attribs->orgUnit) { psFree(attribs->orgUnit); } attribs->orgUnit = stringOut; break; case ATTRIB_COMMON_NAME: if (attribs->commonName) { psFree(attribs->commonName); } attribs->commonName = stringOut; break;/* Not a MUST support*/ default: psFree(stringOut); stringOut = NULL; break; }/* Hash up the DN. Nice for validation later*/ if (stringOut != NULL) { matrixSha1Update(&hash, (unsigned char*)stringOut, llen); } } matrixSha1Final(&hash, (unsigned char*)attribs->hash); *pp = p; return 0;}/******************************************************************************//* Get the BIT STRING key and plug into RSA structure. Not included in asn1.c because it deals directly with the sslRsaKey_t struct.*/int32 getPubKey(psPool_t *pool, unsigned char **pp, int32 len, sslRsaKey_t *pubKey){ unsigned char *p = *pp; int32 pubKeyLen, ignore_bits, seqLen; if (len < 1 || (*(p++) != ASN_BIT_STRING) || asnParseLength(&p, len - 1, &pubKeyLen) < 0 || (len - 1) < pubKeyLen) { return -1; } ignore_bits = *p++;/* We assume this is always zero*/ sslAssert(ignore_bits == 0); if (getSequence(&p, pubKeyLen, &seqLen) < 0 || getBig(pool, &p, seqLen, &pubKey->N) < 0 || getBig(pool, &p, seqLen, &pubKey->e) < 0) { return -1; } pubKey->size = mp_unsigned_bin_size(&pubKey->N); *pp = p; return 0;}/******************************************************************************//* Free helper*/void psFreeDNStruct(DNattributes_t *dn){ if (dn->country) psFree(dn->country); if (dn->state) psFree(dn->state); if (dn->locality) psFree(dn->locality); if (dn->organization) psFree(dn->organization); if (dn->orgUnit) psFree(dn->orgUnit); if (dn->commonName) psFree(dn->commonName);}/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -