libfreerdp-core: started parsing of X.509 certificates

This commit is contained in:
Marc-André Moreau 2011-07-12 21:43:52 -04:00
parent 518498546e
commit a8e1da7252
6 changed files with 227 additions and 1 deletions

View File

@ -27,7 +27,8 @@ void ber_read_length(STREAM* s, int* length)
if (byte & 0x80)
{
if (byte & ~(0x80) == 2)
byte &= ~(0x80);
if (byte == 2)
{
stream_read_uint16_be(s, *length);
}
@ -57,6 +58,13 @@ void ber_write_length(STREAM* s, int length)
}
}
/**
* Read BER Universal tag.
* @param s stream
* @param tag BER universally-defined tag
* @return
*/
boolean ber_read_universal_tag(STREAM* s, uint8 tag)
{
uint8 byte;
@ -133,6 +141,20 @@ boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length)
return True;
}
boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc)
{
uint8 byte;
stream_read_uint8(s, byte);
if (byte != (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag))
return False;
ber_read_length(s, length);
return True;
}
boolean ber_read_sequence_of_tag(STREAM* s, int* length)
{
uint8 byte;
@ -213,6 +235,21 @@ void ber_write_boolean(STREAM* s, boolean value)
stream_write_uint8(s, (value == True) ? 0xFF : 0);
}
boolean ber_read_integer64(STREAM* s, uint8* value)
{
int length;
ber_read_universal_tag(s, BER_TAG_INTEGER);
ber_read_length(s, &length);
if (length != 8)
return False;
stream_read(s, value, 8);
return True;
}
boolean ber_read_integer(STREAM* s, uint32* value)
{
int length;
@ -220,6 +257,12 @@ boolean ber_read_integer(STREAM* s, uint32* value)
ber_read_universal_tag(s, BER_TAG_INTEGER);
ber_read_length(s, &length);
if (value == NULL)
{
stream_seek(s, length);
return True;
}
if (length == 1)
stream_read_uint8(s, *value);
else if (length == 2)

View File

@ -41,10 +41,14 @@
#define BER_TAG_MASK 0x1F
#define BER_TAG_BOOLEAN 0x01
#define BER_TAG_INTEGER 0x02
#define BER_TAG_BIT_STRING 0x03
#define BER_TAG_OCTET_STRING 0x04
#define BER_TAG_OBJECT_IDENFIER 0x06
#define BER_TAG_ENUMERATED 0x0A
#define BER_TAG_SEQUENCE_OF 0x10
#define BER_PC(_pc) (_pc ? BER_CONSTRUCT : BER_PRIMITIVE)
void ber_read_length(STREAM* s, int* length);
void ber_write_length(STREAM* s, int length);
void ber_write_universal_tag(STREAM* s, uint8 tag);
@ -52,11 +56,13 @@ void ber_write_application_tag(STREAM* s, uint8 tag, int length);
boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length);
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count);
boolean ber_read_sequence_of_tag(STREAM* s, int* length);
boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc);
void ber_write_sequence_of_tag(STREAM* s, int length);
boolean ber_read_octet_string(STREAM* s, int* length);
void ber_write_octet_string(STREAM* s, uint8* oct_str, int length);
void ber_write_boolean(STREAM* s, boolean value);
boolean ber_read_integer(STREAM* s, uint32* value);
boolean ber_read_integer64(STREAM* s, uint8* value);
void ber_write_integer(STREAM* s, uint32 value);
#endif /* __BER_H */

View File

