1 // Copyright 2015 The Chromium Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "extended_key_usage.h"
16 
17 #include <openssl/bytestring.h>
18 
19 #include "input.h"
20 #include "parser.h"
21 
22 BSSL_NAMESPACE_BEGIN
23 
ParseEKUExtension(der::Input extension_value,std::vector<der::Input> * eku_oids)24 bool ParseEKUExtension(der::Input extension_value,
25                        std::vector<der::Input> *eku_oids) {
26   der::Parser extension_parser(extension_value);
27   der::Parser sequence_parser;
28   if (!extension_parser.ReadSequence(&sequence_parser)) {
29     return false;
30   }
31 
32   // Section 4.2.1.12 of RFC 5280 defines ExtKeyUsageSyntax as:
33   // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
34   //
35   // Therefore, the sequence must contain at least one KeyPurposeId.
36   if (!sequence_parser.HasMore()) {
37     return false;
38   }
39   while (sequence_parser.HasMore()) {
40     der::Input eku_oid;
41     if (!sequence_parser.ReadTag(CBS_ASN1_OBJECT, &eku_oid)) {
42       // The SEQUENCE OF must contain only KeyPurposeIds (OIDs).
43       return false;
44     }
45     eku_oids->push_back(eku_oid);
46   }
47   if (extension_parser.HasMore()) {
48     // The extension value must follow ExtKeyUsageSyntax - there is no way that
49     // it could be extended to allow for something after the SEQUENCE OF.
50     return false;
51   }
52   return true;
53 }
54 
55 BSSL_NAMESPACE_END
56