Example #1
0
static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
			      struct spnego_negTokenTarg *token)
{
	ZERO_STRUCTP(token);

	asn1_start_tag(asn1, ASN1_CONTEXT(1));
	asn1_start_tag(asn1, ASN1_SEQUENCE(0));

	while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
		uint8_t context;
		char *oid;
		if (!asn1_peek_uint8(asn1, &context)) {
			asn1->has_error = true;
			break;
		}

		switch (context) {
		case ASN1_CONTEXT(0):
			asn1_start_tag(asn1, ASN1_CONTEXT(0));
			asn1_start_tag(asn1, ASN1_ENUMERATED);
			asn1_read_uint8(asn1, &token->negResult);
			asn1_end_tag(asn1);
			asn1_end_tag(asn1);
			break;
		case ASN1_CONTEXT(1):
			asn1_start_tag(asn1, ASN1_CONTEXT(1));
			asn1_read_OID(asn1, mem_ctx, &oid);
			token->supportedMech = oid;
			asn1_end_tag(asn1);
			break;
		case ASN1_CONTEXT(2):
			asn1_start_tag(asn1, ASN1_CONTEXT(2));
			asn1_read_OctetString(asn1, mem_ctx, &token->responseToken);
			asn1_end_tag(asn1);
			break;
		case ASN1_CONTEXT(3):
			asn1_start_tag(asn1, ASN1_CONTEXT(3));
			asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC);
			asn1_end_tag(asn1);
			break;
		default:
			asn1->has_error = true;
			break;
		}
	}

	asn1_end_tag(asn1);
	asn1_end_tag(asn1);

	return !asn1->has_error;
}
Example #2
0
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;
}
Example #3
0
static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
                              struct spnego_negTokenInit *token)
{
    ZERO_STRUCTP(token);

    asn1_start_tag(asn1, ASN1_CONTEXT(0));
    asn1_start_tag(asn1, ASN1_SEQUENCE(0));

    while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
        int i;
        uint8_t context;
        if (!asn1_peek_uint8(asn1, &context)) {
            asn1->has_error = true;
            break;
        }

        switch (context) {
        /* Read mechTypes */
        case ASN1_CONTEXT(0):
            asn1_start_tag(asn1, ASN1_CONTEXT(0));
            asn1_start_tag(asn1, ASN1_SEQUENCE(0));

            token->mechTypes = talloc(NULL, const char *);
            for (i = 0; !asn1->has_error &&
                    0 < asn1_tag_remaining(asn1); i++) {
                token->mechTypes = talloc_realloc(NULL,
                                                  token->mechTypes,
                                                  const char *, i+2);
                asn1_read_OID(asn1, token->mechTypes, token->mechTypes + i);
            }
            token->mechTypes[i] = NULL;

            asn1_end_tag(asn1);
            asn1_end_tag(asn1);
            break;
        /* Read reqFlags */
        case ASN1_CONTEXT(1):
            asn1_start_tag(asn1, ASN1_CONTEXT(1));
            asn1_read_Integer(asn1, &token->reqFlags);
            token->reqFlags |= SPNEGO_REQ_FLAG;
            asn1_end_tag(asn1);
            break;
        /* Read mechToken */
        case ASN1_CONTEXT(2):
            asn1_start_tag(asn1, ASN1_CONTEXT(2));
            asn1_read_OctetString(asn1, mem_ctx, &token->mechToken);
            asn1_end_tag(asn1);
            break;
        /* Read mecListMIC */
        case ASN1_CONTEXT(3):
        {
            uint8_t type_peek;
            asn1_start_tag(asn1, ASN1_CONTEXT(3));
            if (!asn1_peek_uint8(asn1, &type_peek)) {
                asn1->has_error = true;
                break;
            }
            if (type_peek == ASN1_OCTET_STRING) {
                asn1_read_OctetString(asn1, mem_ctx,
                                      &token->mechListMIC);
            } else {
                /* RFC 2478 says we have an Octet String here,
                   but W2k sends something different... */
                char *mechListMIC;
                asn1_push_tag(asn1, ASN1_SEQUENCE(0));
                asn1_push_tag(asn1, ASN1_CONTEXT(0));
                asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC);
                asn1_pop_tag(asn1);
                asn1_pop_tag(asn1);

                token->targetPrincipal = mechListMIC;
            }
            asn1_end_tag(asn1);
            break;
        }
        default:
            asn1->has_error = true;
            break;
        }
    }

    asn1_end_tag(asn1);
    asn1_end_tag(asn1);

    return !asn1->has_error;
}
Example #4
0
static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
			      struct spnego_negTokenInit *token)
{
	ZERO_STRUCTP(token);

