certcgi.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,362 行 · 第 1/5 页

C
2,362
字号
    int                      len;    PRBool                   odd = PR_FALSE;    encodedValue.data = NULL;    encodedValue.len = 0;    first = read = write = find_field(data,"subjectKeyIdentifier-text", 				      PR_TRUE);    len = PORT_Strlen(first);    odd = ((len % 2) != 0 ) ? PR_TRUE : PR_FALSE;    if (find_field_bool(data, "subjectKeyIdentifier-radio-hex", PR_TRUE)) {	if (odd) {	    error_out("ERROR: Improperly formated subject key identifier, hex values must be expressed as an octet string");	}	while (*read != '\0') {	    if (!isxdigit(*read)) {		error_out("ERROR: Improperly formated subject key identifier");	    }	    *read = toupper(*read);	    if ((*read >= 'A') && (*read <= 'F')) {		high_digit = *read - 'A' + 10;	    }  else {		high_digit = *read - '0';	    }	    ++read;	    if (!isxdigit(*read)) {		error_out("ERROR: Improperly formated subject key identifier");	    }	    *read = toupper(*read);	    if ((*read >= 'A') && (*read <= 'F')) {		low_digit = *(read) - 'A' + 10;	    } else {		low_digit = *(read) - '0';	    }	    character = (high_digit << 4) | low_digit;	    *write = character;	    ++write;	    ++read;	}	*write = '\0';	len = write - first;    }    subjectCert->subjectKeyID.data = (unsigned char *) find_field	(data,"subjectKeyIdentifier-text", PR_TRUE);    subjectCert->subjectKeyID.len = len;    rv = CERT_EncodeSubjectKeyID	(NULL, find_field(data,"subjectKeyIdentifier-text", PR_TRUE),	 len, &encodedValue);    if (rv) {	return (rv);    }    return (CERT_AddExtension(extHandle,  SEC_OID_X509_SUBJECT_KEY_ID, 			      &encodedValue, PR_FALSE, PR_TRUE));}static SECStatus AddAuthKeyID (void              *extHandle,	      Pair              *data, 	      char              *issuerNameStr, 	      CERTCertDBHandle  *handle){    CERTAuthKeyID               *authKeyID = NULL;        PRArenaPool                 *arena = NULL;    SECStatus                   rv = SECSuccess;    CERTCertificate             *issuerCert = NULL;    CERTGeneralName             *genNames;    CERTName                    *directoryName = NULL;    issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( !arena ) {	error_allocate();    }    authKeyID = PORT_ArenaZAlloc (arena, sizeof (CERTAuthKeyID));    if (authKeyID == NULL) {	error_allocate();    }    if (find_field_bool(data, "authorityKeyIdentifier-radio-keyIdentifier", 			PR_TRUE)) {	authKeyID->keyID.data = PORT_ArenaAlloc (arena, PORT_Strlen 				       ((char *)issuerCert->subjectKeyID.data));	if (authKeyID->keyID.data == NULL) {	    error_allocate();	}	PORT_Memcpy (authKeyID->keyID.data, issuerCert->subjectKeyID.data, 		     authKeyID->keyID.len = 		        PORT_Strlen((char *)issuerCert->subjectKeyID.data));    } else {		PORT_Assert (arena);	genNames = (CERTGeneralName *) PORT_ArenaZAlloc (arena, (sizeof(CERTGeneralName)));	if (genNames == NULL){	    error_allocate();	}	genNames->l.next = genNames->l.prev = &(genNames->l);	genNames->type = certDirectoryName;	directoryName = CERT_AsciiToName(issuerCert->subjectName);	if (!directoryName) {	    error_out("ERROR: Unable to create Directory Name");	}	rv = CERT_CopyName (arena, &genNames->name.directoryName, 			    directoryName);        CERT_DestroyName (directoryName);	if (rv != SECSuccess) {	    error_out("ERROR: Unable to copy Directory Name");	}	authKeyID->authCertIssuer = genNames;	if (authKeyID->authCertIssuer == NULL && SECFailure == 	                                            PORT_GetError ()) {	    error_out("ERROR: Unable to get Issuer General Name for Authority Key ID Extension");	}	authKeyID->authCertSerialNumber = issuerCert->serialNumber;    }    rv = EncodeAndAddExtensionValue(arena, extHandle, authKeyID, PR_FALSE, 				    SEC_OID_X509_AUTH_KEY_ID, 				    (EXTEN_VALUE_ENCODER)				    CERT_EncodeAuthKeyID);    if (arena) {	PORT_FreeArena (arena, PR_FALSE);    }    return (rv);}static SECStatus AddPrivKeyUsagePeriod(void             *extHandle, 		      Pair             *data, 		      CERTCertificate  *cert){    char *notBeforeStr;    char *notAfterStr;    PRArenaPool *arena = NULL;    SECStatus rv = SECSuccess;    PKUPEncodedContext *pkup;    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( !arena ) {	error_allocate();    }    pkup = PORT_ArenaZAlloc (arena, sizeof (PKUPEncodedContext));    if (pkup == NULL) {	error_allocate();    }    notBeforeStr = (char *) PORT_Alloc(16 * sizeof(char));    notAfterStr = (char *) PORT_Alloc(16 * sizeof(char));    *notBeforeStr = '\0';    *notAfterStr = '\0';    pkup->arena = arena;    pkup->notBefore.len = 0;    pkup->notBefore.data = NULL;    pkup->notAfter.len = 0;    pkup->notAfter.data = NULL;    if (find_field_bool(data, "privKeyUsagePeriod-radio-notBefore", PR_TRUE) ||	find_field_bool(data, "privKeyUsagePeriod-radio-both", PR_TRUE)) {	pkup->notBefore.len = 15;	pkup->notBefore.data = (unsigned char *)notBeforeStr;	if (find_field_bool(data, "privKeyUsagePeriod-notBefore-radio-manual", 			    PR_TRUE)) {	    PORT_Strcat(notBeforeStr,find_field(data,					   "privKeyUsagePeriod-notBefore-year",					   PR_TRUE));	    PORT_Strcat(notBeforeStr,find_field(data,					   "privKeyUsagePeriod-notBefore-month",					   PR_TRUE));	    PORT_Strcat(notBeforeStr,find_field(data,					   "privKeyUsagePeriod-notBefore-day",					   PR_TRUE));	    PORT_Strcat(notBeforeStr,find_field(data,					   "privKeyUsagePeriod-notBefore-hour",					   PR_TRUE));	    PORT_Strcat(notBeforeStr,find_field(data,					  "privKeyUsagePeriod-notBefore-minute",					   PR_TRUE));	    PORT_Strcat(notBeforeStr,find_field(data,					  "privKeyUsagePeriod-notBefore-second",					   PR_TRUE));	    if ((*(notBeforeStr + 14) != '\0') ||		(!isdigit(*(notBeforeStr + 13))) ||		(*(notBeforeStr + 12) >= '5' && *(notBeforeStr + 12) <= '0') ||		(!isdigit(*(notBeforeStr + 11))) ||		(*(notBeforeStr + 10) >= '5' && *(notBeforeStr + 10) <= '0') ||		(!isdigit(*(notBeforeStr + 9))) ||		(*(notBeforeStr + 8) >= '2' && *(notBeforeStr + 8) <= '0') ||		(!isdigit(*(notBeforeStr + 7))) ||		(*(notBeforeStr + 6) >= '3' && *(notBeforeStr + 6) <= '0') ||		(!isdigit(*(notBeforeStr + 5))) ||		(*(notBeforeStr + 4) >= '1' && *(notBeforeStr + 4) <= '0') ||		(!isdigit(*(notBeforeStr + 3))) ||		(!isdigit(*(notBeforeStr + 2))) ||		(!isdigit(*(notBeforeStr + 1))) ||		(!isdigit(*(notBeforeStr + 0))) ||		(*(notBeforeStr + 8) == '2' && *(notBeforeStr + 9) >= '4') ||		(*(notBeforeStr + 6) == '3' && *(notBeforeStr + 7) >= '1') ||		(*(notBeforeStr + 4) == '1' && *(notBeforeStr + 5) >= '2')) {		error_out("ERROR: Improperly formated private key usage period");	    }	    *(notBeforeStr + 14) = 'Z';	    *(notBeforeStr + 15) = '\0';	} else {	    if ((*(cert->validity.notBefore.data) > '5') || 		((*(cert->validity.notBefore.data) == '5') &&		 (*(cert->validity.notBefore.data + 1) != '0'))) {		PORT_Strcat(notBeforeStr, "19");	    } else {		PORT_Strcat(notBeforeStr, "20");	    }	    PORT_Strcat(notBeforeStr, (char *)cert->validity.notBefore.data);	}    }    if (find_field_bool(data, "privKeyUsagePeriod-radio-notAfter", PR_TRUE) ||	find_field_bool(data, "privKeyUsagePeriod-radio-both", PR_TRUE)) {	pkup->notAfter.len = 15;	pkup->notAfter.data = (unsigned char *)notAfterStr;	PORT_Strcat(notAfterStr,find_field(data,"privKeyUsagePeriod-notAfter-year", 				      PR_TRUE));	PORT_Strcat(notAfterStr,find_field(data,"privKeyUsagePeriod-notAfter-month",				      PR_TRUE));	PORT_Strcat(notAfterStr,find_field(data,"privKeyUsagePeriod-notAfter-day", 				      PR_TRUE));	PORT_Strcat(notAfterStr,find_field(data,"privKeyUsagePeriod-notAfter-hour", 				      PR_TRUE));	PORT_Strcat(notAfterStr,find_field(data,"privKeyUsagePeriod-notAfter-minute",				      PR_TRUE));	PORT_Strcat(notAfterStr,find_field(data,"privKeyUsagePeriod-notAfter-second",				      PR_TRUE));	if ((*(notAfterStr + 14) != '\0') ||	    (!isdigit(*(notAfterStr + 13))) ||	    (*(notAfterStr + 12) >= '5' && *(notAfterStr + 12) <= '0') ||	    (!isdigit(*(notAfterStr + 11))) ||	    (*(notAfterStr + 10) >= '5' && *(notAfterStr + 10) <= '0') ||	    (!isdigit(*(notAfterStr + 9))) ||	    (*(notAfterStr + 8) >= '2' && *(notAfterStr + 8) <= '0') ||	    (!isdigit(*(notAfterStr + 7))) ||	    (*(notAfterStr + 6) >= '3' && *(notAfterStr + 6) <= '0') ||	    (!isdigit(*(notAfterStr + 5))) ||	    (*(notAfterStr + 4) >= '1' && *(notAfterStr + 4) <= '0') ||	    (!isdigit(*(notAfterStr + 3))) ||	    (!isdigit(*(notAfterStr + 2))) ||	    (!isdigit(*(notAfterStr + 1))) ||	    (!isdigit(*(notAfterStr + 0))) ||	    (*(notAfterStr + 8) == '2' && *(notAfterStr + 9) >= '4') ||	    (*(notAfterStr + 6) == '3' && *(notAfterStr + 7) >= '1') ||	    (*(notAfterStr + 4) == '1' && *(notAfterStr + 5) >= '2')) {	    error_out("ERROR: Improperly formated private key usage period");	}	*(notAfterStr + 14) = 'Z';	*(notAfterStr + 15) = '\0';    }	    PORT_Assert (arena);    rv = EncodeAndAddExtensionValue(arena, extHandle, pkup, 				    find_field_bool(data,						    "privKeyUsagePeriod-crit", 						    PR_TRUE), 				    SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD, 				    (EXTEN_VALUE_ENCODER)				    CERT_EncodePublicKeyUsagePeriod);    if (arena) {	PORT_FreeArena (arena, PR_FALSE);    }    if (notBeforeStr != NULL) {	PORT_Free(notBeforeStr);    }    if (notAfterStr != NULL) {	PORT_Free(notAfterStr);    }    return (rv);}    static SECStatus AddBasicConstraint(void   *extHandle, 		   Pair   *data){    CERTBasicConstraints  basicConstraint;    SECItem               encodedValue;    SECStatus             rv;    encodedValue.data = NULL;    encodedValue.len = 0;    basicConstraint.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT;    basicConstraint.isCA = (find_field_bool(data,"basicConstraints-cA-radio-CA",					    PR_TRUE));    if (find_field_bool(data,"basicConstraints-pathLengthConstraint", PR_TRUE)){	basicConstraint.pathLenConstraint = atoi 	    (find_field(data,"basicConstraints-pathLengthConstraint-text", 			PR_TRUE));    }        rv = CERT_EncodeBasicConstraintValue (NULL, &basicConstraint, 					  &encodedValue);    if (rv)	return (rv);    rv = CERT_AddExtension(extHandle, SEC_OID_X509_BASIC_CONSTRAINTS, 			   &encodedValue, 			   (find_field_bool(data,"basicConstraints-crit", 					    PR_TRUE)), PR_TRUE);    PORT_Free (encodedValue.data);    return (rv);}static SECStatus AddNscpCertType (void  *extHandle, 		 Pair  *data){    SECItem            bitStringValue;    unsigned char      CertType = 0x0;    if (find_field_bool(data,"netscape-cert-type-ssl-client", PR_TRUE)){	CertType |= (0x80 >> 0);    }    if (find_field_bool(data,"netscape-cert-type-ssl-server", PR_TRUE)){	CertType |= (0x80 >> 1);    }    if (find_field_bool(data,"netscape-cert-type-smime", PR_TRUE)){	CertType |= (0x80 >> 2);    }    if (find_field_bool(data,"netscape-cert-type-object-signing", PR_TRUE)){	CertType |= (0x80 >> 3);    }    if (find_field_bool(data,"netscape-cert-type-reserved", PR_TRUE)){	CertType |= (0x80 >> 4);    }    if (find_field_bool(data,"netscape-cert-type-ssl-ca", PR_TRUE)) {	CertType |= (0x80 >> 5);    }    if (find_field_bool(data,"netscape-cert-type-smime-ca", PR_TRUE)) {	CertType |= (0x80 >> 6);    }    if (find_field_bool(data,"netscape-cert-type-object-signing-ca", PR_TRUE)) {	CertType |= (0x80 >> 7);    }    bitStringValue.data = &CertType;    bitStringValue.len = 1;    return (CERT_EncodeAndAddBitStrExtension	    (extHandle, SEC_OID_NS_CERT_EXT_CERT_TYPE, &bitStringValue,	     (find_field_bool(data, "netscape-cert-type-crit", PR_TRUE))));}static SECStatusadd_IA5StringExtension(void    *extHandle, 		       char    *string, 		       PRBool  crit, 		       int     idtag){    SECItem                    encodedValue;    SECStatus                  rv;    encodedValue.data = NULL;    encodedValue.len = 0;    rv = CERT_EncodeIA5TypeExtension(NULL, string, &encodedValue);    if (rv) {	return (rv);    }    return (CERT_AddExtension(extHandle, idtag, &encodedValue, crit, PR_TRUE));}static SECItem *string_to_oid(char  *string){    int             i;    int             length = 20;    int             remaining;    int             first_value;    int             second_value;    int             value;    int             oidLength;    unsigned char   *oidString;    unsigned char   *write;    unsigned char   *read;    unsigned char   *temp;    SECItem         *oid;            remaining = length;    i = 0;    while (*string == ' ') {	string++;    }    while (isdigit(*(string + i))) {	i++;    }    if (*(string + i) == '.') {	*(string + i) = '\0';    } else {	error_out("ERROR: Improperly formated OID");    }    first_value = atoi(string);    if (first_value < 0 || first_value > 2) {	error_out("ERROR: Improperly formated OID");    }    string += i + 1;    i = 0;    while (isdigit(*(string + i))) {	i++;    }    if (*(string + i) == '.') {	*(string + i) = '\0';    } else {	error_out("ERROR: Improperly formated OID");    }    second_value = atoi(string);    if (second_value < 0 || second_value > 39) {	error_out("ERROR: Improperly formated OID");    }    oidString = PORT_ZAlloc(2);    *oidString = (first_value * 40) + second_value;    *(oidString + 1) = '\0';    oidLength = 1;    string += i + 1;    i = 0;    temp = write = PORT_ZAlloc(length);    while (*string != '\0') {	value = 0;	while(isdigit(*(string + i))) {	    i++;	}	if (*(string + i) == '\0') {	    value = atoi(string);	    string += i;	} else {	    if (*(string + i) == '.') {		*(string + i) == '\0';		value = atoi(string);		string += i + 1;	    } else {		*(string + i) = '\0';		i++;		value = atoi(string);		if (*(string + i) == ' ') {		    while (*(string + i) == ' ')			i++;		}		if (*(string + i) != '\0') {		    error_out("ERROR: Improperly formated OID");		}	    }	}	i = 0;	while (value != 0) {	    if (remaining < 1) {		remaining += length;		length = length * 2;		temp = PORT_Realloc(temp, length);		write = temp + length - remaining;	    }	    *write = (value & 0x7f) | (0x80);	    write++;	    remaining--;	    value = value >> 7;	}	*temp = *temp & (0x7f);	oidLength += write - temp;	oidString = PORT_Realloc(oidString, (oidLength + 1));	read = write - 1;	write = oidLength + oidString - 1;	for (i = 0; i < (length - remaining); i++) {	    *write = *read;	    write--;	    read++;	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?