📄 osptnepenroll.c
字号:
* be returned. In this case, OSPC_ERR_NO_ERROR should be returned * as well. Otherwise, an error code other than OSPC_ERR_NO_ERROR * will be returned and the status and certificate are * potentially useless. */int OSPPEnrollDevice ( OSPTCOMM* ospvCommMgrIn, OSPTMSGINFO* ospvEnrollMsgIn, OSPTASN1OBJECT* ospvRequestPublicKeyIn, unsigned* ospvEnrollStatusOut, unsigned char** ospvCertOut, unsigned* ospvCertLenOut){ int retVal = OSPC_ERR_NO_ERROR; /* The security manager for the communication manager; it keeps track * of certificates used and so on: */ OSPTSEC* commMgrSec = OSPC_OSNULL; /* The status of the certificate request that we retrieve from teh * enrollment server's response: */ unsigned char* statusStr = OSPC_OSNULL; /* The base64-encoded cert that we retrieve from the enrollment * server's response: */ unsigned char* certb64Buf = OSPC_OSNULL; /* The status of the request: */ unsigned status = OSPC_ENROLL_STATUS_FAILURE_DEFAULT; /* This will represent the null-terminated response received from the * enrollment server; the response that we get from the communications * manager isn't null-terminated, which may otherwise introduce problems * with reading non-heap memory with common functions: */ unsigned char* enrollResponse = OSPC_OSNULL; /* Check the parameters; if any of them are null, then set an * error code and complain. */ if ( ( ospvCommMgrIn == OSPC_OSNULL ) || ( ospvEnrollMsgIn == OSPC_OSNULL ) || ( ospvEnrollStatusOut == OSPC_OSNULL ) || ( ospvCertOut == OSPC_OSNULL ) || ( ospvCertLenOut == OSPC_OSNULL ) ) { retVal = OSPC_ERR_ENROLL_INVALID_ARG; OSPM_DBGERRORLOG( retVal, "The parameters for enrolling a device are invalid.\n" ); } /* Now add the enrollment transaction to the communication manager's * message queue and complain if we have any problems doing it: */ if ( retVal == OSPC_ERR_NO_ERROR ) { OSPM_DBGMISC(( "Enrollment request: <%d> bytes: <%s>\n", ospvEnrollMsgIn->RequestSz, ospvEnrollMsgIn->RequestMsg )); OSPM_DBGMISC(( "Adding enrollment message to transaction queue.\n" )); retVal = OSPPCommAddTransaction( ospvCommMgrIn, ospvEnrollMsgIn ); if ( retVal != OSPC_ERR_NO_ERROR ) { OSPM_DBGERRORLOG( retVal, "Unable to add the enrollment request to the communications manager.\n" ); } } /* We may have gotten a valid return value for adding a request to the * communication manager's message queue even if the server rejected it. * So, we'll check the error code of the message here to make sure that * we could in fact send it: */ if ( retVal == OSPC_ERR_NO_ERROR ) { retVal = ospvEnrollMsgIn->ErrorCode; if ( retVal != OSPC_ERR_NO_ERROR ) { OSPM_DBGERRORLOG( retVal, "Unable to transmit request to the enrollment server.\n" ); } } /* We'll need a copy of the response message that's null-terminated in * order to use the parsing mechanism. Another solution would be to * rewrite the string parser and every other piece of code that uses * the response to avoid using strlen, strcpy, and any other function * that may potentially access characters outside the bounds of the * non-null-terminated response, but that isn't done here. */ if ( retVal == OSPC_ERR_NO_ERROR ) { OSPM_MALLOC( enrollResponse, unsigned char, ospvEnrollMsgIn->ResponseSz + 1 ); /* Complain if the memory isn't available: */ if ( enrollResponse == OSPC_OSNULL ) { retVal = OSPC_ERR_ENROLL_NO_MEMORY; OSPM_DBGERRORLOG( retVal, "Unable to allocate memory for null-terminated response.\n" ); } } /* Now we can create a null-terminated version of the response. * Then look for the status and the certificate that should be returned * from the enrollment server within the null-terminated response. */ if ( retVal == OSPC_ERR_NO_ERROR ) { /* Create the null-terminated response by zeroing out everything * and then copying in the string that fits it: */ OSPM_MEMSET( enrollResponse, 0, ospvEnrollMsgIn->ResponseSz + 1 ); OSPM_STRNCPY( enrollResponse, ospvEnrollMsgIn->ResponseMsg, ospvEnrollMsgIn->ResponseSz ); /* Get the status code from the response: */ retVal = OSPPExtractFieldFromResponse( enrollResponse, ospvEnrollMsgIn->ResponseSz, OSPC_ENROLL_STATUS_RSP_PARAM, &statusStr ); if ( retVal != OSPC_ERR_NO_ERROR ) { OSPM_DBGERRORLOG( retVal, "Unable to find the cert request status in the response.\n" ); } } /* Check to make sure that the status is a string of digits. Since atoi * returns a 0 for strings that are invalid, we will interpret a garbled * message the same way that we'll interpret a successful enrollment if * we just use atoi first. */ if ( retVal == OSPC_ERR_NO_ERROR ) { OSPM_DBGMISC(( "status: <%s>\n", statusStr )); retVal = OSPPValidateDigitString( statusStr ); if ( retVal == OSPC_ERR_NO_ERROR ) { status = OSPM_ATOI( (const char *)statusStr ); } else { OSPM_DBGERRORLOG( retVal, "Invalid status returned - assuming cert request failed.\n" ); } } /* Now check the status code that was returned. If the status is * equal to a code that says that the request was successful, then * look for the certificate in the response. If the status is equal to * a code that says that the request is pending approval, then do * nothing. If the status is equal to anything else, then print out * an error. */ if ( retVal == OSPC_ERR_NO_ERROR ) { OSPM_DBGMISC(( "status returned: <%d>\n", status )); *ospvEnrollStatusOut = status; if ( status == OSPC_ENROLL_STATUS_OK ) { retVal = OSPPExtractFieldFromResponse( enrollResponse, ospvEnrollMsgIn->ResponseSz, OSPC_ENROLL_CERT_RSP_PARAM, &certb64Buf ); if ( retVal == OSPC_ERR_NO_ERROR ) { commMgrSec = OSPPCommGetSecurity( ospvCommMgrIn ); if ( commMgrSec == OSPC_OSNULL ) { OSPM_DBGMISC(( "Warning: Unable to validate the certificate returned.\n" )); } } if ( retVal == OSPC_ERR_NO_ERROR ) { retVal = OSPPValidateDeviceCert( commMgrSec, ospvRequestPublicKeyIn, certb64Buf, ospvCertOut, ospvCertLenOut ); if ( retVal != OSPC_ERR_NO_ERROR ) { retVal = OSPC_ERR_ENROLL_INVALID_RESPONSE; OSPM_DBGERRORLOG( retVal, "Unable to extract certificate from response indicating success.\n" ); } } } /* Nothing to do in this case. */ else if ( status == OSPC_ENROLL_STATUS_PENDING ) { OSPM_DBGMISC(( "Enrollment status pending\n" )); } /* It looks like the request failed for some reason. We can try to * decode it, but we definitely need to tell the user what the error * code is. This code should be propagated to a customer service rep * or someone who can tell the user what this error indicates, so * more diagnostics output would be nice. */ else { OSPM_DBGMISC(( "Warning: Failure code received from server: %d\n", *ospvEnrollStatusOut )); } } /* Now free everything up: */ if ( statusStr != OSPC_OSNULL ) { OSPM_FREE( statusStr ); } /* The certificate should be contained in the ospvCertOut field * if it was successfully obtained, so this is no longer useful: */ if ( certb64Buf != OSPC_OSNULL ) { OSPM_FREE( certb64Buf ); } /* The null-terminated response is no longer necessary: */ if ( enrollResponse != OSPC_OSNULL ) { OSPM_FREE( enrollResponse ); } return retVal;}/* * Given a certificate for a device that has been received, validate it * against the public key used ( to be added ), the CA certificate that * we expected to sign it, and its general construction. The certificate * is placed in *ospvCertOut. * * Input: * o ospvSecIn: contains the authority certificate, and will be used for * validating the CA certificate used for signing the request. * o ospvRequestPublicKeyIn: contains the public key that was contained in * the certificate request. * o ospvCertB64In: the certificate to be taken apart and validated. * * Output: * o ospvCertOut: a pointer to the unsigned char* that will ultimately * contain the certificate that was transmitted. * * - the return value is OSPC_ERR_NO_ERROR( 0 ) if the certificate is ok, * or non-zero if there's an error. * * Errors: Errors are generated when: * o any of the parameters are null; * o the CA certificate(s) in the OSPTSEC object are not the signers of * the received certificate; * o the public key of the received certificate does not match the one * that was requested; * o the certificate received was improperly base64-encoded. */int OSPPValidateDeviceCert ( OSPTSEC* ospvSecIn, OSPTASN1OBJECT* ospvRequestPublicKeyIn, unsigned char* ospvCertB64In, unsigned char** ospvCertOut, unsigned* ospvCertLenOut ){ int retVal = OSPC_ERR_NO_ERROR; int certb64BufLen = -1; /* This object will be used for validating that the certificate * passed in is in fact an X.509 certificate: */ OSPTASN1OBJECT* x509CertOut = OSPC_OSNULL; /* This is the temporary variable for holding the * outgoing subjectPublicKeyInfo: */ OSPTASN1OBJECT certOutPublicKey; /* This is the index of the root CA certificate within the CA cert chain: */ int caCertIndex = -1; OSPM_DBGENTER(( "ENTER: OSPPValidateDeviceCert\n" )); /* If ( the parameters are ok ) then * o get the size of the base64-encoded cert and set the size of * the binary cert to be twice that ( this is only needed for the * base64 decoding; in reality the base64-decoded message should be * no more than 4/3 the size of the base64-encoded message. ) * o Allocate the memory for the output certificate */ if ( ( ospvCertB64In == OSPC_OSNULL ) || ( ospvCertOut == OSPC_OSNULL ) || ( ospvCertLenOut == OSPC_OSNULL ) ) { retVal = OSPC_ERR_ENROLL_INVALID_ARG; OSPM_DBGERRORLOG( retVal, "Invalid parameters for validating a device cert.\n" ); } if ( retVal == OSPC_ERR_NO_ERROR ) { certb64BufLen = OSPM_STRLEN( (const char *)ospvCertB64In ); *ospvCertLenOut = 2 * certb64BufLen; OSPM_MALLOC( *ospvCertOut, unsigned char, *ospvCertLenOut + 1 ); /* If ( the memory couldn't be allocated ) then * o we're in trouble; set the error code to indicate that no * memory could be allocated. */ if ( *ospvCertOut == OSPC_OSNULL ) { retVal = OSPC_ERR_ENROLL_NO_MEMORY; OSPM_DBGERRORLOG( retVal, "Unable to allocate memory" ); } } /* Else ( everything's ok ) so * o decode the base64 encoding of the certificate and put it into * ospvCertOut and its length in the certificate's output length. */ if ( retVal == OSPC_ERR_NO_ERROR ) { OSPM_MEMSET( *ospvCertOut, 0, *ospvCertLenOut + 1 ); retVal = OSPPBase64Decode( (const char *)ospvCertB64In, certb64BufLen, *ospvCertOut, ospvCertLenOut ); /* If ( there was a problem ) then * o set the error code to indicate the certificate received was bogus. */ if ( retVal != OSPC_ERR_NO_ERROR ) { OSPM_DBGERRORLOG( retVal, "Unable to base64-decode certificate\n" ); } } /* If ( everything's ok ) then * o Check the certificate's public key and CA certificate. */ if ( retVal == OSPC_ERR_NO_ERROR ) { OSPM_DBGMISC(( "creating x509 cert..\n" )); retVal = OSPPX509CertCreate( *ospvCertOut, &x509CertOut );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -