コード例 #1
0
ファイル: gensec_krb5.c プロジェクト: rchicoli/samba
/*
  parse a krb5 GSS-API wrapper packet giving a ticket
*/
static bool gensec_gssapi_parse_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, DATA_BLOB *ticket, uint8_t tok_id[2])
{
    bool ret;
    struct asn1_data *data = asn1_init(mem_ctx);
    int data_remaining;

    if (!data) {
        return false;
    }

    asn1_load(data, *blob);
    asn1_start_tag(data, ASN1_APPLICATION(0));
    asn1_check_OID(data, GENSEC_OID_KERBEROS5);

    data_remaining = asn1_tag_remaining(data);

    if (data_remaining < 3) {
        data->has_error = true;
    } else {
        asn1_read(data, tok_id, 2);
        data_remaining -= 2;
        *ticket = data_blob_talloc(mem_ctx, NULL, data_remaining);
        asn1_read(data, ticket->data, ticket->length);
    }

    asn1_end_tag(data);

    ret = !data->has_error;

    asn1_free(data);

    return ret;
}
/*
 * Parse PKCS#7 wrapped X.509 certificates
 */
bool
parse_pkcs7_cert(chunk_t blob, x509cert_t **cert)
{
    asn1_ctx_t ctx;
    chunk_t object;
    int objectID = 0;

    asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);

    while (objectID < PKCS7_INFO_ROOF) {

	if (!extract_object(contentInfoObjects, &objectID, &object, &ctx))
	     return FALSE;

	if (objectID == PKCS7_INFO_TYPE)
	{
	    if (known_oid(object) != OID_PKCS7_SIGNED_DATA)
	    {
		log("PKCS#7 content type is not signedData");
		return FALSE;
	    }
	}
	else if (objectID == PKCS7_INFO_CONTENT)
	{
	    u_int level = contentInfoObjects[objectID].level + 1;

	    parse_pkcs7_signedData(object, level, cert);
	}
	objectID++;
    }
    return TRUE;
}
コード例 #3
0
ファイル: spnego_parse.c プロジェクト: gojdic/samba
bool spnego_write_mech_types(TALLOC_CTX *mem_ctx,
                             const char **mech_types,
                             DATA_BLOB *blob)
{
    struct asn1_data *asn1 = asn1_init(mem_ctx);

    /* Write mechTypes */
    if (mech_types && *mech_types) {
        int i;

        asn1_push_tag(asn1, ASN1_SEQUENCE(0));
        for (i = 0; mech_types[i]; i++) {
            asn1_write_OID(asn1, mech_types[i]);
        }
        asn1_pop_tag(asn1);
    }

    if (asn1->has_error) {
        asn1_free(asn1);
        return false;
    }

    *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
    if (blob->length != asn1->length) {
        asn1_free(asn1);
        return false;
    }

    asn1_free(asn1);

    return true;
}
コード例 #4
0
ファイル: pkcs.c プロジェクト: hydromet/libreswan
/*
 * Parse PKCS#7 wrapped X.509 certificates
 */
static bool parse_pkcs7_signedData(chunk_t blob, int level0, x509cert_t **cert)
{
	asn1_ctx_t ctx;
	chunk_t object;
	u_int level;
	u_int objectID = 0;

	asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);

	while (objectID < PKCS7_SIGNED_ROOF) {

		if (!extract_object(signedDataObjects, &objectID, &object,
				    &level, &ctx))
			return FALSE;

		if (objectID == PKCS7_SIGNED_CERT) {
			chunk_t cert_blob;
			x509cert_t *newcert = alloc_thing(x509cert_t,
							  "pkcs7 wrapped x509cert");

			clonetochunk(cert_blob, object.ptr, object.len,
				     "pkcs7 cert blob");
			*newcert = empty_x509cert;

			if (parse_x509cert(cert_blob, level + 1, newcert)) {
				newcert->next = *cert;
				*cert = newcert;
			} else {
				free_x509cert(newcert);
			}
		}
		objectID++;
	}
	return TRUE;
}
/*
 *  Parses a PKCS#1 private key
 */
bool
parse_pkcs1_private_key(chunk_t blob, pkcs1privkey_t *key)
{
    asn1_ctx_t ctx;
    chunk_t object;
    int objectID = 0;

    asn1_init(&ctx, blob, 0, FALSE, DBG_PRIVATE);

    while (objectID < PKCS1_PRIV_KEY_ROOF) {

	if (!extract_object(privkeyObjects, &objectID, &object, &ctx))
	     return FALSE;

	if (objectID == PKCS1_PRIV_KEY_OBJECT)
	{
	    key->pkcs1object = object;
	}
	else if (objectID == PKCS1_PRIV_KEY_VERSION)
	{
	    if (*object.ptr != 0)
	    {
		log("  wrong PKCS#1 private key version");
		return FALSE;
	    }
	}
	else if (objectID >= PKCS1_PRIV_KEY_MODULUS &&
		 objectID <= PKCS1_PRIV_KEY_COEFF)
	{
	    key->field[objectID - PKCS1_PRIV_KEY_MODULUS] = object;
	}
	objectID++;
    }
    return TRUE;
}
コード例 #6
0
ファイル: clispnego.c プロジェクト: miguelinux/samba
/*
 generate a SPNEGO auth packet. This will contain the encrypted passwords
*/
DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
{
	ASN1_DATA *data;
	DATA_BLOB ret = data_blob_null;

	data = asn1_init(talloc_tos());
	if (data == NULL) {
		return data_blob_null;
	}

	if (!asn1_push_tag(data, ASN1_CONTEXT(1))) goto err;
	if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
	if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err;
	if (!asn1_write_OctetString(data,blob.data,blob.length)) goto err;
	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_extract_blob(data, ctx, &ret)) {
		goto err;
	}

 err:

	asn1_free(data);

	return ret;
}
コード例 #7
0
ファイル: gensec_krb5.c プロジェクト: rchicoli/samba
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
static DATA_BLOB gensec_gssapi_gen_krb5_wrap(TALLOC_CTX *mem_ctx, const DATA_BLOB *ticket, const uint8_t tok_id[2])
{
    struct asn1_data *data;
    DATA_BLOB ret;

    data = asn1_init(mem_ctx);
    if (!data || !ticket->data) {
        return data_blob(NULL,0);
    }

    asn1_push_tag(data, ASN1_APPLICATION(0));
    asn1_write_OID(data, GENSEC_OID_KERBEROS5);

    asn1_write(data, tok_id, 2);
    asn1_write(data, ticket->data, ticket->length);
    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
        asn1_free(data);
        return data_blob(NULL,0);
    }

    ret = data_blob_talloc(mem_ctx, data->data, data->length);
    asn1_free(data);

    return ret;
}
コード例 #8
0
ファイル: ldap_server.c プロジェクト: AllardJ/Tomato
/*
  decode/process data
*/
static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob)
{
	NTSTATUS status;
	struct ldapsrv_connection *conn = talloc_get_type(private_data,
							  struct ldapsrv_connection);
	struct asn1_data *asn1 = asn1_init(conn);
	struct ldap_message *msg = talloc(conn, struct ldap_message);

	if (asn1 == NULL || msg == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	if (!asn1_load(asn1, blob)) {
		talloc_free(msg);
		talloc_free(asn1);
		return NT_STATUS_NO_MEMORY;
	}

	status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
	if (!NT_STATUS_IS_OK(status)) {
		asn1_free(asn1);
		return status;
	}

	data_blob_free(&blob);
	talloc_steal(conn, msg);
	asn1_free(asn1);

	ldapsrv_process_message(conn, msg);
	return NT_STATUS_OK;
}
コード例 #9
0
ファイル: clispnego.c プロジェクト: miguelinux/samba
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8_t tok_id[2])
{
	ASN1_DATA *data;
	DATA_BLOB ret = data_blob_null;

	data = asn1_init(talloc_tos());
	if (data == NULL) {
		return data_blob_null;
	}

	if (!asn1_push_tag(data, ASN1_APPLICATION(0))) goto err;
	if (!asn1_write_OID(data, OID_KERBEROS5)) goto err;

	if (!asn1_write(data, tok_id, 2)) goto err;
	if (!asn1_write(data, ticket.data, ticket.length)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_extract_blob(data, ctx, &ret)) {
		goto err;
	}

  err:

	if (asn1_has_error(data)) {
		DEBUG(1, ("Failed to build krb5 wrapper at offset %d\n",
			  (int)asn1_current_ofs(data)));
	}

	asn1_free(data);

	return ret;
}
コード例 #10
0
ファイル: spnego_parse.c プロジェクト: gojdic/samba
ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_data *spnego)
{
    struct asn1_data *asn1 = asn1_init(mem_ctx);
    ssize_t ret = -1;

    if (asn1 == NULL) {
        return -1;
    }

    switch (spnego->type) {
    case SPNEGO_NEG_TOKEN_INIT:
        asn1_push_tag(asn1, ASN1_APPLICATION(0));
        asn1_write_OID(asn1, GENSEC_OID_SPNEGO);
        write_negTokenInit(asn1, &spnego->negTokenInit);
        asn1_pop_tag(asn1);
        break;
    case SPNEGO_NEG_TOKEN_TARG:
        write_negTokenTarg(asn1, &spnego->negTokenTarg);
        break;
    default:
        asn1->has_error = true;
        break;
    }

    if (!asn1->has_error) {
        *blob = data_blob_talloc(mem_ctx, asn1->data, asn1->length);
        ret = asn1->ofs;
    }
    asn1_free(asn1);

    return ret;
}
コード例 #11
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
/*
  generate a krb5 GSS-API wrapper packet given a ticket
*/
DATA_BLOB spnego_gen_krb5_wrap(TALLOC_CTX *ctx, const DATA_BLOB ticket, const uint8 tok_id[2])
{
    ASN1_DATA *data;
    DATA_BLOB ret;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data, ASN1_APPLICATION(0));
    asn1_write_OID(data, OID_KERBEROS5);

    asn1_write(data, tok_id, 2);
    asn1_write(data, ticket.data, ticket.length);
    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data->ofs));
    }

    ret = data_blob_talloc(ctx, data->data, data->length);
    asn1_free(data);

    return ret;
}
コード例 #12
0
/*
 * parse X.501 attributes
 */
bool
parse_attributes(chunk_t blob, scep_attributes_t *attrs)
{
    asn1_ctx_t ctx;
    chunk_t object;
    u_int level;
    int oid = OID_UNKNOWN;
    int objectID = 0;

    asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);

    DBG(DBG_CONTROL | DBG_PARSING,
	DBG_log("parsing attributes")
    )
    while (objectID < ATTRIBUTE_OBJ_ROOF)
    {
	if (!extract_object(attributesObjects, &objectID
			   , &object, &level, &ctx))
	     return FALSE;

	switch (objectID)
	{
	case ATTRIBUTE_OBJ_TYPE:
	    oid = known_oid(object);
	    break;
	case ATTRIBUTE_OBJ_VALUE:
	   if (!extract_attribute(oid, object, level, attrs))
		return FALSE;
	}
	objectID++;
    }
    return TRUE;
}
コード例 #13
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
                                  const char *OIDs[],
                                  DATA_BLOB *psecblob,
                                  const char *principal)
{
    int i;
    ASN1_DATA *data;
    DATA_BLOB ret;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data,ASN1_APPLICATION(0));
    asn1_write_OID(data,OID_SPNEGO);
    asn1_push_tag(data,ASN1_CONTEXT(0));
    asn1_push_tag(data,ASN1_SEQUENCE(0));

    asn1_push_tag(data,ASN1_CONTEXT(0));
    asn1_push_tag(data,ASN1_SEQUENCE(0));
    for (i=0; OIDs[i]; i++) {
        asn1_write_OID(data,OIDs[i]);
    }
    asn1_pop_tag(data);
    asn1_pop_tag(data);

    if (psecblob && psecblob->length && psecblob->data) {
        asn1_push_tag(data, ASN1_CONTEXT(2));
        asn1_write_OctetString(data,psecblob->data,
                               psecblob->length);
        asn1_pop_tag(data);
    }

    if (principal) {
        asn1_push_tag(data, ASN1_CONTEXT(3));
        asn1_push_tag(data, ASN1_SEQUENCE(0));
        asn1_push_tag(data, ASN1_CONTEXT(0));
        asn1_write_GeneralString(data,principal);
        asn1_pop_tag(data);
        asn1_pop_tag(data);
        asn1_pop_tag(data);
    }

    asn1_pop_tag(data);
    asn1_pop_tag(data);

    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data->ofs));
    }

    ret = data_blob_talloc(ctx, data->data, data->length);
    asn1_free(data);

    return ret;
}
コード例 #14
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
/*
  generate a minimal SPNEGO response packet.  Doesn't contain much.
*/
DATA_BLOB spnego_gen_auth_response_and_mic(TALLOC_CTX *ctx,
        NTSTATUS nt_status,
        const char *mechOID,
        DATA_BLOB *reply,
        DATA_BLOB *mechlistMIC)
{
    ASN1_DATA *data;
    DATA_BLOB ret;
    uint8 negResult;

    if (NT_STATUS_IS_OK(nt_status)) {
        negResult = SPNEGO_ACCEPT_COMPLETED;
    } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
        negResult = SPNEGO_ACCEPT_INCOMPLETE;
    } else {
        negResult = SPNEGO_REJECT;
    }

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data, ASN1_CONTEXT(1));
    asn1_push_tag(data, ASN1_SEQUENCE(0));
    asn1_push_tag(data, ASN1_CONTEXT(0));
    asn1_write_enumerated(data, negResult);
    asn1_pop_tag(data);

    if (mechOID) {
        asn1_push_tag(data,ASN1_CONTEXT(1));
        asn1_write_OID(data, mechOID);
        asn1_pop_tag(data);
    }

    if (reply && reply->data != NULL) {
        asn1_push_tag(data,ASN1_CONTEXT(2));
        asn1_write_OctetString(data, reply->data, reply->length);
        asn1_pop_tag(data);
    }

    if (mechlistMIC && mechlistMIC->data != NULL) {
        asn1_push_tag(data, ASN1_CONTEXT(3));
        asn1_write_OctetString(data,
                               mechlistMIC->data,
                               mechlistMIC->length);
        asn1_pop_tag(data);
    }

    asn1_pop_tag(data);
    asn1_pop_tag(data);

    ret = data_blob_talloc(ctx, data->data, data->length);
    asn1_free(data);
    return ret;
}
コード例 #15
0
ファイル: clispnego.c プロジェクト: miguelinux/samba
/*
  parse a spnego NTLMSSP challenge packet giving two security blobs
*/
bool spnego_parse_challenge(TALLOC_CTX *ctx, const DATA_BLOB blob,
			    DATA_BLOB *chal1, DATA_BLOB *chal2)
{
	bool ret = false;
	ASN1_DATA *data;

	ZERO_STRUCTP(chal1);
	ZERO_STRUCTP(chal2);

	data = asn1_init(talloc_tos());
	if (data == NULL) {
		return false;
	}

	if (!asn1_load(data, blob)) goto err;
	if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err;
	if (!asn1_start_tag(data,ASN1_SEQUENCE(0))) goto err;

	if (!asn1_start_tag(data,ASN1_CONTEXT(0))) goto err;
	if (!asn1_check_enumerated(data,1)) goto err;
	if (!asn1_end_tag(data)) goto err;

	if (!asn1_start_tag(data,ASN1_CONTEXT(1))) goto err;
	if (!asn1_check_OID(data, OID_NTLMSSP)) goto err;
	if (!asn1_end_tag(data)) goto err;

	if (!asn1_start_tag(data,ASN1_CONTEXT(2))) goto err;
	if (!asn1_read_OctetString(data, ctx, chal1)) goto err;
	if (!asn1_end_tag(data)) goto err;

	/* the second challenge is optional (XP doesn't send it) */
	if (asn1_tag_remaining(data)) {
		if (!asn1_start_tag(data,ASN1_CONTEXT(3))) goto err;
		if (!asn1_read_OctetString(data, ctx, chal2)) goto err;
		if (!asn1_end_tag(data)) goto err;
	}

	if (!asn1_end_tag(data)) goto err;
	if (!asn1_end_tag(data)) goto err;

	ret = !asn1_has_error(data);

  err:

	if (asn1_has_error(data)) {
		data_blob_free(chal1);
		data_blob_free(chal2);
	}

	asn1_free(data);
	return ret;
}
コード例 #16
0
ファイル: spnego_parse.c プロジェクト: gojdic/samba
ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data *token)
{
    struct asn1_data *asn1;
    ssize_t ret = -1;
    uint8_t context;

    ZERO_STRUCTP(token);

    if (data.length == 0) {
        return ret;
    }

    asn1 = asn1_init(mem_ctx);
    if (asn1 == NULL) {
        return -1;
    }

    asn1_load(asn1, data);

    if (!asn1_peek_uint8(asn1, &context)) {
        asn1->has_error = true;
    } else {
        switch (context) {
        case ASN1_APPLICATION(0):
            asn1_start_tag(asn1, ASN1_APPLICATION(0));
            asn1_check_OID(asn1, GENSEC_OID_SPNEGO);
            if (read_negTokenInit(asn1, mem_ctx, &token->negTokenInit)) {
                token->type = SPNEGO_NEG_TOKEN_INIT;
            }
            asn1_end_tag(asn1);
            break;
        case ASN1_CONTEXT(1):
            if (read_negTokenTarg(asn1, mem_ctx, &token->negTokenTarg)) {
                token->type = SPNEGO_NEG_TOKEN_TARG;
            }
            break;
        default:
            asn1->has_error = true;
            break;
        }
    }

    if (!asn1->has_error) ret = asn1->ofs;
    asn1_free(asn1);

    return ret;
}
コード例 #17
0
/*
  magic check a GSS-API wrapper packet for an Kerberos OID
*/
static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
{
	bool ret;
	struct asn1_data *data = asn1_init(NULL);

	if (!data) return false;

	asn1_load(data, *blob);
	asn1_start_tag(data, ASN1_APPLICATION(0));
	asn1_check_OID(data, oid);

	ret = !data->has_error;

	asn1_free(data);

	return ret;
}
コード例 #18
0
ファイル: ac.c プロジェクト: st3fan/libreswan
/*
 * parses ietfAttrSyntax
 */
