1c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompackage org.bouncycastle.jce.provider;
2c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.IOException;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.io.InputStream;
54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1InputStream;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive;
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1Sequence;
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.encoders.Base64;
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrompublic class PEMUtil
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom{
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private final String _header1;
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private final String _header2;
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private final String _footer1;
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private final String _footer2;
17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    PEMUtil(
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String type)
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _header1 = "-----BEGIN " + type + "-----";
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _header2 = "-----BEGIN X509 " + type + "-----";
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _footer1 = "-----END " + type + "-----";
24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        _footer2 = "-----END X509 " + type + "-----";
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private String readLine(
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        InputStream in)
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int             c;
32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer    l = new StringBuffer();
33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        do
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            while (((c = in.read()) != '\r') && c != '\n' && (c >= 0))
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (c == '\r')
39c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
40c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    continue;
41c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                l.append((char)c);
44c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
45c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
46c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        while (c >= 0 && l.length() == 0);
47c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
48c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (c < 0)
49c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return null;
51c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return l.toString();
54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
55c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    ASN1Sequence readPEMObject(
57c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        InputStream  in)
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throws IOException
59c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
60c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String          line;
61c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer    pemBuf = new StringBuffer();
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        while ((line = readLine(in)) != null)
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (line.startsWith(_header1) || line.startsWith(_header2))
66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                break;
68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
71c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        while ((line = readLine(in)) != null)
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (line.startsWith(_footer1) || line.startsWith(_footer2))
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                break;
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            pemBuf.append(line);
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
81c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (pemBuf.length() != 0)
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o = new ASN1InputStream(Base64.decode(pemBuf.toString())).readObject();
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (!(o instanceof ASN1Sequence))
85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                throw new IOException("malformed PEM data encountered");
87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return (ASN1Sequence)o;
90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return null;
93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom}
95