PKI_OID * PKI_CONFIG_OID_search ( PKI_CONFIG *doc, char *searchName ) { PKI_OID *oid = NULL; PKI_CONFIG_ELEMENT *curr = NULL; PKI_CONFIG_ELEMENT_STACK *sk = NULL; xmlChar oidSearchBuff[BUFF_MAX_SIZE]; int size = 0; int i = 0; if( !doc || !searchName ) return (NULL); if((oid = PKI_OID_get( searchName )) != NULL ) { return ( oid ); } snprintf( (char *) oidSearchBuff, BUFF_MAX_SIZE, "/objectIdentifiers/oid[@name=\"%s\"]", searchName ); if (( sk = PKI_CONFIG_get_element_stack ( doc, (char *)oidSearchBuff )) == NULL ) { return NULL; } size = PKI_STACK_CONFIG_ELEMENT_elements ( sk ); for( i = 0; i < size; i++ ) { curr = PKI_STACK_CONFIG_ELEMENT_get_num ( sk, i ); if( curr && curr->type == XML_ELEMENT_NODE ) { xmlChar *name = NULL; xmlChar *descr = NULL; xmlChar *val = NULL; name = xmlGetProp( curr, (xmlChar *) "name" ); descr = xmlGetProp( curr, (xmlChar *) "description" ); val = xmlNodeListGetString(doc, curr->xmlChildrenNode, 1); oid = PKI_OID_new ( (char *) val, (char *) name, (char *) descr); if( descr ) xmlFree ( descr ); if( name ) xmlFree ( name ); if( val ) xmlFree ( val ); if( oid != NULL ) { PKI_log_debug("Failed Creating OID (%s, %s, %s)", name, descr, val ); continue; } } } return (oid); }
PKI_X509_CRL_ENTRY * PKI_X509_CRL_ENTRY_new_serial( const char *serial, PKI_X509_CRL_REASON reason, const PKI_TIME *revDate, const PKI_X509_PROFILE *profile ) { PKI_X509_CRL_ENTRY *entry = NULL; // Entry to be added to the CRL PKI_INTEGER * s_int = NULL; // ASN1 Integer PKI_TIME * a_date = NULL; // ASN1 Rev Date // Input check if (!serial) { PKI_ERROR(PKI_ERR_PARAM_NULL, "Missing serial number"); return NULL; } // Allocates the Memory for the entry if((entry = (PKI_X509_CRL_ENTRY *) X509_REVOKED_new()) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } // If no revocation date is provided, let's use "now" if (!revDate && (a_date = PKI_TIME_new(0)) == NULL) { // Can not allocate the revocation date time PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); return NULL; } else { // Gets the Pointer from the caller a_date = (PKI_TIME *)revDate; } // Generates the integer carrying the serial number if ((s_int = PKI_INTEGER_new_char(serial)) != NULL) { // Sets the serial number in the X509_REVOKED structure if (X509_REVOKED_set_serialNumber(entry, s_int) == 1) { // Sets the revocation date if (a_date && !X509_REVOKED_set_revocationDate((X509_REVOKED *) entry, a_date)) { PKI_ERROR(PKI_ERR_GENERAL, "Can not assign revocation date"); goto err; } // All Ok here } else { // Error While assigning the serial PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not assign the serial (%s)", serial); goto err; } } else { // Error generating the ASN1 Integer PKI_ERROR(PKI_ERR_MEMORY_ALLOC, "Can not convert serial %s to Integer", serial); goto err; } if (reason != PKI_CRL_REASON_UNSPECIFIED) { int supported_reason = -1; ASN1_ENUMERATED *rtmp = ASN1_ENUMERATED_new(); switch (reason ) { case PKI_CRL_REASON_CERTIFICATE_HOLD: case PKI_CRL_REASON_HOLD_INSTRUCTION_REJECT: if (!X509_REVOKED_add1_ext_i2d(entry, NID_hold_instruction_code, PKI_OID_get("holdInstructionReject"), 0, 0)) { PKI_ERROR(PKI_ERR_X509_CRL, "Can not add holdInstructionReject"); goto err; } if (revDate && !X509_REVOKED_add1_ext_i2d(entry, NID_invalidity_date, (PKI_TIME *)revDate, 0, 0)) { PKI_ERROR(PKI_ERR_X509_CRL, "Can not add invalidity date"); goto err; } supported_reason = PKI_CRL_REASON_CERTIFICATE_HOLD; break; /* --- Deprecated in RFC 5280 --- case PKI_CRL_REASON_HOLD_INSTRUCTION_NONE: if (!X509_REVOKED_add1_ext_i2d(entry, NID_hold_instruction_code, PKI_OID_get( "holdInstructionReject"), 0, 0)) { goto err; }; if( revDate && !X509_REVOKED_add1_ext_i2d ( entry, NID_invalidity_date, revDate, 0, 0)) { goto err; }; reason = PKI_CRL_REASON_CERTIFICATE_HOLD; break; */ case PKI_CRL_REASON_HOLD_INSTRUCTION_CALLISSUER: if (!X509_REVOKED_add1_ext_i2d( entry, NID_hold_instruction_code, PKI_OID_get( "holdInstructionCallIssuer"), 0, 0)) { goto err; } if( revDate && !X509_REVOKED_add1_ext_i2d( entry, NID_invalidity_date, (PKI_TIME *)revDate, 0, 0)) { goto err; } supported_reason = PKI_CRL_REASON_CERTIFICATE_HOLD; break; case PKI_CRL_REASON_KEY_COMPROMISE: case PKI_CRL_REASON_CA_COMPROMISE: case PKI_CRL_REASON_AFFILIATION_CHANGED: case PKI_CRL_REASON_SUPERSEDED: case PKI_CRL_REASON_CESSATION_OF_OPERATION: case PKI_CRL_REASON_REMOVE_FROM_CRL: case PKI_CRL_REASON_PRIVILEGE_WITHDRAWN: case PKI_CRL_REASON_AA_COMPROMISE: PKI_ERROR(PKI_ERR_GENERAL, "CRL Reason Not Implemented Yet %d", reason); break; default: PKI_ERROR(PKI_ERR_GENERAL, "CRL Reason Unknown %d", reason); supported_reason = -1; break; } if (supported_reason >= 0) { if (!ASN1_ENUMERATED_set(rtmp, supported_reason)) goto err; if (!X509_REVOKED_add1_ext_i2d( entry, NID_crl_reason, rtmp, 0, 0)) goto err; } /* if( reason == CRL_REASON_HOLD_INSTRUCTION ) { // if (!X509_REVOKED_add1_ext_i2d ( entry, // NID_invalidity_date, revDate, 0, 0)) { // goto err; // }; // if (!X509_REVOKED_add1_ext_i2d(entry, NID_hold_instruction_code, // PKI_OID_get( "holdInstructionReject"), 0, 0)) { // goto err; // }; }; */ } /* if (rev && !X509_REVOKED_set_revocationDate(rev, revDate)) goto err; if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) { rtmp = ASN1_ENUMERATED_new(); if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) goto err; if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0)) goto err; } if (rev && comp_time) { if (!X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, comp_time, 0, 0)) goto err; } if (rev && hold) { if (!X509_REVOKED_add1_ext_i2d(rev, NID_hold_instruction_code, hold, 0, 0)) goto err; } */ // Free Allocated Memory if (s_int) PKI_INTEGER_free(s_int); if (a_date && !revDate) PKI_TIME_free(a_date); // Returns the created entry return entry; err: // Free Allocated memory if (s_int) PKI_INTEGER_free(s_int); if (a_date && !revDate) PKI_TIME_free(a_date); if (entry) X509_REVOKED_free((X509_REVOKED *) entry); // Returns null (error) return NULL; }
PKI_X509_EXTENSION *PKI_X509_EXTENSION_value_new_profile ( PKI_X509_PROFILE *profile, PKI_CONFIG *oids, PKI_CONFIG_ELEMENT *extNode, PKI_TOKEN *tk ) { /* TODO: Implement the extended version of the extensions, this should allow better extensions management. That is, the value will be encoded as: extName=@section [ section ] extName=value otherVal=val otherVal=val ... The corresponding XML should be: <pki:extension name=".." critical=".." > <pki:value name="" type=".." tag=".."> .. </pki:value> <pki:value name="" type=".." tag=".."> .. </pki:value> </pki:extension> */ PKI_CONFIG_ELEMENT *valNode = NULL; PKI_X509_EXTENSION *ret = NULL; PKI_X509_EXTENSION_VALUE *ext = NULL; xmlChar *type_s = NULL; xmlChar *tag_s = NULL; xmlChar *oid_s = NULL; xmlChar *value_s = NULL; xmlChar *name_s = NULL; xmlChar *crit_s = NULL; PKI_OID *oid = NULL; X509V3_CTX v3_ctx; CONF *conf = NULL; char *envValString = NULL; char *valString = NULL; int crit = 0; if( !profile || !extNode ) { PKI_log_debug("ERROR, no profile or extNode provided in " "PKI_X509_EXTENSION_value_new_profile()"); return (NULL); } if((crit_s = xmlGetProp( extNode, BAD_CAST "critical" )) != NULL ) { if( strncmp_nocase( (char *) crit_s, "n", 1 ) == 0) { crit = 0; } else { crit = 1; } } if((name_s = xmlGetProp( extNode, BAD_CAST "name" )) == NULL ) { PKI_log_debug("ERROR, no name property in node %s", extNode->name); if( crit_s ) xmlFree ( crit_s ); return (NULL); } if ((oid = PKI_OID_get((char *) name_s)) == NULL) { if ((oid = PKI_CONFIG_OID_search(oids, (char *)name_s)) == NULL) { PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL); return NULL; } } else { PKI_OID_free ( oid ); } /* int nid = NID_undef; if((nid = OBJ_sn2nid( (char *) name_s )) == NID_undef ) { PKI_OID *oid = NULL; oid = PKI_CONFIG_OID_search ( oids, (char *) name_s ); if( !oid ) { PKI_log_debug( "ERROR, can not create object (%s)!", name_s ); return( NULL ); } } */ if ((valString = (char *) PKI_Malloc(BUFF_MAX_SIZE)) == NULL) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); if( name_s ) xmlFree ( name_s ); if( crit_s ) xmlFree (crit_s); return( NULL ); } memset( valString, 0, BUFF_MAX_SIZE ); if( crit == 1 ) snprintf( valString, BUFF_MAX_SIZE -1, "%s", "critical" ); for (valNode = extNode->children; valNode; valNode = valNode->next) { if ((valNode->type == XML_ELEMENT_NODE) && ((strncmp_nocase((char *)(valNode->name),"value",5)) == 0)) { char tmp[BUFF_MAX_SIZE]; type_s = xmlGetProp( valNode, BAD_CAST "type" ); tag_s = xmlGetProp( valNode, BAD_CAST "tag" ); oid_s = xmlGetProp( valNode, BAD_CAST "oid" ); value_s = xmlNodeListGetString( profile, valNode->xmlChildrenNode, 0); if( oid_s ) { /* Let's be sure the OID is created */ if((oid = PKI_CONFIG_OID_search(oids, (char *) value_s)) == NULL ) { PKI_log_debug ("WARNING, no oid " "created for %s!", oid_s ); } else { PKI_OID_free ( oid ); } } memset((unsigned char * )tmp, 0, BUFF_MAX_SIZE ); if( tag_s ) { snprintf( tmp, BUFF_MAX_SIZE - 1, "%s;", _ext_txt( tag_s ) ); } if( type_s == NULL ) { if( !oid_s ) { strncat( tmp, (char *) value_s, BUFF_MAX_SIZE - strlen( tmp )); } else { if( value_s && (strlen((char *) value_s) > 0) ) { strncat( tmp, (char *) oid_s, BUFF_MAX_SIZE - strlen( tmp ) ); strncat( tmp, ":", BUFF_MAX_SIZE - strlen ( tmp )); strncat( tmp, (char *) value_s, BUFF_MAX_SIZE - strlen (tmp )); } else { strncat( tmp, "OID:", BUFF_MAX_SIZE - strlen(tmp)); strncat( tmp, (char *) oid_s, BUFF_MAX_SIZE - strlen( tmp )); } } } else { strncat( tmp, (char *) _ext_txt(type_s), BUFF_MAX_SIZE - strlen( tmp )); if( value_s && (strlen((char*)value_s) > 0) ) { if(strcmp_nocase( (char*) type_s, "ia5org")) { strncat( tmp, ":", BUFF_MAX_SIZE - strlen( tmp )); } else { strncat( tmp, ",", BUFF_MAX_SIZE - strlen( tmp )); } strncat( tmp, (char *) value_s, BUFF_MAX_SIZE - strlen( tmp )); } } if( strlen( valString ) > 0 ) { strncat( valString, ",", BUFF_MAX_SIZE - 1); } strncat( valString, (char *) tmp, BUFF_MAX_SIZE - 1 ); if( type_s ) xmlFree ( type_s ); if( oid_s ) xmlFree ( oid_s ); if( tag_s ) xmlFree ( tag_s ); if( value_s ) xmlFree ( value_s ); } } //PKI_log_debug("INFO, Encoding %s=%s", name_s, valString); v3_ctx.db = NULL; v3_ctx.db_meth = NULL; v3_ctx.crl = NULL; v3_ctx.flags = 0; if ( tk ) { v3_ctx.issuer_cert = (X509 *) PKI_X509_get_value ( tk->cacert ); v3_ctx.subject_cert = (X509 *) PKI_X509_get_value ( tk->cert ); v3_ctx.subject_req = (X509_REQ *) PKI_X509_get_value ( tk->req ); } else { v3_ctx.issuer_cert = NULL; v3_ctx.subject_cert = NULL; v3_ctx.subject_req = NULL; } /* Sets the ctx.db and ctx.method */ conf = NCONF_new( NULL ); X509V3_set_nconf(&v3_ctx, conf); if((envValString = get_env_string( valString )) != NULL ) { PKI_log_debug("EXT STRING => %s=%s", name_s, envValString); ext = X509V3_EXT_conf(NULL, &v3_ctx, (char *) name_s, (char *) envValString); PKI_Free ( envValString ); } else { ext = X509V3_EXT_conf(NULL, &v3_ctx, (char *) name_s, (char *) valString); } if( !ext ) { PKI_log_debug("EXT::ERR::%s", ERR_error_string(ERR_get_error(), NULL )); return NULL; } if(( ret = PKI_X509_EXTENSION_new()) == NULL ) { PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL); X509_EXTENSION_free ( ext ); return NULL; } ret->value = ext; ret->oid = ext->object; if( name_s ) xmlFree ( name_s ); if( crit_s ) xmlFree (crit_s ); if( valString ) PKI_Free ( valString ); if( conf ) NCONF_free ( conf ); return ( ret ); }