static ietfAttrList_t*
parse_ietfAttrSyntax(chunk_t blob, int level0)
{
    asn1_ctx_t ctx;
    chunk_t object;
    u_int level;
    u_int objectID = 0;
    
    ietfAttrList_t *list = NULL;
	
    asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);

    while (objectID < IETF_ATTR_ROOF)
    {
       if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
            return NULL;

       switch (objectID)
       {
       case IETF_ATTR_OCTETS:
       case IETF_ATTR_OID:
       case IETF_ATTR_STRING:
           {
               ietfAttr_t *attr   = alloc_thing(ietfAttr_t, "ietfAttr");
               ietfAttrList_t *el = alloc_thing(ietfAttrList_t, "ietfAttrList");
            
               attr->kind  = (objectID - IETF_ATTR_OCTETS) / 2;
               attr->value = object;
               attr->count = 0;
       
               el->attr = add_ietfAttr(attr);
               el->next = list;
               list = el;
           }
           break;
	default:
	   break;
	}
	objectID++;
    }
    return list;
}
コード例 #19
0
ファイル: ac.c プロジェクト: st3fan/libreswan
/*
 * parses roleSyntax
 */
static void
parse_roleSyntax(chunk_t blob, int level0)
{
    asn1_ctx_t ctx;
    chunk_t object;
    u_int level;
    u_int objectID = 0;

    asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);

    while (objectID < ROLE_ROOF)
    {
	if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
	     return;

	switch (objectID) {
	default:
	    break;
	}
	objectID++;
    }
}
コード例 #20
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
/*
  parse a krb5 GSS-API wrapper packet giving a ticket
*/
bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
{
    bool ret;
    ASN1_DATA *data;
    int data_remaining;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return false;
    }

    asn1_load(data, blob);
    asn1_start_tag(data, ASN1_APPLICATION(0));
    asn1_check_OID(data, OID_KERBEROS5);

    data_remaining = asn1_tag_remaining(data);

    if (data_remaining < 3) {
        data->has_error = True;
    } else {
        asn1_read(data, tok_id, 2);
        data_remaining -= 2;
        *ticket = data_blob_talloc(ctx, NULL, data_remaining);
        asn1_read(data, ticket->data, ticket->length);
    }

    asn1_end_tag(data);

    ret = !data->has_error;

    if (data->has_error) {
        data_blob_free(ticket);
    }

    asn1_free(data);

    return ret;
}
コード例 #21
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
bool spnego_mech_list_blob(TALLOC_CTX *mem_ctx,
                           char **oid_list, DATA_BLOB *raw_data)
{
    ASN1_DATA *data;
    unsigned int idx;

    if (!oid_list || !oid_list[0] || !raw_data) {
        return false;
    }

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return false;
    }

    asn1_push_tag(data, ASN1_SEQUENCE(0));
    for (idx = 0; oid_list[idx]; idx++) {
        asn1_write_OID(data, oid_list[idx]);
    }
    asn1_pop_tag(data);

    if (data->has_error) {
        DEBUG(3, (__location__ " failed at %d\n", (int)data->ofs));
        asn1_free(data);
        return false;
    }

    *raw_data = data_blob_talloc(mem_ctx, data->data, data->length);
    if (!raw_data->data) {
        DEBUG(3, (__location__": data_blob_talloc() failed!\n"));
        asn1_free(data);
        return false;
    }

    asn1_free(data);
    return true;
}
コード例 #22
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
/*
 generate a SPNEGO auth packet. This will contain the encrypted passwords
*/
DATA_BLOB spnego_gen_auth(TALLOC_CTX *ctx, DATA_BLOB blob)
{
    ASN1_DATA *data;
    DATA_BLOB ret;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return data_blob_null;
    }

    asn1_push_tag(data, ASN1_CONTEXT(1));
    asn1_push_tag(data, ASN1_SEQUENCE(0));
    asn1_push_tag(data, ASN1_CONTEXT(2));
    asn1_write_OctetString(data,blob.data,blob.length);
    asn1_pop_tag(data);
    asn1_pop_tag(data);
    asn1_pop_tag(data);

    ret = data_blob_talloc(ctx, data->data, data->length);

    asn1_free(data);

    return ret;
}
コード例 #23
0
ファイル: ac.c プロジェクト: st3fan/libreswan
/*
 *  Parses an X.509 attribute certificate
 */
