void SslConnection::open() { auto self = shared_from_this(); auto query = endpoints(); _socket.set_verify_mode(ssl::verify_peer); _socket.set_verify_callback([this](bool preverified, ssl::verify_context &ctx) -> bool { return verifyCertificate(preverified, ctx); }); _resolver.async_resolve(query, boost::bind( &SslConnection::handleResolve, this, pl::error, pl::iterator)); }
recvCertificate (sslStruct *sslC, uchar *p_buff, int event) { int status; // Get the packet bytes and save to handshakeMsgs // buff[0] points to Handshake Type - ServerHello memcpy(&(sslC->clientHandshakeMsgs[sslC->clientHandshakeMsgsIndex]), &(sslC->buff[0]), sslC->buffLen); sslC->clientHandshakeMsgsIndex += sslC->buffLen; printf("Certificate saved bytes: %d\n", sslC->buffLen); status = verifyCertificate(sslC); if (status == -1) { printf("\n Certificate verification failed"); return -1; } return 0; }
void net::ssl::SSLConnection::setupSocket(const std::string& hostName) { net::Socket_T fd = mSocket->getHandle(); BIO *sbio = BIO_new_socket(fd, BIO_NOCLOSE); SSL_set_bio(mSSL, sbio, sbio); int val = SSL_connect(mSSL); if(val <= 0) { #if defined(__DEBUG_SOCKET) if(SSL_get_error(mSSL, val) == SSL_ERROR_WANT_CONNECT) printf("ERROR_WANT_CONNECT\n"); else if(SSL_get_error(mSSL, val) == SSL_ERROR_ZERO_RETURN) printf("ERROR_ZERO_RETURN\n"); else if(SSL_get_error(mSSL, val) == SSL_ERROR_SSL) { printf("ERROR_SSL: "); char buffer[120]; ERR_error_string(val, buffer); BIO_printf(mBioErr, "%s\n", buffer); } else if(SSL_get_error(mSSL, val) == SSL_ERROR_SYSCALL) { printf("ERROR_SYSCALL: "); char buffer[120]; ERR_error_string(val, buffer); BIO_printf(mBioErr, "%s\n", buffer); } else if(SSL_get_error(mSSL, val) == SSL_ERROR_NONE) printf("NO ERROR: WHY AM I HERE?\n"); #endif throw net::ssl::SSLException (Ctxt(FmtX("SSL_connect failed: %d", SSL_get_error(mSSL, val)))); } if(mServerAuthentication) { verifyCertificate(hostName); } }
/** * TrustedObject::verifyInitMessage * * Verifies M0 and sends back M1 * * @param M0 Message from UntrustedObject * @return M1 * @author Timothy Thong, Jackson Reed */ Message TrustedObject::verifyInitMessage(Message M0) { std::vector<unsigned char> tmpVector; std::string K0; std::string K1; std::string X1; std::string encK1; std::string signedX1; std::string X1DataSig; std::string encX1Data; std::string decX0Data; std::string p; std::string hashedX0; std::string M1; std::string tmpStr; std::string logName; Message M1part; unsigned char *tmpBuf; unsigned char tmpFixedBuf[5000]; size_t decBytes; size_t X0Len; size_t cuLen; X509 *untrustCert; mkr = MessageMaker(T_ID, MessageState::VER_INIT_RESP); mkr.clear_payload(); // obtain K0 tmpVector = M0.get_payload("ENCRYPTED_K0"); if ( ! cryptsuite::pkDecrypt((unsigned char *) &tmpVector[0], tmpVector.size(), &tmpBuf, priv) ) { fprintf(fpErr, "Failed to obtain K0\n"); // TODO: Stop here? } K0 = std::string((const char *) tmpBuf, SESSION_KEY_LEN); delete[] tmpBuf; // obtain X0 || signedX0 tmpVector = M0.get_payload("ENCRYPTED_X0_DATA"); decBytes = cryptsuite::symDecrypt((unsigned char *) &tmpVector[0], tmpVector.size(), &tmpBuf, (unsigned char *) &K0[0]); if (decBytes <= 0) { fprintf(fpErr, "Failed to decrypt X0DATASIG\n"); // TODO: Stop here? } decX0Data = std::string((const char *) tmpBuf, decBytes); delete[] tmpBuf; // verify X0 - p, d, Cu, A0 tmpVector = M0.get_payload("X0LEN"); tmpVector.push_back('\0'); X0Len = atoi((const char *) &tmpVector[0]); if ( ! cryptsuite::verifySignature((unsigned char *) &decX0Data[0], X0Len, (unsigned char *) &decX0Data[0] + X0Len, untrustPub) ) { fprintf(fpErr, "Error: Signature verification failed\n"); } // get DER-encoded cert and read into X509 struct tmpVector = M0.get_payload("CULEN"); tmpVector.push_back('\0'); cuLen = atoi((const char *) &tmpVector[0]); untrustCert = cryptsuite::derToX509((unsigned char *) &decX0Data[0] + MSTATE_LEN + TSTMP_LEN, cuLen); // verify cert if ( ! verifyCertificate(untrustCert) ) { fprintf(fpErr, "Error: Certificate verification failed\n"); // TODO: Stop here? } // read in A0 and associate it with current log _keyA0 = std::string((const char *) &decX0Data[0] + MSTATE_LEN + TSTMP_LEN + cuLen, AUTH_KEY_LEN); tmpVector = M0.get_payload("logName"); logName = std::string(tmpVector.begin(), tmpVector.end()); logNameA0Map[logName] = _keyA0; // form X1 - p, IDlog hash(X0) mkr.set_MessageState(MessageState::VER_INIT_RESP); p = std::to_string(VER_INIT_RESP); if ( ! cryptsuite::calcMD((unsigned char *) &decX0Data[0], X0Len, &tmpBuf) ) { fprintf(fpErr, "Error: Could not hash X0\n"); } hashedX0 = std::string((const char *) tmpBuf, MD_BYTES); delete[] tmpBuf; X1 = p; X1.replace(X1.length(), logName.length(), &logName[0], logName.length()); X1.replace(X1.length(), MD_BYTES, (const char *) &hashedX0[0], MD_BYTES); // generate random key K1 and encrypt it cryptsuite::genRandBytes(tmpFixedBuf, SESSION_KEY_LEN); K1 = std::string((const char *) tmpFixedBuf, SESSION_KEY_LEN); if ( ! mkr.set_pkencrypt("ENCRYPTED_K1", SESSION_KEY_LEN, (unsigned char *) &K1[0], untrustPub) ) { fprintf(fpErr, "Error could not encrypt K1\n"); // TODO Stop here? } // sign X1 if ( ! mkr.set_sign("SIGNED_X1", X1.length(), (unsigned char *) &X1[0], priv) ) { fprintf(fpErr, "Error: Failed to sign X1\n"); // TODO: Stop here? } // EK1(encrypt X1 || signedX1) M1part = mkr.get_message(); tmpVector = M1part.get_payload("SIGNED_X1"); signedX1 = std::string(tmpVector.begin(), tmpVector.end()); X1DataSig = X1; X1DataSig.replace(X1DataSig.length(), signedX1.length(), (const char *) &signedX1[0], signedX1.length()); if ( ! mkr.set_symencrypt("ENCRYPTED_X1_DATA", X1DataSig.length(), (unsigned char *) &X1DataSig[0], (unsigned char *) &K1[0]) ) { fprintf(fpErr, "Error: Failed to encrypt X1DATASIG\n"); // TODO: Stop here? } // form M1 M1part = mkr.get_message(); tmpVector = M1part.get_payload("ENCRYPTED_K1"); encK1 = std::string(tmpVector.begin(), tmpVector.end()); tmpVector = M1part.get_payload("ENCRYPTED_X1_DATA"); encX1Data = std::string(tmpVector.begin(), tmpVector.end()); M1 = p; M1.replace(M1.length(), strlen(T_ID), T_ID, strlen(T_ID)); M1.replace(M1.length(), encK1.length(), (const char *) &encK1[0], encK1.length()); M1.replace(M1.length(), encX1Data.length(), (const char *) &encX1Data[0], encX1Data.length()); mkr.set("M1", M1.length(), (unsigned char *) &M1[0]); // add length markers for parsing later tmpStr = std::to_string(encX1Data.length()); mkr.set("ENCRYPTED_X1_DATA_LEN", tmpStr.length(), (unsigned char *) &tmpStr[0]); tmpStr = std::to_string(X1.length()); mkr.set("X1LEN", tmpStr.length(), (unsigned char *) &tmpStr[0]); /* DEBUG first4Last4("verifyInit K0", (unsigned char *) &K0[0], SESSION_KEY_LEN); first4Last4("verifyInit A0", (unsigned char *) &decX0Data[0] + MSTATE_LEN + TSTMP_LEN + cuLen, AUTH_KEY_LEN); first4Last4("verifyInit X0", (unsigned char *) &decX0Data[0], X0Len); first4Last4("verifyInit X0||signedX0", (unsigned char *) &decX0Data[0], decX0Data.length()); printf("\n"); first4Last4("verifyInit K1", (unsigned char *) &K1[0], SESSION_KEY_LEN); first4Last4("verifyInit X1||signedX1", (unsigned char *) &X1DataSig[0], X1DataSig.length()); */ return mkr.get_message(); }
nsresult VerifyCMSDetachedSignatureIncludingCertificate( const SECItem& buffer, const SECItem& detachedDigest, nsresult (*verifyCertificate)(CERTCertificate* cert, void* context, void* pinArg), void *verifyCertificateContext, void* pinArg) { // XXX: missing pinArg is tolerated. if (NS_WARN_IF(!buffer.data && buffer.len > 0) || NS_WARN_IF(!detachedDigest.data && detachedDigest.len > 0) || (!verifyCertificate) || NS_WARN_IF(!verifyCertificateContext)) { return NS_ERROR_INVALID_ARG; } ScopedNSSCMSMessage cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast<SECItem*>(&buffer), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); if (!cmsMsg) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } if (!NSS_CMSMessage_IsSigned(cmsMsg.get())) { return NS_ERROR_CMS_VERIFY_NOT_SIGNED; } NSSCMSContentInfo* cinfo = NSS_CMSMessage_ContentLevel(cmsMsg.get(), 0); if (!cinfo) { return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO; } // signedData is non-owning NSSCMSSignedData* signedData = reinterpret_cast<NSSCMSSignedData*>(NSS_CMSContentInfo_GetContent(cinfo)); if (!signedData) { return NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO; } // Set digest value. if (NSS_CMSSignedData_SetDigestValue(signedData, SEC_OID_SHA1, const_cast<SECItem*>(&detachedDigest))) { return NS_ERROR_CMS_VERIFY_BAD_DIGEST; } // Parse the certificates into CERTCertificate objects held in memory so // verifyCertificate will be able to find them during path building. ScopedCERTCertList certs(CERT_NewCertList()); if (!certs) { return NS_ERROR_OUT_OF_MEMORY; } if (signedData->rawCerts) { for (size_t i = 0; signedData->rawCerts[i]; ++i) { ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), signedData->rawCerts[i], nullptr, false, true)); // Skip certificates that fail to parse if (cert) { if (CERT_AddCertToListTail(certs.get(), cert.get()) == SECSuccess) { cert.forget(); // ownership transfered } else { return NS_ERROR_OUT_OF_MEMORY; } } } } // Get the end-entity certificate. int numSigners = NSS_CMSSignedData_SignerInfoCount(signedData); if (NS_WARN_IF(numSigners != 1)) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } // signer is non-owning. NSSCMSSignerInfo* signer = NSS_CMSSignedData_GetSignerInfo(signedData, 0); if (NS_WARN_IF(!signer)) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } CERTCertificate* signerCert = NSS_CMSSignerInfo_GetSigningCertificate(signer, CERT_GetDefaultCertDB()); if (!signerCert) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } nsresult rv = verifyCertificate(signerCert, verifyCertificateContext, pinArg); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } // See NSS_CMSContentInfo_GetContentTypeOID, which isn't exported from NSS. SECOidData* contentTypeOidData = SECOID_FindOID(&signedData->contentInfo.contentType); if (!contentTypeOidData) { return NS_ERROR_CMS_VERIFY_ERROR_PROCESSING; } return MapSECStatus(NSS_CMSSignerInfo_Verify(signer, const_cast<SECItem*>(&detachedDigest), &contentTypeOidData->oid)); }