EchoLeak attack against M360 Copilot
The background to read is OWASP Top 10 LLM security risks (attached)
EchoLeak attack against M360 Copilot
The background to read is OWASP Top 10 LLM security risks (attached)
Content.IntegrationTests/Tests/GameObjects/Components/EntityPrototypeComponentsTest.cs: var paths = sResourceManager.ContentFindFiles(prototypePath)
Content.IntegrationTests/Tests/GameObjects/Components/EntityPrototypeComponentsTest.cs: var file = sResourceManager.ContentFileRead(path);
Originally written Feb 2008
Why I Believe
It seems that my life has been a turbulent journey,
full of inner struggles.
I was born in 1967 -- the year Mao's Culture Revolution began. A few days after
my birth, the warring Red Guard factions forced Mother to flee the hospital
with me in her bosom.
Culture Revolution came hard on my parents, for the simple reason that my
grandparents were political prisoners affiliated with KMT. My parents were
treated harshly by the local Red Guards. I still recall that, as soon as I
began to perceive emotions, I sensed a constant, hovering, thickening layer of
stressful, inferior and hopeless feelings projected from my father to me. I was
a survivor at 5 or 6, so before long I learnt to take refuge in books and
fantasies, my favorite been Andersson Fairy Tales and Asimov Science fictions,
not to mention poetry by 泰戈尔(Rabindranath
Tagore). Looking back, it was mom's love and strength, plus the relief from
books and fantasies that my own budding inner world could develop before the
harsh environment suffocated it. At that point, I sworn to myself to grow up a
man of character strength and moral goodness. My dream was to escape from the
totalitarian system to a free world. I thought that if I live in a free
society, is well educated and have lots of money, I can realize my dreams.
My intellectual adventures led me, somehow, out of the deprived oppressive
environment -- thanks to my father's upbringing, my mother's loving nurture and
helps from teachers and friends. I did fulfill the three conditions: freedom education
and a decent income. Yet, I seem to have discovered on myself more and more
character flaws and moral weakness. How come? I was baffled. I tried to find
answers in behavioral science, self-help books and psychology. But it seems to
be a quicksand in which my soul was drowning. No kidding, I was deeply
troubled, depressed, losing hope.
Besides books and philosophy, I also tried sports: triathlon, half marathon,
winter triathlon. They gave me temporary thrills but no lasting answers.
I became more disappointed of myself. My self-esteem began sinking lower and
lower in the quicksand. I sought help from a psychological counseling. A lady
named Cynthia provided a good deal of much appreciated clinical help. But the
real question was un-answered. I began to lose purpose and losing it quickly. I
was at my wit's end, unable to sit up in the quicksand.
One day I went to a wedding banquet and met a United Church minister, Rev Wing
Mak. He challenged me to turn my eyes to Bible. Prior to that I was drawn to
Bible study while attending graduate school in Vancouver. Rev Mak was very nice
to me. He filled to some extent a father-like role at that point when my father
had been far away, distance-wise, and, more acutely, emotion-wise. Overtime, to
my delight I found that reading Bible seemed to make my inner world clear. I
learnt that I am one of the sinners made in divine image whom GOd is ready to
forgive and take back. This explained why I was foolish to rely on my strength
to achieve moral goodness. When I read Bible, not only were there instructions
beaching me how to deal with daily practical problems (like re-connect with my
estranged father). The mystery of the Bible seemed to be able to bring strange
unexplainable joy and peace to my inner self. Joy and peace, how precious to a
man in depression! I used to get up every morning, reading Psalm 143 and plea
God: may each morning bring me, word of your unfailing love!
Surprisingly, much of my prayers got answered, so in keeping up with my side of
the bargain, I somewhat reluctantly submitted to Jesus.
A small act of submission to Jesus brought new life. Trust and obey, there is
no other way, to be happy in Jesus, but trust and obey,
Bible taught me the purpose of life. Rather than relying on my own to become
righteous, it is better to trust in the Creator's plan and submit to Jesus for
the redemption of my sins. There trully were abundant life when I participate
in the worthy cause of being Christ's disciple. Live in Christ is a meaningful
one. I only regret that I didn't come to the cross sooner.
| (until C++17) |
| (since C++17) |
uftrace record --nest-libcall ../openssl-cmake/build/usr/local/bin/openssl cms -cades -sign -in assertion_store.json\
-signer "rsa.signed_pub.pem"\
-inkey rsa.pem\
-outform DER -out signed_claim.p7sAt line 54355, we invoke CMS_sign() with two flags: CMS_DETACHED | CMS_PARTIAL.
CMS_PARTIAL is required otherwise the manpage for CMS_sign() says SHA1 will be invoked to hash over claim_bio
We invoke cms_add1_signer() (line 74943, col 31 )
Which seems to call, at #146127 (col 62) call “cms_add1_signing_cert_v2()” . This will support CAdES-B format.
Finally we invoke, at #147594: CMS_final()
BOOL CryptSignMessage(
PCRYPT_SIGN_MESSAGE_PARA pSignPara,
BOOL fDetachedSignature,
DWORD cToBeSigned,
const BYTE * [] rgpbToBeSigned,
DWORD [] rgcbToBeSigned,
BYTE *pbSignedBlob,
DWORD *pcbSignedBlob
);
pSignParafDetachedSignaturecToBeSignedrgpbToBeSignedrgcbToBeSignedpbSignedBlobpcbSignedBlob| Return code | Description |
|---|---|
|
If the buffer specified by the pbSignedBlob parameter is not large enough to hold the returned data, the function sets the ERROR_MORE_DATA code, and stores the required buffer size, in bytes, into the variable pointed to by pcbSignedBlob. |
|
The message encoding type is not valid. Currently only PKCS_7_ASN_ENCODING is supported. The cbSize in *pSignPara is not valid. |
|
The pSigningCert in *pSignPara does not have a CERT_KEY_PROV_INFO_PROP_ID or CERT_KEY_CONTEXT_PROP_ID property. |
//-------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <windows.h>
#include <wincrypt.h>
// Link with the Crypt32.lib file.
#pragma comment (lib, "Crypt32")
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
//-------------------------------------------------------------------
// Define the name of a certificate subject.
// To use this program, the definition of SIGNER_NAME
// must be changed to the name of the subject of
// a certificate that has access to a private key. That certificate
// must have either the CERT_KEY_PROV_INFO_PROP_ID or
// CERT_KEY_CONTEXT_PROP_ID property set for the context to
// provide access to the private signature key.
//-------------------------------------------------------------------
// You can use a command similar to the following to create a
// certificate that can be used with this example:
//
// makecert -n "cn=Test" -sk Test -ss my
//#define SIGNER_NAME L"test"
#define SIGNER_NAME L"Insert_signer_name_here"
//-------------------------------------------------------------------
// Define the name of the store where the needed certificate
// can be found.
#define CERT_STORE_NAME L"MY"
//-------------------------------------------------------------------
// Local function prototypes.
void MyHandleError(LPTSTR psz);
bool SignMessage(CRYPT_DATA_BLOB *pSignedMessageBlob);
bool VerifySignedMessage(
CRYPT_DATA_BLOB *pSignedMessageBlob,
CRYPT_DATA_BLOB *pDecodedMessageBlob);
int _tmain(int argc, _TCHAR* argv[])
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
CRYPT_DATA_BLOB SignedMessage;
if(SignMessage(&SignedMessage))
{
CRYPT_DATA_BLOB DecodedMessage;
if(VerifySignedMessage(&SignedMessage, &DecodedMessage))
{
free(DecodedMessage.pbData);
}
free(SignedMessage.pbData);
}
_tprintf(TEXT("Press any key to exit."));
_getch();
}
//-------------------------------------------------------------------
// MyHandleError
void MyHandleError(LPTSTR psz)
{
_ftprintf(stderr, TEXT("An error occurred in the program. \n"));
_ftprintf(stderr, TEXT("%s\n"), psz);
_ftprintf(stderr, TEXT("Error number %x.\n"), GetLastError());
_ftprintf(stderr, TEXT("Program terminating. \n"));
} // End of MyHandleError
//-------------------------------------------------------------------
// SignMessage
bool SignMessage(CRYPT_DATA_BLOB *pSignedMessageBlob)
{
bool fReturn = false;
BYTE* pbMessage;
DWORD cbMessage;
HCERTSTORE hCertStore = NULL;
PCCERT_CONTEXT pSignerCert;
CRYPT_SIGN_MESSAGE_PARA SigParams;
DWORD cbSignedMessageBlob;
BYTE *pbSignedMessageBlob = NULL;
// Initialize the output pointer.
pSignedMessageBlob->cbData = 0;
pSignedMessageBlob->pbData = NULL;
// The message to be signed.
// Usually, the message exists somewhere and a pointer is
// passed to the application.
pbMessage =
(BYTE*)TEXT("CryptoAPI is a good way to handle security");
// Calculate the size of message. To include the
// terminating null character, the length is one more byte
// than the length returned by the strlen function.
cbMessage = (lstrlen((TCHAR*) pbMessage) + 1) * sizeof(TCHAR);
// Create the MessageArray and the MessageSizeArray.
const BYTE* MessageArray[] = {pbMessage};
DWORD_PTR MessageSizeArray[1];
MessageSizeArray[0] = cbMessage;
// Begin processing.
_tprintf(TEXT("The message to be signed is \"%s\".\n"),
pbMessage);
// Open the certificate store.
if ( !( hCertStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
CERT_STORE_NAME)))
{
MyHandleError(TEXT("The MY store could not be opened."));
goto exit_SignMessage;
}
// Get a pointer to the signer's certificate.
// This certificate must have access to the signer's private key.
if(pSignerCert = CertFindCertificateInStore(
hCertStore,
MY_ENCODING_TYPE,
0,
CERT_FIND_SUBJECT_STR,
SIGNER_NAME,
NULL))
{
_tprintf(TEXT("The signer's certificate was found.\n"));
}
else
{
MyHandleError( TEXT("Signer certificate not found."));
goto exit_SignMessage;
}
// Initialize the signature structure.
SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
SigParams.pSigningCert = pSignerCert;
SigParams.HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
SigParams.HashAlgorithm.Parameters.cbData = NULL;
SigParams.cMsgCert = 1;
SigParams.rgpMsgCert = &pSignerCert;
SigParams.cAuthAttr = 0;
SigParams.dwInnerContentType = 0;
SigParams.cMsgCrl = 0;
SigParams.cUnauthAttr = 0;
SigParams.dwFlags = 0;
SigParams.pvHashAuxInfo = NULL;
SigParams.rgAuthAttr = NULL;
// First, get the size of the signed BLOB.
if(CryptSignMessage(
&SigParams,
FALSE,
1,
MessageArray,
MessageSizeArray,
NULL,
&cbSignedMessageBlob))
{
_tprintf(TEXT("%d bytes needed for the encoded BLOB.\n"),
cbSignedMessageBlob);
}
else
{
MyHandleError(TEXT("Getting signed BLOB size failed"));
goto exit_SignMessage;
}
// Allocate memory for the signed BLOB.
if(!(pbSignedMessageBlob =
(BYTE*)malloc(cbSignedMessageBlob)))
{
MyHandleError(
TEXT("Memory allocation error while signing."));
goto exit_SignMessage;
}
// Get the signed message BLOB.
if(CryptSignMessage(
&SigParams,
FALSE,
1,
MessageArray,
MessageSizeArray,
pbSignedMessageBlob,
&cbSignedMessageBlob))
{
_tprintf(TEXT("The message was signed successfully. \n"));
// pbSignedMessageBlob now contains the signed BLOB.
fReturn = true;
}
else
{
MyHandleError(TEXT("Error getting signed BLOB"));
goto exit_SignMessage;
}
exit_SignMessage:
// Clean up and free memory as needed.
if(pSignerCert)
{
CertFreeCertificateContext(pSignerCert);
}
if(hCertStore)
{
CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
hCertStore = NULL;
}
// Only free the signed message if a failure occurred.
if(!fReturn)
{
if(pbSignedMessageBlob)
{
free(pbSignedMessageBlob);
pbSignedMessageBlob = NULL;
}
}
if(pbSignedMessageBlob)
{
pSignedMessageBlob->cbData = cbSignedMessageBlob;
pSignedMessageBlob->pbData = pbSignedMessageBlob;
}
return fReturn;
}
//-------------------------------------------------------------------
// VerifySignedMessage
//
// Verify the message signature. Usually, this would be done in
// a separate program.
bool VerifySignedMessage(
CRYPT_DATA_BLOB *pSignedMessageBlob,
CRYPT_DATA_BLOB *pDecodedMessageBlob)
{
bool fReturn = false;
DWORD cbDecodedMessageBlob;
BYTE *pbDecodedMessageBlob = NULL;
CRYPT_VERIFY_MESSAGE_PARA VerifyParams;
// Initialize the output.
pDecodedMessageBlob->cbData = 0;
pDecodedMessageBlob->pbData = NULL;
// Initialize the VerifyParams data structure.
VerifyParams.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
VerifyParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
VerifyParams.hCryptProv = 0;
VerifyParams.pfnGetSignerCertificate = NULL;
VerifyParams.pvGetArg = NULL;
// First, call CryptVerifyMessageSignature to get the length
// of the buffer needed to hold the decoded message.
if(CryptVerifyMessageSignature(
&VerifyParams,
0,
pSignedMessageBlob->pbData,
pSignedMessageBlob->cbData,
NULL,
&cbDecodedMessageBlob,
NULL))
{
_tprintf(TEXT("%d bytes needed for the decoded message.\n"),
cbDecodedMessageBlob);
}
else
{
_tprintf(TEXT("Verification message failed. \n"));
goto exit_VerifySignedMessage;
}
//---------------------------------------------------------------
// Allocate memory for the decoded message.
if(!(pbDecodedMessageBlob =
(BYTE*)malloc(cbDecodedMessageBlob)))
{
MyHandleError(
TEXT("Memory allocation error allocating decode BLOB."));
goto exit_VerifySignedMessage;
}
//---------------------------------------------------------------
// Call CryptVerifyMessageSignature again to verify the signature
// and, if successful, copy the decoded message into the buffer.
// This will validate the signature against the certificate in
// the local store.
if(CryptVerifyMessageSignature(
&VerifyParams,
0,
pSignedMessageBlob->pbData,
pSignedMessageBlob->cbData,
pbDecodedMessageBlob,
&cbDecodedMessageBlob,
NULL))
{
_tprintf(TEXT("The verified message is \"%s\".\n"),
pbDecodedMessageBlob);
fReturn = true;
}
else
{
_tprintf(TEXT("Verification message failed. \n"));
}
exit_VerifySignedMessage:
// If something failed and the decoded message buffer was
// allocated, free it.
if(!fReturn)
{
if(pbDecodedMessageBlob)
{
free(pbDecodedMessageBlob);
pbDecodedMessageBlob = NULL;
}
}
// If the decoded message buffer is still around, it means the
// function was successful. Copy the pointer and size into the
// output parameter.
if(pbDecodedMessageBlob)
{
pDecodedMessageBlob->cbData = cbDecodedMessageBlob;
pDecodedMessageBlob->pbData = pbDecodedMessageBlob;
}
return fReturn;
}
| Content type | Description |
|---|---|
| Data | An octet (BYTE) string. |
| Signed Data | Content of any type and encrypted message hashes (digests) of the content for zero or more signers. |
| Enveloped Data | Encrypted content of any type and encrypted content-encryption keys for one or more recipients. The combination of encrypted content and encrypted content-encryption key for a recipient is a digital envelope for that recipient. |
| Signed-and-Enveloped Data | Encrypted content of any type, encrypted content-encryption keys for one or more recipients, and doubly encrypted message digests for one or more signers. The double encryption consists of an encryption with a signer's private key followed by an encryption with the content-encryption key. |
| Digested Data | Content of any type and a message hash (digest) of the content. |
| Encrypted Data | Encrypted content of any type. Unlike the enveloped-data content type, the encrypted-data content type has neither recipients nor encrypted content-encryption keys. Keys are assumed to be managed by other means. |
CAdES-BES: CMS Advanced Electronic Signature - Basic Electronic Signature
PKCS#7:
see: https://boringssl.googlesource.com/boringssl/+/master/include/openssl/pkcs7.h
| // Deprecated functions. |
| // |
| // These functions are a compatibility layer over a subset of OpenSSL's PKCS#7 |
| // API. It intentionally does not implement the whole thing, only the minimum |
| // needed to build cryptography.io. |
| typedef struct { |
| STACK_OF(X509) *cert; |
| STACK_OF(X509_CRL) *crl; |
| } PKCS7_SIGNED; |
| typedef struct { |
| STACK_OF(X509) *cert; |
| STACK_OF(X509_CRL) *crl; |
| } PKCS7_SIGN_ENVELOPE; |
| typedef void PKCS7_ENVELOPE; |
| typedef void PKCS7_DIGEST; |
| typedef void PKCS7_ENCRYPT; |
| typedef struct { |
| uint8_t *ber_bytes; |
| size_t ber_len; |
| // Unlike OpenSSL, the following fields are immutable. They filled in when the |
| // object is parsed and ignored in serialization. |
| ASN1_OBJECT *type; |
| union { |
| char *ptr; |
| ASN1_OCTET_STRING *data; |
| PKCS7_SIGNED *sign; |
| PKCS7_ENVELOPE *enveloped; |
| PKCS7_SIGN_ENVELOPE *signed_and_enveloped; |
| PKCS7_DIGEST *digest; |
| PKCS7_ENCRYPT *encrypted; |
| ASN1_TYPE *other; |
| } d; |
| } PKCS7; |
| // d2i_PKCS7 parses a BER-encoded, PKCS#7 signed data ContentInfo structure from |
| // |len| bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the |
| // result is in |*out|. Note that, even if |*out| is already non-NULL on entry, |
| // it will not be written to. Rather, a fresh |PKCS7| is allocated and the |
| // previous one is freed. On successful exit, |*inp| is advanced past the BER |
| // structure. It returns the result or NULL on error. |
| OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, |