Produced by Araxis Merge on 9/25/2018 2:13:23 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\security\krb5\internal\crypto\dk | ArcFourCrypto.java | Mon Jan 22 14:46:54 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\security\krb5\internal\crypto\dk | ArcFourCrypto.java | Wed Sep 12 17:52:46 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 11 | 932 |
Changed | 10 | 32 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 200 5, 2008, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package su n.security .krb5.inte rnal.crypt o.dk; | |
27 | ||
28 | import jav a.security .*; | |
29 | import jav ax.crypto. *; | |
30 | import jav ax.crypto. spec.*; | |
31 | import jav a.util.*; | |
32 | import sun .security. krb5.Encry ptedData; | |
33 | import sun .security. krb5.KrbCr yptoExcept ion; | |
34 | import sun .security. krb5.Confo under; | |
35 | import sun .security. krb5.inter nal.crypto .KeyUsage; | |
36 | ||
37 | /** | |
38 | * Support for ArcFo ur in Kerb eros | |
39 | * as defi ned in RFC 4757. | |
40 | * http:// www.ietf.o rg/rfc/rfc 4757.txt | |
41 | * | |
42 | * @author Seema Mal kani | |
43 | */ | |
44 | ||
45 | public cla ss ArcFour Crypto ext ends DkCry pto { | |
46 | ||
47 | privat e static f inal boole an debug = false; | |
48 | ||
49 | privat e static f inal int c onfounderS ize = 8; | |
50 | privat e static f inal byte[ ] ZERO_IV = new byte [] {0, 0, 0, 0, 0, 0 , 0, 0}; | |
51 | privat e static f inal int h ashSize = 16; | |
52 | privat e final in t keyLengt h; | |
53 | ||
54 | public ArcFourCr ypto(int l ength) { | |
55 | ke yLength = length; | |
56 | } | |
57 | ||
58 | protec ted int ge tKeySeedLe ngth() { | |
59 | re turn keyLe ngth; // bits; RC4 key mater ial | |
60 | } | |
61 | ||
62 | protec ted byte[] randomToK ey(byte[] in) { | |
63 | // simple id entity ope ration | |
64 | re turn in; | |
65 | } | |
66 | ||
67 | public byte[] st ringToKey( char[] pas swd) | |
68 | th rows Gener alSecurity Exception { | |
69 | re turn strin gToKey(pas swd, null) ; | |
70 | } | |
71 | ||
72 | /* | |
73 | * Str ing2Key(Pa ssword) | |
74 | * K = MD4(UNICO DE(passwor d)) | |
75 | */ | |
76 | private by te[] strin gToKey(cha r[] PW , byte[] o paque) | |
77 | th rows Gener alSecurity Exception { | |
78 | ||
79 | if (opaque ! = null && opaque.len gth > 0) { | |
80 | throw ne w RuntimeE xception(" Invalid pa rameter to stringToK ey"); | |
81 | } | |
82 | ||
83 | by te[] passw d = null; | |
84 | by te[] diges t = null; | |
85 | tr y { | |
86 | // conve rt ascii t o unicode | |
87 | passwd = c harToUtf16 ( PW ); | |
88 | ||
89 | // provi der for MD 4 | |
90 | MessageD igest md = sun.secur ity.provid er.MD4.get Instance() ; | |
91 | md.updat e(passwd); | |
92 | digest = md.digest (); | |
93 | } catch (Exc eption e) { | |
94 | return n ull; | |
95 | } finally { | |
96 | if (pass wd != null ) { | |
97 | Arra ys.fill(pa sswd, (byt e)0); | |
98 | } | |
99 | } | |
100 | ||
101 | re turn diges t; | |
102 | } | |
103 | ||
104 | protec ted Cipher getCipher (byte[] ke y, byte[] ivec, int mode) | |
105 | th rows Gener alSecurity Exception { | |
106 | ||
107 | // IV | |
108 | if (ivec == null) { | |
109 | ivec = ZE RO_IV; | |
110 | } | |
111 | SecretKeyS pec PW Key = new SecretKeyS pec(key, " ARCFOUR"); | |
112 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
113 | Iv ParameterS pec encIv = new IvPa rameterSpe c(ivec, 0, ivec.leng th); | |
114 | cipher.ini t(mode, PW Key, encIv ); | |
115 | re turn ciphe r; | |
116 | } | |
117 | ||
118 | public int getCh ecksumLeng th() { | |
119 | re turn hashS ize; // b ytes | |
120 | } | |
121 | ||
122 | /** | |
123 | * Get the HMAC- MD5 | |
124 | */ | |
125 | protec ted byte[] getHmac(b yte[] key, byte[] ms g) | |
126 | th rows Gener alSecurity Exception { | |
127 | ||
128 | Se cretKey ke yKi = new SecretKeyS pec(key, " HmacMD5"); | |
129 | Ma c m = Mac. getInstanc e("HmacMD5 "); | |
130 | m. init(keyKi ); | |
131 | ||
132 | // generate hash | |
133 | by te[] hash = m.doFina l(msg); | |
134 | re turn hash; | |
135 | } | |
136 | ||
137 | /** | |
138 | * Cal culate the checksum | |
139 | */ | |
140 | public byte[] ca lculateChe cksum(byte [] baseKey , int usag e, byte[] input, | |
141 | in t start, i nt len) th rows Gener alSecurity Exception { | |
142 | ||
143 | if (debug) { | |
144 | System.o ut.println ("ARCFOUR: calculate Checksum w ith usage = " + | |
145 | us age); | |
146 | } | |
147 | ||
148 | if (!KeyUsag e.isValid( usage)) { | |
149 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
150 | + usage); | |
151 | } | |
152 | ||
153 | by te[] Ksign = null; | |
154 | // Derive si gning key from sessi on key | |
155 | tr y { | |
156 | byte[] ss = "signat urekey".ge tBytes(); | |
157 | // need t o append e nd-of-stri ng 00 | |
158 | byte[] ne w_ss = new byte[ss.l ength+1]; | |
159 | System.ar raycopy(ss , 0, new_s s, 0, ss.l ength); | |
160 | Ksign = g etHmac(bas eKey, new_ ss); | |
161 | } catch (Exc eption e) { | |
162 | GeneralS ecurityExc eption gse = | |
163 | new GeneralSec urityExcep tion("Calc ulate Chec kum Failed !"); | |
164 | gse.init Cause(e); | |
165 | throw gs e; | |
166 | } | |
167 | ||
168 | // get the s alt using key usage | |
169 | by te[] salt = getSalt( usage); | |
170 | ||
171 | // Generate checksum o f message | |
172 | Me ssageDiges t messageD igest = nu ll; | |
173 | tr y { | |
174 | messageD igest = Me ssageDiges t.getInsta nce("MD5") ; | |
175 | } catch (NoS uchAlgorit hmExceptio n e) { | |
176 | GeneralS ecurityExc eption gse = | |
177 | new GeneralSec urityExcep tion("Calc ulate Chec kum Failed !"); | |
178 | gse.init Cause(e); | |
179 | throw gs e; | |
180 | } | |
181 | me ssageDiges t.update(s alt); | |
182 | me ssageDiges t.update(i nput, star t, len); | |
183 | by te[] md5tm p = messag eDigest.di gest(); | |
184 | ||
185 | // Generate checksum | |
186 | by te[] hmac = getHmac( Ksign, md5 tmp); | |
187 | if (debug) { | |
188 | traceOut put("hmac" , hmac, 0, hmac.leng th); | |
189 | } | |
190 | if (hmac.len gth == get ChecksumLe ngth()) { | |
191 | return h mac; | |
192 | } else if (h mac.length > getChec ksumLength ()) { | |
193 | byte[] b uf = new b yte[getChe cksumLengt h()]; | |
194 | System.a rraycopy(h mac, 0, bu f, 0, buf. length); | |
195 | return b uf; | |
196 | } else { | |
197 | throw ne w GeneralS ecurityExc eption("ch ecksum siz e too shor t: " + | |
198 | hmac.l ength + "; expecting : " + get ChecksumLe ngth()); | |
199 | } | |
200 | } | |
201 | ||
202 | /** | |
203 | * Per forms encr yption of Sequence N umber usin g derived key. | |
204 | */ | |
205 | public byte[] en cryptSeq(b yte[] base Key, int u sage, | |
206 | by te[] check sum, byte[ ] plaintex t, int sta rt, int le n) | |
207 | th rows Gener alSecurity Exception, KrbCrypto Exception { | |
208 | ||
209 | if (!KeyUsag e.isValid( usage)) { | |
210 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
211 | + usage); | |
212 | } | |
213 | // derive en cryption f or sequenc e number | |
214 | by te[] salt = new byte [4]; | |
215 | by te[] kSeq = getHmac( baseKey, s alt); | |
216 | ||
217 | // derive ne w encrypti on key sal ted with s equence nu mber | |
218 | kS eq = getHm ac(kSeq, c hecksum); | |
219 | ||
220 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
221 | SecretKeyS pec PW Key = new SecretKeyS pec(kSeq, "ARCFOUR") ; | |
222 | cipher.ini t(Cipher.E NCRYPT_MOD E, PW Key); | |
223 | by te[] outpu t = cipher .doFinal(p laintext, start, len ); | |
224 | ||
225 | re turn outpu t; | |
226 | } | |
227 | ||
228 | /** | |
229 | * Per forms decr yption of Sequence N umber usin g derived key. | |
230 | */ | |
231 | public byte[] de cryptSeq(b yte[] base Key, int u sage, | |
232 | by te[] check sum, byte[ ] cipherte xt, int st art, int l en) | |
233 | th rows Gener alSecurity Exception, KrbCrypto Exception { | |
234 | ||
235 | if (!KeyUsag e.isValid( usage)) { | |
236 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
237 | + usage); | |
238 | } | |
239 | ||
240 | // derive de cryption f or sequenc e number | |
241 | by te[] salt = new byte [4]; | |
242 | by te[] kSeq = getHmac( baseKey, s alt); | |
243 | ||
244 | // derive ne w encrypti on key sal ted with s equence nu mber | |
245 | kS eq = getHm ac(kSeq, c hecksum); | |
246 | ||
247 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
248 | SecretKeyS pec PW Key = new SecretKeyS pec(kSeq, "ARCFOUR") ; | |
249 | cipher.ini t(Cipher.D ECRYPT_MOD E, PW Key); | |
250 | by te[] outpu t = cipher .doFinal(c iphertext, start, le n); | |
251 | ||
252 | re turn outpu t; | |
253 | } | |
254 | ||
255 | /** | |
256 | * Per forms encr yption usi ng derived key; adds confounde r. | |
257 | */ | |
258 | public byte[] en crypt(byte [] baseKey , int usag e, | |
259 | by te[] ivec, byte[] ne w_ivec, by te[] plain text, int start, int len) | |
260 | th rows Gener alSecurity Exception, KrbCrypto Exception { | |
261 | ||
262 | if (!KeyUsag e.isValid( usage)) { | |
263 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
264 | + usage); | |
265 | } | |
266 | ||
267 | if (debug) { | |
268 | System.o ut.println ("ArcFour: ENCRYPT w ith key us age = " + usage); | |
269 | } | |
270 | ||
271 | // get the c onfounder | |
272 | by te[] confo under = Co nfounder.b ytes(confo underSize) ; | |
273 | ||
274 | // add confo under to t he plainte xt for enc ryption | |
275 | in t plainSiz e = roundu p(confound er.length + len, 1); | |
276 | by te[] toBeE ncrypted = new byte[ plainSize] ; | |
277 | Sy stem.array copy(confo under, 0, toBeEncryp ted, 0, co nfounder.l ength); | |
278 | Sy stem.array copy(plain text, star t, toBeEnc rypted, | |
279 | confound er.length, len); | |
280 | ||
281 | /* begin the encryptio n, compute K1 */ | |
282 | by te[] k1 = new byte[b aseKey.len gth]; | |
283 | Sy stem.array copy(baseK ey, 0, k1, 0, baseKe y.length); | |
284 | ||
285 | // get the s alt using key usage | |
286 | by te[] salt = getSalt( usage); | |
287 | ||
288 | // compute K 2 using K1 | |
289 | by te[] k2 = getHmac(k1 , salt); | |
290 | ||
291 | // generate checksum u sing K2 | |
292 | by te[] check sum = getH mac(k2, to BeEncrypte d); | |
293 | ||
294 | // compute K 3 using K2 and check sum | |
295 | by te[] k3 = getHmac(k2 , checksum ); | |
296 | ||
297 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
298 | SecretKeyS pec PW Key = new SecretKeyS pec(k3, "A RCFOUR"); | |
299 | cipher.ini t(Cipher.E NCRYPT_MOD E, PW Key); | |
300 | by te[] outpu t = cipher .doFinal(t oBeEncrypt ed, 0, toB eEncrypted .length); | |
301 | ||
302 | // encrypted Data + HMA C | |
303 | by te[] resul t = new by te[hashSiz e + output .length]; | |
304 | Sy stem.array copy(check sum, 0, re sult, 0, h ashSize); | |
305 | Sy stem.array copy(outpu t, 0, resu lt, hashSi ze, output .length); | |
306 | ||
307 | re turn resul t; | |
308 | } | |
309 | ||
310 | /** | |
311 | * Per forms encr yption usi ng derived key; does not add c onfounder. | |
312 | */ | |
313 | public byte[] en cryptRaw(b yte[] base Key, int u sage, | |
314 | by te[] seqNu m, byte[] plaintext, int start , int len) | |
315 | th rows Gener alSecurity Exception, KrbCrypto Exception { | |
316 | ||
317 | if (!KeyUsag e.isValid( usage)) { | |
318 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
319 | + usage); | |
320 | } | |
321 | ||
322 | if (debug) { | |
323 | System.o ut.println ("\nARCFOU R: encrypt Raw with u sage = " + usage); | |
324 | } | |
325 | ||
326 | // Derive en cryption k ey for dat a | |
327 | // Key der ivation sa lt = 0 | |
328 | by te[] kloca l = new by te[baseKey .length]; | |
329 | fo r (int i = 0; i <= 1 5; i++) { | |
330 | klocal[i ] = (byte) (baseKey[ i] ^ 0xF0) ; | |
331 | } | |
332 | by te[] salt = new byte [4]; | |
333 | by te[] kcryp t = getHma c(klocal, salt); | |
334 | ||
335 | // Note: Whe n using th is RC4 bas ed encrypt ion type, the sequen ce number | |
336 | // is always sent in b ig-endian rather tha n little-e ndian orde r. | |
337 | ||
338 | // new encry ption key salted wit h sequence number | |
339 | kc rypt = get Hmac(kcryp t, seqNum) ; | |
340 | ||
341 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
342 | SecretKeyS pec PW Key = new SecretKeyS pec(kcrypt , "ARCFOUR "); | |
343 | cipher.ini t(Cipher.E NCRYPT_MOD E, PW Key); | |
344 | by te[] outpu t = cipher .doFinal(p laintext, start, len ); | |
345 | ||
346 | re turn outpu t; | |
347 | } | |
348 | ||
349 | /** | |
350 | * @pa ram baseKe y key from which key s are to b e derived using usag e | |
351 | * @pa ram cipher text E(Ke , conf | p laintext | padding, ivec) | H1 [1..h] | |
352 | */ | |
353 | public byte[] de crypt(byte [] baseKey , int usag e, byte[] ivec, | |
354 | by te[] ciphe rtext, int start, in t len) | |
355 | th rows Gener alSecurity Exception { | |
356 | ||
357 | if (!KeyUsag e.isValid( usage)) { | |
358 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
359 | + usage); | |
360 | } | |
361 | if (debug) { | |
362 | System.o ut.println ("\nARCFOU R: DECRYPT using key usage = " + usage); | |
363 | } | |
364 | ||
365 | // compute K 1 | |
366 | by te[] k1 = new byte[b aseKey.len gth]; | |
367 | Sy stem.array copy(baseK ey, 0, k1, 0, baseKe y.length); | |
368 | ||
369 | // get the s alt using key usage | |
370 | by te[] salt = getSalt( usage); | |
371 | ||
372 | // compute K 2 using K1 | |
373 | by te[] k2 = getHmac(k1 , salt); | |
374 | ||
375 | // compute K 3 using K2 and check sum | |
376 | by te[] check sum = new byte[hashS ize]; | |
377 | Sy stem.array copy(ciphe rtext, sta rt, checks um, 0, has hSize); | |
378 | by te[] k3 = getHmac(k2 , checksum ); | |
379 | ||
380 | // Decrypt [ confounder | plainte xt ] (with out checks um) | |
381 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
382 | SecretKeyS pec PW Key = new SecretKeyS pec(k3, "A RCFOUR"); | |
383 | cipher.ini t(Cipher.D ECRYPT_MOD E, PW Key); | |
384 | by te[] plain text = cip her.doFina l(cipherte xt, start+ hashSize, | |
385 | le n-hashSize ); | |
386 | ||
387 | // Verify ch ecksum | |
388 | by te[] calcu latedHmac = getHmac( k2, plaint ext); | |
389 | if (debug) { | |
390 | traceOut put("calcu lated Hmac ", calcula tedHmac, 0 , | |
391 | calculat edHmac.len gth); | |
392 | traceOut put("messa ge Hmac", ciphertext , 0, | |
393 | hashSize ); | |
394 | } | |
395 | bo olean cksu mFailed = false; | |
396 | if (calculat edHmac.len gth >= has hSize) { | |
397 | for (int i = 0; i < hashSize ; i++) { | |
398 | if ( calculated Hmac[i] != ciphertex t[i]) { | |
399 | cksumFaile d = true; | |
400 | if (debug) { | |
401 | System .err.print ln("Checks um failed !"); | |
402 | } | |
403 | break; | |
404 | } | |
405 | } | |
406 | } | |
407 | if (cksumFai led) { | |
408 | throw ne w GeneralS ecurityExc eption("Ch ecksum fai led"); | |
409 | } | |
410 | ||
411 | // Get rid o f confound er | |
412 | // [ confoun der | plai ntext ] | |
413 | by te[] outpu t = new by te[plainte xt.length - confound erSize]; | |
414 | Sy stem.array copy(plain text, conf ounderSize , output, 0, output. length); | |
415 | ||
416 | re turn outpu t; | |
417 | } | |
418 | ||
419 | /** | |
420 | * Dec rypts data using spe cified key and initi al vector. | |
421 | * @pa ram baseKe y encrypti on key to use | |
422 | * @pa ram cipher text encr ypted data to be dec rypted | |
423 | * @pa ram usage ignored | |
424 | */ | |
425 | public byte[] de cryptRaw(b yte[] base Key, int u sage, byte [] ivec, | |
426 | by te[] ciphe rtext, int start, in t len, byt e[] seqNum ) | |
427 | th rows Gener alSecurity Exception { | |
428 | ||
429 | if (!KeyUsag e.isValid( usage)) { | |
430 | throw ne w GeneralS ecurityExc eption("In valid key usage numb er: " | |
431 | + usage); | |
432 | } | |
433 | if (debug) { | |
434 | System.o ut.println ("\nARCFOU R: decrypt Raw with u sage = " + usage); | |
435 | } | |
436 | ||
437 | // Derive en cryption k ey for dat a | |
438 | // Key der ivation sa lt = 0 | |
439 | by te[] kloca l = new by te[baseKey .length]; | |
440 | fo r (int i = 0; i <= 1 5; i++) { | |
441 | klocal[i ] = (byte) (baseKey[ i] ^ 0xF0) ; | |
442 | } | |
443 | by te[] salt = new byte [4]; | |
444 | by te[] kcryp t = getHma c(klocal, salt); | |
445 | ||
446 | // need only first 4 b ytes of se quence num ber | |
447 | by te[] seque nceNum = n ew byte[4] ; | |
448 | Sy stem.array copy(seqNu m, 0, sequ enceNum, 0 , sequence Num.length ); | |
449 | ||
450 | // new encry ption key salted wit h sequence number | |
451 | kc rypt = get Hmac(kcryp t, sequenc eNum); | |
452 | ||
453 | Ci pher ciphe r = Cipher .getInstan ce("ARCFOU R"); | |
454 | SecretKeyS pec PW Key = new SecretKeyS pec(kcrypt , "ARCFOUR "); | |
455 | cipher.ini t(Cipher.D ECRYPT_MOD E, PW Key); | |
456 | by te[] outpu t = cipher .doFinal(c iphertext, start, le n); | |
457 | ||
458 | re turn outpu t; | |
459 | } | |
460 | ||
461 | // get the salt using key usage | |
462 | privat e byte[] g etSalt(int usage) { | |
463 | in t ms_usage = arcfour _translate _usage(usa ge); | |
464 | by te[] salt = new byte [4]; | |
465 | sa lt[0] = (b yte)(ms_us age & 0xff ); | |
466 | sa lt[1] = (b yte)((ms_u sage >> 8) & 0xff); | |
467 | sa lt[2] = (b yte)((ms_u sage >> 16 ) & 0xff); | |
468 | sa lt[3] = (b yte)((ms_u sage >> 24 ) & 0xff); | |
469 | re turn salt; | |
470 | } | |
471 | ||
472 | // Key usage tra nslation f or MS | |
473 | privat e int arcf our_transl ate_usage( int usage) { | |
474 | sw itch (usag e) { | |
475 | case 3: return 8; | |
476 | case 9: return 8; | |
477 | case 23: return 13 ; | |
478 | default: return us age; | |
479 | } | |
480 | } | |
481 | ||
482 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.