	asn1_start_tag(asn1, ASN1_CONTEXT(0));
	asn1_start_tag(asn1, ASN1_SEQUENCE(0));

	while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
		int i;
		uint8_t context;
		if (!asn1_peek_uint8(asn1, &context)) {
			asn1->has_error = true;
			break;
		}

		switch (context) {
		/* Read mechTypes */
		case ASN1_CONTEXT(0): {
			const char **mechTypes;

			asn1_start_tag(asn1, ASN1_CONTEXT(0));
			asn1_start_tag(asn1, ASN1_SEQUENCE(0));

			mechTypes = talloc(mem_ctx, const char *);
			if (mechTypes == NULL) {
				asn1->has_error = true;
				return false;
			}
			for (i = 0; !asn1->has_error &&
				     0 < asn1_tag_remaining(asn1); i++) {
				char *oid;
				const char **p;
				p = talloc_realloc(mem_ctx,
						   mechTypes,
						   const char *, i+2);
				if (p == NULL) {
					talloc_free(mechTypes);
					asn1->has_error = true;
					return false;
				}
				mechTypes = p;

				asn1_read_OID(asn1, mechTypes, &oid);
				mechTypes[i] = oid;
			}
			mechTypes[i] = NULL;
			token->mechTypes = mechTypes;

			asn1_end_tag(asn1);
			asn1_end_tag(asn1);
			break;
		}
		/* Read reqFlags */
		case ASN1_CONTEXT(1):
			asn1_start_tag(asn1, ASN1_CONTEXT(1));
			asn1_read_BitString(asn1, mem_ctx, &token->reqFlags,
					    &token->reqFlagsPadding);
			asn1_end_tag(asn1);
			break;
                /* Read mechToken */
		case ASN1_CONTEXT(2):
			asn1_start_tag(asn1, ASN1_CONTEXT(2));
			asn1_read_OctetString(asn1, mem_ctx, &token->mechToken);
			asn1_end_tag(asn1);
			break;
		/* Read mecListMIC */
		case ASN1_CONTEXT(3):
		{
			uint8_t type_peek;
			asn1_start_tag(asn1, ASN1_CONTEXT(3));
			if (!asn1_peek_uint8(asn1, &type_peek)) {
				asn1->has_error = true;
				break;
			}
			if (type_peek == ASN1_OCTET_STRING) {
				asn1_read_OctetString(asn1, mem_ctx,
						      &token->mechListMIC);
			} else {
				/* RFC 2478 says we have an Octet String here,
				   but W2k sends something different... */
				char *mechListMIC;
				asn1_start_tag(asn1, ASN1_SEQUENCE(0));
				asn1_start_tag(asn1, ASN1_CONTEXT(0));
				asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC);
				asn1_end_tag(asn1);
				asn1_end_tag(asn1);

				token->targetPrincipal = mechListMIC;
			}
			asn1_end_tag(asn1);
			break;
		}
		default:
			asn1->has_error = true;
			break;
		}
	}

	asn1_end_tag(asn1);
	asn1_end_tag(asn1);

	return !asn1->has_error;
}