/security/nss/cmd/certcgi/certcgi.c
C | 2408 lines | 2107 code | 224 blank | 77 comment | 557 complexity | c127247590ce3c50e5db505d09422edb MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause, GPL-2.0, JSON, Apache-2.0, 0BSD
Large files files are truncated, but you can click here to view the full file
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
- /* Cert-O-Matic CGI */
- #include "nspr.h"
- #include "prtypes.h"
- #include "prtime.h"
- #include "prlong.h"
- #include "pk11func.h"
- #include "cert.h"
- #include "cryptohi.h"
- #include "secoid.h"
- #include "secder.h"
- #include "genname.h"
- #include "xconst.h"
- #include "secutil.h"
- #include "pk11pqg.h"
- #include "certxutl.h"
- #include "nss.h"
- /* #define TEST 1 */
- /* #define FILEOUT 1 */
- /* #define OFFLINE 1 */
- #define START_FIELDS 100
- #define PREFIX_LEN 6
- #define SERIAL_FILE "../serial"
- #define DB_DIRECTORY ".."
- static char *progName;
- typedef struct PairStr Pair;
- struct PairStr {
- char *name;
- char *data;
- };
- char prefix[PREFIX_LEN];
- const SEC_ASN1Template CERTIA5TypeTemplate[] = {
- { SEC_ASN1_IA5_STRING }
- };
- SECKEYPrivateKey *privkeys[9] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL};
- #ifdef notdef
- const SEC_ASN1Template CERT_GeneralNameTemplate[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate }
- };
- #endif
- static void
- error_out(char *error_string)
- {
- printf("Content-type: text/plain\n\n");
- printf(error_string);
- fflush(stderr);
- fflush(stdout);
- exit(1);
- }
- static void
- error_allocate(void)
- {
- error_out("ERROR: Unable to allocate memory");
- }
- static char *
- make_copy_string(char *read_pos,
- int length,
- char sentinal_value)
- /* copys string from to a new string it creates and
- returns a pointer to the new string */
- {
- int remaining = length;
- char *write_pos;
- char *new;
- new = write_pos = (char *) PORT_Alloc (length);
- if (new == NULL) {
- error_allocate();
- }
- while (*read_pos != sentinal_value) {
- if (remaining == 1) {
- remaining += length;
- length = length * 2;
- new = PORT_Realloc(new,length);
- if (new == NULL) {
- error_allocate();
- }
- write_pos = new + length - remaining;
- }
- *write_pos = *read_pos;
- ++write_pos;
- ++read_pos;
- remaining = remaining - 1;
- }
- *write_pos = '\0';
- return new;
- }
- static SECStatus
- clean_input(Pair *data)
- /* converts the non-alphanumeric characters in a form post
- from hex codes back to characters */
- {
- int length;
- int hi_digit;
- int low_digit;
- char character;
- char *begin_pos;
- char *read_pos;
- char *write_pos;
- PRBool name = PR_TRUE;
- begin_pos = data->name;
- while (begin_pos != NULL) {
- length = strlen(begin_pos);
- read_pos = write_pos = begin_pos;
- while ((read_pos - begin_pos) < length) {
- if (*read_pos == '+') {
- *read_pos = ' ';
- }
- if (*read_pos == '%') {
- hi_digit = *(read_pos + 1);
- low_digit = *(read_pos +2);
- read_pos += 3;
- if (isdigit(hi_digit)){
- hi_digit = hi_digit - '0';
- } else {
- hi_digit = toupper(hi_digit);
- if (isxdigit(hi_digit)) {
- hi_digit = (hi_digit - 'A') + 10;
- } else {
- error_out("ERROR: Form data incorrectly formated");
- }
- }
- if (isdigit(low_digit)){
- low_digit = low_digit - '0';
- } else {
- low_digit = toupper(low_digit);
- if ((low_digit >='A') && (low_digit <= 'F')) {
- low_digit = (low_digit - 'A') + 10;
- } else {
- error_out("ERROR: Form data incorrectly formated");
- }
- }
- character = (hi_digit << 4) | low_digit;
- if (character != 10) {
- *write_pos = character;
- ++write_pos;
- }
- } else {
- *write_pos = *read_pos;
- ++write_pos;
- ++read_pos;
- }
- }
- *write_pos = '\0';
- if (name == PR_TRUE) {
- begin_pos = data->data;
- name = PR_FALSE;
- } else {
- data++;
- begin_pos = data->name;
- name = PR_TRUE;
- }
- }
- return SECSuccess;
- }
- static char *
- make_name(char *new_data)
- /* gets the next field name in the input string and returns
- a pointer to a string containing a copy of it */
- {
- int length = 20;
- char *name;
- name = make_copy_string(new_data, length, '=');
- return name;
- }
-
- static char *
- make_data(char *new_data)
- /* gets the data for the next field in the input string
- and returns a pointer to a string containing it */
- {
- int length = 100;
- char *data;
- char *read_pos;
- read_pos = new_data;
- while (*(read_pos - 1) != '=') {
- ++read_pos;
- }
- data = make_copy_string(read_pos, length, '&');
- return data;
- }
- static Pair
- make_pair(char *new_data)
- /* makes a pair name/data pair from the input string */
- {
- Pair temp;
- temp.name = make_name(new_data);
- temp.data = make_data(new_data);
- return temp;
- }
- static Pair *
- make_datastruct(char *data, int len)
- /* parses the input from the form post into a data
- structure of field name/data pairs */
- {
- Pair *datastruct;
- Pair *current;
- char *curr_pos;
- int fields = START_FIELDS;
- int remaining = START_FIELDS;
- curr_pos = data;
- datastruct = current = (Pair *) PORT_Alloc(fields * sizeof(Pair));
- if (datastruct == NULL) {
- error_allocate();
- }
- while (curr_pos - data < len) {
- if (remaining == 1) {
- remaining += fields;
- fields = fields * 2;
- datastruct = (Pair *) PORT_Realloc
- (datastruct, fields * sizeof(Pair));
- if (datastruct == NULL) {
- error_allocate();
- }
- current = datastruct + (fields - remaining);
- }
- *current = make_pair(curr_pos);
- while (*curr_pos != '&') {
- ++curr_pos;
- }
- ++curr_pos;
- ++current;
- remaining = remaining - 1;
- }
- current->name = NULL;
- return datastruct;
- }
- static char *
- return_name(Pair *data_struct,
- int n)
- /* returns a pointer to the name of the nth
- (starting from 0) item in the data structure */
- {
- char *name;
- if ((data_struct + n)->name != NULL) {
- name = (data_struct + n)->name;
- return name;
- } else {
- return NULL;
- }
- }
- static char *
- return_data(Pair *data_struct,int n)
- /* returns a pointer to the data of the nth (starting from 0)
- itme in the data structure */
- {
- char *data;
- data = (data_struct + n)->data;
- return data;
- }
- static char *
- add_prefix(char *field_name)
- {
- extern char prefix[PREFIX_LEN];
- int i = 0;
- char *rv;
- char *write;
- rv = write = PORT_Alloc(PORT_Strlen(prefix) + PORT_Strlen(field_name) + 1);
- for(i = 0; i < PORT_Strlen(prefix); i++) {
- *write = prefix[i];
- write++;
- }
- *write = '\0';
- rv = PORT_Strcat(rv,field_name);
- return rv;
- }
- static char *
- find_field(Pair *data,
- char *field_name,
- PRBool add_pre)
- /* returns a pointer to the data of the first pair
- thats name matches the string it is passed */
- {
- int i = 0;
- char *retrieved;
- int found = 0;
- if (add_pre) {
- field_name = add_prefix(field_name);
- }
- while(return_name(data, i) != NULL) {
- if (PORT_Strcmp(return_name(data, i), field_name) == 0) {
- retrieved = return_data(data, i);
- found = 1;
- break;
- }
- i++;
- }
- if (!found) {
- retrieved = NULL;
- }
- return retrieved;
- }
- static PRBool
- find_field_bool(Pair *data,
- char *fieldname,
- PRBool add_pre)
- {
- char *rv;
- rv = find_field(data, fieldname, add_pre);
-
- if ((rv != NULL) && (PORT_Strcmp(rv, "true")) == 0) {
- return PR_TRUE;
- } else {
- return PR_FALSE;
- }
- }
- static char *
- update_data_by_name(Pair *data,
- char *field_name,
- char *new_data)
- /* replaces the data in the data structure associated with
- a name with new data, returns null if not found */
- {
- int i = 0;
- int found = 0;
- int length = 100;
- char *new;
- while (return_name(data, i) != NULL) {
- if (PORT_Strcmp(return_name(data, i), field_name) == 0) {
- new = make_copy_string( new_data, length, '\0');
- PORT_Free(return_data(data, i));
- found = 1;
- (*(data + i)).data = new;
- break;
- }
- i++;
- }
- if (!found) {
- new = NULL;
- }
- return new;
- }
- static char *
- update_data_by_index(Pair *data,
- int n,
- char *new_data)
- /* replaces the data of a particular index in the data structure */
- {
- int length = 100;
- char *new;
- new = make_copy_string(new_data, length, '\0');
- PORT_Free(return_data(data, n));
- (*(data + n)).data = new;
- return new;
- }
- static Pair *
- add_field(Pair *data,
- char* field_name,
- char* field_data)
- /* adds a new name/data pair to the data structure */
- {
- int i = 0;
- int j;
- int name_length = 100;
- int data_length = 100;
- while(return_name(data, i) != NULL) {
- i++;
- }
- j = START_FIELDS;
- while ( j < (i + 1) ) {
- j = j * 2;
- }
- if (j == (i + 1)) {
- data = (Pair *) PORT_Realloc(data, (j * 2) * sizeof(Pair));
- if (data == NULL) {
- error_allocate();
- }
- }
- (*(data + i)).name = make_copy_string(field_name, name_length, '\0');
- (*(data + i)).data = make_copy_string(field_data, data_length, '\0');
- (data + i + 1)->name = NULL;
- return data;
- }
- static CERTCertificateRequest *
- makeCertReq(Pair *form_data,
- int which_priv_key)
- /* makes and encodes a certrequest */
- {
- PK11SlotInfo *slot;
- CERTCertificateRequest *certReq = NULL;
- CERTSubjectPublicKeyInfo *spki;
- SECKEYPrivateKey *privkey = NULL;
- SECKEYPublicKey *pubkey = NULL;
- CERTName *name;
- char *key;
- extern SECKEYPrivateKey *privkeys[9];
- int keySizeInBits;
- char *challenge = "foo";
- SECStatus rv = SECSuccess;
- PQGParams *pqgParams = NULL;
- PQGVerify *pqgVfy = NULL;
- name = CERT_AsciiToName(find_field(form_data, "subject", PR_TRUE));
- if (name == NULL) {
- error_out("ERROR: Unable to create Subject Name");
- }
- key = find_field(form_data, "key", PR_TRUE);
- if (key == NULL) {
- switch (*find_field(form_data, "keysize", PR_TRUE)) {
- case '0':
- keySizeInBits = 2048;
- break;
- case '1':
- keySizeInBits = 1024;
- break;
- case '2':
- keySizeInBits = 512;
- break;
- default:
- error_out("ERROR: Unsupported Key length selected");
- }
- if (find_field_bool(form_data, "keyType-dsa", PR_TRUE)) {
- rv = PK11_PQG_ParamGen(keySizeInBits, &pqgParams, &pqgVfy);
- if (rv != SECSuccess) {
- error_out("ERROR: Unable to generate PQG parameters");
- }
- slot = PK11_GetBestSlot(CKM_DSA_KEY_PAIR_GEN, NULL);
- privkey = PK11_GenerateKeyPair(slot, CKM_DSA_KEY_PAIR_GEN,
- pqgParams,&pubkey, PR_FALSE,
- PR_TRUE, NULL);
- } else {
- privkey = SECKEY_CreateRSAPrivateKey(keySizeInBits, &pubkey, NULL);
- }
- privkeys[which_priv_key] = privkey;
- spki = SECKEY_CreateSubjectPublicKeyInfo(pubkey);
- } else {
- spki = SECKEY_ConvertAndDecodePublicKeyAndChallenge(key, challenge,
- NULL);
- if (spki == NULL) {
- error_out("ERROR: Unable to decode Public Key and Challenge String");
- }
- }
- certReq = CERT_CreateCertificateRequest(name, spki, NULL);
- if (certReq == NULL) {
- error_out("ERROR: Unable to create Certificate Request");
- }
- if (pubkey != NULL) {
- SECKEY_DestroyPublicKey(pubkey);
- }
- if (spki != NULL) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
- if (pqgParams != NULL) {
- PK11_PQG_DestroyParams(pqgParams);
- }
- if (pqgVfy != NULL) {
- PK11_PQG_DestroyVerify(pqgVfy);
- }
- return certReq;
- }
- static CERTCertificate *
- MakeV1Cert(CERTCertDBHandle *handle,
- CERTCertificateRequest *req,
- char *issuerNameStr,
- PRBool selfsign,
- int serialNumber,
- int warpmonths,
- Pair *data)
- {
- CERTCertificate *issuerCert = NULL;
- CERTValidity *validity;
- CERTCertificate *cert = NULL;
- PRExplodedTime printableTime;
- PRTime now,
- after;
- SECStatus rv;
-
-
- if ( !selfsign ) {
- issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);
- if (!issuerCert) {
- error_out("ERROR: Could not find issuer's certificate");
- return NULL;
- }
- }
- if (find_field_bool(data, "manValidity", PR_TRUE)) {
- rv = DER_AsciiToTime(&now, find_field(data, "notBefore", PR_TRUE));
- } else {
- now = PR_Now();
- }
- PR_ExplodeTime (now, PR_GMTParameters, &printableTime);
- if ( warpmonths ) {
- printableTime.tm_month += warpmonths;
- now = PR_ImplodeTime (&printableTime);
- PR_ExplodeTime (now, PR_GMTParameters, &printableTime);
- }
- if (find_field_bool(data, "manValidity", PR_TRUE)) {
- rv = DER_AsciiToTime(&after, find_field(data, "notAfter", PR_TRUE));
- PR_ExplodeTime (after, PR_GMTParameters, &printableTime);
- } else {
- printableTime.tm_month += 3;
- after = PR_ImplodeTime (&printableTime);
- }
- /* note that the time is now in micro-second unit */
- validity = CERT_CreateValidity (now, after);
- if ( selfsign ) {
- cert = CERT_CreateCertificate
- (serialNumber,&(req->subject), validity, req);
- } else {
- cert = CERT_CreateCertificate
- (serialNumber,&(issuerCert->subject), validity, req);
- }
-
- CERT_DestroyValidity(validity);
- if ( issuerCert ) {
- CERT_DestroyCertificate (issuerCert);
- }
- return(cert);
- }
- static int
- get_serial_number(Pair *data)
- {
- int serial = 0;
- int error;
- char *filename = SERIAL_FILE;
- char *SN;
- FILE *serialFile;
- if (find_field_bool(data, "serial-auto", PR_TRUE)) {
- serialFile = fopen(filename, "r");
- if (serialFile != NULL) {
- fread(&serial, sizeof(int), 1, serialFile);
- if (ferror(serialFile) != 0) {
- error_out("Error: Unable to read serial number file");
- }
- if (serial == 4294967295) {
- serial = 21;
- }
- fclose(serialFile);
- ++serial;
- serialFile = fopen(filename,"w");
- if (serialFile == NULL) {
- error_out("ERROR: Unable to open serial number file for writing");
- }
- fwrite(&serial, sizeof(int), 1, serialFile);
- if (ferror(serialFile) != 0) {
- error_out("Error: Unable to write to serial number file");
- }
- } else {
- fclose(serialFile);
- serialFile = fopen(filename,"w");
- if (serialFile == NULL) {
- error_out("ERROR: Unable to open serial number file");
- }
- serial = 21;
- fwrite(&serial, sizeof(int), 1, serialFile);
- if (ferror(serialFile) != 0) {
- error_out("Error: Unable to write to serial number file");
- }
- error = ferror(serialFile);
- if (error != 0) {
- error_out("ERROR: Unable to write to serial file");
- }
- }
- fclose(serialFile);
- } else {
- SN = find_field(data, "serial_value", PR_TRUE);
- while (*SN != '\0') {
- serial = serial * 16;
- if ((*SN >= 'A') && (*SN <='F')) {
- serial += *SN - 'A' + 10;
- } else {
- if ((*SN >= 'a') && (*SN <='f')) {
- serial += *SN - 'a' + 10;
- } else {
- serial += *SN - '0';
- }
- }
- ++SN;
- }
- }
- return serial;
- }
-
- typedef SECStatus (* EXTEN_VALUE_ENCODER)
- (PRArenaPool *extHandle, void *value, SECItem *encodedValue);
- static SECStatus
- EncodeAndAddExtensionValue(
- PRArenaPool *arena,
- void *extHandle,
- void *value,
- PRBool criticality,
- int extenType,
- EXTEN_VALUE_ENCODER EncodeValueFn)
- {
- SECItem encodedValue;
- SECStatus rv;
-
- encodedValue.data = NULL;
- encodedValue.len = 0;
- rv = (*EncodeValueFn)(arena, value, &encodedValue);
- if (rv != SECSuccess) {
- error_out("ERROR: Unable to encode extension value");
- }
- rv = CERT_AddExtension
- (extHandle, extenType, &encodedValue, criticality, PR_TRUE);
- return (rv);
- }
- static SECStatus
- AddKeyUsage (void *extHandle,
- Pair *data)
- {
- SECItem bitStringValue;
- unsigned char keyUsage = 0x0;
- if (find_field_bool(data,"keyUsage-digitalSignature", PR_TRUE)){
- keyUsage |= (0x80 >> 0);
- }
- if (find_field_bool(data,"keyUsage-nonRepudiation", PR_TRUE)){
- keyUsage |= (0x80 >> 1);
- }
- if (find_field_bool(data,"keyUsage-keyEncipherment", PR_TRUE)){
- keyUsage |= (0x80 >> 2);
- }
- if (find_field_bool(data,"keyUsage-dataEncipherment", PR_TRUE)){
- keyUsage |= (0x80 >> 3);
- }
- if (find_field_bool(data,"keyUsage-keyAgreement", PR_TRUE)){
- keyUsage |= (0x80 >> 4);
- }
- if (find_field_bool(data,"keyUsage-keyCertSign", PR_TRUE)) {
- keyUsage |= (0x80 >> 5);
- }
- if (find_field_bool(data,"keyUsage-cRLSign", PR_TRUE)) {
- keyUsage |= (0x80 >> 6);
- }
- bitStringValue.data = &keyUsage;
- bitStringValue.len = 1;
- return (CERT_EncodeAndAddBitStrExtension
- (extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue,
- (find_field_bool(data, "keyUsage-crit", PR_TRUE))));
- }
- static CERTOidSequence *
- CreateOidSequence(void)
- {
- CERTOidSequence *rv = (CERTOidSequence *)NULL;
- PRArenaPool *arena = (PRArenaPool *)NULL;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if( (PRArenaPool *)NULL == arena ) {
- goto loser;
- }
- rv = (CERTOidSequence *)PORT_ArenaZAlloc(arena, sizeof(CERTOidSequence));
- if( (CERTOidSequence *)NULL == rv ) {
- goto loser;
- }
- rv->oids = (SECItem **)PORT_ArenaZAlloc(arena, sizeof(SECItem *));
- if( (SECItem **)NULL == rv->oids ) {
- goto loser;
- }
- rv->arena = arena;
- return rv;
- loser:
- if( (PRArenaPool *)NULL != arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
- return (CERTOidSequence *)NULL;
- }
- static SECStatus
- AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag)
- {
- SECItem **oids;
- PRUint32 count = 0;
- SECOidData *od;
- od = SECOID_FindOIDByTag(oidTag);
- if( (SECOidData *)NULL == od ) {
- return SECFailure;
- }
- for( oids = os->oids; (SECItem *)NULL != *oids; oids++ ) {
- count++;
- }
- /* ArenaZRealloc */
- {
- PRUint32 i;
- oids = (SECItem **)PORT_ArenaZAlloc(os->arena, sizeof(SECItem *) * (count+2));
- if( (SECItem **)NULL == oids ) {
- return SECFailure;
- }
-
- for( i = 0; i < count; i++ ) {
- oids[i] = os->oids[i];
- }
- /* ArenaZFree(os->oids); */
- }
- os->oids = oids;
- os->oids[count] = &od->oid;
- return SECSuccess;
- }
- static SECItem *
- EncodeOidSequence(CERTOidSequence *os)
- {
- SECItem *rv;
- extern const SEC_ASN1Template CERT_OidSeqTemplate[];
- rv = (SECItem *)PORT_ArenaZAlloc(os->arena, sizeof(SECItem));
- if( (SECItem *)NULL == rv ) {
- goto loser;
- }
- if( !SEC_ASN1EncodeItem(os->arena, rv, os, CERT_OidSeqTemplate) ) {
- goto loser;
- }
- return rv;
- loser:
- return (SECItem *)NULL;
- }
- static SECStatus
- AddExtKeyUsage(void *extHandle, Pair *data)
- {
- SECStatus rv;
- CERTOidSequence *os;
- SECItem *value;
- PRBool crit;
- os = CreateOidSequence();
- if( (CERTOidSequence *)NULL == os ) {
- return SECFailure;
- }
- if( find_field_bool(data, "extKeyUsage-serverAuth", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH);
- if( SECSuccess != rv ) goto loser;
- }
- if( find_field_bool(data, "extKeyUsage-clientAuth", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH);
- if( SECSuccess != rv ) goto loser;
- }
- if( find_field_bool(data, "extKeyUsage-codeSign", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CODE_SIGN);
- if( SECSuccess != rv ) goto loser;
- }
- if( find_field_bool(data, "extKeyUsage-emailProtect", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT);
- if( SECSuccess != rv ) goto loser;
- }
- if( find_field_bool(data, "extKeyUsage-timeStamp", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_TIME_STAMP);
- if( SECSuccess != rv ) goto loser;
- }
- if( find_field_bool(data, "extKeyUsage-ocspResponder", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_OCSP_RESPONDER);
- if( SECSuccess != rv ) goto loser;
- }
- if( find_field_bool(data, "extKeyUsage-NS-govtApproved", PR_TRUE) ) {
- rv = AddOidToSequence(os, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED);
- if( SECSuccess != rv ) goto loser;
- }
- value = EncodeOidSequence(os);
- crit = find_field_bool(data, "extKeyUsage-crit", PR_TRUE);
- rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, value,
- crit, PR_TRUE);
- /*FALLTHROUGH*/
- loser:
- CERT_DestroyOidSequence(os);
- return rv;
- }
- static SECStatus
- AddSubKeyID(void *extHandle,
- Pair *data,
- CERTCertificate *subjectCert)
- {
- SECItem encodedValue;
- SECStatus rv;
- char *read;
- char *write;
- char *first;
- char character;
- int high_digit = 0,
- low_digit = 0;
- 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, &subjectCert->subjectKeyID, &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;
- CERTPrivKeyUsagePeriod *pkup;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( !arena ) {
- error_allocate();
- }
- pkup = PORT_ArenaZNew (arena, CERTPrivKeyUsagePeriod);
- if (pkup == NULL) {
- error_allocate();
- }
- notBeforeStr = (char *) PORT_Alloc(16 );
- notAfterStr = (char *) PORT_Alloc(16 );
- *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_EncodePrivateKeyUsagePeriod);
- 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 SECStatus
- add_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);
- 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++;
- }
- write = temp;
- remaining = length;
- }
- *(oidString + oidLength) = '\0';
- oid = (SECItem *) PORT_ZAlloc(sizeof(SECItem));
- oid->data = oidString;
- oid->len = oidLength;
- PORT_Free(temp);
- return oid;
- }
- static SECItem *
- string_to_ipaddress(char *string)
- {
- int i = 0;
- int value;
- int j = 0;
- SECItem *ipaddress;
-
- while (*string == ' ') {
- string++;
- }
- ipaddress = (SECItem *) PORT_ZAlloc(sizeof(SECItem));
- ipaddress->data = PORT_ZAlloc(9);
- while (*string != '\0' && j < 8) {
- while (isdigit(*(string + i))) {
- i++;
- }
- if (*(string + i) == '.') {
- *(string + i) = '\0';
- value = atoi(string);
- string = string + i + 1;
- i = 0;
- } else {
- if (*(string + i) == '\0') {
- value = atoi(string);
- string = string + i;
- i = 0;
- } else {
- *(string + i) = '\0';
- while (*(string + i) == ' ') {
- i++;
- }
- if (*(string + i) == '\0') {
- value = atoi(string);
- string = string + i;
- i = 0;
- } else {
- error_out("ERROR: Improperly formated IP Address");
- }
- }
- }
- if (value >= 0 || value < 256) {
- *(ipaddress->data + j) = value;
- } else {
- error_out("ERROR: Improperly formated IP Address");
- }
- j++;
- }
- *(ipaddress->data + j) = '\0';
- if (j != 4 && j != 8) {
- error_out("ERROR: Improperly formated IP Address");
- }
- ipaddress->len = j;
- return ipaddress;
- }
- static SECItem *
- string_to_binary(char *string)
- {
- SECItem *rv;
- int high_digit;
- int low_digit;
- rv = (SECItem *) PORT_ZAlloc(sizeof(SECItem));
- if (rv == NULL) {
- error_allocate();
- }
- rv->data = (unsigned char *) PORT_ZAlloc((PORT_Strlen(string))/3 + 2);
- while (!isxdigit(*string)) {
- string++;
- }
- rv->len = 0;
- while (*string != '\0') {
- if (isxdigit(*string)) {
- if (*string >= '0' && *string <= '9') {
- high_digit = *string - '0';
- } else {
- *string = toupper(*string);
- high_digit = *string - 'A';
- }
- string++;
- if (*string >= '0' && *string <= '9') {
- low_digit = *string - '0';
- } else {
- *string = toupper(*string);
- low_digit = *string = 'A';
- }
- (rv->len)++;
- } else {
- if (*string == ':') {
- string++;
- } else {
- if (*string == ' ') {
- while (*string == ' ') {
- string++;
- }
- }
- if (*string != '\0') {
- error_out("ERROR: Improperly formated binary encoding");
- }
- }
- }
- }
- return rv;
- }
- static SECStatus
- MakeGeneralName(char *name,
- CERTGeneralName *genName,
- PRArenaPool *arena)
- {
- SECItem *oid;
- SECOidData *oidData;
- SECItem *ipaddress;
- SECItem *temp = NULL;
- int i;
- int nameType;
- PRBool binary = PR_FALSE;
- SECStatus rv = SECSuccess;
- PRBool nickname = PR_FALSE;
- PORT_Assert(genName);
- PORT_Assert(arena);
- nameType = *(name + PORT_Strlen(name) - 1) - '0';
- if (nameType == 0 && *(name +PORT_Strlen(name) - 2) == '1') {
- nickname = PR_TRUE;
- nameType = certOtherName;
- }
- if (nameType < 1 || nameType > 9) {
- error_out("ERROR: Unknown General Name Type");
- }
- *(name + PORT_Strlen(name) - 4) = '\0';
- genName->type = nameType;
-
- switch (genName->type) {
- case certURI:
- case certRFC822Name:
- case certDNSName: {
- genName->name.other.data = (unsigned char *)name;
- genName->name.other.len = PORT_Strlen(name);
- break;
- }
-
- case certIPAddress: {
- ipaddress = string_to_ipaddress(name);
- genName->name.other.data = ipaddress->data;
- genName->name.other.len = ipaddress->len;
- break;
- }
-
- case certRegisterID: {
- oid = string_to_oid(name);
- genName->name.other.data = oid->data;
- genName->name.other.len = oid->len;
- break;
- }
-
- case certEDIPartyName:
- case certX400Address: {
-
- genName->name.other.data = PORT_ArenaAlloc (arena,
- PORT_Strlen (name) + 2);
- if (genName->name.other.data == NULL) {
- error_allocate();
- }
-
- PORT_Memcpy (genName->name.other.data + 2, name, PORT_Strlen (name));
- /* This may not be accurate for all cases.
- For now, use this tag type */
- genName->name.other.data[0] = (char)(((genName->type - 1) &
- 0x1f)| 0x80);
- genName->name.other.data[1] = (char)PORT_Strlen (name);
- genName->name.other.len = PORT_Strlen (name) + 2;
- break;
- }
-
- case certOtherName: {
- i = 0;
- if (!nickname) {
- while (!isdigit(*(name + PORT_Strlen(name) - i))) {
- i++;
- }
- if (*(name + PORT_Strlen(name) - i) == '1') {
- binary = PR_TRUE;
- } else {
- binary = PR_FALSE;
- }
- while (*(name + PORT_Strlen(name) - i) != '-') {
- i++;
- }
- *(name + PORT_Strlen(name) - i - 1) = '\0';
- i = 0;
- while (*(name + i) != '-') {
- i++;
- }
- *(name + i - 1) = '\0';
- oid = string_to_oid(name + i + 2);
- } else {
- oidData = SECOID_FindOIDByTag(SEC_OID_NETSCAPE_NICKNAME);
- oid = &oidData->oid;
- while (*(name + PORT_Strlen(name) - i) != '-') {
- i++;
- }
- *(name + PORT_Strlen(name) - i) = '\0';
- }
- genName->name.OthName.oid.data = oid->data;
- genName->name.OthName.oid.len = oid->len;
- if (binary) {
- temp = string_to_binary(name);
- genName->name.OthName.name.data = temp->data;
- genName->name.OthName.name.len = temp->len;
- } else {
- temp = (SECItem *) PORT_ZAlloc(sizeof(SECItem));
- if (temp == NULL) {
- error_allocate();
- }
- temp->data = (unsigned char *)name;
- temp->len = PORT_Strlen(name);
- SEC_ASN1EncodeItem (arena, &(genName->name.OthName.name), temp,
- CERTIA5TypeTemplate);
- }
- PORT_Free(temp);
- break;
- }
-
- case certDirectoryName: {
- CERTName *directoryName = NULL;
-
- directoryName = CERT_AsciiToName (name);
- if (!directoryName) {
- error_out("ERROR: Improperly formated alternative name");
- break;
- }
- rv = CERT_CopyName (arena, &genName->name.directoryName,
- directoryName);
- CERT_DestroyName (directoryName);
-
- break;
- }
- }
- genName->l.next = &(genName->l);
- genName->l.prev = &(genName->l);
- return rv;
- }
- static CERTGeneralName *
- MakeAltName(Pair *data,
- char *which,
- PRArenaPool *arena)
- {
- CERTGeneralName *SubAltName;
- CERTGeneralName *current;
- CERTGeneralName *newname;
- char *name = NULL;
- SECStatus rv = SECSuccess;
- int len;
-
- len = PORT_Strlen(which);
- name = find_field(data, which, PR_TRUE);
- SubAltName = current = (CERTGeneralName *) PORT_ZAlloc
- (sizeof(CERTGeneralName));
- if (current == NULL) {
- error_allocate();
- }
- while (name != NULL) {
- rv = MakeGeneralName(name, current, arena);
- if (rv != SECSuccess) {
- break;
- }
- if (*(which + len -1) < '9') {
- *(which + len - 1) = *(which + len - 1) + 1;
- } else {
- if (isdigit(*(which + len - 2) )) {
- *(which + len - 2) = *(which + len - 2) + 1;
- *(which + len - 1) = '0';
- } else {
- *(which + len - 1) = '1';
- *(which + len) = '0';
- *(which + len + 1) = '\0';
- len++;
- }
- }
- len = PORT_Strlen(which);
- name = find_field(data, which, PR_TRUE);
- if (name != NULL) {
- newname = (CERTGeneralName *) PORT_ZAlloc(sizeof(CERTGeneralName));
- if (newname == NULL) {
- error_allocate();
- }
- current->l.next = &(newname->l);
- newname->l.prev = &(current->l);
- current = newname;
- newname = NULL;
- } else {
- current->l.next = &(SubAltName->l);
- SubAltName->l.prev = &(current->l);
- }
- }
- if (rv == SECFailure) {
- return NULL;
- }
- return SubAltName;
- }
- static CERTNameConstraints *
- MakeNameConstraints(Pair *data,
- PRArenaPool *arena)
- {
- CERTNameConstraints *NameConstraints;
- CERTNameConstraint *current = NULL;
- CERTNameConstraint *last_permited = NULL;
- CERTNameConstraint *last_excluded = NULL;
- char *constraint = NULL;
- char *which;
- SECStatus rv = SECSuccess;
- int len;
- int i;
- long max;
- long min;
- PRBool permited;
-
- NameConstraints = (CERTNameConstraints *) PORT_ZAlloc
- (sizeof(CERTNameConstraints));
- which = make_copy_string("NameConstraintSelect0", 25,'\0');
- len = PORT_Strlen(which);
- constraint = find_field(data, which, PR_TRUE);
- NameConstraints->permited = NameConstraints->excluded = NULL;
- while (constraint != NULL) {
- current = (CERTNameConstraint *) PORT_ZAlloc
- (sizeof(CERTNameConstraint));
- if (current == NULL) {
- error_allocate();
- }
- i = 0;
- while (*(constraint + PORT_Strlen(constraint) - i) != '-') {
- i++;
- }
- *(constraint + PORT_Strlen(constraint) - i - 1) = '\0';
- max = (long) atoi(constraint + PORT_Strlen(constraint) + 3);
- if (max > 0) {
- (void) SEC_ASN1EncodeInteger(arena, ¤t->max, max);
- }
- i = 0;
- while (*(constraint + PORT_Strlen(constraint) - i) != '-') {
- i++;
- }
- *(constraint + PORT_Strlen(constraint) - i - 1) = '\0';
- min = (long) atoi(constraint + PORT_Strlen(constraint) + 3);
- (void) SEC_ASN1EncodeInteger(arena, ¤t->min, min);
- while (*(constraint + PORT_Strlen(constraint) - i) != '-') {
- i++;
- }
- *(constraint + PORT_Strlen(constraint) - i - 1) = '\0';
- if (*(constraint + PORT_Strlen(constraint) + 3) == 'p') {
- permited = PR_TRUE;
- } else {
- permited = PR_FALSE;
- }
- rv = MakeGeneralName(constraint, &(current->name), arena);
- if (rv != SECSuccess) {
- break;
- }
- if (*(which + len - 1) < '9') {
- *(which + len - 1) = *(which + len - 1) + 1;
- } else {
- if (isdigit(*(which + len - 2) )) {
- *(which + len - 2) = *(which + len - 2) + 1;
- *(which + len - 1) = '0';
- } else {
- *(which + len - 1) = '1';
- *(which + len) = '0';
- *(which + len + 1) = '\0';
- len++;
- }
- }
- len = PORT_Strlen(which);
- if (permited) {
- if (NameConstraints->permited == NULL) {
- NameConstraints->permited = last_permited = current;
- }
- last_permited->l.next = &(current->l);
- current->l.prev = &(last_permited->l);
- last_permited = current;
- } else {
- if (NameConstraints->excluded == NULL) {
- NameConstraints->excluded = last_excluded = current;
- }
- last_excluded->l.next = &(current->l);
- current->l.prev = &(last_excluded->l);
- last_excluded = current;
- }
- constraint = find_field(data, which, PR_TRUE);
- if (constraint != NULL) {
- current = (CERTNameConstraint *) PORT_ZAlloc(sizeof(CERTNameConstraint));
- if (current == NULL) {
- error_allocate();
- }
- }
- }
- if (NameConstraints->permited != NULL) {
- last_permited->l.next = &(NameConstraints->permited->l);
- NameConstraints->permited->l.prev = &(last_permited->l);
- }
- if (NameConstraints->excluded != NULL) {
- last_excluded->l.next = &(NameConstraints->excluded->l);
- NameConstraints->excluded->l.prev = &(last_excluded->l);
- }
- if (which != NULL) {
- PORT_Free(which);
- }
- if (rv == SECFailure) {
- return NULL;
- }
- return NameConstraints;
- }
- static SECStatus
- AddAltName(void *extHandle,
- Pair *data,
- char *issuerNameStr,
- CERTCertDBHandle *handle,
- int type)
- {
- PRBool autoIssuer = PR_FALSE;
- PRArenaPool *arena = NULL;
- CERTGeneralName *genName = NULL;
- char *which = NULL;
- char *name = NULL;
- SECStatus rv = SECSuccess;
- SECItem *issuersAltName = NULL;
- CERTCertificate *issuerCert = NULL;
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- error_allocate();
- }
- if (type == 0) {
- which = make_copy_string("SubAltNameSelect0", 20,'\0');
- genName = MakeAltName(data, which, arena);
- } else {
- if (autoIssuer) {
- autoIssuer = find_field_bool(data,"IssuerAltNameSourceRadio-auto",
- PR_TRUE);
- issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);
- rv = cert_FindExtension((*issuerCert).extensions,
- SEC_OID_X509_SUBJECT_ALT_NAME,
- issuersAltName);
- if (issuersA…
Large files files are truncated, but you can click here to view the full file