static bool
parse_ac(chunk_t blob, x509acert_t *ac)
{
    asn1_ctx_t ctx;
    bool critical;
    chunk_t extnID;
    chunk_t type;
    chunk_t object;
    u_int level;
    u_int objectID = 0;

    asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);

    while (objectID < AC_OBJ_ROOF) {

	if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
	     return FALSE;

	/* those objects which will parsed further need the next higher level */
	level++;

	switch (objectID)
	{
	case AC_OBJ_CERTIFICATE:
	    ac->certificate = object;
	    break;
	case AC_OBJ_CERTIFICATE_INFO:
	    ac->certificateInfo = object;
	    break;
	case AC_OBJ_VERSION:
	    ac->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
	    DBG(DBG_PARSING,
		DBG_log("  v%d", ac->version);
	    )
	    if (ac->version != 2)
	    {
		libreswan_log("v%d attribute certificates are not supported"
		    , ac->version);
		return FALSE;
	    }
	    break;
	case AC_OBJ_HOLDER_ISSUER:
	    ac->holderIssuer = get_directoryName(object, level, FALSE);
	    break;
	case AC_OBJ_HOLDER_SERIAL:
	    ac->holderSerial = object;
	    break;
	case AC_OBJ_ENTITY_NAME:
	    ac->entityName = get_directoryName(object, level, TRUE);
	    break;
	case AC_OBJ_ISSUER_NAME:
	    ac->issuerName = get_directoryName(object, level, FALSE);
	    break;
	case AC_OBJ_SIG_ALG:
	    ac->sigAlg = parse_algorithmIdentifier(object, level);
	    break;
	case AC_OBJ_SERIAL_NUMBER:
	    ac->serialNumber = object;
	    break;
	case AC_OBJ_NOT_BEFORE:
	    ac->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
	    break;
	case AC_OBJ_NOT_AFTER:
	    ac->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
	    break;
	case AC_OBJ_ATTRIBUTE_TYPE:
	    type = object;
	    break;
	case AC_OBJ_ATTRIBUTE_VALUE:
	    {
		u_int type_oid = known_oid(type);

		switch (type_oid) {
		case OID_AUTHENTICATION_INFO:
		    DBG(DBG_PARSING,
			DBG_log("  need to parse authenticationInfo")
		    )
		    break;
		case OID_ACCESS_IDENTITY:
		    DBG(DBG_PARSING,
			DBG_log("  need to parse accessIdentity")
		    )
		    break;
		case OID_CHARGING_IDENTITY:
		    ac->charging = parse_ietfAttrSyntax(object, level);
		    break;
		case OID_GROUP:
		    ac->groups = parse_ietfAttrSyntax(object, level);
		    break;
		case OID_ROLE:
		    parse_roleSyntax(object, level);
		    break;
		default:
		    break;
		}
	    }
	    break;
	case AC_OBJ_EXTN_ID:
	    extnID = object;
	    break;
	case AC_OBJ_CRITICAL:
	    critical = object.len && *object.ptr;
	    DBG(DBG_PARSING,
		DBG_log("  %s",(critical)?"TRUE":"FALSE");
	    )
	    break;
	case AC_OBJ_EXTN_VALUE:
	    {
		u_int extn_oid = known_oid(extnID);

		switch (extn_oid) {
		case OID_CRL_DISTRIBUTION_POINTS:
		    DBG(DBG_PARSING,
			DBG_log("  need to parse crlDistributionPoints")
		    )
		    break;
		case OID_AUTHORITY_KEY_ID:
		    parse_authorityKeyIdentifier(object, level
			, &ac->authKeyID, &ac->authKeySerialNumber);
		    break;
		case OID_TARGET_INFORMATION:
		    DBG(DBG_PARSING,
			DBG_log("  need to parse targetInformation")
		    )
		    break;
		case OID_NO_REV_AVAIL:
		    ac->noRevAvail = TRUE;
		    break;
		default:
		    break;
		}
	    }
	    break;
	case AC_OBJ_ALGORITHM:
	    ac->algorithm = parse_algorithmIdentifier(object, level);
	    break;
	case AC_OBJ_SIGNATURE:
	    ac->signature = object;
	    break;

	default:
	    break;
	}
コード例 #24
0
ファイル: ldap_server.c プロジェクト: Alexandr-Galko/samba
static void ldapsrv_call_read_done(struct tevent_req *subreq)
{
	struct ldapsrv_connection *conn =
		tevent_req_callback_data(subreq,
		struct ldapsrv_connection);
	NTSTATUS status;
	struct ldapsrv_call *call;
	struct asn1_data *asn1;
	DATA_BLOB blob;

	call = talloc_zero(conn, struct ldapsrv_call);
	if (!call) {
		ldapsrv_terminate_connection(conn, "no memory");
		return;
	}

	call->conn = conn;

	status = tstream_read_pdu_blob_recv(subreq,
					    call,
					    &blob);
	TALLOC_FREE(subreq);
	if (!NT_STATUS_IS_OK(status)) {
		const char *reason;

		reason = talloc_asprintf(call, "ldapsrv_call_loop: "
					 "tstream_read_pdu_blob_recv() - %s",
					 nt_errstr(status));
		if (!reason) {
			reason = nt_errstr(status);
		}

		ldapsrv_terminate_connection(conn, reason);
		return;
	}

	asn1 = asn1_init(call);
	if (asn1 == NULL) {
		ldapsrv_terminate_connection(conn, "no memory");
		return;
	}

	call->request = talloc(call, struct ldap_message);
	if (call->request == NULL) {
		ldapsrv_terminate_connection(conn, "no memory");
		return;
	}

	if (!asn1_load(asn1, blob)) {
		ldapsrv_terminate_connection(conn, "asn1_load failed");
		return;
	}

	status = ldap_decode(asn1, samba_ldap_control_handlers(),
			     call->request);
	if (!NT_STATUS_IS_OK(status)) {
		ldapsrv_terminate_connection(conn, nt_errstr(status));
		return;
	}

	data_blob_free(&blob);


	/* queue the call in the global queue */
	subreq = ldapsrv_process_call_send(call,
					   conn->connection->event.ctx,
					   conn->service->call_queue,
					   call);
	if (subreq == NULL) {
		ldapsrv_terminate_connection(conn, "ldapsrv_process_call_send failed");
		return;
	}
	tevent_req_set_callback(subreq, ldapsrv_call_process_done, call);
	conn->active_call = subreq;
}
コード例 #25
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
/*
  parse a negTokenInit packet giving a GUID, a list of supported
  OIDs (the mechanisms) and a principal name string
*/
bool spnego_parse_negTokenInit(TALLOC_CTX *ctx,
                               DATA_BLOB blob,
                               char *OIDs[ASN1_MAX_OIDS],
                               char **principal,
                               DATA_BLOB *secblob)
{
    int i;
    bool ret;
    ASN1_DATA *data;

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return false;
    }

    asn1_load(data, blob);

    asn1_start_tag(data,ASN1_APPLICATION(0));

    asn1_check_OID(data,OID_SPNEGO);

    /* negTokenInit  [0]  NegTokenInit */
    asn1_start_tag(data,ASN1_CONTEXT(0));
    asn1_start_tag(data,ASN1_SEQUENCE(0));

    /* mechTypes [0] MechTypeList  OPTIONAL */

    /* Not really optional, we depend on this to decide
     * what mechanisms we have to work with. */

    asn1_start_tag(data,ASN1_CONTEXT(0));
    asn1_start_tag(data,ASN1_SEQUENCE(0));
    for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
        asn1_read_OID(data,ctx, &OIDs[i]);
        if (data->has_error) {
            break;
        }
    }
    OIDs[i] = NULL;
    asn1_end_tag(data);
    asn1_end_tag(data);

    if (principal) {
        *principal = NULL;
    }
    if (secblob) {
        *secblob = data_blob_null;
    }

    /*
      Win7 + Live Sign-in Assistant attaches a mechToken
      ASN1_CONTEXT(2) to the negTokenInit packet
      which breaks our negotiation if we just assume
      the next tag is ASN1_CONTEXT(3).
    */

    if (asn1_peek_tag(data, ASN1_CONTEXT(1))) {
        uint8 flags;

        /* reqFlags [1] ContextFlags  OPTIONAL */
        asn1_start_tag(data, ASN1_CONTEXT(1));
        asn1_start_tag(data, ASN1_BIT_STRING);
        while (asn1_tag_remaining(data) > 0) {
            asn1_read_uint8(data, &flags);
        }
        asn1_end_tag(data);
        asn1_end_tag(data);
    }

    if (asn1_peek_tag(data, ASN1_CONTEXT(2))) {
        DATA_BLOB sblob = data_blob_null;
        /* mechToken [2] OCTET STRING  OPTIONAL */
        asn1_start_tag(data, ASN1_CONTEXT(2));
        asn1_read_OctetString(data, ctx, &sblob);
        asn1_end_tag(data);
        if (secblob) {
            *secblob = sblob;
        } else {
            data_blob_free(&sblob);
        }
    }

    if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
        char *princ = NULL;
        /* mechListMIC [3] OCTET STRING  OPTIONAL */
        asn1_start_tag(data, ASN1_CONTEXT(3));
        asn1_start_tag(data, ASN1_SEQUENCE(0));
        asn1_start_tag(data, ASN1_CONTEXT(0));
        asn1_read_GeneralString(data, ctx, &princ);
        asn1_end_tag(data);
        asn1_end_tag(data);
        asn1_end_tag(data);
        if (principal) {
            *principal = princ;
        } else {
            TALLOC_FREE(princ);
        }
    }

    asn1_end_tag(data);
    asn1_end_tag(data);

    asn1_end_tag(data);

    ret = !data->has_error;
    if (data->has_error) {
        int j;
        if (principal) {
            TALLOC_FREE(*principal);
        }
        if (secblob) {
            data_blob_free(secblob);
        }
        for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) {
            TALLOC_FREE(OIDs[j]);
        }
    }

    asn1_free(data);
    return ret;
}
コード例 #26
0
ファイル: clispnego.c プロジェクト: berserker/android_samba
/*
 parse a SPNEGO auth packet. This contains the encrypted passwords
*/
bool spnego_parse_auth_response(TALLOC_CTX *ctx,
                                DATA_BLOB blob, NTSTATUS nt_status,
                                const char *mechOID,
                                DATA_BLOB *auth)
{
    ASN1_DATA *data;
    uint8 negResult;

    if (NT_STATUS_IS_OK(nt_status)) {
        negResult = SPNEGO_ACCEPT_COMPLETED;
    } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
        negResult = SPNEGO_ACCEPT_INCOMPLETE;
    } else {
        negResult = SPNEGO_REJECT;
    }

    data = asn1_init(talloc_tos());
    if (data == NULL) {
        return false;
    }

    asn1_load(data, blob);
    asn1_start_tag(data, ASN1_CONTEXT(1));
    asn1_start_tag(data, ASN1_SEQUENCE(0));
    asn1_start_tag(data, ASN1_CONTEXT(0));
    asn1_check_enumerated(data, negResult);
    asn1_end_tag(data);

    *auth = data_blob_null;

    if (asn1_tag_remaining(data)) {
        asn1_start_tag(data,ASN1_CONTEXT(1));
        asn1_check_OID(data, mechOID);
        asn1_end_tag(data);

        if (asn1_tag_remaining(data)) {
            asn1_start_tag(data,ASN1_CONTEXT(2));
            asn1_read_OctetString(data, ctx, auth);
            asn1_end_tag(data);
        }
    } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) {
        data->has_error = 1;
    }

    /* Binding against Win2K DC returns a duplicate of the responseToken in
     * the optional mechListMIC field. This is a bug in Win2K. We ignore
     * this field if it exists. Win2K8 may return a proper mechListMIC at
     * which point we need to implement the integrity checking. */
    if (asn1_tag_remaining(data)) {
        DATA_BLOB mechList = data_blob_null;
        asn1_start_tag(data, ASN1_CONTEXT(3));
        asn1_read_OctetString(data, ctx, &mechList);
        asn1_end_tag(data);
        data_blob_free(&mechList);
        DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
                 "ignoring.\n"));
    }

    asn1_end_tag(data);
    asn1_end_tag(data);

    if (data->has_error) {
        DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data->ofs));
        asn1_free(data);
        data_blob_free(auth);
        return False;
    }

    asn1_free(data);
    return True;
}
コード例 #27
0
/*
  handle recv events on a cldap socket
*/
static bool cldap_socket_recv_dgram(struct cldap_socket *c,
				    struct cldap_incoming *in)
{
	DATA_BLOB blob;
	struct asn1_data *asn1;
	void *p;
	struct cldap_search_state *search;
	NTSTATUS status;