@ -19,6 +19,151 @@
#include "certificate.h"
/**
*
* X.509 Certificate Structure
*
* Certificate ::= SEQUENCE
* {
* tbsCertificate TBSCertificate,
* signatureAlgorithm AlgorithmIdentifier,
* signatureValue BIT_STRING
* }
*
* TBSCertificate ::= SEQUENCE
* {
* version [0] EXPLICIT Version DEFAULT v1,
* serialNumber CertificateSerialNumber,
* signature AlgorithmIdentifier,
* issuer Name,
* validity Validity,
* subject Name,
* subjectPublicKeyInfo SubjectPublicKeyInfo,
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
* subjectUniqueId [2] IMPLICIT UniqueIdentifier OPTIONAL,
* extensions [3] EXPLICIT Extensions OPTIONAL
* }
*
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
*
* CertificateSerialNumber ::= INTEGER
*
* AlgorithmIdentifier ::= SEQUENCE
* {
* algorithm OBJECT_IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* Name ::= CHOICE { RDNSequence }
*
* RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
*
* RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
*
* AttributeTypeAndValue ::= SEQUENCE
* {
* type AttributeType,
* value AttributeValue
* }
*
* AttributeType ::= OBJECT_IDENTIFIER
*
* AttributeValue ::= ANY DEFINED BY AttributeType
*
* Validity ::= SEQUENCE
* {
* notBefore Time,
* notAfter Time
* }
*
* Time ::= CHOICE
* {
* utcTime UTCTime,
* generalTime GeneralizedTime
* }
*
* UniqueIdentifier ::= BIT_STRING
*
* SubjectPublicKeyInfo ::= SEQUENCE
* {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT_STRING
* }
*
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
*
* Extension ::= SEQUENCE
* {
* extnID OBJECT_IDENTIFIER
* critical BOOLEAN DEFAULT FALSE,
* extnValue OCTET_STRING
* }
*
*/
/**
* Read X.509 Certificate
* @param certificate certificate module
* @param cert X.509 certificate
*/
void certificate_read_x509_certificate(rdpCertificate* certificate, CERT_BLOB* cert)
{
STREAM* s;
int length;
uint32 version;
uint8 serialNumber[8];
s = stream_new(0);
s->p = s->data = cert->data;
ber_read_sequence_of_tag(s, &length); /* Certificate (SEQUENCE) */
ber_read_sequence_of_tag(s, &length); /* TBSCertificate (SEQUENCE) */
/* Explicit Contextual Tag [0] */
ber_read_contextual_tag(s, 0, &length, True);
ber_read_integer(s, &version); /* version (INTEGER) */
version++;
printf("X509v%d\n", version);
/* serialNumber */
ber_read_integer(s, NULL); /* CertificateSerialNumber (INTEGER) */
/* signature */
ber_read_sequence_of_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
stream_seek(s, length);
/* issuer */
ber_read_sequence_of_tag(s, &length); /* Name (SEQUENCE) */
stream_seek(s, length);
/* validity */
ber_read_sequence_of_tag(s, &length); /* Validity (SEQUENCE) */
stream_seek(s, length);
/* subject */
ber_read_sequence_of_tag(s, &length); /* Name (SEQUENCE) */
stream_seek(s, length);
/* subjectPublicKeyInfo */
ber_read_sequence_of_tag(s, &length); /* SubjectPublicKeyInfo (SEQUENCE) */
/* subjectPublicKeyInfo::AlgorithmIdentifier */
ber_read_sequence_of_tag(s, &length); /* AlgorithmIdentifier (SEQUENCE) */
stream_seek(s, length);
/* subjectPublicKeyInfo::subjectPublicKey */
/* BIT_STRING */
}
/**
* Instantiate new X.509 Certificate Chain.
* @param count certificate chain count
* @return new X.509 certificate chain
*/
X509_CERT_CHAIN* certificate_new_x509_certificate_chain(uint32 count)
{
X509_CERT_CHAIN* x509_cert_chain;
@ -31,6 +176,11 @@ X509_CERT_CHAIN* certificate_new_x509_certificate_chain(uint32 count)
return x509_cert_chain;
}
/**
* Free X.509 Certificate Chain.
* @param x509_cert_chain X.509 certificate chain to be freed
*/
void certificate_free_x509_certificate_chain(X509_CERT_CHAIN* x509_cert_chain)
{
int i;
@ -47,11 +197,23 @@ void certificate_free_x509_certificate_chain(X509_CERT_CHAIN* x509_cert_chain)
xfree(x509_cert_chain);
}
/**
* Read a Server Proprietary Certificate.\n
* @param certificate certificate module
* @param s stream
*/
void certificate_read_server_proprietary_certificate(rdpCertificate* certificate, STREAM* s)
{
printf("Server Proprietary Certificate\n");
}
/**
* Read an X.509 Certificate Chain.\n
* @param certificate certificate module
* @param s stream
*/
void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate, STREAM* s)
{
int i;
@ -82,9 +244,18 @@ void certificate_read_server_x509_certificate_chain(rdpCertificate* certificate,
certificate->x509_cert_chain->array[i].length = certLength;
freerdp_hexdump(certificate->x509_cert_chain->array[i].data, certificate->x509_cert_chain->array[i].length);
certificate_read_x509_certificate(certificate, &certificate->x509_cert_chain->array[i]);
}
}
/**
* Read a Server Certificate.\n
* @param certificate certificate module
* @param server_cert server certificate
* @param length certificate length
*/
void certificate_read_server_certificate(rdpCertificate* certificate, uint8* server_cert, int length)
{
STREAM* s;

View File

@ -23,6 +23,7 @@
typedef struct rdp_certificate rdpCertificate;
#include "rdp.h"
#include "ber.h"
#include "crypto.h"
#include <freerdp/utils/stream.h>

View File

@ -425,6 +425,7 @@ void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s)
/* EncryptedPlatformChallenge */
/* MACData (16 bytes) */
}
@ -539,6 +540,7 @@ void license_write_platform_challenge_response_packet(rdpLicense* license, STREA
license_generate_hwid(license);
/* EncryptedPlatformChallengeResponse */
license_read_binary_blob(s, license->encrypted_platform_challenge);
/* EncryptedHWID */
@ -585,6 +587,7 @@ rdpLicense* license_new(rdpRdp* rdp)
license->encrypted_pre_master_secret = license_new_binary_blob(BB_RANDOM_BLOB);
license->client_user_name = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB);
license->client_machine_name = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB);
license->encrypted_platform_challenge = license_new_binary_blob(BB_ANY_BLOB);
license->scope_list = license_new_scope_list();
}
@ -607,6 +610,7 @@ void license_free(rdpLicense* license)
license_free_binary_blob(license->encrypted_pre_master_secret);
license_free_binary_blob(license->client_user_name);
license_free_binary_blob(license->client_machine_name);
license_free_binary_blob(license->encrypted_platform_challenge);
license_free_scope_list(license->scope_list);
xfree(license);
}

View File

@ -120,6 +120,7 @@ struct rdp_license
LICENSE_BLOB* client_user_name;
LICENSE_BLOB* client_machine_name;
LICENSE_BLOB* encrypted_pre_master_secret;
LICENSE_BLOB* encrypted_platform_challenge;
SCOPE_LIST* scope_list;
};