diff options
Diffstat (limited to 'fs/cifs/asn1.c')
-rw-r--r-- | fs/cifs/asn1.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index 1b09f1670061..20692fbfdb24 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #define ASN1_OJI 6 /* Object Identifier */ | 49 | #define ASN1_OJI 6 /* Object Identifier */ |
50 | #define ASN1_OJD 7 /* Object Description */ | 50 | #define ASN1_OJD 7 /* Object Description */ |
51 | #define ASN1_EXT 8 /* External */ | 51 | #define ASN1_EXT 8 /* External */ |
52 | #define ASN1_ENUM 10 /* Enumerated */ | ||
52 | #define ASN1_SEQ 16 /* Sequence */ | 53 | #define ASN1_SEQ 16 /* Sequence */ |
53 | #define ASN1_SET 17 /* Set */ | 54 | #define ASN1_SET 17 /* Set */ |
54 | #define ASN1_NUMSTR 18 /* Numerical String */ | 55 | #define ASN1_NUMSTR 18 /* Numerical String */ |
@@ -78,10 +79,12 @@ | |||
78 | #define SPNEGO_OID_LEN 7 | 79 | #define SPNEGO_OID_LEN 7 |
79 | #define NTLMSSP_OID_LEN 10 | 80 | #define NTLMSSP_OID_LEN 10 |
80 | #define KRB5_OID_LEN 7 | 81 | #define KRB5_OID_LEN 7 |
82 | #define KRB5U2U_OID_LEN 8 | ||
81 | #define MSKRB5_OID_LEN 7 | 83 | #define MSKRB5_OID_LEN 7 |
82 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; | 84 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; |
83 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; | 85 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; |
84 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; | 86 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; |
87 | static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 }; | ||
85 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; | 88 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; |
86 | 89 | ||
87 | /* | 90 | /* |
@@ -122,6 +125,28 @@ asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) | |||
122 | return 1; | 125 | return 1; |
123 | } | 126 | } |
124 | 127 | ||
128 | #if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */ | ||
129 | static unsigned char | ||
130 | asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val) | ||
131 | { | ||
132 | unsigned char ch; | ||
133 | |||
134 | if (ctx->pointer >= ctx->end) { | ||
135 | ctx->error = ASN1_ERR_DEC_EMPTY; | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */ | ||
140 | if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */ | ||
141 | *val = *(++(ctx->pointer)); /* value has enum value */ | ||
142 | else | ||
143 | return 0; | ||
144 | |||
145 | ctx->pointer++; | ||
146 | return 1; | ||
147 | } | ||
148 | #endif | ||
149 | |||
125 | static unsigned char | 150 | static unsigned char |
126 | asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) | 151 | asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) |
127 | { | 152 | { |
@@ -476,10 +501,9 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
476 | unsigned int cls, con, tag, oidlen, rc; | 501 | unsigned int cls, con, tag, oidlen, rc; |
477 | bool use_ntlmssp = false; | 502 | bool use_ntlmssp = false; |
478 | bool use_kerberos = false; | 503 | bool use_kerberos = false; |
504 | bool use_kerberosu2u = false; | ||
479 | bool use_mskerberos = false; | 505 | bool use_mskerberos = false; |
480 | 506 | ||
481 | *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ | ||
482 | |||
483 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ | 507 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ |
484 | 508 | ||
485 | asn1_open(&ctx, security_blob, length); | 509 | asn1_open(&ctx, security_blob, length); |
@@ -515,6 +539,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
515 | return 0; | 539 | return 0; |
516 | } | 540 | } |
517 | 541 | ||
542 | /* SPNEGO */ | ||
518 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 543 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
519 | cFYI(1, ("Error decoding negTokenInit")); | 544 | cFYI(1, ("Error decoding negTokenInit")); |
520 | return 0; | 545 | return 0; |
@@ -526,6 +551,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
526 | return 0; | 551 | return 0; |
527 | } | 552 | } |
528 | 553 | ||
554 | /* negTokenInit */ | ||
529 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 555 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
530 | cFYI(1, ("Error decoding negTokenInit")); | 556 | cFYI(1, ("Error decoding negTokenInit")); |
531 | return 0; | 557 | return 0; |
@@ -537,6 +563,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
537 | return 0; | 563 | return 0; |
538 | } | 564 | } |
539 | 565 | ||
566 | /* sequence */ | ||
540 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 567 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
541 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 568 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); |
542 | return 0; | 569 | return 0; |
@@ -548,6 +575,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
548 | return 0; | 575 | return 0; |
549 | } | 576 | } |
550 | 577 | ||
578 | /* sequence of */ | ||
551 | if (asn1_header_decode | 579 | if (asn1_header_decode |
552 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { | 580 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { |
553 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 581 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); |
@@ -560,6 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
560 | return 0; | 588 | return 0; |
561 | } | 589 | } |
562 | 590 | ||
591 | /* list of security mechanisms */ | ||
563 | while (!asn1_eoc_decode(&ctx, sequence_end)) { | 592 | while (!asn1_eoc_decode(&ctx, sequence_end)) { |
564 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); | 593 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); |
565 | if (!rc) { | 594 | if (!rc) { |
@@ -576,11 +605,15 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
576 | 605 | ||
577 | if (compare_oid(oid, oidlen, MSKRB5_OID, | 606 | if (compare_oid(oid, oidlen, MSKRB5_OID, |
578 | MSKRB5_OID_LEN) && | 607 | MSKRB5_OID_LEN) && |
579 | !use_kerberos) | 608 | !use_mskerberos) |
580 | use_mskerberos = true; | 609 | use_mskerberos = true; |
610 | else if (compare_oid(oid, oidlen, KRB5U2U_OID, | ||
611 | KRB5U2U_OID_LEN) && | ||
612 | !use_kerberosu2u) | ||
613 | use_kerberosu2u = true; | ||
581 | else if (compare_oid(oid, oidlen, KRB5_OID, | 614 | else if (compare_oid(oid, oidlen, KRB5_OID, |
582 | KRB5_OID_LEN) && | 615 | KRB5_OID_LEN) && |
583 | !use_mskerberos) | 616 | !use_kerberos) |
584 | use_kerberos = true; | 617 | use_kerberos = true; |
585 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, | 618 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, |
586 | NTLMSSP_OID_LEN)) | 619 | NTLMSSP_OID_LEN)) |
@@ -593,7 +626,12 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
593 | } | 626 | } |
594 | } | 627 | } |
595 | 628 | ||
629 | /* mechlistMIC */ | ||
596 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 630 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
631 | /* Check if we have reached the end of the blob, but with | ||
632 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ | ||
633 | if (ctx.error == ASN1_ERR_DEC_EMPTY) | ||
634 | goto decode_negtoken_exit; | ||
597 | cFYI(1, ("Error decoding last part negTokenInit exit3")); | 635 | cFYI(1, ("Error decoding last part negTokenInit exit3")); |
598 | return 0; | 636 | return 0; |
599 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | 637 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { |
@@ -602,6 +640,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
602 | cls, con, tag, end, *end)); | 640 | cls, con, tag, end, *end)); |
603 | return 0; | 641 | return 0; |
604 | } | 642 | } |
643 | |||
644 | /* sequence */ | ||
605 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 645 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
606 | cFYI(1, ("Error decoding last part negTokenInit exit5")); | 646 | cFYI(1, ("Error decoding last part negTokenInit exit5")); |
607 | return 0; | 647 | return 0; |
@@ -611,6 +651,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
611 | cls, con, tag, end, *end)); | 651 | cls, con, tag, end, *end)); |
612 | } | 652 | } |
613 | 653 | ||
654 | /* sequence of */ | ||
614 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 655 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
615 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); | 656 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); |
616 | return 0; | 657 | return 0; |
@@ -619,6 +660,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
619 | cls, con, tag, end, *end)); | 660 | cls, con, tag, end, *end)); |
620 | return 0; | 661 | return 0; |
621 | } | 662 | } |
663 | |||
664 | /* general string */ | ||
622 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 665 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
623 | cFYI(1, ("Error decoding last part negTokenInit exit9")); | 666 | cFYI(1, ("Error decoding last part negTokenInit exit9")); |
624 | return 0; | 667 | return 0; |
@@ -630,13 +673,13 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
630 | } | 673 | } |
631 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", | 674 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", |
632 | ctx.pointer)); /* is this UTF-8 or ASCII? */ | 675 | ctx.pointer)); /* is this UTF-8 or ASCII? */ |
633 | 676 | decode_negtoken_exit: | |
634 | if (use_kerberos) | 677 | if (use_kerberos) |
635 | *secType = Kerberos; | 678 | *secType = Kerberos; |
636 | else if (use_mskerberos) | 679 | else if (use_mskerberos) |
637 | *secType = MSKerberos; | 680 | *secType = MSKerberos; |
638 | else if (use_ntlmssp) | 681 | else if (use_ntlmssp) |
639 | *secType = NTLMSSP; | 682 | *secType = RawNTLMSSP; |
640 | 683 | ||
641 | return 1; | 684 | return 1; |
642 | } | 685 | } |