	if (in->recv_errno != 0) {
		goto error;
	}

	blob = data_blob_const(in->buf, in->len);

	asn1 = asn1_init(in);
	if (!asn1) {
		goto nomem;
	}

	if (!asn1_load(asn1, blob)) {
		goto nomem;
	}

	in->ldap_msg = talloc(in, struct ldap_message);
	if (in->ldap_msg == NULL) {
		goto nomem;
	}

	/* this initial decode is used to find the message id */
	status = ldap_decode(asn1, NULL, in->ldap_msg);
	if (!NT_STATUS_IS_OK(status)) {
		goto nterror;
	}

	/* find the pending request */
	p = idr_find(c->searches.idr, in->ldap_msg->messageid);
	if (p == NULL) {
		if (!c->incoming.handler) {
			TALLOC_FREE(in);
			return true;
		}

		/* this function should free or steal 'in' */
		c->incoming.handler(c, c->incoming.private_data, in);
		return false;
	}

	search = talloc_get_type_abort(p, struct cldap_search_state);
	search->response.in = talloc_move(search, &in);
	search->response.asn1 = asn1;
	search->response.asn1->ofs = 0;

	DLIST_REMOVE(c->searches.list, search);

	if (cldap_recvfrom_setup(c)) {
		tevent_req_done(search->req);
		return true;
	}

