Git init
[external/xmlsec1.git] / src / nss / bignum.c
1 /** 
2  * XMLSec library
3  * 
4  * Reading/writing bignum values
5  * 
6  * This is free software; see Copyright file in the source
7  * distribution for precise wording.
8  * 
9  * Copyright (c) 2003 America Online, Inc.  All rights reserved.
10  */
11 #include "globals.h"
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include <nss.h> 
17 #include <secitem.h> 
18
19 #include <libxml/tree.h> 
20
21 #include <xmlsec/xmlsec.h>
22 #include <xmlsec/buffer.h>
23 #include <xmlsec/base64.h>
24 #include <xmlsec/errors.h>
25
26 #include <xmlsec/nss/crypto.h>
27 #include <xmlsec/nss/bignum.h>
28
29 /**
30  * xmlSecNssNodeGetBigNumValue:
31  * @arena: the arena from which to allocate memory
32  * @cur: the poitner to an XML node.
33  * @a: a SECItem object to hold the BigNum value
34  *
35  * Converts the node content from CryptoBinary format 
36  * (http://www.w3.org/TR/xmldsig-core/#sec-CryptoBinary) 
37  * to a SECItem. If no SECItem object provided then a new
38  * one is created (caller is responsible for freeing it).
39  *
40  * Returns: a pointer to SECItem produced from CryptoBinary string
41  * or NULL if an error occurs.
42  */
43 SECItem *
44 xmlSecNssNodeGetBigNumValue(PRArenaPool *arena, const xmlNodePtr cur, 
45                             SECItem *a) {
46     xmlSecBuffer buf;
47     int ret;
48     SECItem *rv;
49     int len;
50
51     xmlSecAssert2(arena != NULL, NULL);
52     xmlSecAssert2(cur != NULL, NULL);
53
54     ret = xmlSecBufferInitialize(&buf, 128);
55     if(ret < 0) {
56         xmlSecError(XMLSEC_ERRORS_HERE,
57                     NULL,
58                     "xmlSecBufferInitialize",
59                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
60                     XMLSEC_ERRORS_NO_MESSAGE);
61         return(NULL);
62     }    
63     
64     ret = xmlSecBufferBase64NodeContentRead(&buf, cur);
65     if(ret < 0) {
66         xmlSecError(XMLSEC_ERRORS_HERE,
67                     NULL,
68                     "xmlSecBufferBase64NodeContentRead",
69                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
70                     XMLSEC_ERRORS_NO_MESSAGE);
71         xmlSecBufferFinalize(&buf);
72         return(NULL);
73     }    
74     
75     len = xmlSecBufferGetSize(&buf);
76
77     if (a == NULL) {
78         rv = SECITEM_AllocItem(arena, NULL, len);
79     } else {
80         rv = a;
81         xmlSecAssert2(rv->data == NULL, NULL);
82         rv->len = len;
83         rv->data = PORT_ArenaZAlloc(arena, len);
84     }
85         
86     PORT_Memcpy(rv->data, xmlSecBufferGetData(&buf), len);
87
88     xmlSecBufferFinalize(&buf);
89     return(rv);
90 }
91
92 /**
93  * xmlSecNssNodeSetBigNumValue:
94  * @cur: the pointer to an XML node.
95  * @a: a SECItem containing the BigNum value.
96  * @addLineBreaks: if the flag is equal to 1 then 
97  *              linebreaks will be added before and after
98  *              new buffer content.
99  *
100  * Converts SECItem to CryptoBinary string
101  * (http://www.w3.org/TR/xmldsig-core/#sec-CryptoBinary) 
102  * and sets it as the content of the given node. If the 
103  * addLineBreaks is set then line breaks are added 
104  * before and after the CryptoBinary string.
105  * 
106  * Returns: 0 on success or -1 otherwise.
107  */
108 int
109 xmlSecNssNodeSetBigNumValue(xmlNodePtr cur, const SECItem *a, int addLineBreaks) {
110     xmlSecBuffer buf;
111     int ret;
112     
113     xmlSecAssert2(a != NULL, -1);
114     xmlSecAssert2(cur != NULL, -1);
115
116     ret = xmlSecBufferInitialize(&buf, a->len + 1);
117     if(ret < 0) {
118         xmlSecError(XMLSEC_ERRORS_HERE,
119                     NULL,
120                     "xmlSecBufferInitialize",
121                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
122                     "size=%d", a->len + 1);
123         return(-1);
124     }    
125
126     PORT_Memcpy(xmlSecBufferGetData(&buf), a->data, a->len);
127     
128     ret = xmlSecBufferSetSize(&buf, a->len);
129     if(ret < 0) {
130         xmlSecError(XMLSEC_ERRORS_HERE,
131                     NULL,
132                     "xmlSecBufferSetSize",
133                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
134                     "size=%d", a->len);
135         xmlSecBufferFinalize(&buf);
136         return(-1);
137     }
138
139     if(addLineBreaks) {
140         xmlNodeSetContent(cur, xmlSecStringCR);
141     } else {
142         xmlNodeSetContent(cur, xmlSecStringEmpty);
143     }
144     
145     ret = xmlSecBufferBase64NodeContentWrite(&buf, cur, xmlSecBase64GetDefaultLineSize());
146     if(ret < 0) {
147         xmlSecError(XMLSEC_ERRORS_HERE,
148                     NULL,
149                     "xmlSecBufferBase64NodeContentWrite",
150                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
151                     XMLSEC_ERRORS_NO_MESSAGE);
152         xmlSecBufferFinalize(&buf);
153         return(-1);
154     }
155
156     if(addLineBreaks) {
157         xmlNodeAddContent(cur, xmlSecStringCR);
158     }
159
160     xmlSecBufferFinalize(&buf);
161     return(0);
162 }
163