Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Decode CSR (Certificate Sign Request)

michal_masztal1
Tera Contributor

Hi everybody.
I have some issue with decoding csr file content in ServiceNow.

CSR file content is for example

"

-----BEGIN CERTIFICATE REQUEST-----

MIIByjCCATMCAQAwgYkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh

MRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMR8w

HQYDVQQLExZJbmZvcm1hdGlvbiBUZWNobm9sb2d5MRcwFQYDVQQDEw53d3cuZ29v

Z2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApZtYJCHJ4VpVXHfV

IlstQTlO4qC03hjX+ZkPyvdYd1Q4+qbAeTwXmCUKYHThVRd5aXSqlPzyIBwieMZr

WFlRQddZ1IzXAlVRDWwAo60KecqeAXnnUK+5fXoTI/UgWshre8tJ+x/TMHaQKR/J

cIWPhqaQhsJuzZbvAdGA80BLxdMCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4GBAIhl

4PvFq+e7ipARgI5ZM+GZx6mpCz44DTo0JkwfRDf+BtrsaC0q68eTf2XhYOsq4fkH

Q0uA0aVog3f5iJxCa3Hp5gxbJQ6zV6kJ0TEsuaaOhEko9sdpCoPOnRBm2i/XRD2D

6iNh8f8z0ShGsFqjDgFHyF3o+lUyj+UC6H1QW7bn

-----END CERTIFICATE REQUEST-----

".

Is it possible to decode this content using some ServiceNow API to get some information about certificate?

Thanks for response.

1 ACCEPTED SOLUTION

Jace Benson
Mega Sage

The only way I'm aware of handling and Certificate Signing Request would be to use something like OpenSSL on a midserver.   You could send the data down to the mid and return what you are trying to get out of it.


View solution in original post

6 REPLIES 6

I was not able to get this to work.  I added logging to the OOTB script include and it seems like  it is breaking when it tries to access the json object with the CSRAttributes. Did you definitely get it to work? If so, can you compare your version of the OOTB script include code to my version?

 

Thank you,

Colleen

 

 

Here is my client script along with notations in green to show what alerts are coming up.

 

function onChange(control, oldValue, newValue, isLoading) {
if (isLoading || newValue == '') {
return;
}
if (newValue != '') {
var ga = new GlideAjax("global.CSRDecodeCertificateAjax");
ga.addParam("sysparm_name", "getSubjectAttributesFromCSR");
ga.addParam("sysparm_CSRString", g_form.getValue('u_csr'));    // This is the CSR from the catalog item.
ga.getXMLAnswer(getCSR);
}
}

function getCSR(response) {
alert('response: ' + response);  // This is alerting "response: null"
var answer = JSON.parse(response);
if (answer) {   // This code is apparently not running
if (answer.country != '') {
g_form.setValue('u_additional_notes', answer.country);
}
else alert('no country');  
}
else alert('no answer');   // This code is alerting "no answer"

}

 

Here is the code in the OOTB Script include with my added logging statements in blue. See my notes about the log messages in green.