	/*
	 * This request was ok, just defer the notify of the caller
	 * and then just fail the next request if needed
	 */
	tevent_req_defer_callback(search->req, search->caller.ev);
	tevent_req_done(search->req);

	status = NT_STATUS_NO_MEMORY;
	/* in is NULL it this point */
	goto nterror;
nomem:
	in->recv_errno = ENOMEM;
error:
	status = map_nt_error_from_unix_common(in->recv_errno);
nterror:
	TALLOC_FREE(in);
	/* in connected mode the first pending search gets the error */
	if (!c->connected) {
		/* otherwise we just ignore the error */
		return false;
	}
	if (!c->searches.list) {
		return false;
	}
	/*
	 * We might called tevent_req_done() for a successful
	 * search before, so we better deliver the failure
	 * after the success, that is why we better also
	 * use tevent_req_defer_callback() here.
	 */
	tevent_req_defer_callback(c->searches.list->req,
				  c->searches.list->caller.ev);
	tevent_req_nterror(c->searches.list->req, status);
	return false;
}
コード例 #28
0
ファイル: clispnego.c プロジェクト: miguelinux/samba
DATA_BLOB spnego_gen_negTokenInit(TALLOC_CTX *ctx,
				  const char *OIDs[],
				  DATA_BLOB *psecblob,
				  const char *principal)
{
	int i;
	ASN1_DATA *data;
	DATA_BLOB ret = data_blob_null;

	data = asn1_init(talloc_tos());
	if (data == NULL) {
		return data_blob_null;
	}

	if (!asn1_push_tag(data,ASN1_APPLICATION(0))) goto err;
	if (!asn1_write_OID(data,OID_SPNEGO)) goto err;
	if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err;
	if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err;

	if (!asn1_push_tag(data,ASN1_CONTEXT(0))) goto err;
	if (!asn1_push_tag(data,ASN1_SEQUENCE(0))) goto err;
	for (i=0; OIDs[i]; i++) {
		if (!asn1_write_OID(data,OIDs[i])) goto err;
	}
	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (psecblob && psecblob->length && psecblob->data) {
		if (!asn1_push_tag(data, ASN1_CONTEXT(2))) goto err;
		if (!asn1_write_OctetString(data,psecblob->data,
			psecblob->length)) goto err;
		if (!asn1_pop_tag(data)) goto err;
	}

	if (principal) {
		if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
		if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
		if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
		if (!asn1_write_GeneralString(data,principal)) goto err;
		if (!asn1_pop_tag(data)) goto err;
		if (!asn1_pop_tag(data)) goto err;
		if (!asn1_pop_tag(data)) goto err;
	}

	if (!asn1_pop_tag(data)) goto err;
	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_pop_tag(data)) goto err;

	if (!asn1_extract_blob(data, ctx, &ret)) {
		goto err;
	}

  err:

	if (asn1_has_error(data)) {
		DEBUG(1, ("Failed to build negTokenInit at offset %d\n",
			  (int)asn1_current_ofs(data)));
	}

	asn1_free(data);

	return ret;
}
コード例 #29
0
ファイル: krb5_setpw.c プロジェクト: AIdrifter/samba
/* This implements kerberos password change protocol as specified in 
 * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt
 * as well as microsoft version of the protocol 
 * as specified in kerberos-set-passwd-00.txt
 */
