updated copyright statement
[strongswan.git] / src / pluto / pem.c
1 /* Loading of PEM encoded files with optional encryption
2 * Copyright (C) 2001-2009 Andreas Steffen
3 *
4 * HSR Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /* decrypt a PEM encoded data block using DES-EDE3-CBC
18 * see RFC 1423 PEM: Algorithms, Modes and Identifiers
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stddef.h>
27 #include <sys/types.h>
28
29 #include <freeswan.h>
30
31 #include <library.h>
32 #include <asn1/pem.h>
33
34 #include "constants.h"
35 #include "defs.h"
36 #include "log.h"
37 #include "whack.h"
38 #include "pem.h"
39
40 /**
41 * Converts a PEM encoded file into its binary form
42 * RFC 1421 Privacy Enhancement for Electronic Mail, February 1993
43 * RFC 934 Message Encapsulation, January 1985
44 */
45 err_t pemtobin(chunk_t *blob, prompt_pass_t *pass, const char* label, bool *pgp)
46 {
47 chunk_t password = chunk_empty;
48
49 /* do we prompt for the passphrase? */
50 if (pass && pass->prompt && pass->fd != NULL_FD)
51 {
52 int i;
53 chunk_t blob_copy;
54 err_t ugh = "invalid passphrase, too many trials";
55 status_t status;
56
57 whack_log(RC_ENTERSECRET, "need passphrase for '%s'", label);
58
59 for (i = 0; i < MAX_PROMPT_PASS_TRIALS; i++)
60 {
61 int n;
62
63 if (i > 0)
64 {
65 whack_log(RC_ENTERSECRET, "invalid passphrase, please try again");
66 }
67 n = read(pass->fd, pass->secret, PROMPT_PASS_LEN);
68
69 if (n == -1)
70 {
71 err_t ugh = "read(whackfd) failed";
72
73 whack_log(RC_LOG_SERIOUS,ugh);
74 return ugh;
75 }
76
77 pass->secret[n-1] = '\0';
78
79 if (strlen(pass->secret) == 0)
80 {
81 err_t ugh = "no passphrase entered, aborted";
82
83 whack_log(RC_LOG_SERIOUS, ugh);
84 return ugh;
85 }
86
87 blob_copy = chunk_clone(*blob);
88 password = chunk_create(pass->secret, strlen(pass->secret));
89
90 status = pem_to_bin(blob, password, pgp);
91 if (status != INVALID_ARG)
92 {
93 if (status == SUCCESS)
94 {
95 whack_log(RC_SUCCESS, "valid passphrase");
96 }
97 else
98 {
99 whack_log(RC_LOG_SERIOUS, "%N, aborted", status_names, status);
100 }
101 free(blob_copy.ptr);
102 return NULL;
103 }
104
105 /* blob is useless after wrong decryption, restore the original */
106 free(blob->ptr);
107 *blob = blob_copy;
108 }
109 whack_log(RC_LOG_SERIOUS, ugh);
110 return ugh;
111 }
112 else
113 {
114 if (pass)
115 {
116 password = chunk_create(pass->secret, strlen(pass->secret));
117 }
118 if (pem_to_bin(blob, password, pgp) == SUCCESS)
119 {
120 return NULL;
121 }
122 else
123 {
124 return "pem to bin conversion failed";
125 }
126 }
127 }