Signature d’un message
Lorsqu’un client et un serveur terminent la configuration du contexte de sécurité, les fonctions de support des messages peuvent être utilisées. Le client et le serveur utilisent le jeton de contexte de sécurité créé lors de l’établissement de la session pour appeler les fonctions MakeSignature et VerifySignature . Le jeton de contexte peut être utilisé avec EncryptMessage (Général) et DecryptMessage (Général) pour la confidentialité des communications.
L’exemple suivant montre le côté client générant un message signé à envoyer au serveur. Avant d’appeler MakeSignature, le client appelle QueryContextAttributes (Général) avec une structure SecPkgContext_Sizes pour déterminer la longueur de la mémoire tampon nécessaire pour contenir la signature du message. Si le membre cbMaxSignature est égal à zéro, le package de sécurité ne prend pas en charge les messages de signature. Sinon, ce membre indique la taille de la mémoire tampon à allouer pour recevoir la signature.
L’exemple suppose qu’une variable SecHandle nommée phContext et une structure SOCKET nommée s sont initialisées. Pour connaître les déclarations et les initiations de ces variables, consultez Utilisation de SSPI avec un client Windows Sockets et Utilisation de SSPI avec un serveur Windows Sockets Server. Cet exemple inclut des appels à des fonctions dans Secur32.lib, qui doivent être incluses dans les bibliothèques de liens.
//--------------------------------------------------------------------
// Declare and initialize local variables.
SecPkgContext_Sizes ContextSizes;
char *MessageBuffer = "This is a sample buffer to be signed.";
DWORD MessageBufferSize = strlen(MessageBuffer);
SecBufferDesc InputBufferDescriptor;
SecBuffer InputSecurityToken[2];
ss = QueryContextAttributes(
&phContext,
SECPKG_ATTR_SIZES,
&ContextSizes
);
if(ContextSizes.cbMaxSignature == 0)
{
MyHandleError("This session does not support message signing.");
}
//--------------------------------------------------------------------
// The message as a byte string is in the variable
// MessageBuffer, and its length is in MessageBufferSize.
//--------------------------------------------------------------------
// Build the buffer descriptor and the buffers
// to pass to the MakeSignature call.
InputBufferDescriptor.cBuffers = 2;
InputBufferDescriptor.pBuffers = InputSecurityToken;
InputBufferDescriptor.ulVersion = SECBUFFER_VERSION;
//--------------------------------------------------------------------
// Build a security buffer for the message itself. If
// the SECBUFFER_READONLY attribute is set, the buffer will not be
// signed.
InputSecurityToken[0].BufferType = SECBUFFER_DATA;
InputSecurityToken[0].cbBuffer = MessageBufferSize;
InputSecurityToken[0].pvBuffer = MessageBuffer;
//--------------------------------------------------------------------
// Allocate and build a security buffer for the message
// signature.
InputSecurityToken[1].BufferType = SECBUFFER_TOKEN;
InputSecurityToken[1].cbBuffer = ContextSizes.cbMaxSignature;
InputSecurityToken[1].pvBuffer =
(void *)malloc(ContextSizes.cbMaxSignature);
//--------------------------------------------------------------------
// Call MakeSignature
// For the NTLM package, the sequence number need not be specified
// because the package provides sequencing.
// The quality of service parameter is ignored.
Ss = MakeSignature(
&phContext,
0, // no quality of service
&InputBufferDescriptor, // input message descriptor
0 // no sequence number
);
if (SEC_SUCCESS(ss))
{
printf("Have made a signature.\n");
}
else
{
MyHandleError("MakeSignature Failed.");
}
//--------------------------------------------------------------------
// Send the message.
if(!SendMsg(
s,
(BYTE *)InputSecurityToken[0].pvBuffer,
InputSecurityToken[0].cbBuffer))
{
MyHandleError("The message was not sent.");
}
//--------------------------------------------------------------------
// Send the signature.
if(!SendMsg(
s,
(BYTE *)InputSecurityToken[1].pvBuffer,
InputSecurityToken[1].cbBuffer ))
{
MyHandleError("The signature was not sent.");
}
MakeSignature retourne TRUE si le contexte est configuré pour autoriser la signature des messages et si le descripteur de mémoire tampon d’entrée est correctement mis en forme. Une fois le message signé, le message et la signature avec leurs longueurs sont envoyés à l’ordinateur distant.
Notes
Le contenu des données des structures SecBuffer est envoyé, pas les structures SecBuffer elles-mêmes ni la structure SecBufferDesc . De nouvelles structures SecBuffer et une nouvelle structure SecBufferDesc sont créées par l’application réceptrice pour vérifier la signature.