static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password)
{
        char* princ_part1 = NULL;
	char* princ_part2 = NULL;
	char* realm = NULL;
	char* c;
	char* princ;

	ASN1_DATA *req;
	DATA_BLOB ret;


	princ = SMB_STRDUP(principal);

	if ((c = strchr_m(princ, '/')) == NULL) {
		c = princ; 
	} else {
		*c = '\0';
		c++;
		princ_part1 = princ;
	}

	princ_part2 = c;

	if ((c = strchr_m(c, '@')) != NULL) {
		*c = '\0';
		c++;
		realm = c;
	} else {
		/* We must have a realm component. */
		return data_blob_null;
	}

	req = asn1_init(talloc_tos());
	if (req == NULL) {
		return data_blob_null;
	}

	asn1_push_tag(req, ASN1_SEQUENCE(0));
	asn1_push_tag(req, ASN1_CONTEXT(0));
	asn1_write_OctetString(req, password, strlen(password));
	asn1_pop_tag(req);

	asn1_push_tag(req, ASN1_CONTEXT(1));
	asn1_push_tag(req, ASN1_SEQUENCE(0));

	asn1_push_tag(req, ASN1_CONTEXT(0));
	asn1_write_Integer(req, 1);
	asn1_pop_tag(req);

	asn1_push_tag(req, ASN1_CONTEXT(1));
	asn1_push_tag(req, ASN1_SEQUENCE(0));

	if (princ_part1) {
		asn1_write_GeneralString(req, princ_part1);
	}
	
	asn1_write_GeneralString(req, princ_part2);
	asn1_pop_tag(req);
	asn1_pop_tag(req);
	asn1_pop_tag(req);
	asn1_pop_tag(req);

	asn1_push_tag(req, ASN1_CONTEXT(2));
	asn1_write_GeneralString(req, realm);
	asn1_pop_tag(req);
	asn1_pop_tag(req);

	ret = data_blob(req->data, req->length);
	asn1_free(req);

	free(princ);

	return ret;
}	
コード例 #30
0
ファイル: cldap.c プロジェクト: gojdic/samba
/*
  handle recv events on a cldap socket
*/
static void cldap_socket_recv_dgram(struct cldap_socket *c,
				    struct cldap_incoming *in)
{
	DATA_BLOB blob;
	struct asn1_data *asn1;
	void *p;
	struct cldap_search_state *search;
	NTSTATUS status;

	if (in->recv_errno != 0) {
		goto error;
	}

	blob = data_blob_const(in->buf, in->len);

	asn1 = asn1_init(in);
	if (!asn1) {
		goto nomem;
	}

	if (!asn1_load(asn1, blob)) {
		goto nomem;
	}

	in->ldap_msg = talloc(in, struct ldap_message);
	if (in->ldap_msg == NULL) {
		goto nomem;
	}

	/* this initial decode is used to find the message id */
	status = ldap_decode(asn1, NULL, in->ldap_msg);
	if (!NT_STATUS_IS_OK(status)) {
		goto nterror;
	}

	/* find the pending request */
	p = idr_find(c->searches.idr, in->ldap_msg->messageid);
	if (p == NULL) {
		if (!c->incoming.handler) {
			goto done;
		}

		/* this function should free or steal 'in' */
		c->incoming.handler(c, c->incoming.private_data, in);
		return;
	}

	search = talloc_get_type(p, struct cldap_search_state);
	search->response.in = talloc_move(search, &in);
	search->response.asn1 = asn1;
	search->response.asn1->ofs = 0;

	tevent_req_done(search->req);
	goto done;

nomem:
	in->recv_errno = ENOMEM;
error:
	status = map_nt_error_from_unix(in->recv_errno);
nterror:
	/* in connected mode the first pending search gets the error */
	if (!c->connected) {
		/* otherwise we just ignore the error */
		goto done;
	}
	if (!c->searches.list) {
		goto done;
	}
	tevent_req_nterror(c->searches.list->req, status);
done:
	talloc_free(in);
}