Browse Source

[crypto] Expose pem_asn1() for use with non-image data

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
14e3b4b29a
2 changed files with 81 additions and 42 deletions
  1. 74
    41
      src/image/pem.c
  2. 7
    1
      src/include/ipxe/pem.h

+ 74
- 41
src/image/pem.c View File

@@ -27,10 +27,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
27 27
 #include <errno.h>
28 28
 #include <assert.h>
29 29
 #include <ipxe/asn1.h>
30
-#include <ipxe/pem.h>
31 30
 #include <ipxe/base64.h>
32 31
 #include <ipxe/uaccess.h>
33 32
 #include <ipxe/image.h>
33
+#include <ipxe/pem.h>
34 34
 
35 35
 /** @file
36 36
  *
@@ -41,95 +41,98 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
41 41
 /**
42 42
  * Locate next line
43 43
  *
44
- * @v image		PEM image
44
+ * @v data		PEM data
45
+ * @v len		Length of PEM data
45 46
  * @v offset		Starting offset
46 47
  * @ret next		Offset to next line
47 48
  */
48
-static size_t pem_next ( struct image *image, size_t offset ) {
49
+static size_t pem_next ( userptr_t data, size_t len, size_t offset ) {
49 50
 	off_t eol;
50 51
 
51 52
 	/* Find and skip next newline character, if any */
52
-	eol = memchr_user ( image->data, offset, '\n', ( image->len - offset ));
53
+	eol = memchr_user ( data, offset, '\n', ( len - offset ) );
53 54
 	if ( eol < 0 )
54
-		return image->len;
55
+		return len;
55 56
 	return ( eol + 1 );
56 57
 }
57 58
 
58 59
 /**
59 60
  * Locate boundary marker line
60 61
  *
61
- * @v image		PEM image
62
+ * @v data		PEM data
63
+ * @v len		Length of PEM data
62 64
  * @v offset		Starting offset
63 65
  * @v marker		Boundary marker
64 66
  * @ret offset		Offset to boundary marker line, or negative error
65 67
  */
66
-static int pem_marker ( struct image *image, size_t offset,
68
+static int pem_marker ( userptr_t data, size_t len, size_t offset,
67 69
 			const char *marker ) {
68 70
 	char buf[ strlen ( marker ) ];
69 71
 
70 72
 	/* Sanity check */
71
-	assert ( offset <= image->len );
73
+	assert ( offset <= len );
72 74
 
73 75
 	/* Scan for marker at start of line */
74
-	while ( offset < image->len ) {
76
+	while ( offset < len ) {
75 77
 
76 78
 		/* Check for marker */
77
-		if ( ( image->len - offset ) < sizeof ( buf ) )
79
+		if ( ( len - offset ) < sizeof ( buf ) )
78 80
 			break;
79
-		copy_from_user ( buf, image->data, offset, sizeof ( buf ) );
81
+		copy_from_user ( buf, data, offset, sizeof ( buf ) );
80 82
 		if ( memcmp ( buf, marker, sizeof ( buf ) ) == 0 )
81 83
 			return offset;
82 84
 
83 85
 		/* Move to next line */
84
-		offset = pem_next ( image, offset );
85
-		assert ( offset <= image->len );
86
+		offset = pem_next ( data, len, offset );
87
+		assert ( offset <= len );
86 88
 	}
87 89
 
88 90
 	return -ENOENT;
89 91
 }
90 92
 
91 93
 /**
92
- * Extract ASN.1 object from image
94
+ * Extract ASN.1 object from PEM data
93 95
  *
94
- * @v image		PEM image
95
- * @v offset		Offset within image
96
+ * @v data		PEM data
97
+ * @v len		Length of PEM data
98
+ * @v offset		Offset within data
96 99
  * @v cursor		ASN.1 cursor to fill in
97
- * @ret next		Offset to next image, or negative error
100
+ * @ret next		Offset to next object, or negative error
98 101
  *
99 102
  * The caller is responsible for eventually calling free() on the
100 103
  * allocated ASN.1 cursor.
101 104
  */
102
-static int pem_asn1 ( struct image *image, size_t offset,
103
-		      struct asn1_cursor **cursor ) {
105
+int pem_asn1 ( userptr_t data, size_t len, size_t offset,
106
+	       struct asn1_cursor **cursor ) {
104 107
 	size_t encoded_len;
105 108
 	size_t decoded_max_len;
106 109
 	char *encoded;
107 110
 	void *decoded;
111
+	int decoded_len;
108 112
 	int begin;
109 113
 	int end;
110
-	int len;
111 114
 	int rc;
112 115
 
113 116
 	/* Locate and skip BEGIN marker */
114
-	begin = pem_marker ( image, offset, PEM_BEGIN );
117
+	begin = pem_marker ( data, len, offset, PEM_BEGIN );
115 118
 	if ( begin < 0 ) {
116 119
 		rc = begin;
117
-		DBGC ( image, "PEM %s [%#zx,%#zx) missing BEGIN marker: %s\n",
118
-		       image->name, offset, image->len, strerror ( rc ) );
120
+		DBGC ( data, "PEM [%#zx,%#zx) missing BEGIN marker: %s\n",
121
+		       offset, len, strerror ( rc ) );
119 122
 		goto err_begin;
120 123
 	}
121
-	begin = pem_next ( image, begin );
124
+	begin = pem_next ( data, len, begin );
122 125
 
123 126
 	/* Locate and skip END marker */
124
-	end = pem_marker ( image, begin, PEM_END );
127
+	end = pem_marker ( data, len, begin, PEM_END );
125 128
 	if ( end < 0 ) {
126 129
 		rc = end;
127
-		DBGC ( image, "PEM %s [%#zx,%#zx) missing END marker: %s\n",
128
-		       image->name, offset, image->len, strerror ( rc ) );
130
+		DBGC ( data, "PEM [%#zx,%#zx) missing END marker: %s\n",
131
+		       offset, len, strerror ( rc ) );
129 132
 		goto err_end;
130 133
 	}
131 134
 	encoded_len = ( end - begin );
132
-	end = pem_next ( image, end );
135
+	end = pem_next ( data, len, end );
133 136
 
134 137
 	/* Extract Base64-encoded data */
135 138
 	encoded = malloc ( encoded_len + 1 /* NUL */ );
@@ -137,7 +140,7 @@ static int pem_asn1 ( struct image *image, size_t offset,
137 140
 		rc = -ENOMEM;
138 141
 		goto err_alloc_encoded;
139 142
 	}
140
-	copy_from_user ( encoded, image->data, begin, encoded_len );
143
+	copy_from_user ( encoded, data, begin, encoded_len );
141 144
 	encoded[encoded_len] = '\0';
142 145
 
143 146
 	/* Allocate cursor and data buffer */
@@ -150,15 +153,14 @@ static int pem_asn1 ( struct image *image, size_t offset,
150 153
 	decoded = ( ( ( void * ) *cursor ) + sizeof ( **cursor ) );
151 154
 
152 155
 	/* Decode Base64-encoded data */
153
-	len = base64_decode ( encoded, decoded, decoded_max_len );
154
-	if ( len < 0 ) {
155
-		rc = len;
156
-		DBGC ( image, "PEM %s could not decode: %s\n",
157
-		       image->name, strerror ( rc ) );
156
+	decoded_len = base64_decode ( encoded, decoded, decoded_max_len );
157
+	if ( decoded_len < 0 ) {
158
+		rc = decoded_len;
159
+		DBGC ( data, "PEM could not decode: %s\n", strerror ( rc ) );
158 160
 		goto err_decode;
159 161
 	}
160 162
 	(*cursor)->data = decoded;
161
-	(*cursor)->len = len;
163
+	(*cursor)->len = decoded_len;
162 164
 	assert ( (*cursor)->len <= decoded_max_len );
163 165
 
164 166
 	/* Free Base64-encoded data */
@@ -166,8 +168,8 @@ static int pem_asn1 ( struct image *image, size_t offset,
166 168
 
167 169
 	/* Update offset and skip any unencapsulated trailer */
168 170
 	offset = end;
169
-	if ( pem_marker ( image, offset, PEM_BEGIN ) < 0 )
170
-		offset = image->len;
171
+	if ( pem_marker ( data, len, offset, PEM_BEGIN ) < 0 )
172
+		offset = len;
171 173
 
172 174
 	return offset;
173 175
 
@@ -188,11 +190,14 @@ static int pem_asn1 ( struct image *image, size_t offset,
188 190
  * @v image		PEM image
189 191
  * @ret rc		Return status code
190 192
  */
191
-static int pem_probe ( struct image *image ) {
193
+static int pem_image_probe ( struct image *image ) {
194
+	int offset;
192 195
 	int rc;
193 196
 
194 197
 	/* Check that image contains a BEGIN marker */
195
-	if ( ( rc = pem_marker ( image, 0, PEM_BEGIN ) ) < 0 ) {
198
+	if ( ( offset = pem_marker ( image->data, image->len, 0,
199
+				     PEM_BEGIN ) ) < 0 ) {
200
+		rc = offset;
196 201
 		DBGC ( image, "PEM %s has no BEGIN marker: %s\n",
197 202
 		       image->name, strerror ( rc ) );
198 203
 		return rc;
@@ -201,9 +206,37 @@ static int pem_probe ( struct image *image ) {
201 206
 	return 0;
202 207
 }
203 208
 
209
+/**
210
+ * Extract ASN.1 object from image
211
+ *
212
+ * @v image		PEM image
213
+ * @v offset		Offset within image
214
+ * @v cursor		ASN.1 cursor to fill in
215
+ * @ret next		Offset to next image, or negative error
216
+ *
217
+ * The caller is responsible for eventually calling free() on the
218
+ * allocated ASN.1 cursor.
219
+ */
220
+static int pem_image_asn1 ( struct image *image, size_t offset,
221
+			    struct asn1_cursor **cursor ) {
222
+	int next;
223
+	int rc;
224
+
225
+	/* Extract ASN.1 object */
226
+	if ( ( next = pem_asn1 ( image->data, image->len, offset,
227
+				 cursor ) ) < 0 ) {
228
+		rc = next;
229
+		DBGC ( image, "PEM %s could not extract ASN.1: %s\n",
230
+		       image->name, strerror ( rc ) );
231
+		return rc;
232
+	}
233
+
234
+	return next;
235
+}
236
+
204 237
 /** PEM image type */
205 238
 struct image_type pem_image_type __image_type ( PROBE_NORMAL ) = {
206 239
 	.name = "PEM",
207
-	.probe = pem_probe,
208
-	.asn1 = pem_asn1,
240
+	.probe = pem_image_probe,
241
+	.asn1 = pem_image_asn1,
209 242
 };

+ 7
- 1
src/include/ipxe/pem.h View File

@@ -3,12 +3,15 @@
3 3
 
4 4
 /** @file
5 5
  *
6
- * PEM image format
6
+ * PEM-encoded ASN.1 data
7 7
  *
8 8
  */
9 9
 
10 10
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 11
 
12
+#include <stdint.h>
13
+#include <ipxe/uaccess.h>
14
+#include <ipxe/asn1.h>
12 15
 #include <ipxe/image.h>
13 16
 
14 17
 /** Pre-encapsulation boundary marker */
@@ -17,6 +20,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
17 20
 /** Post-encapsulation boundary marker */
18 21
 #define PEM_END "-----END"
19 22
 
23
+extern int pem_asn1 ( userptr_t data, size_t len, size_t offset,
24
+		      struct asn1_cursor **cursor );
25
+
20 26
 extern struct image_type pem_image_type __image_type ( PROBE_NORMAL );
21 27
 
22 28
 #endif /* _IPXE_PEM_H */

Loading…
Cancel
Save