//To get all the subject attributes from CSR
getSubjectAttributesFromCSR: function() {
gs.log('>>> entered the script include CSRDecodeCertificateAjax');   // This prints to the log successfully
var csr = this.getParameter('sysparm_CSRString');
gs.log('>>> csr is ' + csr);  //This displays the valid CSR
var csrAttributes = JSON.parse(SNC.DiscoveryCertificateUtil.readSubjectAttributesFromCSR(csr));
gs.log('>>> completed call to get the attributes'); //This is successfully written to the log.
if (gs.nil(csrAttributes.subject_common_name)) { //Pretty sure this is failing somehow with no log message to indicate why
gs.log('>>> common name is nil');  //Neither this or anything after it this shows up in the log.
}
else gs.log('>>> common name is ' + csrAttributes.subject_common_name); //Not written to log
 
var csrAttrObj = {
"subject_common_name": (!gs.nil(csrAttributes.subject_common_name)) ? csrAttributes.subject_common_name : '',
"subject_alternative_name": (!gs.nil(csrAttributes.subject_alternative_name)) ? csrAttributes.subject_alternative_name.replace(/\n/g , ", ").replace(/[,]\s*$/g, "") : '',
"organization": (!gs.nil(csrAttributes.organization)) ? csrAttributes.organization : '',
"organizational_unit": (!gs.nil(csrAttributes.organizational_unit)) ? csrAttributes.organizational_unit : '',
"locality": (!gs.nil(csrAttributes.locality)) ? csrAttributes.locality : '',
"province": (!gs.nil(csrAttributes.state)) ? csrAttributes.state : '',
"country": (!gs.nil(csrAttributes.country)) ? csrAttributes.country : '',
"email": (!gs.nil(csrAttributes.email)) ? csrAttributes.email : ''
};
gs.log('>>> common name is csrAttrObj.subject_common_name');  //Not written to log
 
return JSON.stringify(csrAttrObj);
},

 

 

Hey Colleen, 

 

Here's my catalog client script which runs when the value in the CSR field on the intake form changes. This is working, as we speak. I'm just leveraging the script include I identified in my earlier reply. 

See if any of this helps. I didn't have time to compare to yours as I'm in the middle of a few things but wanted to post this for reference for you.

 

// This script will read the CSR entered by the customer and populate form fields based on that.

function onChange(control, oldValue, newValue, isLoading) {
	if (isLoading) {
		return;
	}

	// ====================
	// Core Thread
	// ====================
	if(!newValue || newValue == '' || newValue == null){
		clearCSRFields();
		return;
	}
	var formattedCSR = formatCSR(newValue);
	decodeCSRAndPopulateFormFields(formattedCSR);
	
	// ====================
	// Functions
	// ====================
	function formatCSR(rawCSR){
		var formattedCSR = '';
		formattedCSR = cleanHeadersAndFooters(rawCSR);
		formattedCSR = removeTrailingDashes(formattedCSR);
		return formattedCSR;
	}
	function cleanHeadersAndFooters(inputString){
		return inputString.replaceAll("NEW CERTIFICATE",'CERTIFICATE');
	}	
	function removeTrailingDashes(inputString){
		return inputString.substring(0,inputString.indexOf('END CERTIFICATE REQUEST') + 23);
	}
	// decodeCSRAndPopulateFormFields() is an ajax function. Once called, script execution will not return from this function.
	function decodeCSRAndPopulateFormFields(newValue){
		var ga = new GlideAjax("global.CSRDecodeCertificateAjax");
		ga.addParam("sysparm_name", "getSubjectAttributesFromCSR");
		ga.addParam('sysparm_CSRString', newValue);
		ga.getXML(ajaxCallback);

		// ajax response function
		function ajaxCallback(response) {
			var csrAttributes = response.responseXML.documentElement.getAttribute("answer");
			var csrAttrsObj = (csrAttributes) ? JSON.parse(csrAttributes) : '';
			if (!csrAttrsObj || !csrAttrsObj['subject_common_name']){
				g_form.showFieldMsg('csr', getMessage('Invalid CSR'), 'error');
				clearCSRFields();
			}else{
				populateFormFieldsFromCSR(csrAttrsObj);
			}
		}		
	}
    function populateFormFieldsFromCSR(csrAttributes) {
		var csrFields = getCSRFields();
		csrFields.forEach(function(fieldName){
			g_form.setValue(fieldName,(csrAttributes[fieldName]) ? csrAttributes[fieldName] : '');
		});
    }
	function clearCSRFields(){
		var csrFields = getCSRFields();
		csrFields.forEach(function(fieldName){
			g_form.clearValue(fieldName);
		});		
	}
	function getCSRFields(){
		return [
			'subject_common_name',
			'organization',
			'organizational_unit',
			'locality',
			'province',
			'country',
			'email',
			'subject_alternative_name'
		];
	}	

}