libfreerdp-core: started parsing of X.509 certificates
This commit is contained in:
parent
518498546e
commit
a8e1da7252
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -23,6 +23,7 @@
|
||||
typedef struct rdp_certificate rdpCertificate;
|
||||
|
||||
#include "rdp.h"
|
||||
#include "ber.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user